TianoCore EDK2 master
Loading...
Searching...
No Matches
SecMain.c
Go to the documentation of this file.
1
10#include <PiPei.h>
11
12#include <Library/BaseLib.h>
15#include <Library/DebugLib.h>
16#include <Library/PcdLib.h>
17#include <Library/PeCoffLib.h>
21
23
36EFIAPI
38 IN CONST EFI_PEI_SERVICES **PeiServices,
39 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
40 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
41 IN UINTN CopySize
42 );
43
44STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
46};
47
48STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
49 {
50 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
51 &gEfiTemporaryRamSupportPpiGuid,
52 &mTemporaryRamSupportPpi
53 },
54};
55
76 IN VOID *Sections,
77 IN UINTN SizeOfSections,
78 IN EFI_SECTION_TYPE SectionType,
79 IN UINTN Instance,
80 OUT EFI_COMMON_SECTION_HEADER **FoundSection
81 )
82{
83 EFI_PHYSICAL_ADDRESS CurrentAddress;
84 UINT32 Size;
85 EFI_PHYSICAL_ADDRESS EndOfSections;
87 EFI_PHYSICAL_ADDRESS EndOfSection;
88
89 //
90 // Loop through the FFS file sections within the PEI Core FFS file
91 //
92 EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;
93 EndOfSections = EndOfSection + SizeOfSections;
94 for ( ; ; ) {
95 if (EndOfSection == EndOfSections) {
96 break;
97 }
98
99 CurrentAddress = (EndOfSection + 3) & ~(3ULL);
100 if (CurrentAddress >= EndOfSections) {
101 return EFI_VOLUME_CORRUPTED;
102 }
103
104 Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
105
106 Size = SECTION_SIZE (Section);
107 if (Size < sizeof (*Section)) {
108 return EFI_VOLUME_CORRUPTED;
109 }
110
111 EndOfSection = CurrentAddress + Size;
112 if (EndOfSection > EndOfSections) {
113 return EFI_VOLUME_CORRUPTED;
114 }
115
116 //
117 // Look for the requested section type
118 //
119 if (Section->Type == SectionType) {
120 if (Instance == 0) {
121 *FoundSection = Section;
122 return EFI_SUCCESS;
123 } else {
124 Instance--;
125 }
126 }
127 }
128
129 return EFI_NOT_FOUND;
130}
131
145STATIC
148 IN VOID *Sections,
149 IN UINTN SizeOfSections,
150 IN EFI_SECTION_TYPE SectionType,
151 OUT EFI_COMMON_SECTION_HEADER **FoundSection
152 )
153{
155 Sections,
156 SizeOfSections,
157 SectionType,
158 0,
159 FoundSection
160 );
161}
162
176STATIC
180 IN EFI_FV_FILETYPE FileType,
181 IN EFI_SECTION_TYPE SectionType,
182 OUT EFI_COMMON_SECTION_HEADER **FoundSection
183 )
184{
185 EFI_STATUS Status;
186 EFI_PHYSICAL_ADDRESS CurrentAddress;
187 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
189 UINT32 Size;
190 EFI_PHYSICAL_ADDRESS EndOfFile;
191
192 if (Fv->Signature != EFI_FVH_SIGNATURE) {
193 DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
194 return EFI_VOLUME_CORRUPTED;
195 }
196
197 CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv;
198 EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
199
200 //
201 // Loop through the FFS files in the Boot Firmware Volume
202 //
203 for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
204 CurrentAddress = (EndOfFile + 7) & ~(7ULL);
205 if (CurrentAddress > EndOfFirmwareVolume) {
206 return EFI_VOLUME_CORRUPTED;
207 }
208
209 File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
210 Size = *(UINT32 *)File->Size & 0xffffff;
211 if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
212 return EFI_VOLUME_CORRUPTED;
213 }
214
215 EndOfFile = CurrentAddress + Size;
216 if (EndOfFile > EndOfFirmwareVolume) {
217 return EFI_VOLUME_CORRUPTED;
218 }
219
220 //
221 // Look for the request file type
222 //
223 if (File->Type != FileType) {
224 continue;
225 }
226
227 Status = FindFfsSectionInSections (
228 (VOID *)(File + 1),
229 (UINTN)EndOfFile - (UINTN)(File + 1),
230 SectionType,
231 FoundSection
232 );
233 if (!EFI_ERROR (Status) ||
234 (Status == EFI_VOLUME_CORRUPTED))
235 {
236 return Status;
237 }
238 }
239}
240
251STATIC
255 OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
256 )
257{
258 EFI_STATUS Status;
260
261 Status = FindFfsFileAndSection (
262 Fv,
263 EFI_FV_FILETYPE_PEI_CORE,
265 &Section
266 );
267 if (EFI_ERROR (Status)) {
268 Status = FindFfsFileAndSection (
269 Fv,
270 EFI_FV_FILETYPE_PEI_CORE,
271 EFI_SECTION_TE,
272 &Section
273 );
274 if (EFI_ERROR (Status)) {
275 DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
276 return Status;
277 }
278 }
279
280 *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
281 return EFI_SUCCESS;
282}
283
290STATIC
291VOID
293 IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
294 OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
295 )
296{
297 EFI_STATUS Status;
298 EFI_PHYSICAL_ADDRESS PeiCoreImageBase = 0;
299 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
300
301 Status = FindPeiCoreImageBaseInFv (*BootFirmwareVolumePtr, &PeiCoreImageBase);
302 ASSERT (Status == EFI_SUCCESS);
303
304 ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
305
306 //
307 // Report PEI Core debug information when remote debug is enabled
308 //
309 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
310 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
312
313 //
314 // Find PEI Core entry point
315 //
316 Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint);
317 if (EFI_ERROR (Status)) {
318 *PeiCoreEntryPoint = 0;
319 }
320
321 return;
322}
323
329STATIC
330VOID
331EFIAPI
333 IN VOID *Context
334 )
335{
336 EFI_SEC_PEI_HAND_OFF *SecCoreData;
338 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
339
340 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
341
342 //
343 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
344 // is enabled.
345 //
346 BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
347 FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
348 SecCoreData->BootFirmwareVolumeBase = BootFv;
349 SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;
350
351 DEBUG ((DEBUG_INFO, "Find Pei EntryPoint=%p\n", PeiCoreEntryPoint));
352
353 //
354 // Transfer the control to the PEI core
355 //
356 DEBUG ((DEBUG_INFO, "SecStartupPhase2 %p\n", PeiCoreEntryPoint));
357
358 (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
359
360 //
361 // If we get here then the PEI Core returned, which is not recoverable.
362 //
363 ASSERT (FALSE);
364 CpuDeadLoop ();
365}
366
374VOID
375EFIAPI
376SecCoreStartupWithStack (
378 IN VOID *TopOfCurrentStack
379 )
380{
381 EFI_SEC_PEI_HAND_OFF SecCoreData;
383
384 DEBUG ((DEBUG_INFO, "Entering C environment\n"));
385
387
388 DEBUG ((
389 DEBUG_INFO,
390 "SecCoreStartupWithStack (0x%lx, 0x%lx)\n",
391 (UINTN)BootFv,
392 (UINTN)TopOfCurrentStack
393 ));
394 DEBUG ((
395 DEBUG_INFO,
396 "(0x%lx, 0x%lx)\n",
397 (UINTN)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase)),
398 (UINTN)(FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
399 ));
400
401 // |-------------| <-- TopOfCurrentStack
402 // | BSP Stack | 32k
403 // |-------------|
404 // | BSP Heap | 32k
405 // |-------------| <-- SecCoreData.TemporaryRamBase
406 // | Ap Stack | 384k
407 // |-------------|
408 // | Exception | 64k
409 // |-------------| <-- PcdOvmfSecPeiTempRamBase
410
411 ASSERT (
412 (UINTN)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) +
413 FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) ==
414 (UINTN)TopOfCurrentStack
415 );
416
417 //
418 // Initialize SEC hand-off state
419 //
420 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
421
422 SecCoreData.TemporaryRamSize = (UINTN)SIZE_64KB;
423 SecCoreData.TemporaryRamBase = (VOID *)(FixedPcdGet64 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) - SecCoreData.TemporaryRamSize);
424
425 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
426 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
427
428 SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
429 SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
430
431 SecCoreData.BootFirmwareVolumeBase = BootPeiFv;
432 SecCoreData.BootFirmwareVolumeSize = (UINTN)BootPeiFv->FvLength;
433
434 DEBUG ((
435 DEBUG_INFO,
436 "&SecCoreData.BootFirmwareVolumeBase=%lx SecCoreData.BootFirmwareVolumeBase=%lx\n",
437 (UINT64)&(SecCoreData.BootFirmwareVolumeBase),
438 (UINT64)(SecCoreData.BootFirmwareVolumeBase)
439 ));
440 DEBUG ((
441 DEBUG_INFO,
442 "&SecCoreData.BootFirmwareVolumeSize=%lx SecCoreData.BootFirmwareVolumeSize=%lx\n",
443 (UINT64)&(SecCoreData.BootFirmwareVolumeSize),
444 (UINT64)(SecCoreData.BootFirmwareVolumeSize)
445 ));
446
447 //
448 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
449 //
450 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);
451 SecStartupPhase2 (&SecCoreData);
452}
453
464STATIC
466EFIAPI
468 IN CONST EFI_PEI_SERVICES **PeiServices,
469 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
470 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
471 IN UINTN CopySize
472 )
473{
474 VOID *OldHeap;
475 VOID *NewHeap;
476 VOID *OldStack;
477 VOID *NewStack;
478 BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
479
480 DEBUG ((
481 DEBUG_INFO,
482 "TemporaryRamMigration (0x%Lx, 0x%Lx, 0x%Lx)\n",
483 TemporaryMemoryBase,
484 PermanentMemoryBase,
485 (UINT64)CopySize
486 ));
487
488 OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
489 NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1));
490
491 OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
492 NewStack = (VOID *)(UINTN)PermanentMemoryBase;
493
494 //
495 // Migrate Heap
496 //
497 CopyMem (NewHeap, OldHeap, CopySize >> 1);
498
499 //
500 // Migrate Stack
501 //
502 CopyMem (NewStack, OldStack, CopySize >> 1);
503
504 // Use SetJump ()/LongJump () to switch to a new stack.
505 //
506 if (SetJump (&JumpBuffer) == 0) {
507 JumpBuffer.SP = JumpBuffer.SP - (UINTN)OldStack + (UINTN)NewStack;
508 LongJump (&JumpBuffer, (UINTN)-1);
509 }
510
511 return EFI_SUCCESS;
512}
UINT64 UINTN
VOID EFIAPI ProcessLibraryConstructorList(IN EFI_HANDLE ImageHandle, IN EFI_MM_SYSTEM_TABLE *MmSystemTable)
RETURNS_TWICE UINTN EFIAPI SetJump(OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer)
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
VOID EFIAPI LongJump(IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, IN UINTN Value)
Definition: LongJump.c:29
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI InitializeDebugAgent(IN UINT32 InitFlag, IN VOID *Context OPTIONAL, IN DEBUG_AGENT_CONTINUE Function OPTIONAL)
VOID EFIAPI PeCoffLoaderRelocateImageExtraAction(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define VOID
Definition: Base.h:269
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:435
STATIC VOID EFIAPI SecStartupPhase2(IN VOID *Context)
Definition: SecMain.c:332
STATIC EFI_STATUS FindPeiCoreImageBaseInFv(IN EFI_FIRMWARE_VOLUME_HEADER *Fv, OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase)
Definition: SecMain.c:253
STATIC EFI_STATUS FindFfsSectionInstance(IN VOID *Sections, IN UINTN SizeOfSections, IN EFI_SECTION_TYPE SectionType, IN UINTN Instance, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: SecMain.c:75
STATIC VOID FindAndReportEntryPoints(IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr, OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint)
Definition: SecMain.c:292
STATIC EFI_STATUS EFIAPI TemporaryRamMigration(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, IN UINTN CopySize)
Definition: SecMain.c:467
STATIC EFI_STATUS FindFfsFileAndSection(IN EFI_FIRMWARE_VOLUME_HEADER *Fv, IN EFI_FV_FILETYPE FileType, IN EFI_SECTION_TYPE SectionType, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: SecMain.c:178
STATIC EFI_STATUS FindFfsSectionInSections(IN VOID *Sections, IN UINTN SizeOfSections, IN EFI_SECTION_TYPE SectionType, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: SecMain.c:147
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define FixedPcdGet64(TokenName)
Definition: PcdLib.h:106
#define EFI_SECTION_PE32
#define SECTION_SIZE(SectionHeaderPtr)
VOID(EFIAPI * EFI_PEI_CORE_ENTRY_POINT)(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
Definition: PiPeiCis.h:1051
struct _EFI_SEC_PEI_HAND_OFF EFI_SEC_PEI_HAND_OFF
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID * BootFirmwareVolumeBase
Definition: PiPeiCis.h:965
UINTN BootFirmwareVolumeSize
Definition: PiPeiCis.h:970
VOID * PeiTemporaryRamBase
Definition: PiPeiCis.h:991
EFI_FV_FILETYPE Type
PHYSICAL_ADDRESS ImageAddress
Definition: PeCoffLib.h:79