From 91c09cee7943c5a424a49afb6819fda1cf2a32b2 Mon Sep 17 00:00:00 2001 From: Raghava Gudla Date: Tue, 30 Oct 2018 14:33:04 -0700 Subject: [PATCH] Updated FwUpdate to get capsule info from cfg data This patch updates firmware update code to get capsule location information from configuration data instead of searching in all the available boot media. Signed-off-by: Raghava Gudla --- .../Include/Library/FirmwareUpdateLib.h | 64 ---- PayloadPkg/FirmwareUpdate/FirmwareUpdate.c | 2 +- PayloadPkg/FirmwareUpdate/FirmwareUpdate.inf | 1 + PayloadPkg/FirmwareUpdate/GetCapsuleImage.c | 177 +++++----- .../ApollolakeBoardPkg/CfgData/CfgDataDef.dsc | 3 + .../CfgData/CfgData_CapsuleInformation.dsc | 48 +++ .../Library/ShellExtensionLib/CmdFwUpdate.c | 31 +- Platform/QemuBoardPkg/BoardConfig.py | 4 +- Platform/QemuBoardPkg/CfgData/CfgDataDef.dsc | 2 + .../CfgData/CfgData_CapsuleInformation.dsc | 48 +++ .../FirmwareUpdateLib/FirmwareUpdateLib.c | 309 +----------------- .../FirmwareUpdateLib/FirmwareUpdateLib.inf | 3 - 12 files changed, 209 insertions(+), 483 deletions(-) rename {PayloadPkg => BootloaderCommonPkg}/Include/Library/FirmwareUpdateLib.h (88%) create mode 100644 Platform/ApollolakeBoardPkg/CfgData/CfgData_CapsuleInformation.dsc create mode 100644 Platform/QemuBoardPkg/CfgData/CfgData_CapsuleInformation.dsc diff --git a/PayloadPkg/Include/Library/FirmwareUpdateLib.h b/BootloaderCommonPkg/Include/Library/FirmwareUpdateLib.h similarity index 88% rename from PayloadPkg/Include/Library/FirmwareUpdateLib.h rename to BootloaderCommonPkg/Include/Library/FirmwareUpdateLib.h index e23eb490..ada4a5a5 100644 --- a/PayloadPkg/Include/Library/FirmwareUpdateLib.h +++ b/BootloaderCommonPkg/Include/Library/FirmwareUpdateLib.h @@ -94,72 +94,8 @@ typedef struct { FIRMWARE_UPDATE_REGION FwRegion[1]; } FIRMWARE_UPDATE_PARTITION; -// -// Partition information for firmware update -// It may include multiple regions -// -typedef struct { - - /// - /// Boot medium type, Refer OS_BOOT_MEDIUM_TYPE - /// - UINT8 DevType; - - /// - /// If there are multiple controllers, it indicate which - /// controller instance the boot medium belong to. - /// - UINT8 DevInstance; - UINT8 Reserved[3]; - - /// - /// Zero-based hardware partition number - /// - UINT8 HwPart; - - /// - /// Zero-based software partition number for boot image - /// Used for file system only. - /// - UINT8 SwPart; - - /// - /// For File system support only, Refer OS_FILE_SYSTEM_TYPE - /// - UINT8 FsType; - - /// - /// Used for image from file system, Ascii file name - /// If FileName[0] is zero, means this entry is invalid - /// - CHAR8 FileName[MAX_FILE_LEN]; - - /// - /// Lba offset address relative to partition - /// - UINT32 LbaAddr; -} FW_UPD_USER_CFG_DATA; - #define CAPSULE_IMAGE_SIZE(h) ((h)->HeaderSize + (h)->PubKeySize + (h)->ImageSize + (h)->SignatureSize) -/** - Platform code to get capsule image for firmware update. - - This function is platform hook to implement specific way to detecting capsule - firmware update - - @param[out] CapsuleImage The firmware update capsule image. - @param[out] CapsuleImageSize The capsule image size. - - @retval EFI_SUCCESS Get the capsule image successfully. - @retval others Error happening when getting capsule image. -**/ -EFI_STATUS -PlatformGetCapsuleImage ( - OUT VOID **CapsuleImage, - OUT UINT32 *CapsuleImageSize - ); - /** Get capsule image for firmware update. diff --git a/PayloadPkg/FirmwareUpdate/FirmwareUpdate.c b/PayloadPkg/FirmwareUpdate/FirmwareUpdate.c index 394aeb7a..216955df 100644 --- a/PayloadPkg/FirmwareUpdate/FirmwareUpdate.c +++ b/PayloadPkg/FirmwareUpdate/FirmwareUpdate.c @@ -31,8 +31,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include #include +#include /** Update a region block. diff --git a/PayloadPkg/FirmwareUpdate/FirmwareUpdate.inf b/PayloadPkg/FirmwareUpdate/FirmwareUpdate.inf index c1719617..f416340a 100644 --- a/PayloadPkg/FirmwareUpdate/FirmwareUpdate.inf +++ b/PayloadPkg/FirmwareUpdate/FirmwareUpdate.inf @@ -33,6 +33,7 @@ MdePkg/MdePkg.dec BootloaderCommonPkg/BootloaderCommonPkg.dec PayloadPkg/PayloadPkg.dec + Platform/CommonBoardPkg/CommonBoardPkg.dec [LibraryClasses] FirmwareUpdateLib diff --git a/PayloadPkg/FirmwareUpdate/GetCapsuleImage.c b/PayloadPkg/FirmwareUpdate/GetCapsuleImage.c index 04332707..02c8c7bb 100755 --- a/PayloadPkg/FirmwareUpdate/GetCapsuleImage.c +++ b/PayloadPkg/FirmwareUpdate/GetCapsuleImage.c @@ -23,23 +23,18 @@ #include #include #include -#include #include - -#define MM_PCI_BASE(Bus, Device, Function) \ - ( (UINTN)PcdGet64(PcdPciExpressBaseAddress) + \ - (UINTN)(Bus << 20) + \ - (UINTN)(Device << 15) + \ - (UINTN)(Function << 12) \ - ) +#include +#include +#include /** Get hardware partition handle from boot option info - This function will initialize boot device, and get hardware partition + This function will initialize boot device and get hardware partition handle based on boot option. - @param[in] BootOption Current boot option + @param[in] CapsuleInfo Pointer to capsule information config data @param[out] HwPartHandle Hardware partition handle for boot image @retval RETURN_SUCCESS If partition was found successfully @@ -47,24 +42,29 @@ **/ EFI_STATUS FindBootPartition ( - IN OS_BOOT_OPTION *BootOption, - OUT EFI_HANDLE *HwPartHandle + IN CAPSULE_INFO_CFG_DATA *CapsuleInfo, + OUT EFI_HANDLE *HwPartHandle ) { - RETURN_STATUS Status; - UINTN BootMediumPciBase; + RETURN_STATUS Status; + UINTN BootMediumPciBase; + + if (CapsuleInfo == NULL) { + return EFI_INVALID_PARAMETER; + } // // Get OS boot device address // - BootMediumPciBase = GetDeviceAddr (BootOption->DevType, BootOption->DevInstance); + BootMediumPciBase = GetDeviceAddr (CapsuleInfo->DevType, CapsuleInfo->DevInstance); BootMediumPciBase = TO_MM_PCI_ADDRESS (BootMediumPciBase); + DEBUG ((DEBUG_INFO, "BootMediumPciBase(0x%x)\n", BootMediumPciBase)); // // Init Boot device functions // - Status = MediaSetInterfaceType (BootOption->DevType); + Status = MediaSetInterfaceType (CapsuleInfo->DevType); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Invalid Boot device configured\n")); return RETURN_UNSUPPORTED; @@ -76,7 +76,7 @@ FindBootPartition ( } DEBUG ((DEBUG_INFO, "find boot partition\n")); - Status = FindPartitions (BootOption->HwPart, HwPartHandle); + Status = FindPartitions (CapsuleInfo->HwPart, HwPartHandle); if (EFI_ERROR (Status)) { return Status; } @@ -88,15 +88,14 @@ FindBootPartition ( /** Get Capsule image from raw partition - Using boot option info, this function will read capsule image from raw - partition based on hardware partition info saved in LoadedImage. - After capsule image is loaded into memory, information will be saved - to LoadedImage. + Using capsule info, this function will read capsule image from raw + partition based on hardware partition info saved in capsule info. - @param[in] HwPartHandle Partition handler - @param[out] FileBuffer Pointer to the buffer address for the - loaded image. - @param[out] FileSize Pointer to the length of the loaded image. + @param[in] CapsuleInfo Pointer to capsule information config data + @param[in] HwPartHandle Partition handler + @param[out] CapsuleImage Pointer to the buffer address for the + capsule image. + @param[out] CapsuleImageSize Pointer to the length of the capsule image. @retval EFI_OUT_OF_RESOURCES Out of memory resource @retval EFI_NOT_FOUND Cannot find the capsule image @@ -106,9 +105,10 @@ FindBootPartition ( **/ EFI_STATUS GetCapsuleFromRawPartition ( - IN EFI_HANDLE HwPartHandle, - OUT VOID **FileBuffer, - OUT UINTN *FileSize + IN CAPSULE_INFO_CFG_DATA *CapsuleInfo, + IN EFI_HANDLE HwPartHandle, + OUT VOID **CapsuleImage, + OUT UINTN *CapsuleImageSize ) { EFI_STATUS Status; @@ -123,13 +123,13 @@ GetCapsuleFromRawPartition ( FIRMWARE_UPDATE_HEADER *FwUpdHeader; DEBUG ((DEBUG_INFO, "Load image from SwPart (0x%x), LbaAddr(0x%x)\n", 0, 0)); - Status = GetLogicalPartitionInfo (0, HwPartHandle, &LogicBlkDev); + Status = GetLogicalPartitionInfo (CapsuleInfo->SwPart, HwPartHandle, &LogicBlkDev); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "Get logical partition error, Status = %r\n", Status)); return Status; } - Status = MediaGetMediaInfo (0, &BlockInfo); + Status = MediaGetMediaInfo (CapsuleInfo->HwPart, &BlockInfo); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "GetMediaInfo Error %r\n", Status)); return Status; @@ -144,8 +144,8 @@ GetCapsuleFromRawPartition ( sizeof (FIRMWARE_UPDATE_HEADER) : \ ((sizeof (FIRMWARE_UPDATE_HEADER) / BlockSize) + 1) * BlockSize; Status = MediaReadBlocks ( - 0, - LogicBlkDev.StartBlock, + CapsuleInfo->HwPart, + LogicBlkDev.StartBlock + CapsuleInfo->LbaAddr, AlginedHeaderSize, BlockData ); @@ -200,8 +200,8 @@ GetCapsuleFromRawPartition ( // Read the capsule image into the buffer // Status = MediaReadBlocks ( - 0, - LogicBlkDev.StartBlock, + CapsuleInfo->HwPart, + LogicBlkDev.StartBlock + CapsuleInfo->LbaAddr, AlginedImageSize, Buffer ); @@ -214,8 +214,8 @@ GetCapsuleFromRawPartition ( return EFI_LOAD_ERROR; } - *FileBuffer = Buffer; - *FileSize = ImageSize; + *CapsuleImage = Buffer; + *CapsuleImageSize = ImageSize; return EFI_SUCCESS; } @@ -227,7 +227,7 @@ GetCapsuleFromRawPartition ( header. It could be read from EMMC, UFS, USB, SATA, etc. block device. Often the Capsule image could be saved in the root directory of a FAT system. - @param[in] OsImageInfo It includes the boot device info for capsule image. + @param[in] CapsuleInfo Pointer to capsule information config data. @param[out] CapsuleImage The firmware update capsule image. @param[out] CapsuleImageSize The capsule image size. @@ -236,19 +236,20 @@ GetCapsuleFromRawPartition ( **/ EFI_STATUS LoadCapsuleImage ( - IN OS_BOOT_OPTION *OsImageInfo, - OUT VOID **CapsuleImage, - OUT UINT32 *CapsuleImageSize + IN CAPSULE_INFO_CFG_DATA *CapsuleInfo, + OUT VOID **CapsuleImage, + OUT UINT32 *CapsuleImageSize ) { - EFI_STATUS Status; - UINTN HardwareDeviceBlockIndex; - DEVICE_BLOCK_INFO BlockInfo; - EFI_HANDLE FsHandle; - EFI_HANDLE HwPartHandle; + EFI_STATUS Status; + UINTN HardwareDeviceBlockIndex; + DEVICE_BLOCK_INFO BlockInfo; + EFI_HANDLE FsHandle; + EFI_HANDLE HwPartHandle; + CHAR16 FileName[MAX_FILE_LEN]; HwPartHandle = NULL; - Status = FindBootPartition (OsImageInfo, &HwPartHandle); + Status = FindBootPartition (CapsuleInfo, &HwPartHandle); if (EFI_ERROR (Status)) { return Status; } @@ -256,13 +257,13 @@ LoadCapsuleImage ( // // If we do not have file system, try reading capsule from raw partition // - if (OsImageInfo->FsType >= EnumFileSystemMax) { - Status = GetCapsuleFromRawPartition (HwPartHandle, CapsuleImage, CapsuleImageSize); + if (CapsuleInfo->FsType >= EnumFileSystemMax) { + Status = GetCapsuleFromRawPartition (CapsuleInfo, HwPartHandle, CapsuleImage, CapsuleImageSize); return Status; } DEBUG ((DEBUG_ERROR, "Find partition\n")); - HardwareDeviceBlockIndex = OsImageInfo->HwPart; + HardwareDeviceBlockIndex = CapsuleInfo->HwPart; Status = MediaGetMediaInfo (HardwareDeviceBlockIndex, &BlockInfo); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "GetInfo Error %r\n", Status)); @@ -270,7 +271,7 @@ LoadCapsuleImage ( } FsHandle = NULL; - Status = InitFileSystem (OsImageInfo->SwPart, EnumFileSystemTypeFat, HwPartHandle, &FsHandle); + Status = InitFileSystem (CapsuleInfo->SwPart, EnumFileSystemTypeFat, HwPartHandle, &FsHandle); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "No partitions found, Status = %r\n", Status)); goto Done; @@ -281,8 +282,19 @@ LoadCapsuleImage ( // *CapsuleImageSize = 0x1000000; *CapsuleImage = NULL; - // get the capsule image - Status = GetFileByName (FsHandle, L"FwuImage.bin", CapsuleImage, CapsuleImageSize); + + // + // Find capsule using the name provided in configuration data + // + if (CapsuleInfo->FileName[0] != 0) { + AsciiStrToUnicodeStr((CONST CHAR8 *)(&CapsuleInfo->FileName), FileName); + Status = GetFileByName(FsHandle, FileName, CapsuleImage, CapsuleImageSize); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, " Capsule File '%a' Status : %r\n", FileName, Status)); + } + } else { + Status = EFI_NOT_FOUND; + } Done: if (EFI_ERROR (Status)) { @@ -312,7 +324,7 @@ GetOsImageList ( VOID ) { - EFI_HOB_GUID_TYPE *GuidHob; + EFI_HOB_GUID_TYPE *GuidHob; GuidHob = GetNextGuidHob (&gOsBootOptionGuid, GetHobListPtr()); if (GuidHob == NULL) { @@ -330,8 +342,8 @@ GetOsImageList ( header. It could be read from EMMC, UFS, USB, SATA, etc. block device. Often the Capsule image could be saved in the root directory of a FAT system. - @param[out] FwBuffer The firmware update capsule image. - @param[out] FwSize The capsule image size. + @param[out] CapsuleImage The firmware update capsule image. + @param[out] CapsuleImageSize The capsule image size. @retval EFI_SUCCESS Get the capsule image successfully. @retval others Error happening when getting capsule image. @@ -339,57 +351,42 @@ GetOsImageList ( EFI_STATUS EFIAPI GetCapsuleImage ( - OUT VOID **FwBuffer, - OUT UINT32 *FwSize + OUT VOID **CapsuleImage, + OUT UINT32 *CapsuleImageSize ) { - EFI_STATUS Status; - VOID *CapsuleImage; - UINTN CapsuleImageSize; - OS_BOOT_OPTION_LIST *OsImageInfoList; - UINT32 Index; + EFI_STATUS Status; + CAPSULE_INFO_CFG_DATA *CapsuleInfo; Status = EFI_UNSUPPORTED; + CapsuleInfo = NULL; + + if ((CapsuleImage == NULL ) || (CapsuleImageSize == NULL )) { + return EFI_INVALID_PARAMETER; + } DEBUG ((DEBUG_INFO, "\n=================Read Capsule Image==============\n")); - Status = PlatformGetCapsuleImage (&CapsuleImage, &CapsuleImageSize); - DEBUG((DEBUG_ERROR, " PlatformGetCapsuleImage: Status : %r\n", Status)); - if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) { - *FwSize = CapsuleImageSize; - *FwBuffer = CapsuleImage; - return Status; - } - // - // Get Boot Image Info + // Get capsule configuration data // - OsImageInfoList = GetOsImageList (); - if (OsImageInfoList == NULL) { - DEBUG ((DEBUG_ERROR, "Could not obtain OS image list\n")); + CapsuleInfo = (CAPSULE_INFO_CFG_DATA *) FindConfigDataByTag (CDATA_CAPSULE_INFO_TAG); + // + // If we do not find capsule information, return error + // + if (CapsuleInfo == NULL) { + DEBUG((DEBUG_ERROR, " CapsuleInfo not found \n")); return EFI_NOT_FOUND; } - // - // Load and run Image in order from OsImageInfoList - // - for (Index = 0; Index < OsImageInfoList->OsBootOptionCount; Index++) { - Status = LoadCapsuleImage (&OsImageInfoList->OsBootOption[Index], &CapsuleImage, &CapsuleImageSize); - if (!EFI_ERROR (Status)) { - break; - } - } - - if (Index == OsImageInfoList->OsBootOptionCount) { - DEBUG ((DEBUG_ERROR, "Get firmware update capsule image failure!\n")); + Status = LoadCapsuleImage (CapsuleInfo, CapsuleImage, CapsuleImageSize); + if (EFI_ERROR(Status)) { return Status; } - *FwSize = CapsuleImageSize; - *FwBuffer = CapsuleImage; - DEBUG ((DEBUG_INFO, "Capsule Image found, ImageSize=0x%x\n", *FwSize)); + DEBUG ((DEBUG_INFO, "Capsule Image found, ImageSize=0x%x\n", *CapsuleImageSize)); DEBUG ((DEBUG_INFO, "First 256Bytes of capsule image\n")); - DumpHex (2, 0, 256, (VOID *)CapsuleImage); + DumpHex (2, 0, 256, (VOID *)*CapsuleImage); return Status; } diff --git a/Platform/ApollolakeBoardPkg/CfgData/CfgDataDef.dsc b/Platform/ApollolakeBoardPkg/CfgData/CfgDataDef.dsc index bf391e1d..33290f98 100644 --- a/Platform/ApollolakeBoardPkg/CfgData/CfgDataDef.dsc +++ b/Platform/ApollolakeBoardPkg/CfgData/CfgDataDef.dsc @@ -128,3 +128,6 @@ # --------------------------------------------------------------------------------------- !include CfgData_DeviceEnable.dsc + + # --------------------------------------------------------------------------------------- + !include CfgData_CapsuleInformation.dsc diff --git a/Platform/ApollolakeBoardPkg/CfgData/CfgData_CapsuleInformation.dsc b/Platform/ApollolakeBoardPkg/CfgData/CfgData_CapsuleInformation.dsc new file mode 100644 index 00000000..7c3b9b62 --- /dev/null +++ b/Platform/ApollolakeBoardPkg/CfgData/CfgData_CapsuleInformation.dsc @@ -0,0 +1,48 @@ + # !BSF PAGE:{PLT} + # !BSF SUBT:{CFGHDR_TMPL:CAPSULE_INFO_CFG_DATA:0:0} + + # !HDR EMBED:{CAPSULE_INFO_CFG_DATA:TAG_080:START} + + # !BSF NAME:{DevType} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:SATA, 1:SD, 2:EMMC, 3:UFS, 4:SPI, 5:USB, 6:NVME, 7:MAX} + # !BSF HELP:{Specify boot device} + gCfgData.DevType | * | 0x01 | 5 + + # !BSF NAME:{Boot Device instance} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:Device 0, 1:Device 1, 2:Device 2, 3:Device 3} + # !BSF HELP:{Specify boot device instance when then are multple instances} + # !BSF ORDER:{0000.0000} + gCfgData.DevInstance | * | 0x01 | 5 + + gCfgData.Reserved | * | 0x03 | 0 + + # !BSF NAME:{Hardware Partition} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:User Partition, 1:Boot Partition 1, 2:Boot Partition 2} + # !BSF HELP:{Specify hardware partition number} + gCfgData.HwPart | * | 0x01 | 0 + + # !BSF NAME:{Software Partition} + # !BSF TYPE:{EditNum, INT, (0,127)} + # !BSF HELP:{Specify software partition number} + gCfgData.SwPart | * | 0x01 | 0 + + # !BSF NAME:{File System Type} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:FAT, 1:EXT2, 2:AUTO, 3:RAW} + # !BSF HELP:{Image is loaded from file system instead of raw data} + gCfgData.FsType | * | 0x01 | 2 + + # !BSF NAME:{Capsule File Name} + # !BSF TYPE:{EditText} + # !BSF HELP:{Specify file name of capsule image (16-byte max length)} + gCfgData.FileName | * | 0x10 | 'FwuImage.bin' + + # !BSF NAME:{LBA address for capsule image)} + # !BSF TYPE:{EditNum, HEX, (0,0xFFFFFFFF)} + # !BSF HELP:{specify LBA address where to find capsule image} + gCfgData.LbaAddr | * | 0x04 | 0 + + # !HDR EMBED:{CAPSULE_INFO_CFG_DATA:TAG_080:END} \ No newline at end of file diff --git a/Platform/ApollolakeBoardPkg/Library/ShellExtensionLib/CmdFwUpdate.c b/Platform/ApollolakeBoardPkg/Library/ShellExtensionLib/CmdFwUpdate.c index 57f852dc..1681bb08 100644 --- a/Platform/ApollolakeBoardPkg/Library/ShellExtensionLib/CmdFwUpdate.c +++ b/Platform/ApollolakeBoardPkg/Library/ShellExtensionLib/CmdFwUpdate.c @@ -16,17 +16,16 @@ #include #include #include -#include #include #include #include #include #include -#include +#include +#include - -#define FW_UPD_CAPSULE_INFO_LENGTH 128 -#define CDATA_HEADER_LENGTH 8 +#define CDATA_CAPSULE_INFO_LENGTH 128 +#define CDATA_HEADER_LENGTH 8 /** Reset the system. @@ -74,12 +73,12 @@ ShellCommandFwUpdateFunc ( { CDATA_BLOB *UserCfgData; CDATA_HEADER *CdataHeader; - FW_UPD_USER_CFG_DATA *FwUpdUserCfgData; - UINT8 Data[FW_UPD_CAPSULE_INFO_LENGTH]; - EFI_STATUS Status; + CAPSULE_INFO_CFG_DATA *FwUpdUserCfgData; + UINT8 Data[CDATA_CAPSULE_INFO_LENGTH]; PLATFORM_SERVICE *PlatformService; HECI_SERVICE *HeciService; - UINT32 CdataLength; + UINT32 CdataLength; + EFI_STATUS Status; HeciService = (HECI_SERVICE *) GetServiceBySignature (HECI_SERVICE_SIGNATURE); if ((HeciService == NULL) || (HeciService->SimpleHeciCommand == NULL)) { @@ -87,18 +86,18 @@ ShellCommandFwUpdateFunc ( return EFI_UNSUPPORTED; } - ZeroMem (Data, FW_UPD_CAPSULE_INFO_LENGTH); + ZeroMem (Data, CDATA_CAPSULE_INFO_LENGTH); UserCfgData = (CDATA_BLOB *)(&Data[0]); // // Populate configuration data header // - CdataLength = (CDATA_HEADER_LENGTH + sizeof(FW_UPD_USER_CFG_DATA)); + CdataLength = (CDATA_HEADER_LENGTH + sizeof(CAPSULE_INFO_CFG_DATA)); UserCfgData->Signature = CFG_DATA_SIGNATURE; UserCfgData->HeaderLength = sizeof(CDATA_BLOB); UserCfgData->UsedLength = sizeof(CDATA_BLOB) + CdataLength; - UserCfgData->TotalLength = FW_UPD_CAPSULE_INFO_LENGTH; + UserCfgData->TotalLength = CDATA_CAPSULE_INFO_LENGTH; // // Populate CDATA header for the item @@ -107,13 +106,13 @@ ShellCommandFwUpdateFunc ( CdataHeader->ConditionNum = 1; CdataHeader->Length = CdataLength >> 2; CdataHeader->Version = 1; - CdataHeader->Tag = CDATA_CAPSULE_TAG; + CdataHeader->Tag = CDATA_CAPSULE_INFO_TAG; CdataHeader->Condition[0].Value = 0xFFFFFFFF; // // Populate firmware update user configuration data structure // - FwUpdUserCfgData = (FW_UPD_USER_CFG_DATA *)(&Data[sizeof(CDATA_BLOB) + CDATA_HEADER_LENGTH]); + FwUpdUserCfgData = (CAPSULE_INFO_CFG_DATA *)(&Data[sizeof(CDATA_BLOB) + CDATA_HEADER_LENGTH]); FwUpdUserCfgData->DevType = 5; FwUpdUserCfgData->DevInstance = 0; FwUpdUserCfgData->HwPart = 0; @@ -121,12 +120,12 @@ ShellCommandFwUpdateFunc ( FwUpdUserCfgData->FsType = 2; FwUpdUserCfgData->LbaAddr = 0; - AsciiStrCpy(FwUpdUserCfgData->FileName, "FwuImage.bin"); + AsciiStrCpy((CHAR8 *)FwUpdUserCfgData->FileName, "FwuImage.bin"); // // Send HECI user command to save IBB signal data // - Status = HeciService->HeciUserCommand((UINT8 *)Data, FW_UPD_CAPSULE_INFO_LENGTH, 1 ); + Status = HeciService->HeciUserCommand((UINT8 *)Data, CDATA_CAPSULE_INFO_LENGTH, 1 ); if (EFI_ERROR(Status)) { DEBUG((DEBUG_ERROR, " HeciSendUserCommand: Status : %r\n", Status)); return Status; diff --git a/Platform/QemuBoardPkg/BoardConfig.py b/Platform/QemuBoardPkg/BoardConfig.py index 901cbc5f..5d210f43 100644 --- a/Platform/QemuBoardPkg/BoardConfig.py +++ b/Platform/QemuBoardPkg/BoardConfig.py @@ -78,7 +78,7 @@ class Board(BaseBoard): self.STAGE1B_SIZE = 0x0001F000 self.STAGE2_SIZE = 0x00020000 - self.EPAYLOAD_SIZE = 0x00100000 + self.EPAYLOAD_SIZE = 0x000FD000 self.PAYLOAD_SIZE = 0x00020000 self.CFGDATA_SIZE = 0x00001000 self.VARIABLE_SIZE = 0x00002000 @@ -215,5 +215,3 @@ class Board(BaseBoard): ]) return img_list - - diff --git a/Platform/QemuBoardPkg/CfgData/CfgDataDef.dsc b/Platform/QemuBoardPkg/CfgData/CfgDataDef.dsc index bf4159c3..91be03ed 100644 --- a/Platform/QemuBoardPkg/CfgData/CfgDataDef.dsc +++ b/Platform/QemuBoardPkg/CfgData/CfgDataDef.dsc @@ -155,4 +155,6 @@ # --------------------------------------------------------------------------------------- !include CfgDataGpio.dsc + # --------------------------------------------------------------------------------------- + !include CfgData_CapsuleInformation.dsc diff --git a/Platform/QemuBoardPkg/CfgData/CfgData_CapsuleInformation.dsc b/Platform/QemuBoardPkg/CfgData/CfgData_CapsuleInformation.dsc new file mode 100644 index 00000000..e2a23a7c --- /dev/null +++ b/Platform/QemuBoardPkg/CfgData/CfgData_CapsuleInformation.dsc @@ -0,0 +1,48 @@ + # !BSF PAGE:{PLT} + # !BSF SUBT:{CFGHDR_TMPL:CAPSULE_INFO_CFG_DATA:0:0} + + # !HDR EMBED:{CAPSULE_INFO_CFG_DATA:TAG_080:START} + + # !BSF NAME:{DevType} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:SATA, 1:SD, 2:EMMC, 3:UFS, 4:SPI, 5:USB, 6:NVME, 7:MAX} + # !BSF HELP:{Specify boot device} + gCfgData.DevType | * | 0x01 | 0 + + # !BSF NAME:{Boot Device instance} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:Device 0, 1:Device 1, 2:Device 2, 3:Device 3} + # !BSF HELP:{Specify boot device instance when then are multple instances} + # !BSF ORDER:{0000.0000} + gCfgData.DevInstance | * | 0x01 | 5 + + gCfgData.Reserved | * | 0x03 | 0 + + # !BSF NAME:{Hardware Partition} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:User Partition, 1:Boot Partition 1, 2:Boot Partition 2} + # !BSF HELP:{Specify hardware partition number} + gCfgData.HwPart | * | 0x01 | 5 + + # !BSF NAME:{Software Partition} + # !BSF TYPE:{EditNum, INT, (0,127)} + # !BSF HELP:{Specify software partition number} + gCfgData.SwPart | * | 0x01 | 0 + + # !BSF NAME:{File System Type} + # !BSF TYPE:{Combo} + # !BSF OPTION:{0:FAT, 1:EXT2, 2:AUTO, 3:RAW} + # !BSF HELP:{Image is loaded from file system instead of raw data} + gCfgData.FsType | * | 0x01 | 2 + + # !BSF NAME:{Capsule File Name} + # !BSF TYPE:{EditText} + # !BSF HELP:{Specify file name of capsule image (16-byte max length)} + gCfgData.FileName | * | 0x10 | 'FwuImage.bin' + + # !BSF NAME:{LBA address for capsule image)} + # !BSF TYPE:{EditNum, HEX, (0,0xFFFFFFFF)} + # !BSF HELP:{specify LBA address where to find capsule image} + gCfgData.LbaAddr | * | 0x04 | 0 + + # !HDR EMBED:{CAPSULE_INFO_CFG_DATA:TAG_080:END} \ No newline at end of file diff --git a/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.c b/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.c index 073e81fa..b7cd2140 100755 --- a/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.c +++ b/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.c @@ -32,9 +32,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include @@ -43,7 +43,6 @@ SPI_FLASH_SERVICE *mFwuSpiService = NULL; - /** This function initialized boot media. @@ -171,308 +170,6 @@ MarkBootParitionBpdt ( return EFI_SUCCESS; } -/** - Get hardware partition handle from boot option info - - This function will initialize boot device, and get hardware partition - handle based on boot option. - - @param[in] UserCfgData Pointer to user configuration data - @param[out] HwPartHandle Hardware partition handle for boot image - - @retval RETURN_SUCCESS If partition was found successfully - @retval Others If partition was not found -**/ -EFI_STATUS -AplFindBootPartition ( - IN FW_UPD_USER_CFG_DATA *UserCfgData, - OUT EFI_HANDLE *HwPartHandle - ) -{ - RETURN_STATUS Status; - UINTN BootMediumPciBase; - - - // - // Get device address for capsule image - // - BootMediumPciBase = GetDeviceAddr (UserCfgData->DevType, UserCfgData->DevInstance); - BootMediumPciBase = TO_MM_PCI_ADDRESS (BootMediumPciBase); - DEBUG ((DEBUG_INFO, "BootMediumPciBase(0x%x)\n", BootMediumPciBase)); - - // - // Init Boot device functions - // - Status = MediaSetInterfaceType (UserCfgData->DevType); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Invalid Boot device configured\n")); - return RETURN_UNSUPPORTED; - } - - Status = MediaInitialize (BootMediumPciBase, DevInitAll); - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, "find boot partition\n")); - Status = FindPartitions (UserCfgData->HwPart, HwPartHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, "Find partion success\n")); - return RETURN_SUCCESS; -} - -/** - Get capsule image from raw partition - - Using boot option info, this function will read capsule image from raw - partition based on hardware partition info saved in LoadedImage. - After capsule image is loaded into memory, its information will be saved - to LoadedImage. - - @param[in] UserCfgData Pointer to user configuration data - @param[in] HwPartHandle hardware partition handle - @param[out] CapsuleImage The firmware update capsule image. - @param[out] CapsuleImageSize The capsule image size. - - @retval RETURN_SUCCESS If capsule image was loaded successfully - @retval Others If capsule image was not loaded. -**/ -EFI_STATUS -GetCapsuleImageFromRawPartition ( - IN FW_UPD_USER_CFG_DATA *UserCfgData, - IN EFI_HANDLE HwPartHandle, - OUT VOID **CapsuleImage, - OUT UINT32 *CapsuleImageSize - ) -{ - RETURN_STATUS Status; - DEVICE_BLOCK_INFO BlockInfo; - VOID *Buffer; - UINTN ImageSize; - LOGICAL_BLOCK_DEVICE LogicBlkDev; - UINTN AlginedHeaderSize; - UINTN AlginedImageSize; - UINT32 BlockSize; - UINT8 BlockData[4096]; - UINT32 LbaAddr; - UINT8 SwPart; - FIRMWARE_UPDATE_HEADER *FwUpdHeader; - - SwPart = UserCfgData->SwPart; - LbaAddr = (UINT32)UserCfgData->LbaAddr; - - DEBUG ((DEBUG_INFO, "Load image from SwPart (0x%x), LbaAddr(0x%x)\n", SwPart, LbaAddr)); - Status = GetLogicalPartitionInfo (SwPart, HwPartHandle, &LogicBlkDev); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "Get logical partition error, Status = %r\n", Status)); - return Status; - } - - Status = MediaGetMediaInfo (UserCfgData->HwPart, &BlockInfo); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "GetMediaInfo Error %r\n", Status)); - return Status; - } - - // - // Read the firmware update capsule Header first to get total size of the capsule image. - // Make sure to round the Header size to be block aligned in bytes. - // - BlockSize = BlockInfo.BlockSize; - AlginedHeaderSize = ((sizeof (FIRMWARE_UPDATE_HEADER) % BlockSize) == 0) ? \ - sizeof (FIRMWARE_UPDATE_HEADER) : \ - ((sizeof (FIRMWARE_UPDATE_HEADER) / BlockSize) + 1) * BlockSize; - Status = MediaReadBlocks ( - UserCfgData->HwPart, - LogicBlkDev.StartBlock + LbaAddr, - AlginedHeaderSize, - BlockData - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "Read capsule image error, Status = %r\n", Status)); - return Status; - } - - // - // Firmware update header - // - FwUpdHeader = (FIRMWARE_UPDATE_HEADER *) BlockData; - - // - // Make sure this is the capsule image - // - if (!CompareGuid (&gFirmwareUpdateImageFileGuid, &FwUpdHeader->FileGuid)) { - DEBUG ((DEBUG_INFO, "Invalid Capsule image found, Guid mismatch\n")); - return EFI_NOT_FOUND; - } - - if (FwUpdHeader->HeaderSize != sizeof (FIRMWARE_UPDATE_HEADER)) { - DEBUG ((DEBUG_INFO, "Invalid Capsule image found, Header size mismatch\n")); - return EFI_NOT_FOUND; - } - - if (FwUpdHeader->PubKeySize != RSA_MOD_SIZE + RSA_E_SIZE + sizeof (UINT32)) { - DEBUG ((DEBUG_INFO, "Invalid Capsule image found, Public Key size mismatch\n")); - return EFI_NOT_FOUND; - } - - if (FwUpdHeader->SignatureSize != RSA2048NUMBYTES) { - DEBUG ((DEBUG_INFO, "Invalid Capsule image found, Signature size mismatch\n")); - return EFI_NOT_FOUND; - } - - // - // Make sure to round the image size to be block aligned in bytes. - // - ImageSize = CAPSULE_IMAGE_SIZE ((FIRMWARE_UPDATE_HEADER *) BlockData); - AlginedImageSize = ((ImageSize % BlockSize) == 0) ? \ - ImageSize : \ - ((ImageSize / BlockSize) + 1) * BlockSize; - - Buffer = (UINT8 *) AllocatePages (EFI_SIZE_TO_PAGES (AlginedImageSize)); - if (Buffer == NULL) { - DEBUG ((DEBUG_INFO, "Allocate memory (size:0x%x) fail.\n", AlginedImageSize)); - return EFI_OUT_OF_RESOURCES; - } - - // - // Read the rest of the capsule image into the buffer - // - Status = MediaReadBlocks ( - UserCfgData->HwPart, - LogicBlkDev.StartBlock + LbaAddr, - AlginedImageSize, - Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "Read capsule image error, Status = %r\n", Status)); - return Status; - } - - if ((Buffer == NULL) || (ImageSize == 0)) { - return EFI_LOAD_ERROR; - } - - *CapsuleImage = Buffer; - *CapsuleImageSize = ImageSize; - - return EFI_SUCCESS; -} - -/** - Platform code to get capsule image for firmware update. - - This function is platform hook to implement specific way to detecting capsule - firmware update - - @param[out] CapsuleImage The firmware update capsule image. - @param[out] CapsuleImageSize The capsule image size. - - @retval EFI_SUCCESS Get the capsule image successfully. - @retval others Error happening when getting capsule image. -**/ -EFI_STATUS -PlatformGetCapsuleImage ( - OUT VOID **CapsuleImage, - OUT UINT32 *CapsuleImageSize - ) -{ - EFI_STATUS Status; - FW_UPD_USER_CFG_DATA *UserCfgData; - UINTN HardwareDeviceBlockIndex; - DEVICE_BLOCK_INFO BlockInfo; - EFI_HANDLE FsHandle; - EFI_HANDLE HwPartHandle; - CHAR16 FileName[MAX_FILE_LEN]; - - UserCfgData = NULL; - - // - // Get capsule configuration data - // - UserCfgData = (FW_UPD_USER_CFG_DATA *) FindConfigDataByTag (CDATA_CAPSULE_TAG); - - // - // If we do not find capsule information, return error - // - if (UserCfgData == NULL) { - DEBUG((DEBUG_ERROR, " UserCfgData not found \n")); - return EFI_NOT_FOUND; - } - - // - // Find boot partition using capsule configuration - // - HwPartHandle = NULL; - Status = AplFindBootPartition (UserCfgData, &HwPartHandle); - if (EFI_ERROR (Status)) { - DEBUG((DEBUG_ERROR, " AplFindBootPartition: Status : %r\n", Status)); - return EFI_NOT_FOUND; - } - - // - // If we do not have file system, try reading capsule from raw partition - // - if (UserCfgData->FsType >= EnumFileSystemMax) { - Status = GetCapsuleImageFromRawPartition (UserCfgData, HwPartHandle, CapsuleImage, CapsuleImageSize); - if (EFI_ERROR(Status)) { - DEBUG((DEBUG_ERROR, " GetCapsuleImageFromRawPartition: Status : %r\n", Status)); - return EFI_NOT_FOUND; - } - return Status; - } - - HardwareDeviceBlockIndex = UserCfgData->HwPart; - Status = MediaGetMediaInfo (HardwareDeviceBlockIndex, &BlockInfo); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "GetInfo Error %r\n", Status)); - return EFI_NOT_FOUND; - } - - FsHandle = NULL; - Status = InitFileSystem (UserCfgData->SwPart, EnumFileSystemTypeFat, HwPartHandle, &FsHandle); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "No partitions found, Status = %r\n", Status)); - goto Done; - } - - // - // get capsule image size. - // - *CapsuleImageSize = 0x1000000; - *CapsuleImage = NULL; - - // - // Find capsule using the name provided in configuration data - // - if (UserCfgData->FileName[0] != 0) { - AsciiStrToUnicodeStr((CONST CHAR8 *)(&UserCfgData->FileName), FileName); - Status = GetFileByName(FsHandle, FileName, CapsuleImage, CapsuleImageSize); - DEBUG((DEBUG_ERROR, " GetFileByName: Status : %r\n", Status)); - } else { - Status = EFI_NOT_FOUND; - } - -Done: - if (EFI_ERROR (Status)) { - if (FsHandle != NULL) { - FreePool (FsHandle); - } - if (HwPartHandle != NULL) { - FreePool (HwPartHandle); - } - } - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - /** Get offset of Stage 1A in the capsule image @@ -771,7 +468,7 @@ EndFirmwareUpdate ( // PlatformService = (PLATFORM_SERVICE *) GetServiceBySignature (PLATFORM_SERVICE_SIGNATURE); if (PlatformService != NULL && PlatformService->ResetSystem != NULL) { - DEBUG ((EFI_D_INIT, "Firmware Update Done. Resetting the system....\n")); + DEBUG ((EFI_D_INIT, "Rebooting ...\n")); PlatformService->ResetSystem(EfiResetCold); } diff --git a/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.inf b/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.inf index 773b4069..08c0c4f4 100644 --- a/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.inf +++ b/Silicon/ApollolakePkg/Library/FirmwareUpdateLib/FirmwareUpdateLib.inf @@ -30,7 +30,6 @@ Platform/ApollolakeBoardPkg/ApollolakeBoardPkg.dec BootloaderCorePkg/BootloaderCorePkg.dec BootloaderCommonPkg/BootloaderCommonPkg.dec - PayloadPkg/PayloadPkg.dec [LibraryClasses] BaseLib @@ -51,8 +50,6 @@ [Guids] gEfiPartTypeSystemPartGuid gOsBootOptionGuid - gFirmwareUpdateImageFileGuid [Pcd] gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress - gPayloadTokenSpaceGuid.PcdPayloadHobList