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