/** @file
The header file for firmware update library.
Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __FIRMWARE_UPDATE_LIB_H__
#define __FIRMWARE_UPDATE_LIB_H__
#include
#include
#include
#include
#include
#include
#include
#include
#define CMOS_ADDREG 0x70
#define CMOS_DATAREG 0x71
#define MAX_UPDATE_REGIONS 4
#define FW_UPDATE_PARTITION_A 0
#define FW_UPDATE_PARTITION_B 1
#define MAX_FILE_LEN 16
#define MAX_FW_COMPONENTS 6
#define MAX_FW_FAILED_RETRY 3
#define CAPSULE_FLAGS_CFG_DATA BIT0
#define FW_UPDATE_COMP_CSME_REGION_ORDER 1
#define FW_UPDATE_COMP_CSME_DRIVER_ORDER 2
#define FW_UPDATE_COMP_BIOS_REGION_ORDER 3
#define FW_UPDATE_COMP_DEFAULT_ORDER 4
///
/// "FWST" Firmware Update status data Table
/// This table contains pointer to the ESRT (EFI System Resource Table)structure
///
#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
#define CAPSULE_FLAG_FORCE_BIOS_UPDATE BIT31
typedef enum {
TopSwapSet,
TopSwapClear
} TOP_SWAP_OPERATION;
#pragma pack(push, 1)
//
// Firmware Update Status ACPI structure
// This structure has a generic address structure
// which contains the pointer to ESRT structure.
//
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
EFI_SYSTEM_RESOURCE_TABLE EsrtTablePtr;
EFI_SYSTEM_RESOURCE_ENTRY EsrtTableEntry[MAX_FW_COMPONENTS];
} EFI_FWST_ACPI_DESCRIPTION_TABLE;
typedef union _FIRMWARE_UPDATE_POLICY {
UINT32 Data;
struct {
UINT32 StateMachine : 8;
UINT32 UpdatePartitionA : 1;
UINT32 UpdatePartitionB : 1;
UINT32 SwitchtoBackupPart : 1;
UINT32 Reboot : 1;
} Fields;
} FIRMWARE_UPDATE_POLICY;
//
// Capsule image header for firmware update
//
typedef struct {
EFI_GUID FileGuid;
UINT32 HeaderSize;
UINT32 FirmwreVersion;
UINT32 CapsuleFlags;
UINT32 PubKeyOffset;
UINT32 PubKeySize;
UINT32 ImageOffset;
UINT32 ImageSize;
UINT32 SignatureOffset;
UINT32 SignatureSize;
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 ReservedBytes[3];
UINT32 UpdateImageSize;
UINT32 UpdateVendorCodeSize;
UINT64 UpdateHardwareInstance;
} EFI_FW_MGMT_CAP_IMAGE_HEADER;
//
// Region information for firmware update
//
typedef struct {
UINT64 ToUpdateAddress;
UINT32 UpdateSize;
UINT8 *SourceAddress;
} FIRMWARE_UPDATE_REGION;
//
// Partition information for firmware update
// It may include multiple regions
//
typedef struct {
UINT32 RegionCount;
FIRMWARE_UPDATE_REGION FwRegion[1];
} FIRMWARE_UPDATE_PARTITION;
#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.
This function read firmware update capsule image starting with firmware update
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.
@retval EFI_SUCCESS Get the capsule image successfully.
@retval others Error happening when getting capsule image.
**/
EFI_STATUS
EFIAPI
GetCapsuleImage (
OUT VOID **FwBuffer,
OUT UINT32 *FwSize
);
/**
Get offset of Stage 1A in the capsule image
This function will get stage 1A base address from flash map.
Computes offset in the BIOS region from the base address.
Then it calculates base address of stage1A in the 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
@retval EFI_SUCCESS Image offset returned successfully.
@retval EFI_NOT_FOUND Could not get component information from flash map.
@retval others Error happening when updating.
**/
EFI_STATUS
EFIAPI
PlatformGetStage1AOffset (
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
IN BOOLEAN IsBackupPartition,
OUT UINT32 *Base,
OUT UINT32 *Size
);
/**
Get details information on how to update a boot partition.
Platform knows the capsule image and the boot device layout. By parsing capsule
Image and boot media, the platform could produce a list of regions to be updated.
Platform could set partition flag to decide if a reboot is required after a boot
partition is updated.
Platform could set region flag to indicate if the source image is the final image
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] 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.
**/
EFI_STATUS
EFIAPI
GetFirmwareUpdateInfo (
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr,
IN FIRMWARE_UPDATE_POLICY FwPolicy,
OUT FIRMWARE_UPDATE_PARTITION **PartitionInfo
);
/**
Platform hook point before starting to write a boot partition.
This function will do some platform specific things before starting to write
data to boot media. e.g. Send other component message it is going to do boot
media update.
@param[in] UpdatePartition The firmware update capsule image.
**/
EFI_STATUS
EFIAPI
PrepareRegionsUpdate (
IN FIRMWARE_UPDATE_PARTITION *UpdatePartition
);
/**
Platform hook point after firmware update is done.
This function will do some platform specific things after all new firmware
is written to boot media. e.g. set boot mode to normal boot mode if platform
support it.
**/
EFI_STATUS
EFIAPI
PlatformEndFirmwareUpdate (
VOID
);
/**
Get SVN from existing firmware
This routine get SPI base address and read first four bytes
to get STAGE1A FV base address, using this base address
this routine can calculate the offset to the SVN structure.
@param[in] Stage1AFvPointer Pointer to Stage1A fv base.
@param[out] BlVersion Pointer to SBL version struct.
@retval EFI_SUCCESS Read SVN success
@retval EFI_INVALID_PARAMETER Invalid parameter
**/
EFI_STATUS
EFIAPI
GetSvn (
IN UINT32 Stage1AFvPointer,
OUT BOOT_LOADER_VERSION **BlVersion
);
/**
Verify the firmware version to make sure it is no less than current firmware version.
@param[in] Stage1ABase Stage 1A base address.
@param[in] IsFd Does Stage1ABase point to Stage1A FD
or SBL Stage1A FV ?
@param[out] Version Pointer to version of the firmware
@retval EFI_SUCCESS The operation completed successfully.
@retval others There is error happening.
**/
EFI_STATUS
GetVersionfromFv (
IN UINT32 Stage1ABase,
IN BOOLEAN IsFd,
OUT BOOT_LOADER_VERSION **Version
);
/**
Read the data from BootMedia.
@param[in] Address The boot media address to be read.
@param[in] ByteCount The size in the bytes to read from media.
@param[out] Buffer The Destination buffer to read the boot media.
@retval EFI_SUCCESS Read successfully.
@retval others Error happening when Reading.
**/
EFI_STATUS
EFIAPI
BootMediaRead (
IN UINT64 Address,
IN UINT32 ByteCount,
OUT UINT8 *Buffer
);
/**
This function reads blocks from the SPI device.
@param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
@param[in] Address The block address in the FlashRegionAll to read from on the SPI.
@param[in] ByteCount Size of the Buffer in bytes.
@param[out] Buffer Pointer to caller-allocated buffer containing the data received during the SPI cycle.
@retval EFI_SUCCESS Read completes successfully.
@retval others Device error, the command aborts abnormally.
**/
EFI_STATUS
EFIAPI
BootMediaReadByType (
IN FLASH_REGION_TYPE FlashRegionType,
IN UINT64 Address,
IN UINT32 ByteCount,
OUT UINT8 *Buffer
);
/**
Write the data to BootMedia.
@param[in] Address The boot media address to be Write.
@param[in] ByteCount The size in the bytes to write onto media.
@param[out] Buffer The Destination buffer to read the boot media.
@retval EFI_SUCCESS Read successfully.
@retval others Error happening when Reading.
**/
EFI_STATUS
EFIAPI
BootMediaWrite (
IN UINT64 Address,
IN UINT32 ByteCount,
OUT UINT8 *Buffer
);
/**
This function writes blocks to the SPI device based on flash region type.
@param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
@param[in] Address The block address in the FlashRegionAll to read from on the SPI.
@param[in] ByteCount Size of the Buffer in bytes.
@param[out] Buffer Pointer to caller-allocated buffer containing the data received during the SPI cycle.
@retval EFI_SUCCESS Write completes successfully.
@retval others Device error, the command aborts abnormally.
**/
EFI_STATUS
EFIAPI
BootMediaWriteByType (
IN FLASH_REGION_TYPE FlashRegionType,
IN UINT64 Address,
IN UINT32 ByteCount,
OUT UINT8 *Buffer
);
/**
Erase the data on the BootMedia.
@param[in] Address The boot media address to be Erased.
@param[in] ByteCount The size in the bytes to Erase on media.
@retval EFI_SUCCESS Read successfully.
@retval others Error happening when Reading.
**/
EFI_STATUS
EFIAPI
BootMediaErase (
IN UINT64 Address,
IN UINT32 ByteCount
);
/**
Initializes input structure for csme update driver.
This function will initialize input structure for csme
update driver. Since HECI functionality is avaiable to access
only in silicon driver, this init is done in silicon package.
**/
VOID *
InitCsmeUpdInputData (
VOID
);
/**
API to Initialize BootMedia.
**/
VOID
EFIAPI
InitializeBootMedia (
VOID
);
/**
Get the SPI region base and size, based on the enum type
@param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
@param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
@param[out] RegionSize The size for the Region 'n'
@retval EFI_SUCCESS Read success
@retval EFI_INVALID_PARAMETER Invalid region type given
@retval EFI_DEVICE_ERROR The region is not used
**/
EFI_STATUS
EFIAPI
BootMediaGetRegion (
IN FLASH_REGION_TYPE FlashRegionType,
OUT UINT32 *BaseAddress, OPTIONAL
OUT UINT32 *RegionSize OPTIONAL
);
/**
Get all region sizes from flash map.
This function will get topswap, redundant and non redundant region sizes from
flash map.
@param[in,out] TopSwapRegionSize The boot media address to be update.
@param[in,out] RedundantRegionSize The source buffer to write to the boot media.
@param[in,out] NonRedundantRegionSize The length of data to write to boot media.
@retval EFI_SUCCESS Update successfully.
@retval others Error happening when updating.
**/
EFI_STATUS
EFIAPI
GetRegionInfo (
IN OUT UINT32 *TopSwapRegionSize,
IN OUT UINT32 *RedundantRegionSize,
IN OUT UINT32 *NonRedundantRegionSize
);
/**
Get region size from flash map.
This function will get topswap, redundant and non redundant region sizes from
flash map.
@param[in] FlashMap The boot media address to be update.
@param[in] RegionFlag The source buffer to write to the boot media.
@retval EFI_SUCCESS Update successfully.
@retval others Error happening when updating.
**/
UINT32
GetRegionSize (
IN FLASH_MAP *FlashMap,
IN UINT8 RegionFlag
);
/**
Gets component information from the flash map by partition.
This function will look for the component matching the input signature
in the flash map, if found, it will look for the component with back up
flag based on the backup partition parmeter and will return the
offset and size of the component.
@param[in] Signature Signature of the component information required
@param[in] Region Look for the component in desired region
@param[in] IsBackupPartition TRUE for Back up copy, FALSE for primary copy
@param[out] Offset Offset of the component
@param[out] Size Size of the component
@retval EFI_SUCCESS Found the component with the matching signature.
@retval EFI_NOT_FOUND Component with the matching signature not found.
**/
EFI_STATUS
EFIAPI
FirmwareUpdateGetComponentInfo (
IN UINT32 Signature,
IN UINT8 Region,
IN BOOLEAN IsBackupPartition,
OUT UINT32 *Offset,
OUT UINT32 *Size
);
/**
Get state machine flag from flash.
This function will get state machine flag from the bootloader reserved region
First byte in the booloader reserved region is state machine flag
@param[in, out] StateMachine Pointer to state machine flag byte.
**/
VOID
GetStateMachineFlag (
IN OUT UINT8 *StateMachine
);
/**
Switch between the boot partitions.
This function will use platform specific method of switching
between primary and backup partitions.
@param[in] Partition Partition to select
@retval EFI_SUCCESS Switched to desired partition successfully.
@retval others Error happening.
**/
EFI_STATUS
SetBootPartition (
IN BOOT_PARTITION Partition
);
/**
This function will be called after the firmware update is complete.
This function will update firmware update status structure in reserved region
@param[in] Signature Signature of component to update.
@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 UINT64 Signature,
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] CsmeUpdInputData pointer to input data structure for CSME update
@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 VOID *CsmeUpdInputData,
IN EFI_FW_MGMT_CAP_IMAGE_HEADER *ImageHdr
);
/**
Reads a range of PCI configuration registers into a caller supplied buffer.
Reads the range of PCI configuration registers specified by StartAddress and
Size into the buffer specified by Buffer. This function only allows the PCI
configuration registers from a single PCI function to be read. Size is
returned. When possible 32-bit PCI configuration read cycles are used to read
from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit
and 16-bit PCI configuration read cycles may be used at the beginning and the
end of the range.
StartAddress is in EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS format.
- when register offset is < 0x100, it is : bbddffrr
- when register offset is >= 0x100, it is : rrrbbddff00
If StartAddress is not aligned with format defined, then ASSERT().
If the range to be read exceeds a single PCI function, then ASSERT().
If Buffer is NULL or Size == 0, then ASSERT().
@param StartAddress The starting address that encodes the PCI Bus, Device,
Function and Register.
@param Size The size in bytes of the transfer.
@param Buffer The pointer to a buffer receiving the data read.
@return EFI_SUCCESS if data is read into buffer
@return EFI_NOT_FOUND if data is NOT read into buffer
@return EFI_INVALID_PARAMETER Invalid parameter
**/
EFI_STATUS
EFIAPI
CsmePciReadBuffer (
IN UINT64 StartAddress,
IN UINTN Size,
OUT VOID *Buffer
);
/**
Platform hook point to clear firmware update trigger.
This function is responsible for clearing firmware update trigger.
**/
VOID
EFIAPI
ClearFwUpdateTrigger (
VOID
);
/**
Flash descriptor region lock
This function will do some command buffer parsing and check
for additional parameters
@param[in] CmdDataBuf Pointer to command buffer.
@param[in] CmdDataSize size of command data.
@retval EFI_SUCCESS Flash descriptor lock successfully.
@retval others Error happening when updating.
**/
EFI_STATUS
EFIAPI
SetFlashDescriptorLock (
IN CHAR8 *CmdDataBuf,
IN UINTN CmdDataSize
);
/**
Anti Rollback Svn Commit
@param[in] CmdDataBuf Pointer to command buffer.
@param[in] CmdDataSize size of command data.
@retval EFI_SUCCESS ARB Svn commit is successful.
@retval others Error happened while doing commit.
**/
EFI_STATUS
EFIAPI
SetArbSvnCommit (
IN CHAR8 *CmdDataBuf,
IN UINTN CmdDataSize
);
/**
Oem Key Revocation
@param[in] CmdDataBuf Pointer to command buffer.
@param[in] CmdDataSize size of command data.
@retval EFI_SUCCESS Oem Key Revocation is successful.
@retval others Error happened while doing commit.
**/
EFI_STATUS
EFIAPI
SetOemKeyRevocation (
IN CHAR8 *CmdDataBuf,
IN UINTN CmdDataSize
);
#endif