EFI_STATUS EFIAPI LoadDxeCoreFromFfsFile ( IN EFI_PEI_FILE_HANDLE FileHandle, IN UINTN StackSize ) { EFI_STATUS Status; VOID *PeCoffImage; EFI_PHYSICAL_ADDRESS ImageAddress; UINT64 ImageSize; EFI_PHYSICAL_ADDRESS EntryPoint; VOID *BaseOfStack; VOID *TopOfStack; VOID *Hob; EFI_FV_FILE_INFO FvFileInfo; Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage); if (EFI_ERROR (Status)) { return Status; } Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint); // For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint); ASSERT_EFI_ERROR (Status); // // Extract the DxeCore GUID file name. // Status = FfsGetFileInfo (FileHandle, &FvFileInfo); ASSERT_EFI_ERROR (Status); BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint); DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint)); Hob = GetHobList (); if (StackSize == 0) { // User the current stack ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob); } else { // // Allocate 128KB for the Stack // BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize)); ASSERT (BaseOfStack != NULL); // // Compute the top of the stack we were allocated. Pre-allocate a UINTN // for safety. // TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); // // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. // UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize); SwitchStack ( (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint, Hob, NULL, TopOfStack ); } // Should never get here as DXE Core does not return DEBUG ((EFI_D_ERROR, "DxeCore returned\n")); ASSERT (FALSE); return EFI_DEVICE_ERROR; }
EFI_STATUS MmCoreFfsFindMmDriver ( IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader ) /*++ Routine Description: Given the pointer to the Firmware Volume Header find the MM driver and return it's PE32 image. Arguments: FwVolHeader - Pointer to memory mapped FV Returns: other - Failure --*/ { EFI_STATUS Status; EFI_STATUS DepexStatus; EFI_FFS_FILE_HEADER *FileHeader; EFI_FV_FILETYPE FileType; VOID *Pe32Data; UINTN Pe32DataSize; VOID *Depex; UINTN DepexSize; UINTN Index; EFI_COMMON_SECTION_HEADER *Section; VOID *SectionData; UINTN SectionDataSize; UINT32 DstBufferSize; VOID *ScratchBuffer; UINT32 ScratchBufferSize; VOID *DstBuffer; UINT16 SectionAttribute; UINT32 AuthenticationStatus; EFI_FIRMWARE_VOLUME_HEADER *InnerFvHeader; DEBUG ((DEBUG_INFO, "MmCoreFfsFindMmDriver - 0x%x\n", FwVolHeader)); if (FvHasBeenProcessed (FwVolHeader)) { return EFI_SUCCESS; } FvIsBeingProcesssed (FwVolHeader); // // First check for encapsulated compressed firmware volumes // FileHeader = NULL; do { Status = FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, FwVolHeader, &FileHeader); if (EFI_ERROR (Status)) { break; } Status = FfsFindSectionData (EFI_SECTION_GUID_DEFINED, FileHeader, &SectionData, &SectionDataSize); if (EFI_ERROR (Status)) { break; } Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1); Status = ExtractGuidedSectionGetInfo (Section, &DstBufferSize, &ScratchBufferSize, &SectionAttribute); if (EFI_ERROR (Status)) { break; } // // Allocate scratch buffer // ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize)); if (ScratchBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Allocate destination buffer, extra one page for adjustment // DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize)); if (DstBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Call decompress function // Status = ExtractGuidedSectionDecode (Section, &DstBuffer, ScratchBuffer, &AuthenticationStatus); FreePages (ScratchBuffer, EFI_SIZE_TO_PAGES (ScratchBufferSize)); if (EFI_ERROR (Status)) { goto FreeDstBuffer; } DEBUG ((DEBUG_INFO, "Processing compressed firmware volume (AuthenticationStatus == %x)\n", AuthenticationStatus)); Status = FindFfsSectionInSections (DstBuffer, DstBufferSize, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, &Section); if (EFI_ERROR (Status)) { goto FreeDstBuffer; } InnerFvHeader = (VOID *)(Section + 1); Status = MmCoreFfsFindMmDriver (InnerFvHeader); if (EFI_ERROR (Status)) { goto FreeDstBuffer; } } while (TRUE); for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) { DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index])); FileType = mMmFileTypes[Index]; FileHeader = NULL; do { Status = FfsFindNextFile (FileType, FwVolHeader, &FileHeader); if (!EFI_ERROR (Status)) { Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize); DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data)); DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize); if (!EFI_ERROR (DepexStatus)) { MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name); } } } while (!EFI_ERROR (Status)); } return EFI_SUCCESS; FreeDstBuffer: FreePages (DstBuffer, EFI_SIZE_TO_PAGES (DstBufferSize)); return Status; }