diff options
author | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-01-25 11:28:06 +0000 |
---|---|---|
committer | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-01-25 11:28:06 +0000 |
commit | 1e57a46299244793beb27e74be171d1540606999 (patch) | |
tree | 8644a24d6e4b4cfd080d4c40ccf2d3d9f13760f9 /EmbeddedPkg/Library/PrePiLib | |
parent | 5767f22fca7c337cdc113e14b411c1fd0ea7bd53 (diff) | |
download | edk2-platforms-1e57a46299244793beb27e74be171d1540606999.tar.xz |
ARM Packages: Fixed line endings
This large code change only modifies the line endings to be CRLF to be
compliant with the EDK2 coding convention document.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14088 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EmbeddedPkg/Library/PrePiLib')
-rw-r--r-- | EmbeddedPkg/Library/PrePiLib/FwVol.c | 1684 | ||||
-rw-r--r-- | EmbeddedPkg/Library/PrePiLib/PrePi.h | 92 | ||||
-rw-r--r-- | EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 452 | ||||
-rw-r--r-- | EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c | 654 |
4 files changed, 1441 insertions, 1441 deletions
diff --git a/EmbeddedPkg/Library/PrePiLib/FwVol.c b/EmbeddedPkg/Library/PrePiLib/FwVol.c index 75d28a7257..9e4cdd002e 100644 --- a/EmbeddedPkg/Library/PrePiLib/FwVol.c +++ b/EmbeddedPkg/Library/PrePiLib/FwVol.c @@ -1,842 +1,842 @@ -/** @file - Implementation of the 6 PEI Ffs (FV) APIs in library form. - - This code only knows about a FV if it has a EFI_HOB_TYPE_FV entry in the HOB list - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include <PrePi.h> -#include <Library/ExtractGuidedSectionLib.h> - - -#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ - (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)) - - -/** - Returns the highest bit set of the State field - - @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY - in the Attributes field. - @param FfsHeader Pointer to FFS File Header - - - @retval the highest bit in the State field - -**/ -STATIC -EFI_FFS_FILE_STATE -GetFileState( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -{ - EFI_FFS_FILE_STATE FileState; - EFI_FFS_FILE_STATE HighestBit; - - FileState = FfsHeader->State; - - if (ErasePolarity != 0) { - FileState = (EFI_FFS_FILE_STATE)~FileState; - } - - HighestBit = 0x80; - while (HighestBit != 0 && (HighestBit & FileState) == 0) { - HighestBit >>= 1; - } - - return HighestBit; -} - - -/** - Calculates the checksum of the header of a file. - The header is a zero byte checksum, so zero means header is good - - @param FfsHeader Pointer to FFS File Header - - @retval Checksum of the header - -**/ -STATIC -UINT8 -CalculateHeaderChecksum ( - IN EFI_FFS_FILE_HEADER *FileHeader - ) -{ - UINT8 *Ptr; - UINTN Index; - UINT8 Sum; - - Sum = 0; - Ptr = (UINT8 *)FileHeader; - - for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) { - Sum = (UINT8)(Sum + Ptr[Index]); - Sum = (UINT8)(Sum + Ptr[Index+1]); - Sum = (UINT8)(Sum + Ptr[Index+2]); - Sum = (UINT8)(Sum + Ptr[Index+3]); - } - - for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) { - Sum = (UINT8)(Sum + Ptr[Index]); - } - - // - // State field (since this indicates the different state of file). - // - Sum = (UINT8)(Sum - FileHeader->State); - // - // Checksum field of the file is not part of the header checksum. - // - Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File); - - return Sum; -} - - -/** - Given a FileHandle return the VolumeHandle - - @param FileHandle File handle to look up - @param VolumeHandle Match for FileHandle - - @retval TRUE VolumeHandle is valid - -**/ -STATIC -BOOLEAN -EFIAPI -FileHandleToVolume ( - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_PEI_FV_HANDLE *VolumeHandle - ) -{ - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = GetHobList (); - if (Hob.Raw == NULL) { - return FALSE; - } - - do { - Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw); - if (Hob.Raw != NULL) { - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(Hob.FirmwareVolume->BaseAddress); - if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \ - ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) { - *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader; - return TRUE; - } - - Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob)); - } - } while (Hob.Raw != NULL); - - return FALSE; -} - - - -/** - Given the input file pointer, search for the next matching file in the - FFS volume as defined by SearchType. The search starts from FileHeader inside - the Firmware Volume defined by FwVolHeader. - - @param FileHandle File handle to look up - @param VolumeHandle Match for FileHandle - - -**/ -EFI_STATUS -FindFileEx ( - IN CONST EFI_PEI_FV_HANDLE FvHandle, - IN CONST EFI_GUID *FileName, OPTIONAL - IN EFI_FV_FILETYPE SearchType, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_FFS_FILE_HEADER **FileHeader; - EFI_FFS_FILE_HEADER *FfsFileHeader; - EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo; - UINT32 FileLength; - UINT32 FileOccupiedSize; - UINT32 FileOffset; - UINT64 FvLength; - UINT8 ErasePolarity; - UINT8 FileState; - - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle; - FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle; - - FvLength = FwVolHeader->FvLength; - if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) { - ErasePolarity = 1; - } else { - ErasePolarity = 0; - } - - // - // If FileHeader is not specified (NULL) or FileName is not NULL, - // start with the first file in the firmware volume. Otherwise, - // start from the FileHeader. - // - if ((*FileHeader == NULL) || (FileName != NULL)) { - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength); - if (FwVolHeader->ExtHeaderOffset != 0) { - FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset); - FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize); - } - } else { - // - // Length is 24 bits wide so mask upper 8 bits - // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned. - // - FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF; - FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize); - } - - FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader); - ASSERT (FileOffset <= 0xFFFFFFFF); - - while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) { - // - // Get FileState which is the highest bit of the State - // - FileState = GetFileState (ErasePolarity, FfsFileHeader); - - switch (FileState) { - - case EFI_FILE_HEADER_INVALID: - FileOffset += sizeof(EFI_FFS_FILE_HEADER); - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER)); - break; - - case EFI_FILE_DATA_VALID: - case EFI_FILE_MARKED_FOR_UPDATE: - if (CalculateHeaderChecksum (FfsFileHeader) != 0) { - ASSERT (FALSE); - *FileHeader = NULL; - return EFI_NOT_FOUND; - } - - FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF; - FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8); - - if (FileName != NULL) { - if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) { - *FileHeader = FfsFileHeader; - return EFI_SUCCESS; - } - } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) && - (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) { - *FileHeader = FfsFileHeader; - return EFI_SUCCESS; - } - - FileOffset += FileOccupiedSize; - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); - break; - - case EFI_FILE_DELETED: - FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF; - FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8); - FileOffset += FileOccupiedSize; - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); - break; - - default: - *FileHeader = NULL; - return EFI_NOT_FOUND; - } - } - - - *FileHeader = NULL; - return EFI_NOT_FOUND; -} - - -/** - Go through the file to search SectionType section, - when meeting an encapsuled section. - - @param SectionType - Filter to find only section of this type. - @param Section - From where to search. - @param SectionSize - The file size to search. - @param OutputBuffer - Pointer to the section to search. - - @retval EFI_SUCCESS -**/ -EFI_STATUS -FfsProcessSection ( - IN EFI_SECTION_TYPE SectionType, - IN EFI_COMMON_SECTION_HEADER *Section, - IN UINTN SectionSize, - OUT VOID **OutputBuffer - ) -{ - EFI_STATUS Status; - UINT32 SectionLength; - UINT32 ParsedLength; - EFI_COMPRESSION_SECTION *CompressionSection; - UINTN DstBufferSize; - VOID *ScratchBuffer; - UINT32 ScratchBufferSize; - VOID *DstBuffer; - UINT16 SectionAttribute; - UINT32 AuthenticationStatus; - - - *OutputBuffer = NULL; - ParsedLength = 0; - Status = EFI_NOT_FOUND; - while (ParsedLength < SectionSize) { - if (Section->Type == SectionType) { - *OutputBuffer = (VOID *)(Section + 1); - - return EFI_SUCCESS; - } else if ((Section->Type == EFI_SECTION_COMPRESSION) || (Section->Type == EFI_SECTION_GUID_DEFINED)) { - - if (Section->Type == EFI_SECTION_COMPRESSION) { - CompressionSection = (EFI_COMPRESSION_SECTION *) Section; - SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF; - - if (CompressionSection->CompressionType != EFI_STANDARD_COMPRESSION) { - return EFI_UNSUPPORTED; - } - - Status = UefiDecompressGetInfo ( - (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1), - (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION), - (UINT32 *) &DstBufferSize, - &ScratchBufferSize - ); - } else if (Section->Type == EFI_SECTION_GUID_DEFINED) { - Status = ExtractGuidedSectionGetInfo ( - Section, - (UINT32 *) &DstBufferSize, - &ScratchBufferSize, - &SectionAttribute - ); - } - - if (EFI_ERROR (Status)) { - // - // GetInfo failed - // - DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status)); - return EFI_NOT_FOUND; - } - // - // 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) + 1); - if (DstBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header - // to make section data at page alignment. - // - DstBuffer = (UINT8 *)DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER); - // - // Call decompress function - // - if (Section->Type == EFI_SECTION_COMPRESSION) { - Status = UefiDecompress ( - (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1), - DstBuffer, - ScratchBuffer - ); - } else if (Section->Type == EFI_SECTION_GUID_DEFINED) { - Status = ExtractGuidedSectionDecode ( - Section, - &DstBuffer, - ScratchBuffer, - &AuthenticationStatus - ); - } - - if (EFI_ERROR (Status)) { - // - // Decompress failed - // - DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status)); - return EFI_NOT_FOUND; - } else { - return FfsProcessSection ( - SectionType, - DstBuffer, - DstBufferSize, - OutputBuffer - ); - } - } - - // - // Size is 24 bits wide so mask upper 8 bits. - // SectionLength is adjusted it is 4 byte aligned. - // Go to the next section - // - SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF; - SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); - ASSERT (SectionLength != 0); - ParsedLength += SectionLength; - Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength); - } - - return EFI_NOT_FOUND; -} - - - -/** - This service enables discovery sections of a given type within a valid FFS file. - - @param SearchType The value of the section type to find. - @param FfsFileHeader A pointer to the file header that contains the set of sections to - be searched. - @param SectionData A pointer to the discovered section, if successful. - - @retval EFI_SUCCESS The section was found. - @retval EFI_NOT_FOUND The section was not found. - -**/ -EFI_STATUS -EFIAPI -FfsFindSectionData ( - IN EFI_SECTION_TYPE SectionType, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData - ) -{ - EFI_FFS_FILE_HEADER *FfsFileHeader; - UINT32 FileSize; - EFI_COMMON_SECTION_HEADER *Section; - - FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle); - - // - // Size is 24 bits wide so mask upper 8 bits. - // Does not include FfsFileHeader header size - // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. - // - Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1); - FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF; - FileSize -= sizeof (EFI_FFS_FILE_HEADER); - - return FfsProcessSection ( - SectionType, - Section, - FileSize, - SectionData - ); -} - - - - - - -/** - This service enables discovery of additional firmware files. - - @param SearchType A filter to find files only of this type. - @param FwVolHeader Pointer to the firmware volume header of the volume to search. - This parameter must point to a valid FFS volume. - @param FileHeader Pointer to the current file from which to begin searching. - - @retval EFI_SUCCESS The file was found. - @retval EFI_NOT_FOUND The file was not found. - @retval EFI_NOT_FOUND The header checksum was not zero. - -**/ -EFI_STATUS -EFIAPI -FfsFindNextFile ( - IN UINT8 SearchType, - IN EFI_PEI_FV_HANDLE VolumeHandle, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - return FindFileEx (VolumeHandle, NULL, SearchType, FileHandle); -} - - -/** - This service enables discovery of additional firmware volumes. - - @param Instance This instance of the firmware volume to find. The value 0 is the - Boot Firmware Volume (BFV). - @param FwVolHeader Pointer to the firmware volume header of the volume to return. - - @retval EFI_SUCCESS The volume was found. - @retval EFI_NOT_FOUND The volume was not found. - -**/ -EFI_STATUS -EFIAPI -FfsFindNextVolume ( - IN UINTN Instance, - IN OUT EFI_PEI_FV_HANDLE *VolumeHandle - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - - Hob.Raw = GetHobList (); - if (Hob.Raw == NULL) { - return EFI_NOT_FOUND; - } - - do { - Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw); - if (Hob.Raw != NULL) { - if (Instance-- == 0) { - *VolumeHandle = (EFI_PEI_FV_HANDLE)(UINTN)(Hob.FirmwareVolume->BaseAddress); - return EFI_SUCCESS; - } - - Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob)); - } - } while (Hob.Raw != NULL); - - return EFI_NOT_FOUND; - -} - - -/** - Find a file in the volume by name - - @param FileName A pointer to the name of the file to - find within the firmware volume. - - @param VolumeHandle The firmware volume to search FileHandle - Upon exit, points to the found file's - handle or NULL if it could not be found. - - @retval EFI_SUCCESS File was found. - - @retval EFI_NOT_FOUND File was not found. - - @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or - FileName was NULL. - -**/ -EFI_STATUS -EFIAPI -FfsFindFileByName ( - IN CONST EFI_GUID *FileName, - IN EFI_PEI_FV_HANDLE VolumeHandle, - OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - EFI_STATUS Status; - if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - Status = FindFileEx (VolumeHandle, FileName, 0, FileHandle); - if (Status == EFI_NOT_FOUND) { - *FileHandle = NULL; - } - return Status; -} - - - - -/** - Get information about the file by name. - - @param FileHandle Handle of the file. - - @param FileInfo Upon exit, points to the file's - information. - - @retval EFI_SUCCESS File information returned. - - @retval EFI_INVALID_PARAMETER If FileHandle does not - represent a valid file. - - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -FfsGetFileInfo ( - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO *FileInfo - ) -{ - UINT8 FileState; - UINT8 ErasePolarity; - EFI_FFS_FILE_HEADER *FileHeader; - EFI_PEI_FV_HANDLE VolumeHandle; - - if ((FileHandle == NULL) || (FileInfo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - VolumeHandle = 0; - // - // Retrieve the FirmwareVolume which the file resides in. - // - if (!FileHandleToVolume(FileHandle, &VolumeHandle)) { - return EFI_INVALID_PARAMETER; - } - - if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB2_ERASE_POLARITY) { - ErasePolarity = 1; - } else { - ErasePolarity = 0; - } - - // - // Get FileState which is the highest bit of the State - // - FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle); - - switch (FileState) { - case EFI_FILE_DATA_VALID: - case EFI_FILE_MARKED_FOR_UPDATE: - break; - default: - return EFI_INVALID_PARAMETER; - } - - FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle; - CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID)); - FileInfo->FileType = FileHeader->Type; - FileInfo->FileAttributes = FileHeader->Attributes; - FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER); - FileInfo->Buffer = (FileHeader + 1); - return EFI_SUCCESS; -} - - -/** - Get Information about the volume by name - - @param VolumeHandle Handle of the volume. - - @param VolumeInfo Upon exit, points to the volume's - information. - - @retval EFI_SUCCESS File information returned. - - @retval EFI_INVALID_PARAMETER If FileHandle does not - represent a valid file. - - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -FfsGetVolumeInfo ( - IN EFI_PEI_FV_HANDLE VolumeHandle, - OUT EFI_FV_INFO *VolumeInfo - ) -{ - EFI_FIRMWARE_VOLUME_HEADER FwVolHeader; - EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo; - - if (VolumeInfo == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // VolumeHandle may not align at 8 byte, - // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. - // So, Copy FvHeader into the local FvHeader structure. - // - CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); - // - // Check Fv Image Signature - // - if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - VolumeInfo->FvAttributes = FwVolHeader.Attributes; - VolumeInfo->FvStart = (VOID *) VolumeHandle; - VolumeInfo->FvSize = FwVolHeader.FvLength; - CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID)); - - if (FwVolHeader.ExtHeaderOffset != 0) { - FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset); - CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID)); - } - return EFI_SUCCESS; -} - - - -/** - Search through every FV until you find a file of type FileType - - @param FileType File handle of a Fv type file. - @param Volumehandle On succes Volume Handle of the match - @param FileHandle On success File Handle of the match - - @retval EFI_NOT_FOUND FV image can't be found. - @retval EFI_SUCCESS Successfully found FileType - -**/ -EFI_STATUS -EFIAPI -FfsAnyFvFindFirstFile ( - IN EFI_FV_FILETYPE FileType, - OUT EFI_PEI_FV_HANDLE *VolumeHandle, - OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - EFI_STATUS Status; - UINTN Instance; - - // - // Search every FV for the DXE Core - // - Instance = 0; - *FileHandle = NULL; - - while (1) - { - Status = FfsFindNextVolume (Instance++, VolumeHandle); - if (EFI_ERROR (Status)) - { - break; - } - - Status = FfsFindNextFile (FileType, *VolumeHandle, FileHandle); - if (!EFI_ERROR (Status)) - { - break; - } - } - - return Status; -} - - - -/** - Get Fv image from the FV type file, then add FV & FV2 Hob. - - @param FileHandle File handle of a Fv type file. - - - @retval EFI_NOT_FOUND FV image can't be found. - @retval EFI_SUCCESS Successfully to process it. - -**/ -EFI_STATUS -EFIAPI -FfsProcessFvFile ( - IN EFI_PEI_FILE_HANDLE FvFileHandle - ) -{ - EFI_STATUS Status; - EFI_PEI_FV_HANDLE FvImageHandle; - EFI_FV_INFO FvImageInfo; - UINT32 FvAlignment; - VOID *FvBuffer; - EFI_PEI_HOB_POINTERS HobFv2; - - FvBuffer = NULL; - - - // - // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already - // been extracted. - // - HobFv2.Raw = GetHobList (); - while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) { - if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) { - // - // this FILE has been dispatched, it will not be dispatched again. - // - return EFI_SUCCESS; - } - HobFv2.Raw = GET_NEXT_HOB (HobFv2); - } - - // - // Find FvImage in FvFile - // - Status = FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FvFileHandle, (VOID **)&FvImageHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Collect FvImage Info. - // - ZeroMem (&FvImageInfo, sizeof (FvImageInfo)); - Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo); - ASSERT_EFI_ERROR (Status); - - // - // FvAlignment must be more than 8 bytes required by FvHeader structure. - // - FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16); - if (FvAlignment < 8) { - FvAlignment = 8; - } - - // - // Check FvImage - // - if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) { - FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment); - if (FvBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize); - // - // Update FvImageInfo after reload FvImage to new aligned memory - // - FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo); - } - - - // - // Inform HOB consumer phase, i.e. DXE core, the existance of this FV - // - BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart, FvImageInfo.FvSize); - - // - // Makes the encapsulated volume show up in DXE phase to skip processing of - // encapsulated file again. - // - BuildFv2Hob ( - (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart, - FvImageInfo.FvSize, - &FvImageInfo.FvName, - &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name) - ); - - return EFI_SUCCESS; -} - - +/** @file
+ Implementation of the 6 PEI Ffs (FV) APIs in library form.
+
+ This code only knows about a FV if it has a EFI_HOB_TYPE_FV entry in the HOB list
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PrePi.h>
+#include <Library/ExtractGuidedSectionLib.h>
+
+
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+
+/**
+ Returns the highest bit set of the State field
+
+ @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
+ in the Attributes field.
+ @param FfsHeader Pointer to FFS File Header
+
+
+ @retval the highest bit in the State field
+
+**/
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState(
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+
+/**
+ Calculates the checksum of the header of a file.
+ The header is a zero byte checksum, so zero means header is good
+
+ @param FfsHeader Pointer to FFS File Header
+
+ @retval Checksum of the header
+
+**/
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+{
+ UINT8 *Ptr;
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+ Ptr = (UINT8 *)FileHeader;
+
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
+ Sum = (UINT8)(Sum + Ptr[Index]);
+ Sum = (UINT8)(Sum + Ptr[Index+1]);
+ Sum = (UINT8)(Sum + Ptr[Index+2]);
+ Sum = (UINT8)(Sum + Ptr[Index+3]);
+ }
+
+ for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ Sum = (UINT8)(Sum + Ptr[Index]);
+ }
+
+ //
+ // State field (since this indicates the different state of file).
+ //
+ Sum = (UINT8)(Sum - FileHeader->State);
+ //
+ // Checksum field of the file is not part of the header checksum.
+ //
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+
+/**
+ Given a FileHandle return the VolumeHandle
+
+ @param FileHandle File handle to look up
+ @param VolumeHandle Match for FileHandle
+
+ @retval TRUE VolumeHandle is valid
+
+**/
+STATIC
+BOOLEAN
+EFIAPI
+FileHandleToVolume (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetHobList ();
+ if (Hob.Raw == NULL) {
+ return FALSE;
+ }
+
+ do {
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
+ if (Hob.Raw != NULL) {
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(Hob.FirmwareVolume->BaseAddress);
+ if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \
+ ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {
+ *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
+ return TRUE;
+ }
+
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
+ }
+ } while (Hob.Raw != NULL);
+
+ return FALSE;
+}
+
+
+
+/**
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+ @param FileHandle File handle to look up
+ @param VolumeHandle Match for FileHandle
+
+
+**/
+EFI_STATUS
+FindFileEx (
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN CONST EFI_GUID *FileName, OPTIONAL
+ IN EFI_FV_FILETYPE SearchType,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FFS_FILE_HEADER **FileHeader;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+ UINT32 FileOffset;
+ UINT64 FvLength;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
+ FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
+
+ FvLength = FwVolHeader->FvLength;
+ if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // If FileHeader is not specified (NULL) or FileName is not NULL,
+ // start with the first file in the firmware volume. Otherwise,
+ // start from the FileHeader.
+ //
+ if ((*FileHeader == NULL) || (FileName != NULL)) {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ if (FwVolHeader->ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
+ }
+ } else {
+ //
+ // Length is 24 bits wide so mask upper 8 bits
+ // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
+ }
+
+ FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
+ ASSERT (FileOffset <= 0xFFFFFFFF);
+
+ while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
+ ASSERT (FALSE);
+ *FileHeader = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+
+ if (FileName != NULL) {
+ if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+ } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&
+ (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ *FileHeader = NULL;
+ return EFI_NOT_FOUND;
+ }
+ }
+
+
+ *FileHeader = NULL;
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ Go through the file to search SectionType section,
+ when meeting an encapsuled section.
+
+ @param SectionType - Filter to find only section of this type.
+ @param Section - From where to search.
+ @param SectionSize - The file size to search.
+ @param OutputBuffer - Pointer to the section to search.
+
+ @retval EFI_SUCCESS
+**/
+EFI_STATUS
+FfsProcessSection (
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_COMMON_SECTION_HEADER *Section,
+ IN UINTN SectionSize,
+ OUT VOID **OutputBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 SectionLength;
+ UINT32 ParsedLength;
+ EFI_COMPRESSION_SECTION *CompressionSection;
+ UINTN DstBufferSize;
+ VOID *ScratchBuffer;
+ UINT32 ScratchBufferSize;
+ VOID *DstBuffer;
+ UINT16 SectionAttribute;
+ UINT32 AuthenticationStatus;
+
+
+ *OutputBuffer = NULL;
+ ParsedLength = 0;
+ Status = EFI_NOT_FOUND;
+ while (ParsedLength < SectionSize) {
+ if (Section->Type == SectionType) {
+ *OutputBuffer = (VOID *)(Section + 1);
+
+ return EFI_SUCCESS;
+ } else if ((Section->Type == EFI_SECTION_COMPRESSION) || (Section->Type == EFI_SECTION_GUID_DEFINED)) {
+
+ if (Section->Type == EFI_SECTION_COMPRESSION) {
+ CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+
+ if (CompressionSection->CompressionType != EFI_STANDARD_COMPRESSION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = UefiDecompressGetInfo (
+ (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
+ (UINT32 *) &DstBufferSize,
+ &ScratchBufferSize
+ );
+ } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ Status = ExtractGuidedSectionGetInfo (
+ Section,
+ (UINT32 *) &DstBufferSize,
+ &ScratchBufferSize,
+ &SectionAttribute
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // GetInfo failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
+ }
+ //
+ // 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) + 1);
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
+ // to make section data at page alignment.
+ //
+ DstBuffer = (UINT8 *)DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
+ //
+ // Call decompress function
+ //
+ if (Section->Type == EFI_SECTION_COMPRESSION) {
+ Status = UefiDecompress (
+ (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ DstBuffer,
+ ScratchBuffer
+ );
+ } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ Status = ExtractGuidedSectionDecode (
+ Section,
+ &DstBuffer,
+ ScratchBuffer,
+ &AuthenticationStatus
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Decompress failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
+ } else {
+ return FfsProcessSection (
+ SectionType,
+ DstBuffer,
+ DstBufferSize,
+ OutputBuffer
+ );
+ }
+ }
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ ASSERT (SectionLength != 0);
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+
+/**
+ This service enables discovery sections of a given type within a valid FFS file.
+
+ @param SearchType The value of the section type to find.
+ @param FfsFileHeader A pointer to the file header that contains the set of sections to
+ be searched.
+ @param SectionData A pointer to the discovered section, if successful.
+
+ @retval EFI_SUCCESS The section was found.
+ @retval EFI_NOT_FOUND The section was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindSectionData (
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ )
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // Does not include FfsFileHeader header size
+ // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
+ FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileSize -= sizeof (EFI_FFS_FILE_HEADER);
+
+ return FfsProcessSection (
+ SectionType,
+ Section,
+ FileSize,
+ SectionData
+ );
+}
+
+
+
+
+
+
+/**
+ This service enables discovery of additional firmware files.
+
+ @param SearchType A filter to find files only of this type.
+ @param FwVolHeader Pointer to the firmware volume header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ @param FileHeader Pointer to the current file from which to begin searching.
+
+ @retval EFI_SUCCESS The file was found.
+ @retval EFI_NOT_FOUND The file was not found.
+ @retval EFI_NOT_FOUND The header checksum was not zero.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindNextFile (
+ IN UINT8 SearchType,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ return FindFileEx (VolumeHandle, NULL, SearchType, FileHandle);
+}
+
+
+/**
+ This service enables discovery of additional firmware volumes.
+
+ @param Instance This instance of the firmware volume to find. The value 0 is the
+ Boot Firmware Volume (BFV).
+ @param FwVolHeader Pointer to the firmware volume header of the volume to return.
+
+ @retval EFI_SUCCESS The volume was found.
+ @retval EFI_NOT_FOUND The volume was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindNextVolume (
+ IN UINTN Instance,
+ IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+
+ Hob.Raw = GetHobList ();
+ if (Hob.Raw == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ do {
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
+ if (Hob.Raw != NULL) {
+ if (Instance-- == 0) {
+ *VolumeHandle = (EFI_PEI_FV_HANDLE)(UINTN)(Hob.FirmwareVolume->BaseAddress);
+ return EFI_SUCCESS;
+ }
+
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
+ }
+ } while (Hob.Raw != NULL);
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+/**
+ Find a file in the volume by name
+
+ @param FileName A pointer to the name of the file to
+ find within the firmware volume.
+
+ @param VolumeHandle The firmware volume to search FileHandle
+ Upon exit, points to the found file's
+ handle or NULL if it could not be found.
+
+ @retval EFI_SUCCESS File was found.
+
+ @retval EFI_NOT_FOUND File was not found.
+
+ @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
+ FileName was NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindFileByName (
+ IN CONST EFI_GUID *FileName,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ EFI_STATUS Status;
+ if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = FindFileEx (VolumeHandle, FileName, 0, FileHandle);
+ if (Status == EFI_NOT_FOUND) {
+ *FileHandle = NULL;
+ }
+ return Status;
+}
+
+
+
+
+/**
+ Get information about the file by name.
+
+ @param FileHandle Handle of the file.
+
+ @param FileInfo Upon exit, points to the file's
+ information.
+
+ @retval EFI_SUCCESS File information returned.
+
+ @retval EFI_INVALID_PARAMETER If FileHandle does not
+ represent a valid file.
+
+ @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsGetFileInfo (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ )
+{
+ UINT8 FileState;
+ UINT8 ErasePolarity;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+
+ if ((FileHandle == NULL) || (FileInfo == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VolumeHandle = 0;
+ //
+ // Retrieve the FirmwareVolume which the file resides in.
+ //
+ if (!FileHandleToVolume(FileHandle, &VolumeHandle)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
+
+ switch (FileState) {
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
+ CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
+ FileInfo->FileType = FileHeader->Type;
+ FileInfo->FileAttributes = FileHeader->Attributes;
+ FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
+ FileInfo->Buffer = (FileHeader + 1);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get Information about the volume by name
+
+ @param VolumeHandle Handle of the volume.
+
+ @param VolumeInfo Upon exit, points to the volume's
+ information.
+
+ @retval EFI_SUCCESS File information returned.
+
+ @retval EFI_INVALID_PARAMETER If FileHandle does not
+ represent a valid file.
+
+ @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+
+ if (VolumeInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // VolumeHandle may not align at 8 byte,
+ // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
+ // So, Copy FvHeader into the local FvHeader structure.
+ //
+ CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+ //
+ // Check Fv Image Signature
+ //
+ if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ VolumeInfo->FvAttributes = FwVolHeader.Attributes;
+ VolumeInfo->FvStart = (VOID *) VolumeHandle;
+ VolumeInfo->FvSize = FwVolHeader.FvLength;
+ CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));
+
+ if (FwVolHeader.ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);
+ CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Search through every FV until you find a file of type FileType
+
+ @param FileType File handle of a Fv type file.
+ @param Volumehandle On succes Volume Handle of the match
+ @param FileHandle On success File Handle of the match
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully found FileType
+
+**/
+EFI_STATUS
+EFIAPI
+FfsAnyFvFindFirstFile (
+ IN EFI_FV_FILETYPE FileType,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN Instance;
+
+ //
+ // Search every FV for the DXE Core
+ //
+ Instance = 0;
+ *FileHandle = NULL;
+
+ while (1)
+ {
+ Status = FfsFindNextVolume (Instance++, VolumeHandle);
+ if (EFI_ERROR (Status))
+ {
+ break;
+ }
+
+ Status = FfsFindNextFile (FileType, *VolumeHandle, FileHandle);
+ if (!EFI_ERROR (Status))
+ {
+ break;
+ }
+ }
+
+ return Status;
+}
+
+
+
+/**
+ Get Fv image from the FV type file, then add FV & FV2 Hob.
+
+ @param FileHandle File handle of a Fv type file.
+
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully to process it.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsProcessFvFile (
+ IN EFI_PEI_FILE_HANDLE FvFileHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE FvImageHandle;
+ EFI_FV_INFO FvImageInfo;
+ UINT32 FvAlignment;
+ VOID *FvBuffer;
+ EFI_PEI_HOB_POINTERS HobFv2;
+
+ FvBuffer = NULL;
+
+
+ //
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
+ // been extracted.
+ //
+ HobFv2.Raw = GetHobList ();
+ while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
+ if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {
+ //
+ // this FILE has been dispatched, it will not be dispatched again.
+ //
+ return EFI_SUCCESS;
+ }
+ HobFv2.Raw = GET_NEXT_HOB (HobFv2);
+ }
+
+ //
+ // Find FvImage in FvFile
+ //
+ Status = FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FvFileHandle, (VOID **)&FvImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Collect FvImage Info.
+ //
+ ZeroMem (&FvImageInfo, sizeof (FvImageInfo));
+ Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // FvAlignment must be more than 8 bytes required by FvHeader structure.
+ //
+ FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);
+ if (FvAlignment < 8) {
+ FvAlignment = 8;
+ }
+
+ //
+ // Check FvImage
+ //
+ if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {
+ FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment);
+ if (FvBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize);
+ //
+ // Update FvImageInfo after reload FvImage to new aligned memory
+ //
+ FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);
+ }
+
+
+ //
+ // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
+ //
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart, FvImageInfo.FvSize);
+
+ //
+ // Makes the encapsulated volume show up in DXE phase to skip processing of
+ // encapsulated file again.
+ //
+ BuildFv2Hob (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,
+ FvImageInfo.FvSize,
+ &FvImageInfo.FvName,
+ &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)
+ );
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/EmbeddedPkg/Library/PrePiLib/PrePi.h b/EmbeddedPkg/Library/PrePiLib/PrePi.h index 77fe32898b..d637277d2a 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePi.h +++ b/EmbeddedPkg/Library/PrePiLib/PrePi.h @@ -1,46 +1,46 @@ -/** @file - Library that helps implement monolithic PEI (i.e. PEI part of SEC) - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _PI_PEI_H_ -#define _PI_PEI_H_ - -#include <PiPei.h> - -#include <Library/BaseLib.h> -#include <Library/PrePiLib.h> -#include <Library/PcdLib.h> -#include <Library/DebugLib.h> -#include <Library/BaseMemoryLib.h> -#include <Library/UefiDecompressLib.h> -#include <Library/PeCoffLib.h> -#include <Library/CacheMaintenanceLib.h> -#include <Library/TimerLib.h> -#include <Library/PerformanceLib.h> - -#include <Guid/MemoryAllocationHob.h> - - -#define GET_HOB_TYPE(Hob) ((Hob).Header->HobType) -#define GET_HOB_LENGTH(Hob) ((Hob).Header->HobLength) -#define GET_NEXT_HOB(Hob) ((Hob).Raw + GET_HOB_LENGTH (Hob)) -#define END_OF_HOB_LIST(Hob) (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST) - -// -// Get the data and data size field of GUID -// -#define GET_GUID_HOB_DATA(GuidHob) ((VOID *) (((UINT8 *) &((GuidHob)->Name)) + sizeof (EFI_GUID))) -#define GET_GUID_HOB_DATA_SIZE(GuidHob) (((GuidHob)->Header).HobLength - sizeof (EFI_HOB_GUID_TYPE)) - -#endif +/** @file
+ Library that helps implement monolithic PEI (i.e. PEI part of SEC)
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PI_PEI_H_
+#define _PI_PEI_H_
+
+#include <PiPei.h>
+
+#include <Library/BaseLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDecompressLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Guid/MemoryAllocationHob.h>
+
+
+#define GET_HOB_TYPE(Hob) ((Hob).Header->HobType)
+#define GET_HOB_LENGTH(Hob) ((Hob).Header->HobLength)
+#define GET_NEXT_HOB(Hob) ((Hob).Raw + GET_HOB_LENGTH (Hob))
+#define END_OF_HOB_LIST(Hob) (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST)
+
+//
+// Get the data and data size field of GUID
+//
+#define GET_GUID_HOB_DATA(GuidHob) ((VOID *) (((UINT8 *) &((GuidHob)->Name)) + sizeof (EFI_GUID)))
+#define GET_GUID_HOB_DATA_SIZE(GuidHob) (((GuidHob)->Header).HobLength - sizeof (EFI_HOB_GUID_TYPE))
+
+#endif
diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index e46cafec3b..4cc974f1a9 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -1,226 +1,226 @@ -/** @file - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include <PrePi.h> - -// -// Hack to work in NT32 -// -EFI_STATUS - -EFIAPI - -SecWinNtPeiLoadFile ( - IN VOID *Pe32Data, - IN EFI_PHYSICAL_ADDRESS *ImageAddress, - IN UINT64 *ImageSize, - IN EFI_PHYSICAL_ADDRESS *EntryPoint - ); - - -EFI_STATUS -EFIAPI -LoadPeCoffImage ( - IN VOID *PeCoffImage, - OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *ImageSize, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint - ) -{ - RETURN_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - VOID *Buffer; - - ZeroMem (&ImageContext, sizeof (ImageContext)); - - ImageContext.Handle = PeCoffImage; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - - Status = PeCoffLoaderGetImageInfo (&ImageContext); - ASSERT_EFI_ERROR (Status); - - - // - // Allocate Memory for the image - // - Buffer = AllocatePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize)); - ASSERT (Buffer != 0); - - - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer; - - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - ASSERT_EFI_ERROR (Status); - - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); - ASSERT_EFI_ERROR (Status); - - - *ImageAddress = ImageContext.ImageAddress; - *ImageSize = ImageContext.ImageSize; - *EntryPoint = ImageContext.EntryPoint; - - // - // Flush not needed for all architectures. We could have a processor specific - // function in this library that does the no-op if needed. - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize); - - return Status; -} - - - -typedef -VOID -(EFIAPI *DXE_CORE_ENTRY_POINT) ( - IN VOID *HobStart - ); - -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 -EFIAPI -LoadDxeCoreFromFv ( - IN UINTN *FvInstance, OPTIONAL - IN UINTN StackSize - ) -{ - EFI_STATUS Status; - EFI_PEI_FV_HANDLE VolumeHandle; - EFI_PEI_FILE_HANDLE FileHandle = NULL; - - if (FvInstance != NULL) { - // - // Caller passed in a specific FV to try, so only try that one - // - Status = FfsFindNextVolume (*FvInstance, &VolumeHandle); - if (!EFI_ERROR (Status)) { - Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle); - } - } else { - Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle); - } - - if (!EFI_ERROR (Status)) { - return LoadDxeCoreFromFfsFile (FileHandle, StackSize); - } - - return Status; -} - - -EFI_STATUS -EFIAPI -DecompressFirstFv ( - VOID - ) -{ - EFI_STATUS Status; - EFI_PEI_FV_HANDLE VolumeHandle; - EFI_PEI_FILE_HANDLE FileHandle; - - Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle); - if (!EFI_ERROR (Status)) { - Status = FfsProcessFvFile (FileHandle); - } - - return Status; -} - - +/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PrePi.h>
+
+//
+// Hack to work in NT32
+//
+EFI_STATUS
+
+EFIAPI
+
+SecWinNtPeiLoadFile (
+ IN VOID *Pe32Data,
+ IN EFI_PHYSICAL_ADDRESS *ImageAddress,
+ IN UINT64 *ImageSize,
+ IN EFI_PHYSICAL_ADDRESS *EntryPoint
+ );
+
+
+EFI_STATUS
+EFIAPI
+LoadPeCoffImage (
+ IN VOID *PeCoffImage,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
+ OUT UINT64 *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+ )
+{
+ RETURN_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ VOID *Buffer;
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+
+ ImageContext.Handle = PeCoffImage;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Allocate Memory for the image
+ //
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
+ ASSERT (Buffer != 0);
+
+
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+
+ *ImageAddress = ImageContext.ImageAddress;
+ *ImageSize = ImageContext.ImageSize;
+ *EntryPoint = ImageContext.EntryPoint;
+
+ //
+ // Flush not needed for all architectures. We could have a processor specific
+ // function in this library that does the no-op if needed.
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);
+
+ return Status;
+}
+
+
+
+typedef
+VOID
+(EFIAPI *DXE_CORE_ENTRY_POINT) (
+ IN VOID *HobStart
+ );
+
+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
+EFIAPI
+LoadDxeCoreFromFv (
+ IN UINTN *FvInstance, OPTIONAL
+ IN UINTN StackSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle = NULL;
+
+ if (FvInstance != NULL) {
+ //
+ // Caller passed in a specific FV to try, so only try that one
+ //
+ Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);
+ if (!EFI_ERROR (Status)) {
+ Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
+ }
+ } else {
+ Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ return LoadDxeCoreFromFfsFile (FileHandle, StackSize);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+DecompressFirstFv (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+
+ Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);
+ if (!EFI_ERROR (Status)) {
+ Status = FfsProcessFvFile (FileHandle);
+ }
+
+ return Status;
+}
+
+
diff --git a/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c b/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c index f898808deb..8d60d5ab5d 100644 --- a/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c +++ b/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c @@ -1,327 +1,327 @@ -/** @file - Library that helps implement monolithic PEI - - Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include <PrePi.h> -#include <Library/ReportStatusCodeLib.h> -#include <Library/SerialPortLib.h> -#include <Library/PrintLib.h> - -#include <Protocol/StatusCode.h> -#include <Guid/StatusCodeDataTypeId.h> -#include <Guid/StatusCodeDataTypeDebug.h> -#include <FrameworkPei.h> - -#define EFI_STATUS_CODE_DATA_MAX_SIZE 200 - -EFI_STATUS -EFIAPI -SerialReportStatusCode ( - IN EFI_STATUS_CODE_TYPE CodeType, - IN EFI_STATUS_CODE_VALUE Value, - IN UINT32 Instance, - IN CONST EFI_GUID *CallerId, - IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL - ); - - -EFI_STATUS_CODE_PROTOCOL gStatusCode = { - (EFI_REPORT_STATUS_CODE)SerialReportStatusCode -}; - -/** - Extracts ASSERT() information from a status code structure. - - Converts the status code specified by CodeType, Value, and Data to the ASSERT() - arguments specified by Filename, Description, and LineNumber. If CodeType is - an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and - Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract - Filename, Description, and LineNumber from the optional data area of the - status code buffer specified by Data. The optional data area of Data contains - a Null-terminated ASCII string for the FileName, followed by a Null-terminated - ASCII string for the Description, followed by a 32-bit LineNumber. If the - ASSERT() information could be extracted from Data, then return TRUE. - Otherwise, FALSE is returned. - - If Data is NULL, then ASSERT(). - If Filename is NULL, then ASSERT(). - If Description is NULL, then ASSERT(). - If LineNumber is NULL, then ASSERT(). - - @param CodeType The type of status code being converted. - @param Value The status code value being converted. - @param Data Pointer to status code data buffer. - @param Filename Pointer to the source file name that generated the ASSERT(). - @param Description Pointer to the description of the ASSERT(). - @param LineNumber Pointer to source line number that generated the ASSERT(). - - @retval TRUE The status code specified by CodeType, Value, and Data was - converted ASSERT() arguments specified by Filename, Description, - and LineNumber. - @retval FALSE The status code specified by CodeType, Value, and Data could - not be converted to ASSERT() arguments. - -**/ -BOOLEAN -EFIAPI -ReportStatusCodeExtractAssertInfo ( - IN EFI_STATUS_CODE_TYPE CodeType, - IN EFI_STATUS_CODE_VALUE Value, - IN CONST EFI_STATUS_CODE_DATA *Data, - OUT CHAR8 **Filename, - OUT CHAR8 **Description, - OUT UINT32 *LineNumber - ) -{ - EFI_DEBUG_ASSERT_DATA *AssertData; - - ASSERT (Data != NULL); - ASSERT (Filename != NULL); - ASSERT (Description != NULL); - ASSERT (LineNumber != NULL); - - if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) && - ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) && - ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) { - AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1); - *Filename = (CHAR8 *)(AssertData + 1); - *Description = *Filename + AsciiStrLen (*Filename) + 1; - *LineNumber = AssertData->LineNumber; - return TRUE; - } - return FALSE; -} - - -/** - Extracts DEBUG() information from a status code structure. - - Converts the status code specified by Data to the DEBUG() arguments specified - by ErrorLevel, Marker, and Format. If type GUID in Data is - EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and - Format from the optional data area of the status code buffer specified by Data. - The optional data area of Data contains a 32-bit ErrorLevel followed by Marker - which is 12 UINTN parameters, followed by a Null-terminated ASCII string for - the Format. If the DEBUG() information could be extracted from Data, then - return TRUE. Otherwise, FALSE is returned. - - If Data is NULL, then ASSERT(). - If ErrorLevel is NULL, then ASSERT(). - If Marker is NULL, then ASSERT(). - If Format is NULL, then ASSERT(). - - @param Data Pointer to status code data buffer. - @param ErrorLevel Pointer to error level mask for a debug message. - @param Marker Pointer to the variable argument list associated with Format. - @param Format Pointer to a Null-terminated ASCII format string of a - debug message. - - @retval TRUE The status code specified by Data was converted DEBUG() arguments - specified by ErrorLevel, Marker, and Format. - @retval FALSE The status code specified by Data could not be converted to - DEBUG() arguments. - -**/ -BOOLEAN -EFIAPI -ReportStatusCodeExtractDebugInfo ( - IN CONST EFI_STATUS_CODE_DATA *Data, - OUT UINT32 *ErrorLevel, - OUT BASE_LIST *Marker, - OUT CHAR8 **Format - ) -{ - EFI_DEBUG_INFO *DebugInfo; - - ASSERT (Data != NULL); - ASSERT (ErrorLevel != NULL); - ASSERT (Marker != NULL); - ASSERT (Format != NULL); - - // - // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE - // - if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) { - return FALSE; - } - - // - // Retrieve the debug information from the status code record - // - DebugInfo = (EFI_DEBUG_INFO *)(Data + 1); - - *ErrorLevel = DebugInfo->ErrorLevel; - - // - // The first 12 * UINTN bytes of the string are really an - // argument stack to support varargs on the Format string. - // - *Marker = (BASE_LIST) (DebugInfo + 1); - *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12); - - return TRUE; -} - - - - -EFI_STATUS -EFIAPI -SerialReportStatusCode ( - IN EFI_STATUS_CODE_TYPE CodeType, - IN EFI_STATUS_CODE_VALUE Value, - IN UINT32 Instance, - IN CONST EFI_GUID *CallerId, - IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL - ) -{ - CHAR8 *Filename; - CHAR8 *Description; - CHAR8 *Format; - CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE]; - UINT32 ErrorLevel; - UINT32 LineNumber; - UINTN CharCount; - BASE_LIST Marker; - EFI_DEBUG_INFO *DebugInfo; - - Buffer[0] = '\0'; - - - if (Data != NULL && - ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) { - - // - // Print ASSERT() information into output buffer. - // - CharCount = AsciiSPrint ( - Buffer, - EFI_STATUS_CODE_DATA_MAX_SIZE, - "\n\rASSERT!: %a (%d): %a\n\r", - Filename, - LineNumber, - Description - ); - - - // - // Callout to standard output. - // - SerialPortWrite ((UINT8 *)Buffer, CharCount); - return EFI_SUCCESS; - - } else if (Data != NULL && - ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) { - - // - // Print DEBUG() information into output buffer. - // - CharCount = AsciiBSPrint ( - Buffer, - EFI_STATUS_CODE_DATA_MAX_SIZE, - Format, - Marker - ); - - } else if (Data != NULL && - CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) && - (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) { - - // - // Print specific data into output buffer. - // - DebugInfo = (EFI_DEBUG_INFO *) (Data + 1); - Marker = (BASE_LIST) (DebugInfo + 1); - Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12); - - CharCount = AsciiBSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker); - - } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { - // - // Print ERROR information into output buffer. - // - - CharCount = AsciiSPrint ( - Buffer, - EFI_STATUS_CODE_DATA_MAX_SIZE, - "ERROR: C%x:V%x I%x", - CodeType, - Value, - Instance - ); - - // - // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers. - // - if (CallerId != NULL) { - CharCount += AsciiSPrint ( - &Buffer[CharCount - 1], - (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)), - " %g", - CallerId - ); - } - - if (Data != NULL) { - CharCount += AsciiSPrint ( - &Buffer[CharCount - 1], - (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)), - " %x", - Data - ); - - } - - - CharCount += AsciiSPrint ( - &Buffer[CharCount - 1], - (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)), - "\n\r" - ); - - } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { - CharCount = AsciiSPrint ( - Buffer, - EFI_STATUS_CODE_DATA_MAX_SIZE, - "PROGRESS CODE: V%x I%x\n\r", - Value, - Instance - ); - } else { - CharCount = AsciiSPrint ( - Buffer, - EFI_STATUS_CODE_DATA_MAX_SIZE, - "Undefined: C%x:V%x I%x\n\r", - CodeType, - Value, - Instance - ); - - } - - SerialPortWrite ((UINT8 *)Buffer, CharCount); - return EFI_SUCCESS; - -} - - -VOID -EFIAPI -AddDxeCoreReportStatusCodeCallback ( - VOID - ) -{ - BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid, &gStatusCode, sizeof(VOID *)); -} - +/** @file
+ Library that helps implement monolithic PEI
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PrePi.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PrintLib.h>
+
+#include <Protocol/StatusCode.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+#include <FrameworkPei.h>
+
+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
+
+EFI_STATUS
+EFIAPI
+SerialReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN CONST EFI_GUID *CallerId,
+ IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
+ );
+
+
+EFI_STATUS_CODE_PROTOCOL gStatusCode = {
+ (EFI_REPORT_STATUS_CODE)SerialReportStatusCode
+};
+
+/**
+ Extracts ASSERT() information from a status code structure.
+
+ Converts the status code specified by CodeType, Value, and Data to the ASSERT()
+ arguments specified by Filename, Description, and LineNumber. If CodeType is
+ an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
+ Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
+ Filename, Description, and LineNumber from the optional data area of the
+ status code buffer specified by Data. The optional data area of Data contains
+ a Null-terminated ASCII string for the FileName, followed by a Null-terminated
+ ASCII string for the Description, followed by a 32-bit LineNumber. If the
+ ASSERT() information could be extracted from Data, then return TRUE.
+ Otherwise, FALSE is returned.
+
+ If Data is NULL, then ASSERT().
+ If Filename is NULL, then ASSERT().
+ If Description is NULL, then ASSERT().
+ If LineNumber is NULL, then ASSERT().
+
+ @param CodeType The type of status code being converted.
+ @param Value The status code value being converted.
+ @param Data Pointer to status code data buffer.
+ @param Filename Pointer to the source file name that generated the ASSERT().
+ @param Description Pointer to the description of the ASSERT().
+ @param LineNumber Pointer to source line number that generated the ASSERT().
+
+ @retval TRUE The status code specified by CodeType, Value, and Data was
+ converted ASSERT() arguments specified by Filename, Description,
+ and LineNumber.
+ @retval FALSE The status code specified by CodeType, Value, and Data could
+ not be converted to ASSERT() arguments.
+
+**/
+BOOLEAN
+EFIAPI
+ReportStatusCodeExtractAssertInfo (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN CONST EFI_STATUS_CODE_DATA *Data,
+ OUT CHAR8 **Filename,
+ OUT CHAR8 **Description,
+ OUT UINT32 *LineNumber
+ )
+{
+ EFI_DEBUG_ASSERT_DATA *AssertData;
+
+ ASSERT (Data != NULL);
+ ASSERT (Filename != NULL);
+ ASSERT (Description != NULL);
+ ASSERT (LineNumber != NULL);
+
+ if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
+ ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
+ ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {
+ AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
+ *Filename = (CHAR8 *)(AssertData + 1);
+ *Description = *Filename + AsciiStrLen (*Filename) + 1;
+ *LineNumber = AssertData->LineNumber;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/**
+ Extracts DEBUG() information from a status code structure.
+
+ Converts the status code specified by Data to the DEBUG() arguments specified
+ by ErrorLevel, Marker, and Format. If type GUID in Data is
+ EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and
+ Format from the optional data area of the status code buffer specified by Data.
+ The optional data area of Data contains a 32-bit ErrorLevel followed by Marker
+ which is 12 UINTN parameters, followed by a Null-terminated ASCII string for
+ the Format. If the DEBUG() information could be extracted from Data, then
+ return TRUE. Otherwise, FALSE is returned.
+
+ If Data is NULL, then ASSERT().
+ If ErrorLevel is NULL, then ASSERT().
+ If Marker is NULL, then ASSERT().
+ If Format is NULL, then ASSERT().
+
+ @param Data Pointer to status code data buffer.
+ @param ErrorLevel Pointer to error level mask for a debug message.
+ @param Marker Pointer to the variable argument list associated with Format.
+ @param Format Pointer to a Null-terminated ASCII format string of a
+ debug message.
+
+ @retval TRUE The status code specified by Data was converted DEBUG() arguments
+ specified by ErrorLevel, Marker, and Format.
+ @retval FALSE The status code specified by Data could not be converted to
+ DEBUG() arguments.
+
+**/
+BOOLEAN
+EFIAPI
+ReportStatusCodeExtractDebugInfo (
+ IN CONST EFI_STATUS_CODE_DATA *Data,
+ OUT UINT32 *ErrorLevel,
+ OUT BASE_LIST *Marker,
+ OUT CHAR8 **Format
+ )
+{
+ EFI_DEBUG_INFO *DebugInfo;
+
+ ASSERT (Data != NULL);
+ ASSERT (ErrorLevel != NULL);
+ ASSERT (Marker != NULL);
+ ASSERT (Format != NULL);
+
+ //
+ // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
+ //
+ if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {
+ return FALSE;
+ }
+
+ //
+ // Retrieve the debug information from the status code record
+ //
+ DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
+
+ *ErrorLevel = DebugInfo->ErrorLevel;
+
+ //
+ // The first 12 * UINTN bytes of the string are really an
+ // argument stack to support varargs on the Format string.
+ //
+ *Marker = (BASE_LIST) (DebugInfo + 1);
+ *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
+
+ return TRUE;
+}
+
+
+
+
+EFI_STATUS
+EFIAPI
+SerialReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN CONST EFI_GUID *CallerId,
+ IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+{
+ CHAR8 *Filename;
+ CHAR8 *Description;
+ CHAR8 *Format;
+ CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+ UINT32 ErrorLevel;
+ UINT32 LineNumber;
+ UINTN CharCount;
+ BASE_LIST Marker;
+ EFI_DEBUG_INFO *DebugInfo;
+
+ Buffer[0] = '\0';
+
+
+ if (Data != NULL &&
+ ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+
+ //
+ // Print ASSERT() information into output buffer.
+ //
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "\n\rASSERT!: %a (%d): %a\n\r",
+ Filename,
+ LineNumber,
+ Description
+ );
+
+
+ //
+ // Callout to standard output.
+ //
+ SerialPortWrite ((UINT8 *)Buffer, CharCount);
+ return EFI_SUCCESS;
+
+ } else if (Data != NULL &&
+ ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+
+ //
+ // Print DEBUG() information into output buffer.
+ //
+ CharCount = AsciiBSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ Format,
+ Marker
+ );
+
+ } else if (Data != NULL &&
+ CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
+ (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
+
+ //
+ // Print specific data into output buffer.
+ //
+ DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
+ Marker = (BASE_LIST) (DebugInfo + 1);
+ Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12);
+
+ CharCount = AsciiBSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
+
+ } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+ //
+ // Print ERROR information into output buffer.
+ //
+
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "ERROR: C%x:V%x I%x",
+ CodeType,
+ Value,
+ Instance
+ );
+
+ //
+ // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
+ //
+ if (CallerId != NULL) {
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ " %g",
+ CallerId
+ );
+ }
+
+ if (Data != NULL) {
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ " %x",
+ Data
+ );
+
+ }
+
+
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ "\n\r"
+ );
+
+ } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "PROGRESS CODE: V%x I%x\n\r",
+ Value,
+ Instance
+ );
+ } else {
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "Undefined: C%x:V%x I%x\n\r",
+ CodeType,
+ Value,
+ Instance
+ );
+
+ }
+
+ SerialPortWrite ((UINT8 *)Buffer, CharCount);
+ return EFI_SUCCESS;
+
+}
+
+
+VOID
+EFIAPI
+AddDxeCoreReportStatusCodeCallback (
+ VOID
+ )
+{
+ BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid, &gStatusCode, sizeof(VOID *));
+}
+
|