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 <raghava.gudla@intel.com>
This commit is contained in:
Raghava Gudla
2018-10-30 14:33:04 -07:00
committed by Guo Dong
parent b83bf23a93
commit 91c09cee79
12 changed files with 209 additions and 483 deletions
@@ -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.
+1 -1
View File
@@ -31,8 +31,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/ResetSystemLib.h>
#include <Library/SecureBootLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Library/FirmwareUpdateLib.h>
#include <Library/LiteFvLib.h>
#include <Library/FirmwareUpdateLib.h>
/**
Update a region block.
@@ -33,6 +33,7 @@
MdePkg/MdePkg.dec
BootloaderCommonPkg/BootloaderCommonPkg.dec
PayloadPkg/PayloadPkg.dec
Platform/CommonBoardPkg/CommonBoardPkg.dec
[LibraryClasses]
FirmwareUpdateLib
+87 -90
View File
@@ -23,23 +23,18 @@
#include <Library/HobLib.h>
#include <Library/MediaAccessLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Library/FirmwareUpdateLib.h>
#include <Library/CryptoLib.h>
#define MM_PCI_BASE(Bus, Device, Function) \
( (UINTN)PcdGet64(PcdPciExpressBaseAddress) + \
(UINTN)(Bus << 20) + \
(UINTN)(Device << 15) + \
(UINTN)(Function << 12) \
)
#include <Library/FirmwareUpdateLib.h>
#include <Library/ConfigDataLib.h>
#include <ConfigDataCommonStruct.h>
/**
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;
}
@@ -128,3 +128,6 @@
# ---------------------------------------------------------------------------------------
!include CfgData_DeviceEnable.dsc
# ---------------------------------------------------------------------------------------
!include 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}
@@ -16,17 +16,16 @@
#include <Library/IoLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Service/PlatformService.h>
#include <Library/FirmwareUpdateLib.h>
#include <Library/ConfigDataLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/ShellExtensionLib.h>
#include <Service/HeciService.h>
#include <ConfigDataDefs.h>
#include <ConfigDataCommonStruct.h>
#include <Library/FirmwareUpdateLib.h>
#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;
+1 -3
View File
@@ -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
@@ -155,4 +155,6 @@
# ---------------------------------------------------------------------------------------
!include CfgDataGpio.dsc
# ---------------------------------------------------------------------------------------
!include 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}
@@ -32,9 +32,9 @@
#include <Library/PartitionLib.h>
#include <Library/CryptoLib.h>
#include <Library/ConfigDataLib.h>
#include <ConfigDataDefs.h>
#include <ConfigDataCommonStruct.h>
#include <Library/FileSystemLib.h>
#include <Library/PayloadLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Library/ConfigDataLib.h>
#include <Service/PlatformService.h>
#include <Service/HeciService.h>
@@ -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);
}
@@ -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