]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2Pkg/FspSecCore/SecMain.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / SecMain.c
CommitLineData
cf1d4549
JY
1/** @file\r
2\r
630df8c8 3 Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>\r
9672cd30 4 SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
5\r
6**/\r
7\r
8#include "SecMain.h"\r
9#include "SecFsp.h"\r
10\r
111f2228 11EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {\r
cf1d4549
JY
12 SecTemporaryRamSupport\r
13};\r
14\r
111f2228 15EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {\r
a2e61f34
CC
16 {\r
17 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
18 &gFspInApiModePpiGuid,\r
19 NULL\r
20 },\r
cf1d4549
JY
21 {\r
22 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
23 &gEfiTemporaryRamSupportPpiGuid,\r
24 &gSecTemporaryRamSupportPpi\r
25 }\r
26};\r
27\r
28//\r
29// These are IDT entries pointing to 08:FFFFFFE4h.\r
30//\r
31UINT64 mIdtEntryTemplate = 0xffff8e000008ffe4ULL;\r
32\r
33/**\r
34\r
35 Entry point to the C language phase of SEC. After the SEC assembly\r
36 code has initialized some temporary memory and set up the stack,\r
37 the control is transferred to this function.\r
38\r
39\r
40 @param[in] SizeOfRam Size of the temporary memory available for use.\r
058dcbf2 41 @param[in] TempRamBase Base address of temporary ram\r
cf1d4549
JY
42 @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.\r
43 @param[in] PeiCore PeiCore entry point.\r
44 @param[in] BootLoaderStack BootLoader stack.\r
45 @param[in] ApiIdx the index of API.\r
46\r
47 @return This function never returns.\r
48\r
49**/\r
50VOID\r
51EFIAPI\r
52SecStartup (\r
111f2228
MK
53 IN UINT32 SizeOfRam,\r
54 IN UINT32 TempRamBase,\r
55 IN VOID *BootFirmwareVolume,\r
56 IN PEI_CORE_ENTRY PeiCore,\r
630df8c8 57 IN UINTN BootLoaderStack,\r
111f2228 58 IN UINT32 ApiIdx\r
cf1d4549
JY
59 )\r
60{\r
470206ba
KT
61 EFI_SEC_PEI_HAND_OFF SecCoreData;\r
62 IA32_DESCRIPTOR IdtDescriptor;\r
63 SEC_IDT_TABLE IdtTableInStack;\r
64 UINT32 Index;\r
65 FSP_GLOBAL_DATA PeiFspData;\r
66 IA32_IDT_GATE_DESCRIPTOR ExceptionHandler;\r
67 UINTN IdtSize;\r
cf1d4549
JY
68\r
69 //\r
70 // Process all libraries constructor function linked to SecCore.\r
71 //\r
72 ProcessLibraryConstructorList ();\r
73\r
74 //\r
75 // Initialize floating point operating environment\r
76 // to be compliant with UEFI spec.\r
77 //\r
78 InitializeFloatingPointUnits ();\r
79\r
12a0a80b
CC
80 //\r
81 // Scenario 1 memory map when running on bootloader stack\r
82 //\r
83 // |-------------------|---->\r
84 // |Idt Table |\r
85 // |-------------------|\r
86 // |PeiService Pointer |\r
87 // |-------------------|\r
88 // | |\r
89 // | |\r
90 // | Heap |\r
91 // | |\r
92 // | |\r
93 // |-------------------|----> TempRamBase\r
94 //\r
95 //\r
96 // |-------------------|\r
97 // |Bootloader stack |----> somewhere in memory, FSP will share this stack.\r
98 // |-------------------|\r
cf1d4549 99\r
12a0a80b
CC
100 //\r
101 // Scenario 2 memory map when running FSP on a separate stack\r
102 //\r
cf1d4549
JY
103 // |-------------------|---->\r
104 // |Idt Table |\r
105 // |-------------------|\r
106 // |PeiService Pointer | PeiStackSize\r
107 // |-------------------|\r
108 // | |\r
109 // | Stack |\r
110 // |-------------------|---->\r
111 // | |\r
112 // | |\r
91cc60ba 113 // | Heap | PeiTemporaryRamSize\r
cf1d4549
JY
114 // | |\r
115 // | |\r
116 // |-------------------|----> TempRamBase\r
520a1e60 117 IdtTableInStack.PeiService = 0;\r
b1cc6f67 118 AsmReadIdtr (&IdtDescriptor);\r
c09b254b 119 if (IdtDescriptor.Base == 0) {\r
111f2228
MK
120 ExceptionHandler = FspGetExceptionHandler (mIdtEntryTemplate);\r
121 for (Index = 0; Index < FixedPcdGet8 (PcdFspMaxInterruptSupported); Index++) {\r
470206ba 122 CopyMem ((VOID *)&IdtTableInStack.IdtTable[Index], (VOID *)&ExceptionHandler, sizeof (IA32_IDT_GATE_DESCRIPTOR));\r
b1cc6f67 123 }\r
111f2228 124\r
b1cc6f67
CC
125 IdtSize = sizeof (IdtTableInStack.IdtTable);\r
126 } else {\r
901ae29d
CC
127 IdtSize = IdtDescriptor.Limit + 1;\r
128 if (IdtSize > sizeof (IdtTableInStack.IdtTable)) {\r
b1cc6f67
CC
129 //\r
130 // ERROR: IDT table size from boot loader is larger than FSP can support, DeadLoop here!\r
131 //\r
111f2228 132 CpuDeadLoop ();\r
c09b254b 133 } else {\r
111f2228 134 CopyMem ((VOID *)(UINTN)&IdtTableInStack.IdtTable, (VOID *)IdtDescriptor.Base, IdtSize);\r
b1cc6f67 135 }\r
cf1d4549 136 }\r
111f2228
MK
137\r
138 IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;\r
b1cc6f67 139 IdtDescriptor.Limit = (UINT16)(IdtSize - 1);\r
cf1d4549
JY
140\r
141 AsmWriteIdtr (&IdtDescriptor);\r
142\r
143 //\r
144 // Initialize the global FSP data region\r
145 //\r
146 FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx);\r
147\r
148 //\r
149 // Update the base address and length of Pei temporary memory\r
150 //\r
151 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);\r
152 SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
153 SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;\r
154\r
379e5098
CC
155 //\r
156 // Support FSP reserved temporary memory from the whole temporary memory provided by bootloader.\r
157 // FSP reserved temporary memory will not be given to PeiCore.\r
158 //\r
111f2228
MK
159 SecCoreData.TemporaryRamBase = (UINT8 *)(UINTN)TempRamBase + PcdGet32 (PcdFspPrivateTemporaryRamSize);\r
160 SecCoreData.TemporaryRamSize = SizeOfRam - PcdGet32 (PcdFspPrivateTemporaryRamSize);\r
12a0a80b 161 if (PcdGet8 (PcdFspHeapSizePercentage) == 0) {\r
111f2228
MK
162 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
163 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize;\r
164 SecCoreData.StackBase = (VOID *)GetFspEntryStack (); // Share the same boot loader stack\r
165 SecCoreData.StackSize = 0;\r
12a0a80b 166 } else {\r
111f2228
MK
167 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
168 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;\r
169 SecCoreData.StackBase = (VOID *)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);\r
170 SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;\r
12a0a80b 171 }\r
cf1d4549
JY
172\r
173 DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));\r
174 DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));\r
175 DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase));\r
176 DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize));\r
177 DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase));\r
178 DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize));\r
179 DEBUG ((DEBUG_INFO, "Fsp StackBase - 0x%x\n", SecCoreData.StackBase));\r
180 DEBUG ((DEBUG_INFO, "Fsp StackSize - 0x%x\n", SecCoreData.StackSize));\r
181\r
182 //\r
183 // Call PeiCore Entry\r
e37bb20c 184 //\r
cf1d4549
JY
185 PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);\r
186\r
187 //\r
188 // Should never be here\r
189 //\r
190 CpuDeadLoop ();\r
191}\r
192\r
193/**\r
194 This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into\r
195 permanent memory.\r
196\r
197 @param[in] PeiServices Pointer to the PEI Services Table.\r
198 @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the\r
199 Temporary RAM contents.\r
200 @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the\r
201 Temporary RAM contents.\r
202 @param[in] CopySize Amount of memory to migrate from temporary to permanent memory.\r
203\r
204 @retval EFI_SUCCESS The data was successfully returned.\r
205 @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when\r
206 TemporaryMemoryBase > PermanentMemoryBase.\r
207\r
208**/\r
209EFI_STATUS\r
210EFIAPI\r
211SecTemporaryRamSupport (\r
111f2228
MK
212 IN CONST EFI_PEI_SERVICES **PeiServices,\r
213 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,\r
214 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,\r
215 IN UINTN CopySize\r
cf1d4549
JY
216 )\r
217{\r
111f2228
MK
218 IA32_DESCRIPTOR IdtDescriptor;\r
219 VOID *OldHeap;\r
220 VOID *NewHeap;\r
221 VOID *OldStack;\r
222 VOID *NewStack;\r
223 UINTN HeapSize;\r
224 UINTN StackSize;\r
cf1d4549 225\r
111f2228
MK
226 UINTN CurrentStack;\r
227 UINTN FspStackBase;\r
12a0a80b 228\r
f2cdb268
CC
229 //\r
230 // Override OnSeparateStack to 1 because this function will switch stack to permanent memory\r
231 // which makes FSP running on different stack from bootloader temporary ram stack.\r
232 //\r
233 GetFspGlobalDataPointer ()->OnSeparateStack = 1;\r
234\r
12a0a80b 235 if (PcdGet8 (PcdFspHeapSizePercentage) == 0) {\r
630df8c8 236 CurrentStack = AsmReadStackPointer ();\r
111f2228 237 FspStackBase = (UINTN)GetFspEntryStack ();\r
e37bb20c 238\r
12a0a80b
CC
239 StackSize = FspStackBase - CurrentStack;\r
240 HeapSize = CopySize;\r
cf1d4549 241\r
111f2228
MK
242 OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;\r
243 NewHeap = (VOID *)((UINTN)PermanentMemoryBase);\r
cf1d4549 244\r
111f2228 245 OldStack = (VOID *)CurrentStack;\r
12a0a80b 246 //\r
111f2228 247 // The old stack is copied at the end of the stack region because stack grows down.\r
12a0a80b 248 //\r
111f2228 249 NewStack = (VOID *)((UINTN)PermanentMemoryBase - StackSize);\r
12a0a80b 250 } else {\r
111f2228
MK
251 HeapSize = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100;\r
252 StackSize = CopySize - HeapSize;\r
12a0a80b 253\r
111f2228
MK
254 OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;\r
255 NewHeap = (VOID *)((UINTN)PermanentMemoryBase + StackSize);\r
12a0a80b 256\r
111f2228
MK
257 OldStack = (VOID *)((UINTN)TemporaryMemoryBase + HeapSize);\r
258 NewStack = (VOID *)(UINTN)PermanentMemoryBase;\r
12a0a80b 259 }\r
111f2228 260\r
cf1d4549
JY
261 //\r
262 // Migrate Heap\r
263 //\r
264 CopyMem (NewHeap, OldHeap, HeapSize);\r
265\r
266 //\r
267 // Migrate Stack\r
268 //\r
269 CopyMem (NewStack, OldStack, StackSize);\r
270\r
cf1d4549
JY
271 //\r
272 // We need *not* fix the return address because currently,\r
273 // The PeiCore is executed in flash.\r
274 //\r
275\r
276 //\r
277 // Rebase IDT table in permanent memory\r
278 //\r
279 AsmReadIdtr (&IdtDescriptor);\r
280 IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;\r
281\r
282 AsmWriteIdtr (&IdtDescriptor);\r
283\r
284 //\r
285 // Fixed the FSP data pointer\r
286 //\r
287 FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);\r
288\r
289 //\r
290 // SecSwitchStack function must be invoked after the memory migration\r
058dcbf2
GL
291 // immediately, also we need fixup the stack change caused by new call into\r
292 // permanent memory.\r
cf1d4549
JY
293 //\r
294 SecSwitchStack (\r
630df8c8
TK
295 (UINTN)OldStack,\r
296 (UINTN)NewStack\r
cf1d4549
JY
297 );\r
298\r
299 return EFI_SUCCESS;\r
300}\r