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