/** The ExtractSection() function processes the input section and returns a pointer to the section contents. If the section being extracted does not require processing (if the section GuidedSectionHeader.Attributes has the EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then OutputBuffer is just updated to point to the start of the section's contents. Otherwise, *Buffer must be allocated from PEI permanent memory. @param This Indicates the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance. Buffer containing the input GUIDed section to be processed. OutputBuffer OutputBuffer is allocated from PEI permanent memory and contains the new section stream. @param InputSection A pointer to the input buffer, which contains the input section to be processed. @param OutputBuffer A pointer to a caller-allocated buffer, whose size is specified by the contents of OutputSize. @param OutputSize A pointer to a caller-allocated UINTN in which the size of *OutputBuffer allocation is stored. If the function returns anything other than EFI_SUCCESS, the value of OutputSize is undefined. @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the authentication status of the output buffer. If the input section's GuidedSectionHeader. Attributes field has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit as clear, AuthenticationStatus must return zero. These bits reflect the status of the extraction operation. If the function returns anything other than EFI_SUCCESS, the value of AuthenticationStatus is undefined. @retval EFI_SUCCESS The InputSection was successfully processed and the section contents were returned. @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to process the request. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance of the GUIDed Section Extraction PPI. **/ EFI_STATUS EFIAPI CustomGuidedSectionExtract ( IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This, IN CONST VOID *InputSection, OUT VOID **OutputBuffer, OUT UINTN *OutputSize, OUT UINT32 *AuthenticationStatus ) { EFI_STATUS Status; UINT8 *ScratchBuffer; UINT32 ScratchBufferSize; UINT32 OutputBufferSize; UINT16 SectionAttribute; // // Init local variable // ScratchBuffer = NULL; // // Call GetInfo to get the size and attribute of input guided section data. // Status = ExtractGuidedSectionGetInfo ( InputSection, &OutputBufferSize, &ScratchBufferSize, &SectionAttribute ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status)); return Status; } if (ScratchBufferSize != 0) { // // Allocate scratch buffer // ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize)); if (ScratchBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } } if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) { // // Allocate output buffer // *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1); if (*OutputBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer)); // // *OutputBuffer still is one section. Adjust *OutputBuffer offset, // skip EFI section header to make section data at page alignment. // *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER)); } Status = ExtractGuidedSectionDecode ( InputSection, OutputBuffer, ScratchBuffer, AuthenticationStatus ); if (EFI_ERROR (Status)) { // // Decode failed // DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status)); return Status; } *OutputSize = (UINTN) OutputBufferSize; return EFI_SUCCESS; }
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; }