]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/PrePi/PrePi.c
ArmPkg/ArmCpuLib: Replaced complex functions ArmCpuSynchronizeWait & ArmCpuSynchroniz...
[mirror_edk2.git] / ArmPlatformPkg / PrePi / PrePi.c
1 /** @file
2 *
3 * Copyright (c) 2011-2012, ARM Limited. All rights reserved.
4 *
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14
15 #include <PiPei.h>
16
17 #include <Library/DebugAgentLib.h>
18 #include <Library/PrePiLib.h>
19 #include <Library/PrintLib.h>
20 #include <Library/PeCoffGetEntryPointLib.h>
21 #include <Library/PrePiHobListPointerLib.h>
22 #include <Library/TimerLib.h>
23 #include <Library/PerformanceLib.h>
24
25 #include <Ppi/GuidedSectionExtraction.h>
26 #include <Guid/LzmaDecompress.h>
27 #include <Guid/ArmGlobalVariableHob.h>
28
29 #include "PrePi.h"
30 #include "LzmaDecompress.h"
31
32 #define IS_XIP() (((UINT32)FixedPcdGet32 (PcdFdBaseAddress) > (UINT32)(FixedPcdGet32 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemorySize))) || \
33 ((FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet32 (PcdSystemMemoryBase)))
34
35 // Not used when PrePi in run in XIP mode
36 UINTN mGlobalVariableBase = 0;
37
38 VOID
39 PrePiCommonExceptionEntry (
40 IN UINT32 Entry,
41 IN UINT32 LR
42 );
43
44 EFI_STATUS
45 EFIAPI
46 ExtractGuidedSectionLibConstructor (
47 VOID
48 );
49
50 EFI_STATUS
51 EFIAPI
52 LzmaDecompressLibConstructor (
53 VOID
54 );
55
56 VOID
57 EFIAPI
58 BuildGlobalVariableHob (
59 IN EFI_PHYSICAL_ADDRESS GlobalVariableBase,
60 IN UINT32 GlobalVariableSize
61 )
62 {
63 ARM_HOB_GLOBAL_VARIABLE *Hob;
64
65 Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, sizeof (ARM_HOB_GLOBAL_VARIABLE));
66 ASSERT(Hob != NULL);
67
68 CopyGuid (&(Hob->Header.Name), &gArmGlobalVariableGuid);
69 Hob->GlobalVariableBase = GlobalVariableBase;
70 Hob->GlobalVariableSize = GlobalVariableSize;
71 }
72
73 VOID
74 PrePiMain (
75 IN UINTN UefiMemoryBase,
76 IN UINTN StacksBase,
77 IN UINTN GlobalVariableBase,
78 IN UINT64 StartTimeStamp
79 )
80 {
81 EFI_HOB_HANDOFF_INFO_TABLE* HobList;
82 EFI_STATUS Status;
83 CHAR8 Buffer[100];
84 UINTN CharCount;
85 UINTN StacksSize;
86
87 // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
88 ASSERT (IS_XIP() ||
89 ((FixedPcdGet32 (PcdFdBaseAddress) >= FixedPcdGet32 (PcdSystemMemoryBase)) &&
90 ((UINT32)(FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT32)(FixedPcdGet32 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemorySize)))));
91
92 // Enable program flow prediction, if supported.
93 ArmEnableBranchPrediction ();
94
95 if (FixedPcdGet32(PcdVFPEnabled)) {
96 ArmEnableVFP();
97 }
98
99 // Initialize the Serial Port
100 SerialPortInitialize ();
101 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
102 (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
103 SerialPortWrite ((UINT8 *) Buffer, CharCount);
104
105 // Initialize the Debug Agent for Source Level Debugging
106 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
107 SaveAndSetDebugTimerInterrupt (TRUE);
108
109 // Declare the PI/UEFI memory region
110 HobList = HobConstructor (
111 (VOID*)UefiMemoryBase,
112 FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
113 (VOID*)UefiMemoryBase,
114 (VOID*)StacksBase // The top of the UEFI Memory is reserved for the stacks
115 );
116 PrePeiSetHobList (HobList);
117
118 // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
119 Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
120 ASSERT_EFI_ERROR (Status);
121
122 // Create the Stacks HOB (reserve the memory for all stacks)
123 if (ArmIsMpCore ()) {
124 StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) + (FixedPcdGet32(PcdClusterCount) * 4 * FixedPcdGet32(PcdCPUCoreSecondaryStackSize));
125 } else {
126 StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
127 }
128 BuildStackHob (StacksBase, StacksSize);
129
130 // Declare the Global Variable HOB
131 BuildGlobalVariableHob (GlobalVariableBase, FixedPcdGet32 (PcdPeiGlobalVariableSize));
132
133 //TODO: Call CpuPei as a library
134 BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
135
136 // Set the Boot Mode
137 SetBootMode (ArmPlatformGetBootMode ());
138
139 // Initialize Platform HOBs (CpuHob and FvHob)
140 Status = PlatformPeim ();
141 ASSERT_EFI_ERROR (Status);
142
143 // Now, the HOB List has been initialized, we can register performance information
144 PERF_START (NULL, "PEI", NULL, StartTimeStamp);
145
146 // SEC phase needs to run library constructors by hand.
147 ExtractGuidedSectionLibConstructor ();
148 LzmaDecompressLibConstructor ();
149
150 // Build HOBs to pass up our version of stuff the DXE Core needs to save space
151 BuildPeCoffLoaderHob ();
152 BuildExtractSectionHob (
153 &gLzmaCustomDecompressGuid,
154 LzmaGuidedSectionGetInfo,
155 LzmaGuidedSectionExtraction
156 );
157
158 // Assume the FV that contains the SEC (our code) also contains a compressed FV.
159 Status = DecompressFirstFv ();
160 ASSERT_EFI_ERROR (Status);
161
162 // Load the DXE Core and transfer control to it
163 Status = LoadDxeCoreFromFv (NULL, 0);
164 ASSERT_EFI_ERROR (Status);
165 }
166
167 VOID
168 CEntryPoint (
169 IN UINTN MpId,
170 IN UINTN UefiMemoryBase,
171 IN UINTN StacksBase,
172 IN UINTN GlobalVariableBase
173 )
174 {
175 UINT64 StartTimeStamp;
176
177 // Initialize the platform specific controllers
178 ArmPlatformInitialize (MpId);
179
180 if (IS_PRIMARY_CORE(MpId) && PerformanceMeasurementEnabled ()) {
181 // Initialize the Timer Library to setup the Timer HW controller
182 TimerConstructor ();
183 // We cannot call yet the PerformanceLib because the HOB List has not been initialized
184 StartTimeStamp = GetPerformanceCounter ();
185 } else {
186 StartTimeStamp = 0;
187 }
188
189 // Clean Data cache
190 ArmCleanInvalidateDataCache ();
191
192 // Invalidate instruction cache
193 ArmInvalidateInstructionCache ();
194
195 //TODO:Drain Write Buffer
196
197 // Enable Instruction & Data caches
198 ArmEnableDataCache ();
199 ArmEnableInstructionCache ();
200
201 // Define the Global Variable region when we are not running in XIP
202 if (!IS_XIP()) {
203 if (IS_PRIMARY_CORE(MpId)) {
204 mGlobalVariableBase = GlobalVariableBase;
205 if (ArmIsMpCore()) {
206 // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
207 ArmCallSEV ();
208 }
209 } else {
210 // Wait the Primay core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT)
211 ArmCallWFE ();
212 }
213 }
214
215 // Write VBAR - The Vector table must be 32-byte aligned
216 ASSERT (((UINT32)PrePiVectorTable & ((1 << 5)-1)) == 0);
217 ArmWriteVBar ((UINT32)PrePiVectorTable);
218
219 // If not primary Jump to Secondary Main
220 if (IS_PRIMARY_CORE(MpId)) {
221 // Goto primary Main.
222 PrimaryMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);
223 } else {
224 SecondaryMain (MpId);
225 }
226
227 // DXE Core should always load and never return
228 ASSERT (FALSE);
229 }
230
231 VOID
232 PrePiCommonExceptionEntry (
233 IN UINT32 Entry,
234 IN UINT32 LR
235 )
236 {
237 CHAR8 Buffer[100];
238 UINTN CharCount;
239
240 switch (Entry) {
241 case 0:
242 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reset Exception at 0x%X\n\r",LR);
243 break;
244 case 1:
245 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Undefined Exception at 0x%X\n\r",LR);
246 break;
247 case 2:
248 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SWI Exception at 0x%X\n\r",LR);
249 break;
250 case 3:
251 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"PrefetchAbort Exception at 0x%X\n\r",LR);
252 break;
253 case 4:
254 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"DataAbort Exception at 0x%X\n\r",LR);
255 break;
256 case 5:
257 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reserved Exception at 0x%X\n\r",LR);
258 break;
259 case 6:
260 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r",LR);
261 break;
262 case 7:
263 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ Exception at 0x%X\n\r",LR);
264 break;
265 default:
266 CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Unknown Exception at 0x%X\n\r",LR);
267 break;
268 }
269 SerialPortWrite ((UINT8 *) Buffer, CharCount);
270 while(1);
271 }