]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFspWrapperPkg/FspInitPei/SecMain.c
Update IntelFspPkg according to FSP1.1.
[mirror_edk2.git] / IntelFspWrapperPkg / FspInitPei / SecMain.c
CommitLineData
a33a2f62
JY
1/** @file\r
2 C functions in SEC\r
3\r
4 Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT 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_PPI_DESCRIPTOR mPeiSecMainPpi[] = {\r
19 {\r
20 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
21 &gTopOfTemporaryRamPpiGuid,\r
22 NULL // To be patched later.\r
23 },\r
24 {\r
25 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
26 &gFspInitDonePpiGuid,\r
27 &gFspInitDonePpi\r
28 },\r
29};\r
30\r
31//\r
32// These are IDT entries pointing to 10:FFFFFFE4h.\r
33//\r
34UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;\r
35\r
36/**\r
37 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
38\r
39 Entry point to the C language phase of SEC. After the SEC assembly\r
40 code has initialized some temporary memory and set up the stack,\r
41 the control is transferred to this function.\r
42\r
43 @param[in] Context The first input parameter of InitializeDebugAgent().\r
44\r
45**/\r
46VOID\r
47EFIAPI\r
48SecStartupPhase2(\r
49 IN VOID *Context\r
50 );\r
51\r
52\r
53/**\r
54\r
55 Entry point to the C language phase of SEC. After the SEC assembly\r
56 code has initialized some temporary memory and set up the stack,\r
57 the control is transferred to this function.\r
58\r
59 @param[in] SizeOfRam Size of the temporary memory available for use.\r
60 @param[in] TempRamBase Base address of tempory ram\r
61 @param[in] 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 = PcdGet32 (PcdPeiTemporaryRamStackSize);\r
78 if (PeiStackSize == 0) {\r
79 PeiStackSize = (SizeOfRam >> 1);\r
80 }\r
81\r
82 ASSERT (PeiStackSize < SizeOfRam);\r
83\r
84 //\r
85 // Process all libraries constructor function linked to SecCore.\r
86 //\r
87 ProcessLibraryConstructorList ();\r
88\r
89 DEBUG ((DEBUG_INFO, "FspPei - SecStartup\n"));\r
90\r
91 //\r
92 // Initialize floating point operating environment\r
93 // to be compliant with UEFI spec.\r
94 //\r
95 InitializeFloatingPointUnits ();\r
96\r
97\r
98 // |-------------------|---->\r
99 // |Idt Table |\r
100 // |-------------------|\r
101 // |PeiService Pointer | PeiStackSize\r
102 // |-------------------|\r
103 // | |\r
104 // | Stack |\r
105 // |-------------------|---->\r
106 // | |\r
107 // | |\r
108 // | Heap | PeiTemporayRamSize\r
109 // | |\r
110 // | |\r
111 // |-------------------|----> TempRamBase\r
112\r
113 IdtTableInStack.PeiService = 0;\r
114 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {\r
115 CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64));\r
116 }\r
117\r
118 IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;\r
119 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
120\r
121 AsmWriteIdtr (&IdtDescriptor);\r
122\r
123 //\r
124 // Update the base address and length of Pei temporary memory\r
125 //\r
126 SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);\r
127 SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;\r
128 SecCoreData.BootFirmwareVolumeSize = (UINTN)(SIZE_4GB - (UINTN) BootFirmwareVolume);\r
129 SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase;\r
130 SecCoreData.TemporaryRamSize = SizeOfRam;\r
131 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
132 SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize;\r
133 SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);\r
134 SecCoreData.StackSize = PeiStackSize;\r
135\r
136 DEBUG ((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));\r
137 DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));\r
138 DEBUG ((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase));\r
139 DEBUG ((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize));\r
140 DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase));\r
141 DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize));\r
142 DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData.StackBase));\r
143 DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData.StackSize));\r
144\r
145 //\r
146 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
147 //\r
148 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);\r
149\r
150}\r
151\r
152/**\r
153 This API patch the TopOfTemporaryRam value in SecPpiList.\r
154\r
155 @param[in,out] SecPpiList PPI list to be patched.\r
156 @param[in] TopOfTemporaryRam The top of Temporary Ram.\r
157\r
158**/\r
159VOID\r
160PatchTopOfTemporaryRamPpi (\r
161 IN OUT EFI_PEI_PPI_DESCRIPTOR *SecPpiList,\r
162 IN VOID *TopOfTemporaryRam\r
163 )\r
164{\r
165 SecPpiList[0].Ppi = TopOfTemporaryRam;\r
166}\r
167\r
168/**\r
169 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
170\r
171 Entry point to the C language phase of SEC. After the SEC assembly\r
172 code has initialized some temporary memory and set up the stack,\r
173 the control is transferred to this function.\r
174\r
175 @param[in] Context The first input parameter of InitializeDebugAgent().\r
176\r
177**/\r
178VOID\r
179EFIAPI\r
180SecStartupPhase2(\r
181 IN VOID *Context\r
182 )\r
183{\r
184 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
185 EFI_PEI_PPI_DESCRIPTOR *PpiList;\r
186 UINT32 Index;\r
187 EFI_PEI_PPI_DESCRIPTOR LocalSecPpiList[sizeof(mPeiSecMainPpi)/sizeof(mPeiSecMainPpi[0])];\r
188 EFI_PEI_PPI_DESCRIPTOR AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)];\r
189 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;\r
190\r
191 SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;\r
192 //\r
193 // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug\r
194 // is enabled.\r
195 //\r
196 FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);\r
197 if (PeiCoreEntryPoint == NULL)\r
198 {\r
199 CpuDeadLoop ();\r
200 }\r
201\r
202 CopyMem (LocalSecPpiList, mPeiSecMainPpi, sizeof(mPeiSecMainPpi));\r
203 PatchTopOfTemporaryRamPpi (LocalSecPpiList, (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize));\r
204\r
205 //\r
206 // Perform platform specific initialization before entering PeiCore.\r
207 //\r
208 PpiList = SecPlatformMain (SecCoreData);\r
209 if (PpiList != NULL) {\r
210 //\r
211 // Remove the terminal flag from the terminal Ppi\r
212 //\r
213 CopyMem (AllSecPpiList, LocalSecPpiList, sizeof (LocalSecPpiList));\r
214 for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) {\r
215 if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {\r
216 break;\r
217 }\r
218 }\r
219 AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
220\r
221 //\r
222 // Append the platform additional Ppi list\r
223 //\r
224 Index += 1;\r
225 while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) &&\r
226 ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) {\r
227 CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
228 Index++;\r
229 PpiList++;\r
230 }\r
231\r
232 //\r
233 // Check whether the total Ppis exceeds the max supported Ppi.\r
234 //\r
235 if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) {\r
236 //\r
237 // the total Ppi is larger than the supported Max\r
238 // PcdSecCoreMaxPpiSupported can be enlarged to solve it.\r
239 //\r
240 CpuDeadLoop ();\r
241 } else {\r
242 //\r
243 // Add the terminal Ppi\r
244 //\r
245 CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
246 }\r
247\r
248 //\r
249 // Set PpiList to the total Ppi\r
250 //\r
251 PpiList = &AllSecPpiList[0];\r
252 } else {\r
253 //\r
254 // No addition Ppi, PpiList directly point to the common Ppi list.\r
255 //\r
256 PpiList = &LocalSecPpiList[0];\r
257 }\r
258\r
259 //\r
260 // Transfer the control to the PEI core\r
261 //\r
262 ASSERT (PeiCoreEntryPoint != NULL);\r
263 (*PeiCoreEntryPoint) (SecCoreData, PpiList);\r
264\r
265 //\r
266 // Should not come here.\r
267 //\r
268 return ;\r
269}\r