]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFspWrapperPkg/FspInitPei/SecMain.c
DynamicTablesPkg: GTDT updates for ACPI 6.3
[mirror_edk2.git] / IntelFspWrapperPkg / FspInitPei / SecMain.c
CommitLineData
a33a2f62
JY
1/** @file\r
2 C functions in SEC\r
3\r
d8043ce9 4 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
19486360 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a33a2f62
JY
6\r
7**/\r
8\r
9\r
10#include "SecMain.h"\r
11\r
12EFI_PEI_PPI_DESCRIPTOR mPeiSecMainPpi[] = {\r
13 {\r
14 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
15 &gTopOfTemporaryRamPpiGuid,\r
16 NULL // To be patched later.\r
17 },\r
18 {\r
19 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
20 &gFspInitDonePpiGuid,\r
21 &gFspInitDonePpi\r
22 },\r
23};\r
24\r
d8043ce9
JY
25FSP_INIT_DONE_PPI gFspInitDonePpi = {\r
26 FspInitDoneGetFspHobList\r
27};\r
28\r
a33a2f62
JY
29//\r
30// These are IDT entries pointing to 10:FFFFFFE4h.\r
31//\r
32UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;\r
33\r
34/**\r
35 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
36\r
37 Entry point to the C language phase of SEC. After the SEC assembly\r
38 code has initialized some temporary memory and set up the stack,\r
39 the control is transferred to this function.\r
40\r
41 @param[in] Context The first input parameter of InitializeDebugAgent().\r
42\r
43**/\r
44VOID\r
45EFIAPI\r
46SecStartupPhase2(\r
47 IN VOID *Context\r
48 );\r
49\r
50\r
51/**\r
52\r
53 Entry point to the C language phase of SEC. After the SEC assembly\r
54 code has initialized some temporary memory and set up the stack,\r
55 the control is transferred to this function.\r
56\r
57 @param[in] SizeOfRam Size of the temporary memory available for use.\r
b9ca25cb 58 @param[in] TempRamBase Base address of temporary ram\r
a33a2f62
JY
59 @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.\r
60**/\r
61VOID\r
62EFIAPI\r
63SecStartup (\r
64 IN UINT32 SizeOfRam,\r
65 IN UINT32 TempRamBase,\r
66 IN VOID *BootFirmwareVolume\r
67 )\r
68{\r
69 EFI_SEC_PEI_HAND_OFF SecCoreData;\r
70 IA32_DESCRIPTOR IdtDescriptor;\r
71 SEC_IDT_TABLE IdtTableInStack;\r
72 UINT32 Index;\r
73 UINT32 PeiStackSize;\r
74\r
75 PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize);\r
76 if (PeiStackSize == 0) {\r
77 PeiStackSize = (SizeOfRam >> 1);\r
78 }\r
79\r
80 ASSERT (PeiStackSize < SizeOfRam);\r
81\r
82 //\r
83 // Process all libraries constructor function linked to SecCore.\r
84 //\r
85 ProcessLibraryConstructorList ();\r
86\r
87 DEBUG ((DEBUG_INFO, "FspPei - SecStartup\n"));\r
88\r
89 //\r
90 // Initialize floating point operating environment\r
91 // to be compliant with UEFI spec.\r
92 //\r
93 InitializeFloatingPointUnits ();\r
94\r
95\r
96 // |-------------------|---->\r
97 // |Idt Table |\r
98 // |-------------------|\r
99 // |PeiService Pointer | PeiStackSize\r
100 // |-------------------|\r
101 // | |\r
102 // | Stack |\r
103 // |-------------------|---->\r
104 // | |\r
105 // | |\r
106 // | Heap | PeiTemporayRamSize\r
107 // | |\r
108 // | |\r
109 // |-------------------|----> TempRamBase\r
110\r
111 IdtTableInStack.PeiService = 0;\r
112 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {\r
113 CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64));\r
114 }\r
115\r
116 IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;\r
117 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
118\r
119 AsmWriteIdtr (&IdtDescriptor);\r
120\r
121 //\r
122 // Update the base address and length of Pei temporary memory\r
123 //\r
124 SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);\r
125 SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
126 SecCoreData.BootFirmwareVolumeSize = (UINTN)(SIZE_4GB - (UINTN) BootFirmwareVolume);\r
127 SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase;\r
128 SecCoreData.TemporaryRamSize = SizeOfRam;\r
129 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
130 SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize;\r
131 SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);\r
132 SecCoreData.StackSize = PeiStackSize;\r
133\r
134 DEBUG ((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));\r
135 DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));\r
136 DEBUG ((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase));\r
137 DEBUG ((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize));\r
138 DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase));\r
139 DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize));\r
140 DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData.StackBase));\r
141 DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData.StackSize));\r
142\r
143 //\r
144 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
145 //\r
146 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);\r
147\r
148}\r
149\r
150/**\r
151 This API patch the TopOfTemporaryRam value in SecPpiList.\r
152\r
153 @param[in,out] SecPpiList PPI list to be patched.\r
154 @param[in] TopOfTemporaryRam The top of Temporary Ram.\r
155\r
156**/\r
157VOID\r
158PatchTopOfTemporaryRamPpi (\r
159 IN OUT EFI_PEI_PPI_DESCRIPTOR *SecPpiList,\r
160 IN VOID *TopOfTemporaryRam\r
161 )\r
162{\r
163 SecPpiList[0].Ppi = TopOfTemporaryRam;\r
164}\r
165\r
166/**\r
167 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
168\r
169 Entry point to the C language phase of SEC. After the SEC assembly\r
170 code has initialized some temporary memory and set up the stack,\r
171 the control is transferred to this function.\r
172\r
173 @param[in] Context The first input parameter of InitializeDebugAgent().\r
174\r
175**/\r
176VOID\r
177EFIAPI\r
178SecStartupPhase2(\r
179 IN VOID *Context\r
180 )\r
181{\r
182 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
183 EFI_PEI_PPI_DESCRIPTOR *PpiList;\r
184 UINT32 Index;\r
185 EFI_PEI_PPI_DESCRIPTOR LocalSecPpiList[sizeof(mPeiSecMainPpi)/sizeof(mPeiSecMainPpi[0])];\r
186 EFI_PEI_PPI_DESCRIPTOR AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)];\r
187 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;\r
188\r
189 SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;\r
190 //\r
191 // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug\r
192 // is enabled.\r
193 //\r
194 FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);\r
195 if (PeiCoreEntryPoint == NULL)\r
196 {\r
197 CpuDeadLoop ();\r
198 }\r
199\r
200 CopyMem (LocalSecPpiList, mPeiSecMainPpi, sizeof(mPeiSecMainPpi));\r
201 PatchTopOfTemporaryRamPpi (LocalSecPpiList, (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize));\r
202\r
203 //\r
204 // Perform platform specific initialization before entering PeiCore.\r
205 //\r
206 PpiList = SecPlatformMain (SecCoreData);\r
207 if (PpiList != NULL) {\r
208 //\r
209 // Remove the terminal flag from the terminal Ppi\r
210 //\r
211 CopyMem (AllSecPpiList, LocalSecPpiList, sizeof (LocalSecPpiList));\r
212 for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) {\r
213 if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
214 break;\r
215 }\r
216 }\r
217 AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
218\r
219 //\r
220 // Append the platform additional Ppi list\r
221 //\r
222 Index += 1;\r
223 while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) &&\r
224 ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) {\r
225 CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
226 Index++;\r
227 PpiList++;\r
228 }\r
229\r
230 //\r
231 // Check whether the total Ppis exceeds the max supported Ppi.\r
232 //\r
233 if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) {\r
234 //\r
235 // the total Ppi is larger than the supported Max\r
236 // PcdSecCoreMaxPpiSupported can be enlarged to solve it.\r
237 //\r
238 CpuDeadLoop ();\r
239 } else {\r
240 //\r
241 // Add the terminal Ppi\r
242 //\r
243 CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
244 }\r
245\r
246 //\r
247 // Set PpiList to the total Ppi\r
248 //\r
249 PpiList = &AllSecPpiList[0];\r
250 } else {\r
251 //\r
252 // No addition Ppi, PpiList directly point to the common Ppi list.\r
253 //\r
254 PpiList = &LocalSecPpiList[0];\r
255 }\r
256\r
257 //\r
258 // Transfer the control to the PEI core\r
259 //\r
260 ASSERT (PeiCoreEntryPoint != NULL);\r
261 (*PeiCoreEntryPoint) (SecCoreData, PpiList);\r
262\r
263 //\r
264 // Should not come here.\r
265 //\r
266 return ;\r
267}\r
d8043ce9
JY
268\r
269/**\r
270 Return Hob list produced by FSP.\r
271\r
272 @param[in] PeiServices The pointer to the PEI Services Table.\r
273 @param[in] This The pointer to this instance of this PPI.\r
274 @param[out] FspHobList The pointer to Hob list produced by FSP.\r
275\r
276 @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.\r
277**/\r
278EFI_STATUS\r
279EFIAPI\r
280FspInitDoneGetFspHobList (\r
281 IN CONST EFI_PEI_SERVICES **PeiServices,\r
282 IN FSP_INIT_DONE_PPI *This,\r
283 OUT VOID **FspHobList\r
284 )\r
285{\r
286 VOID *TopOfTemporaryRamPpi;\r
287 EFI_STATUS Status;\r
288\r
289 Status = (*PeiServices)->LocatePpi (\r
290 PeiServices,\r
291 &gTopOfTemporaryRamPpiGuid,\r
292 0,\r
293 NULL,\r
294 (VOID **) &TopOfTemporaryRamPpi\r
295 );\r
296 if (EFI_ERROR (Status)) {\r
297 return EFI_NOT_FOUND;\r
298 }\r
299\r
300 *FspHobList = (VOID *)(UINTN)(*(UINT32 *)((UINTN)TopOfTemporaryRamPpi - sizeof(UINT32)));\r
301\r
302 return EFI_SUCCESS;\r
303}\r
304\r