You've already forked slimbootloader
mirror of
https://github.com/Dasharo/slimbootloader.git
synced 2026-03-06 15:26:20 -08:00
Add Multiple firmware update capsule image support
This patch will add support for updating multiple firmwares using a single capsule image. Following modifications are made for existing firmware update flow 1) Gather and validate capsule image 2) State Machine will be set to capsule processing state. 3) Signature of the capsule image is now stored in reserved region During each reboot until the end of firmware update, stored signature will be compared against the capsule image signature to make sure capsule image is not modified until the end of firmware update. 4) Process Capsule image to gather firmware images 5) Each Firmware image information will be stored in reserved region using FW_UPDATE_COMP_STATUS. Update pending will be marked to update pending state indicating that this image is not processed. 6) Firmware update will use the reserved region comp structures starting with the first image with update pending state, update the comp update pending field to processing and applies the image. After the update, pending field will be updated to Done and updates the status of the update in the component structure and moves on to next image found. 7) After all the component structure in the reserved region updating pending field are set to Done. Firmware update mode is exited. Signed-off-by: Raghava Gudla <raghava.gudla@intel.com>
This commit is contained in:
@@ -20,29 +20,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <IndustryStandard/Acpi30.h>
|
||||
#include <Guid/SystemResourceTable.h>
|
||||
|
||||
#define CMOS_ADDREG 0x70
|
||||
#define CMOS_DATAREG 0x71
|
||||
#define CMOS_ADDREG 0x70
|
||||
#define CMOS_DATAREG 0x71
|
||||
|
||||
#define MAX_UPDATE_REGIONS 4
|
||||
#define MAX_UPDATE_REGIONS 4
|
||||
|
||||
#define FW_UPDATE_SM_INIT 0xFF
|
||||
#define FW_UPDATE_SM_PART_A 0xFE
|
||||
#define FW_UPDATE_SM_PART_B 0xFD
|
||||
#define FW_UPDATE_SM_PART_AB 0xFC
|
||||
#define FW_UPDATE_SM_INIT 0xFF
|
||||
#define FW_UPDATE_SM_CAP_PROCESSING 0x7F
|
||||
#define FW_UPDATE_SM_PART_A 0x7E
|
||||
#define FW_UPDATE_SM_PART_B 0x7D
|
||||
#define FW_UPDATE_SM_PART_AB 0x7C
|
||||
|
||||
#define RTC_PORT_ID 0xC3
|
||||
#define PCH_LPC_REG_P2SB_UNHIDE 0xE1
|
||||
#define PCH_LPC_REG_P2SB_BAR 0x10
|
||||
#define FW_UPDATE_IMAGE_UPDATE_NONE 0xFF
|
||||
#define FW_UPDATE_IMAGE_UPDATE_PENDING 0xFE
|
||||
#define FW_UPDATE_IMAGE_UPDATE_PROCESSING 0xFC
|
||||
#define FW_UPDATE_IMAGE_UPDATE_DONE 0xF8
|
||||
|
||||
#define FW_UPDATE_PARTITION_A 0
|
||||
#define FW_UPDATE_PARTITION_B 1
|
||||
#define FW_UPDATE_PARTITION_A 0
|
||||
#define FW_UPDATE_PARTITION_B 1
|
||||
|
||||
#define MAX_FILE_LEN 16
|
||||
#define FW_UPDATE_SIG_LENGTH 256
|
||||
|
||||
#define MAX_FILE_LEN 16
|
||||
#define MAX_FW_COMPONENTS 3
|
||||
|
||||
#define CAPSULE_FLAGS_CFG_DATA BIT0
|
||||
|
||||
#define FIRMWARE_UPDATE_STATUS_SIGNATURE SIGNATURE_32 ('F', 'W', 'U', 'S')
|
||||
#define FIRMWARE_UPDATE_STATUS_VERSION 0x1
|
||||
#define FW_UPDATE_STATUS_SIGNATURE SIGNATURE_32 ('F', 'W', 'U', 'S')
|
||||
#define FW_UPDATE_STATUS_VERSION 0x1
|
||||
|
||||
///
|
||||
/// "FWST" Firmware Update status data Table
|
||||
@@ -50,6 +55,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
///
|
||||
#define EFI_FIRMWARE_UPDATE_STATUS_TABLE_SIGNATURE SIGNATURE_32('F', 'W', 'S', 'T')
|
||||
|
||||
#define ESRT_FIRMWARE_RESOURCE_VERSION 0x1
|
||||
|
||||
#define CREATOR_INTEL_OEM_ID 'I','N','T','E','L',' '
|
||||
#define CREATOR_INTEL_OEM_TABLE_ID SIGNATURE_64('F','W','U','P','D','S','T','S')
|
||||
#define CREATOR_ID_INTEL 0x4C544E49 // "INTL"(Intel)
|
||||
#define CREATOR_REV_INTEL 0x20090903
|
||||
#define ACPI_FWST_OEM_REV 0x00001000
|
||||
|
||||
typedef enum {
|
||||
TopSwapSet,
|
||||
TopSwapClear
|
||||
@@ -60,16 +73,6 @@ typedef enum {
|
||||
BackupPartition
|
||||
} BOOT_PARTITION;
|
||||
|
||||
#define ESRT_FIRMWARE_RESOURCE_VERSION 0x1
|
||||
#define ESRT_FIRMWARE_RESOURCE_COUNT 0x1
|
||||
#define ESRT_FIRMWARE_RESOURCE_COUNT_MAX 0x1
|
||||
|
||||
#define CREATOR_INTEL_OEM_ID 'I','N','T','E','L',' '
|
||||
#define CREATOR_INTEL_OEM_TABLE_ID SIGNATURE_64('F','W','U','P','D','S','T','S')
|
||||
#define CREATOR_ID_INTEL 0x4C544E49 // "INTL"(Intel)
|
||||
#define CREATOR_REV_INTEL 0x20090903
|
||||
#define ACPI_FWST_OEM_REV 0x00001000
|
||||
|
||||
#pragma pack(push, 1)
|
||||
//
|
||||
// Firmware Update Status ACPI structure
|
||||
@@ -79,7 +82,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
EFI_ACPI_DESCRIPTION_HEADER Header;
|
||||
EFI_SYSTEM_RESOURCE_TABLE EsrtTablePtr;
|
||||
EFI_SYSTEM_RESOURCE_ENTRY EsrtTableEntry;
|
||||
EFI_SYSTEM_RESOURCE_ENTRY EsrtTableEntry[MAX_FW_COMPONENTS];
|
||||
} EFI_FWST_ACPI_DESCRIPTION_TABLE;
|
||||
|
||||
//
|
||||
@@ -92,11 +95,18 @@ typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT16 Version;
|
||||
UINT16 Length;
|
||||
UINT8 CapsuleSig[FW_UPDATE_SIG_LENGTH];
|
||||
UINT8 StateMachine;
|
||||
UINT8 Reserved[7];
|
||||
} FW_UPDATE_STATUS;
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID FirmwareId;
|
||||
UINT32 LastAttemptVersion;
|
||||
UINT32 LastAttemptStatus;
|
||||
UINT8 StateMachine;
|
||||
UINT8 UpdatePending;
|
||||
UINT8 Reserved[3];
|
||||
} FIRMWARE_UPDATE_STATUS;
|
||||
} FW_UPDATE_COMP_STATUS;
|
||||
|
||||
typedef union _FIRMWARE_UPDATE_POLICY {
|
||||
UINT32 Data;
|
||||
@@ -126,6 +136,23 @@ typedef struct {
|
||||
UINT32 Reserved[3];
|
||||
} FIRMWARE_UPDATE_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Version;
|
||||
UINT16 EmbeddedDriverCount;
|
||||
UINT16 PayloadItemCount;
|
||||
// UINT64 ItemOffsetList[];
|
||||
} EFI_FW_MGMT_CAP_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Version;
|
||||
EFI_GUID UpdateImageTypeId;
|
||||
UINT8 UpdateImageIndex;
|
||||
UINT8 reserved_bytes[3];
|
||||
UINT32 UpdateImageSize;
|
||||
UINT32 UpdateVendorCodeSize;
|
||||
UINT64 UpdateHardwareInstance;
|
||||
} EFI_FW_MGMT_CAP_IMAGE_HEADER;
|
||||
|
||||
//
|
||||
// Region information for firmware update
|
||||
//
|
||||
@@ -147,6 +174,9 @@ typedef struct {
|
||||
#pragma pack(pop)
|
||||
|
||||
#define CAPSULE_IMAGE_SIZE(h) ((h)->HeaderSize + (h)->PubKeySize + (h)->ImageSize + (h)->SignatureSize)
|
||||
#define COMP_STATUS_OFFSET(x, y) ((x) + sizeof(FW_UPDATE_STATUS) + ((y) * sizeof(FW_UPDATE_COMP_STATUS)))
|
||||
|
||||
typedef VOID (*DRIVER_ENTRY) (VOID *Params);
|
||||
|
||||
/**
|
||||
Get capsule image for firmware update.
|
||||
@@ -175,7 +205,7 @@ GetCapsuleImage (
|
||||
Computes offset in the BIOS region from the base address.
|
||||
Then it calculates base address of stage1A in the capsule image.
|
||||
|
||||
@param[in] FwImage The firmware update capsule image.
|
||||
@param[in] ImageHdr Pointer to Fw Mgmt capsule Image header
|
||||
@param[in] IsBackupPartition TRUE for Back up copy, FALSE for primary copy
|
||||
@param[out] Base Base address of the component
|
||||
@param[out] Size Size of the component
|
||||
@@ -187,7 +217,7 @@ GetCapsuleImage (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformGetStage1AOffset (
|
||||
IN UINT8 *FwImage,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
|
||||
IN BOOLEAN IsBackupPartition,
|
||||
OUT UINT32 *Base,
|
||||
OUT UINT32 *Size
|
||||
@@ -205,10 +235,9 @@ PlatformGetStage1AOffset (
|
||||
to write to boot media. If the flag is set, that source will be used to check if
|
||||
the source is same before doing firmware update.
|
||||
|
||||
@param[in] FwImage The firmware update capsule image.
|
||||
@param[in] FwPolicy Firmware update policy
|
||||
@param[out] PartitionInfo The detail informaion on the partition to update
|
||||
|
||||
@param[in] ImageHdr Pointer to Fw Mgmt capsule Image header
|
||||
@param[in] FwPolicy Firmware update policy.
|
||||
@param[out] PartitionInfo The detail information on the partition to update
|
||||
|
||||
@retval EFI_SUCCESS Update successfully.
|
||||
@retval others Error happening when updating.
|
||||
@@ -216,7 +245,7 @@ PlatformGetStage1AOffset (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetFirmwareUpdateInfo (
|
||||
IN UINT8 *FwImage,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
|
||||
IN FIRMWARE_UPDATE_POLICY FwPolicy,
|
||||
OUT FIRMWARE_UPDATE_PARTITION **PartitionInfo
|
||||
);
|
||||
@@ -472,18 +501,40 @@ AfterUpdateEnforceFwUpdatePolicy (
|
||||
);
|
||||
|
||||
/**
|
||||
This function will be called after the firmware update is complete.
|
||||
This function will update firmware update status structure in reserved region
|
||||
|
||||
@param[in] LastAttemptVersion Version of last firmware update attempted.
|
||||
@param[in] LastAttemptStatus Status of last firmware update attempted.
|
||||
This function will be called after the firmware update is complete.
|
||||
This function will update firmware update status structure in reserved region
|
||||
|
||||
@param[in] ImageHdr Pointer to Fw update image guid
|
||||
@param[in] LastAttemptVersion Version of last firmware update attempted.
|
||||
@param[in] LastAttemptStatus Status of last firmware update attempted.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval others There is error happening.
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateStatus (
|
||||
IN EFI_GUID *ImageId,
|
||||
IN UINT16 LastAttemptVersion,
|
||||
IN EFI_STATUS LastAttemptStatus
|
||||
);
|
||||
|
||||
/**
|
||||
Perform csme Firmware update.
|
||||
|
||||
This function based on the image type id guid from the image header will
|
||||
call the respective functions to perform capsule update.
|
||||
|
||||
@param[in] CapImage The pointer to the firmware update capsule image.
|
||||
@param[in] CapImageSize The size of capsule image in bytes.
|
||||
@param[in] ImageHdr Pointer to fw mgmt capsule Image header
|
||||
|
||||
@retval EFI_SUCCESS Update successful.
|
||||
@retval other error status from the update routine
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateCsme (
|
||||
IN UINT8 *CapImage,
|
||||
IN UINT32 CapImageSize,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr
|
||||
);
|
||||
#endif
|
||||
|
||||
@@ -394,14 +394,11 @@ UpdateFwst (
|
||||
IN UINT8 *Current
|
||||
)
|
||||
{
|
||||
UINT8 Count;
|
||||
UINT32 RsvdBase;
|
||||
EFI_STATUS Status;
|
||||
LOADER_GLOBAL_DATA *LdrGlobal;
|
||||
BOOT_LOADER_VERSION *Version;
|
||||
FIRMWARE_UPDATE_STATUS *FwUpdateStatus;
|
||||
EFI_FWST_ACPI_DESCRIPTION_TABLE *FwstAcpiTablePtr;
|
||||
|
||||
LdrGlobal = (LOADER_GLOBAL_DATA *)GetLoaderGlobalDataPointer();
|
||||
FW_UPDATE_COMP_STATUS *FwUpdCompStatus;
|
||||
|
||||
//
|
||||
// We do not need to populate ACPI table during firmware update
|
||||
@@ -423,27 +420,13 @@ UpdateFwst (
|
||||
// Fill in details for FWST ACPI table
|
||||
//
|
||||
FwstAcpiTablePtr = (EFI_FWST_ACPI_DESCRIPTION_TABLE *)Current;
|
||||
|
||||
CopyMem(&FwstAcpiTablePtr->EsrtTableEntry.FwClass, &gEsrtSystemFirmwareGuid, sizeof (EFI_GUID));
|
||||
FwstAcpiTablePtr->EsrtTableEntry.FwType = ESRT_FW_TYPE_SYSTEMFIRMWARE;
|
||||
|
||||
//
|
||||
// Get current version and lowest supported SVN version
|
||||
//
|
||||
if (LdrGlobal->VerInfoPtr != NULL) {
|
||||
Version = LdrGlobal->VerInfoPtr;
|
||||
FwstAcpiTablePtr->EsrtTableEntry.FwVersion = Version->ImageVersion.SecureVerNum;
|
||||
FwstAcpiTablePtr->EsrtTableEntry.LowestSupportedFwVersion = PcdGet32 (PcdLowestSupportedFwVer);
|
||||
}
|
||||
|
||||
//
|
||||
// Get status of last firmware update attempt
|
||||
//
|
||||
FwUpdateStatus = (FIRMWARE_UPDATE_STATUS *)RsvdBase;
|
||||
|
||||
if (FwUpdateStatus->Signature == FIRMWARE_UPDATE_STATUS_SIGNATURE) {
|
||||
FwstAcpiTablePtr->EsrtTableEntry.LastAttemptVersion = FwUpdateStatus->LastAttemptVersion;
|
||||
FwstAcpiTablePtr->EsrtTableEntry.LastAttemptStatus = FwUpdateStatus->LastAttemptStatus;
|
||||
FwUpdCompStatus = (FW_UPDATE_COMP_STATUS *)(RsvdBase + sizeof(FW_UPDATE_STATUS));
|
||||
for (Count = 0; Count < MAX_FW_COMPONENTS; Count ++) {
|
||||
CopyMem(&(FwstAcpiTablePtr->EsrtTableEntry[Count].FwClass), &(FwUpdCompStatus->FirmwareId), sizeof(EFI_GUID));
|
||||
FwstAcpiTablePtr->EsrtTableEntry[Count].FwType = ESRT_FW_TYPE_SYSTEMFIRMWARE;
|
||||
FwstAcpiTablePtr->EsrtTableEntry[Count].LastAttemptVersion = FwUpdCompStatus->LastAttemptVersion;
|
||||
FwstAcpiTablePtr->EsrtTableEntry[Count].LastAttemptStatus = FwUpdCompStatus->LastAttemptStatus;
|
||||
FwUpdCompStatus = (FW_UPDATE_COMP_STATUS *)((UINT32)FwUpdCompStatus + sizeof(FW_UPDATE_COMP_STATUS));
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,6 +56,9 @@
|
||||
gFirmwareUpdateImageFileGuid
|
||||
gFlashMapInfoGuid
|
||||
gBootLoaderVersionFileGuid
|
||||
gSblFWUpdateImageFileGuid
|
||||
gCfgFWUpdateImageFileGuid
|
||||
gCsmeFWUpdateImageFileGuid
|
||||
|
||||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
|
||||
|
||||
@@ -27,9 +27,13 @@
|
||||
#
|
||||
# GUID defined in package
|
||||
#
|
||||
gPayloadTokenSpaceGuid = { 0x87cc9b46, 0x6742, 0x40d2, { 0x8b, 0x8b, 0xa4, 0x82, 0x2f, 0xbf, 0x8c, 0x15 } }
|
||||
gOsLoaderTokenSpaceGuid = { 0x8dfd71db, 0xae65, 0x46d4, {0x88, 0x6c, 0xcc, 0x0e, 0x6d, 0x31, 0xf8, 0x71 } }
|
||||
gPayloadTokenSpaceGuid = { 0x87cc9b46, 0x6742, 0x40d2, { 0x8b, 0x8b, 0xa4, 0x82, 0x2f, 0xbf, 0x8c, 0x15 } }
|
||||
gOsLoaderTokenSpaceGuid = { 0x8dfd71db, 0xae65, 0x46d4, {0x88, 0x6c, 0xcc, 0x0e, 0x6d, 0x31, 0xf8, 0x71 } }
|
||||
gFirmwareUpdateImageFileGuid = { 0x1a3eae58, 0xb580, 0x4fef, { 0xac, 0xa3, 0xa1, 0x6d, 0x9e, 0x00, 0xdf, 0x5f } }
|
||||
gSblFWUpdateImageFileGuid = { 0x605C6813, 0xC2C7, 0x4242, { 0x9C, 0x27, 0x50, 0xA4, 0xC3, 0x63, 0xDB, 0xA4 } }
|
||||
gCfgFWUpdateImageFileGuid = { 0x66030B7A, 0x47D1, 0x4958, { 0xB7, 0x3D, 0x00, 0xB4, 0x4B, 0x9D, 0xD4, 0xB6 } }
|
||||
gCsmeFWUpdateImageFileGuid = { 0x43AEF186, 0x0CA5, 0x4230, { 0xB1, 0xBD, 0x19, 0x3F, 0xB4, 0x62, 0x72, 0x01 } }
|
||||
gCsmeFWUDriverImageFileGuid = { 0x4A467997, 0xA909, 0x4678, { 0x91, 0x0C, 0xE0, 0xFE, 0x1C, 0x90, 0x56, 0xEA } }
|
||||
|
||||
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
||||
# These will be patched in the FDF file.
|
||||
|
||||
@@ -43,6 +43,29 @@
|
||||
|
||||
SPI_FLASH_SERVICE *mFwuSpiService = NULL;
|
||||
|
||||
/**
|
||||
Perform csme Firmware update.
|
||||
|
||||
This function based on the image type id guid from the image header will
|
||||
call the respective functions to perform capsule update.
|
||||
|
||||
@param[in] CapImage The pointer to the firmware update capsule image.
|
||||
@param[in] CapImageSize The size of capsule image in bytes.
|
||||
@param[in] ImageHdr Pointer to fw mgmt capsule Image header
|
||||
|
||||
@retval EFI_SUCCESS Update successful.
|
||||
@retval other error status from the update routine
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateCsme (
|
||||
IN UINT8 *CapImage,
|
||||
IN UINT32 CapImageSize,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
This function initialized boot media.
|
||||
|
||||
@@ -177,7 +200,7 @@ MarkBootParitionBpdt (
|
||||
Computes offset in the BIOS region from the base address.
|
||||
Then it calculates base address of stage1A in the capsule image.
|
||||
|
||||
@param[in] FwImage The firmware update capsule image.
|
||||
@param[in] ImageHdr Pointer to Fw Mgmt capsule Image header
|
||||
@param[in] IsBackupPartition TRUE for Back up copy, FALSE for primary copy
|
||||
@param[out] Base Base address of the component
|
||||
@param[out] Size Size of the component
|
||||
@@ -189,14 +212,13 @@ MarkBootParitionBpdt (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformGetStage1AOffset (
|
||||
IN UINT8 *FwImage,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
|
||||
IN BOOLEAN IsBackupPartition,
|
||||
OUT UINT32 *Base,
|
||||
OUT UINT32 *Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_UPDATE_HEADER *FwUpdHeader;
|
||||
UINT32 Offset;
|
||||
UINT8 *Ptr;
|
||||
UINT32 Index;
|
||||
@@ -218,10 +240,9 @@ PlatformGetStage1AOffset (
|
||||
|
||||
// Search for Flash Map signature in image
|
||||
FlashMapPtr = NULL;
|
||||
FwUpdHeader = (FIRMWARE_UPDATE_HEADER *)FwImage;
|
||||
Ptr = (UINT8 *)(FwImage + FwUpdHeader->ImageOffset);
|
||||
Ptr = (UINT8 *)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER));
|
||||
BpOffset = IsBackupPartition ? (RgnSize >> 1) : 0;
|
||||
for (Offset = BpOffset; Offset < FwUpdHeader->ImageSize; Offset += SIZE_4KB) {
|
||||
for (Offset = BpOffset; Offset < ImageHdr->UpdateImageSize; Offset += SIZE_4KB) {
|
||||
if (*(UINT32 *)(Ptr + Offset + FLASH_MAP_IN_FV_OFFSET) == FLASH_MAP_SIG_HEADER) {
|
||||
// This is flash map
|
||||
FlashMapPtr = (FLASH_MAP *)(Ptr + Offset + FLASH_MAP_IN_FV_OFFSET);
|
||||
@@ -263,7 +284,7 @@ PlatformGetStage1AOffset (
|
||||
to write to boot media. If the flag is set, that source will be used to check if
|
||||
the source is same before doing firmware update.
|
||||
|
||||
@param[in] FwImage The firmware update capsule image.
|
||||
@param[in] ImageHdr Pointer to Fw Mgmt capsule Image header
|
||||
@param[in] FwPolicy Firmware update policy.
|
||||
@param[out] PartitionInfo The detail informaion on the partition to update
|
||||
|
||||
@@ -273,13 +294,12 @@ PlatformGetStage1AOffset (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetFirmwareUpdateInfo (
|
||||
IN UINT8 *FwImage,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
|
||||
IN FIRMWARE_UPDATE_POLICY FwPolicy,
|
||||
OUT FIRMWARE_UPDATE_PARTITION **PartitionInfo
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_UPDATE_HEADER *Header;
|
||||
FIRMWARE_UPDATE_PARTITION *UpdatePartition;
|
||||
UINT32 AllocateSize;
|
||||
UINT32 ToUpdateAddress;
|
||||
@@ -305,13 +325,12 @@ GetFirmwareUpdateInfo (
|
||||
return Status;
|
||||
}
|
||||
|
||||
Header = (FIRMWARE_UPDATE_HEADER *)FwImage;
|
||||
if (FwPolicy.Fields.UpdatePartitionA == 1) {
|
||||
ToUpdateAddress = 0;
|
||||
} else {
|
||||
ToUpdateAddress = RgnSize >> 1;
|
||||
}
|
||||
BiosAddress = (UINT8 *)(FwImage + Header->ImageOffset + ToUpdateAddress);
|
||||
BiosAddress = (UINT8 *)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER) + ToUpdateAddress);
|
||||
|
||||
//
|
||||
// Mark BPDT header to RED, so if update fails in between, we will have a corrupted partition
|
||||
|
||||
@@ -33,6 +33,29 @@
|
||||
SPI_FLASH_SERVICE *mFwuSpiService = NULL;
|
||||
UINT32 mFlashSize;
|
||||
|
||||
/**
|
||||
Perform csme Firmware update.
|
||||
|
||||
This function based on the image type id guid from the image header will
|
||||
call the respective functions to perform capsule update.
|
||||
|
||||
@param[in] CapImage The pointer to the firmware update capsule image.
|
||||
@param[in] CapImageSize The size of capsule image in bytes.
|
||||
@param[in] ImageHdr Pointer to fw mgmt capsule Image header
|
||||
|
||||
@retval EFI_SUCCESS Update successful.
|
||||
@retval other error status from the update routine
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateCsme (
|
||||
IN UINT8 *CapImage,
|
||||
IN UINT32 CapImageSize,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
Platform code to get capsule image for firmware update.
|
||||
|
||||
@@ -156,7 +179,7 @@ BootMediaErase (
|
||||
Computes offset in the BIOS region from the base address.
|
||||
Then it calculates base address of stage1A in the capsule image.
|
||||
|
||||
@param[in] FwImage The firmware update capsule image.
|
||||
@param[in] ImageHdr Pointer to Fw Mgmt capsule Image header
|
||||
@param[in] IsBackupPartition TRUE for Back up copy, FALSE for primary copy
|
||||
@param[out] Base Base address of the component
|
||||
@param[out] Size Size of the component
|
||||
@@ -168,7 +191,7 @@ BootMediaErase (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformGetStage1AOffset (
|
||||
IN UINT8 *FwImage,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
|
||||
IN BOOLEAN IsBackupPartition,
|
||||
OUT UINT32 *Base,
|
||||
OUT UINT32 *Size
|
||||
@@ -176,7 +199,6 @@ PlatformGetStage1AOffset (
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FLASH_MAP *FlashMap;
|
||||
FIRMWARE_UPDATE_HEADER *FwUpdHeader;
|
||||
|
||||
if ((Base == NULL) || (Size == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@@ -205,12 +227,11 @@ PlatformGetStage1AOffset (
|
||||
//
|
||||
*Base = (UINT32)(FlashMap->RomSize - (0x100000000ULL - *Base));
|
||||
|
||||
FwUpdHeader = (FIRMWARE_UPDATE_HEADER *)FwImage;
|
||||
//
|
||||
// Calculate base address of the component in the capsule image
|
||||
// Capsule image address + bios region offset + offset of the component
|
||||
//
|
||||
*Base = (UINT32)(FwImage + FwUpdHeader->ImageOffset + *Base);
|
||||
*Base = (UINT32)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER) + *Base);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -227,7 +248,7 @@ PlatformGetStage1AOffset (
|
||||
to write to boot media. If the flag is set, that source will be used to check if
|
||||
the source is same before doing firmware update.
|
||||
|
||||
@param[in] FwImage The firmware update capsule image.
|
||||
@param[in] ImageHdr Pointer to Fw Mgmt capsule Image header
|
||||
@param[in] FwPolicy Firmware update policy.
|
||||
@param[out] PartitionInfo The detail information on the partition to update
|
||||
|
||||
@@ -237,7 +258,7 @@ PlatformGetStage1AOffset (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetFirmwareUpdateInfo (
|
||||
IN UINT8 *FwImage,
|
||||
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
|
||||
IN FIRMWARE_UPDATE_POLICY FwPolicy,
|
||||
OUT FIRMWARE_UPDATE_PARTITION **PartitionInfo
|
||||
)
|
||||
@@ -253,7 +274,6 @@ GetFirmwareUpdateInfo (
|
||||
UINT32 CfgDataBase;
|
||||
UINT32 CfgDataSize;
|
||||
UINT8 BootPartition;
|
||||
FIRMWARE_UPDATE_HEADER *Header;
|
||||
FIRMWARE_UPDATE_PARTITION *UpdatePartition;
|
||||
FIRMWARE_UPDATE_REGION *UpdateRegion;
|
||||
UINT8 Idx;
|
||||
@@ -272,8 +292,7 @@ GetFirmwareUpdateInfo (
|
||||
ASSERT (UpdatePartition != NULL);
|
||||
UpdatePartition->RegionCount = RegionNumber;
|
||||
|
||||
Header = (FIRMWARE_UPDATE_HEADER *)FwImage;
|
||||
if (Header->CapsuleFlags & CAPSULE_FLAGS_CFG_DATA) {
|
||||
if (CompareGuid(&ImageHdr->UpdateImageTypeId, &gCfgFWUpdateImageFileGuid) == TRUE) {
|
||||
//
|
||||
// Update CfgData
|
||||
//
|
||||
@@ -286,20 +305,20 @@ GetFirmwareUpdateInfo (
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Header->ImageSize & 0xFFF) {
|
||||
if (ImageHdr->UpdateImageSize & 0xFFF) {
|
||||
DEBUG ((DEBUG_INFO, "CFGDATA capsule payload size is not block aligned!"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (Header->ImageSize > CfgDataSize) {
|
||||
if (ImageHdr->UpdateImageSize > CfgDataSize) {
|
||||
DEBUG ((DEBUG_INFO, "CFGDATA capsule payload size is too big for the region on flash!"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
UpdateRegion = &UpdatePartition->FwRegion[0];
|
||||
UpdateRegion->ToUpdateAddress = FlashMap->RomSize + CfgDataBase;
|
||||
UpdateRegion->UpdateSize = Header->ImageSize;
|
||||
UpdateRegion->SourceAddress = FwImage + Header->ImageOffset;
|
||||
UpdateRegion->UpdateSize = ImageHdr->UpdateImageSize;
|
||||
UpdateRegion->SourceAddress = (UINT8 *)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER));
|
||||
UpdatePartition->RegionCount = 1;
|
||||
|
||||
} else {
|
||||
@@ -347,19 +366,19 @@ GetFirmwareUpdateInfo (
|
||||
UpdateRegion->ToUpdateAddress = TopSwapRegionOffset - TopSwapRegionSize;
|
||||
}
|
||||
UpdateRegion->UpdateSize = TopSwapRegionSize;
|
||||
UpdateRegion->SourceAddress = FwImage + Header->ImageOffset + TopSwapRegionOffset;
|
||||
UpdateRegion->SourceAddress = (UINT8 *)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER) + TopSwapRegionOffset);
|
||||
|
||||
// Redundant region
|
||||
UpdateRegion = &UpdatePartition->FwRegion[1];
|
||||
UpdateRegion->ToUpdateAddress = RedundantRegionOffset;
|
||||
UpdateRegion->UpdateSize = RedundantRegionSize;
|
||||
UpdateRegion->SourceAddress = FwImage + Header->ImageOffset + RedundantRegionOffset;
|
||||
UpdateRegion->SourceAddress = (UINT8 *)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER) + RedundantRegionOffset);
|
||||
|
||||
// Non-redundant region
|
||||
UpdateRegion = &UpdatePartition->FwRegion[2];
|
||||
UpdateRegion->ToUpdateAddress = NonRedundantRegionOffset;
|
||||
UpdateRegion->UpdateSize = NonRedundantRegionSize;
|
||||
UpdateRegion->SourceAddress = FwImage + Header->ImageOffset + NonRedundantRegionOffset;
|
||||
UpdateRegion->SourceAddress = (UINT8 *)((UINTN)ImageHdr + sizeof(EFI_FW_MGMT_CAP_IMAGE_HEADER) + NonRedundantRegionOffset);
|
||||
|
||||
if (BootPartition == 0) {
|
||||
UpdatePartition->RegionCount = 3;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
### @file
|
||||
# Boot Partition Descriptor Table library.
|
||||
#
|
||||
@@ -45,6 +46,7 @@
|
||||
[Guids]
|
||||
gEfiPartTypeSystemPartGuid
|
||||
gOsBootOptionGuid
|
||||
gCfgFWUpdateImageFileGuid
|
||||
|
||||
[Pcd]
|
||||
gPlatformModuleTokenSpaceGuid.PcdTopSwapRegionSize
|
||||
|
||||
Reference in New Issue
Block a user