CorebootPayloadPkg: Use extra braces to prevent gcc compile fail
[mirror_edk2.git] / CorebootModulePkg / SecCore / SecMain.c
CommitLineData
fce4ecd9
MM
1/** @file\r
2 C funtions in SEC\r
3\r
4Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15\r
16#include "SecMain.h"\r
17\r
18EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {\r
19 SecTemporaryRamSupport\r
20};\r
21\r
22EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {\r
23 {\r
24 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
25 &gEfiTemporaryRamSupportPpiGuid,\r
26 &gSecTemporaryRamSupportPpi\r
27 }\r
28};\r
29\r
30//\r
31// These are IDT entries pointing to 10:FFFFFFE4h.\r
32//\r
33UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;\r
34\r
35/**\r
36 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
37\r
38 Entry point to the C language phase of SEC. After the SEC assembly\r
39 code has initialized some temporary memory and set up the stack,\r
40 the control is transferred to this function.\r
41\r
42 @param[in] Context The first input parameter of InitializeDebugAgent().\r
43\r
44**/\r
45VOID\r
46EFIAPI\r
47SecStartupPhase2(\r
48 IN VOID *Context\r
49 );\r
50\r
51\r
52/**\r
53\r
54 Entry point to the C language phase of SEC. After the SEC assembly\r
55 code has initialized some temporary memory and set up the stack,\r
56 the control is transferred to this function.\r
57\r
58\r
59 @param SizeOfRam Size of the temporary memory available for use.\r
60 @param TempRamBase Base address of tempory ram\r
61 @param BootFirmwareVolume Base address of the Boot Firmware Volume.\r
62**/\r
63VOID\r
64EFIAPI\r
65SecStartup (\r
66 IN UINT32 SizeOfRam,\r
67 IN UINT32 TempRamBase,\r
68 IN VOID *BootFirmwareVolume\r
69 )\r
70{\r
71 EFI_SEC_PEI_HAND_OFF SecCoreData;\r
72 IA32_DESCRIPTOR IdtDescriptor;\r
73 SEC_IDT_TABLE IdtTableInStack;\r
74 UINT32 Index;\r
75 UINT32 PeiStackSize;\r
76\r
77 PeiStackSize = (SizeOfRam >> 1);\r
78\r
79 ASSERT (PeiStackSize < SizeOfRam);\r
80\r
81 //\r
82 // Process all libraries constructor function linked to SecCore.\r
83 //\r
84 ProcessLibraryConstructorList ();\r
85\r
86 //\r
87 // Initialize floating point operating environment\r
88 // to be compliant with UEFI spec.\r
89 //\r
90 InitializeFloatingPointUnits ();\r
91\r
92\r
93 // |-------------------|---->\r
94 // |Idt Table |\r
95 // |-------------------|\r
96 // |PeiService Pointer | PeiStackSize\r
97 // |-------------------|\r
98 // | |\r
99 // | Stack |\r
100 // |-------------------|---->\r
101 // | |\r
102 // | |\r
103 // | Heap | PeiTemporayRamSize\r
104 // | |\r
105 // | |\r
106 // |-------------------|----> TempRamBase\r
107\r
108 IdtTableInStack.PeiService = 0;\r
109 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {\r
110 CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64));\r
111 }\r
112\r
113 IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;\r
114 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
115\r
116 AsmWriteIdtr (&IdtDescriptor);\r
117\r
118 //\r
119 // Update the base address and length of Pei temporary memory\r
120 //\r
121 SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);\r
122 SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
123 SecCoreData.BootFirmwareVolumeSize = (UINTN)(0x100000000ULL - (UINTN) BootFirmwareVolume);\r
124 SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase;\r
125 SecCoreData.TemporaryRamSize = SizeOfRam;\r
126 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
127 SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize;\r
128 SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);\r
129 SecCoreData.StackSize = PeiStackSize;\r
130\r
131 //\r
132 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
133 //\r
134 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);\r
135\r
136}\r
137\r
138/**\r
139 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
140\r
141 Entry point to the C language phase of SEC. After the SEC assembly\r
142 code has initialized some temporary memory and set up the stack,\r
143 the control is transferred to this function.\r
144\r
145 @param[in] Context The first input parameter of InitializeDebugAgent().\r
146\r
147**/\r
148VOID\r
149EFIAPI\r
150SecStartupPhase2(\r
151 IN VOID *Context\r
152 )\r
153{\r
154 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
155 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;\r
156\r
157 SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;\r
158 //\r
159 // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug\r
160 // is enabled.\r
161 //\r
162 FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);\r
163 if (PeiCoreEntryPoint == NULL)\r
164 {\r
165 CpuDeadLoop ();\r
166 }\r
167\r
168 //\r
169 // Transfer the control to the PEI core\r
170 //\r
171 ASSERT (PeiCoreEntryPoint != NULL);\r
172 (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPeiSecPlatformInformationPpi);\r
173\r
174 //\r
175 // Should not come here.\r
176 //\r
177 return ;\r
178}\r
179\r
180/**\r
181 This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into\r
182 permanent memory.\r
183\r
184 @param PeiServices Pointer to the PEI Services Table.\r
185 @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the\r
186 Temporary RAM contents.\r
187 @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the\r
188 Temporary RAM contents.\r
189 @param CopySize Amount of memory to migrate from temporary to permanent memory.\r
190\r
191 @retval EFI_SUCCESS The data was successfully returned.\r
192 @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when\r
193 TemporaryMemoryBase > PermanentMemoryBase.\r
194\r
195**/\r
196EFI_STATUS\r
197EFIAPI\r
198SecTemporaryRamSupport (\r
199 IN CONST EFI_PEI_SERVICES **PeiServices,\r
200 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,\r
201 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,\r
202 IN UINTN CopySize\r
203 )\r
204{\r
205 IA32_DESCRIPTOR IdtDescriptor;\r
206 VOID* OldHeap;\r
207 VOID* NewHeap;\r
208 VOID* OldStack;\r
209 VOID* NewStack;\r
210 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;\r
211 BOOLEAN OldStatus;\r
212 UINTN PeiStackSize;\r
213\r
214 PeiStackSize = (CopySize >> 1);\r
215\r
216 ASSERT (PeiStackSize < CopySize);\r
217\r
218 //\r
219 // |-------------------|---->\r
220 // | Stack | PeiStackSize\r
221 // |-------------------|---->\r
222 // | Heap | PeiTemporayRamSize\r
223 // |-------------------|----> TempRamBase\r
224 //\r
225 // |-------------------|---->\r
226 // | Heap | PeiTemporayRamSize\r
227 // |-------------------|---->\r
228 // | Stack | PeiStackSize\r
229 // |-------------------|----> PermanentMemoryBase\r
230 //\r
231\r
232 OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
233 NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize);\r
234 \r
235 OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize);\r
236 NewStack = (VOID*)(UINTN)PermanentMemoryBase;\r
237\r
238 DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;\r
239 DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;\r
240 \r
241 OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);\r
242 //\r
243 // Initialize Debug Agent to support source level debug in PEI phase after memory ready.\r
244 // It will build HOB and fix up the pointer in IDT table.\r
245 //\r
246 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);\r
247\r
248 //\r
249 // Migrate Heap\r
250 //\r
251 CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);\r
252\r
253 //\r
254 // Migrate Stack\r
255 //\r
256 CopyMem (NewStack, OldStack, PeiStackSize);\r
257\r
258\r
259 //\r
260 // We need *not* fix the return address because currently,\r
261 // The PeiCore is executed in flash.\r
262 //\r
263\r
264 //\r
265 // Rebase IDT table in permanent memory\r
266 //\r
267 AsmReadIdtr (&IdtDescriptor);\r
268 IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;\r
269\r
270 AsmWriteIdtr (&IdtDescriptor);\r
271\r
272\r
273 //\r
274 // Program MTRR\r
275 //\r
276\r
277 //\r
278 // SecSwitchStack function must be invoked after the memory migration\r
279 // immediatly, also we need fixup the stack change caused by new call into\r
280 // permenent memory.\r
281 //\r
282 SecSwitchStack (\r
283 (UINT32) (UINTN) OldStack,\r
284 (UINT32) (UINTN) NewStack\r
285 );\r
286\r
287 SaveAndSetDebugTimerInterrupt (OldStatus);\r
288 \r
289 return EFI_SUCCESS;\r
290}\r
291\r