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