Add capsule update from multiple USB devices

This patch will try to find capsule image from each of connected USB
devices if the HwPart of CapsuleInformation is set to 0xFF.

When multiple USB devices are attached, current SBL will try to
find the capsule image from the device with index specified by HwPart
in the CapsuleInformation option. However, it is hard to determine
the USB device index order since it depends on which port the device
is connected to.

This patch extends the feature of "boot from multiple USB device" from
OS Loader to capsule update.

Verified: TGL-UP3 RVP

Signed-off-by: Stanley Chang <stanley.chang@intel.com>
This commit is contained in:
Stanley Chang 2022-03-21 11:09:09 +08:00 committed by Guo Dong
parent 7cd881a6d0
commit 8d84c73f18
1 changed files with 79 additions and 33 deletions

View File

@ -24,21 +24,19 @@
#include <ConfigDataCommonStruct.h>
/**
Get hardware partition handle from boot option info
Initialize Boot Device (Media)
This function will initialize boot device and get hardware partition
handle based on boot option.
This function will initialize boot device based on the info in
capsule config data.
@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
@retval Others If partition was not found
**/
EFI_STATUS
FindBootPartition (
IN CAPSULE_INFO_CFG_DATA *CapsuleInfo,
OUT EFI_HANDLE *HwPartHandle
InitBootDevice (
IN CAPSULE_INFO_CFG_DATA *CapsuleInfo
)
{
RETURN_STATUS Status;
@ -70,6 +68,32 @@ FindBootPartition (
return Status;
}
return RETURN_SUCCESS;
}
/**
Get hardware partition handle from boot option info
This function will get hardware partition handle based on 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
@retval Others If partition was not found
**/
EFI_STATUS
FindBootPartition (
IN CAPSULE_INFO_CFG_DATA *CapsuleInfo,
OUT EFI_HANDLE *HwPartHandle
)
{
RETURN_STATUS Status;
if (CapsuleInfo == NULL) {
return EFI_INVALID_PARAMETER;
}
DEBUG ((DEBUG_INFO, "find boot partition\n"));
Status = FindPartitions (CapsuleInfo->HwPart, HwPartHandle);
if (EFI_ERROR (Status)) {
@ -244,11 +268,21 @@ LoadCapsuleImage (
CHAR16 FileName[MAX_FILE_LEN];
EFI_HANDLE FileHandle;
FileHandle = NULL;
HwPartHandle = NULL;
if ((CapsuleImage == NULL) || (CapsuleImageSize == NULL)) {
Status = EFI_INVALID_PARAMETER;
return Status;
}
*CapsuleImageSize = 0;
*CapsuleImage = NULL;
FileHandle = NULL;
HwPartHandle = NULL;
FsHandle = NULL;
Status = FindBootPartition (CapsuleInfo, &HwPartHandle);
if (EFI_ERROR (Status)) {
return Status;
goto Done;
}
//
@ -256,7 +290,7 @@ LoadCapsuleImage (
//
if (CapsuleInfo->FsType >= EnumFileSystemMax) {
Status = GetCapsuleFromRawPartition (CapsuleInfo, HwPartHandle, CapsuleImage, (UINTN *)CapsuleImageSize);
return Status;
goto Done;
}
DEBUG ((DEBUG_ERROR, "Find partition\n"));
@ -264,22 +298,15 @@ LoadCapsuleImage (
Status = MediaGetMediaInfo (HardwareDeviceBlockIndex, &BlockInfo);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "GetInfo Error %r\n", Status));
return Status;
goto Done;
}
FsHandle = NULL;
Status = InitFileSystem (CapsuleInfo->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 = 0;
*CapsuleImage = NULL;
//
// Find capsule using the name provided in configuration data
//
@ -382,6 +409,9 @@ GetCapsuleImage (
{
EFI_STATUS Status;
CAPSULE_INFO_CFG_DATA *CapsuleInfo;
UINT8 HwPart;
UINT8 StartPart;
UINT8 EndPart;
Status = EFI_UNSUPPORTED;
CapsuleInfo = NULL;
@ -404,23 +434,39 @@ GetCapsuleImage (
return EFI_NOT_FOUND;
}
DEBUG ((DEBUG_INFO, "Read capsule image from %a DevInstance (%4x) HwPart (%4x) SwPart (%4x) FS (%4a)",
GetBootDeviceNameString(CapsuleInfo->DevType), CapsuleInfo->DevInstance, CapsuleInfo->HwPart,
CapsuleInfo->SwPart, GetFsTypeString (CapsuleInfo->FsType)));
if (CapsuleInfo->FsType < EnumFileSystemMax) {
DEBUG ((DEBUG_INFO, " file name: %a\n", CapsuleInfo->FileName));
} else {
DEBUG ((DEBUG_INFO, " LBA offset: 0x%x \n", CapsuleInfo->LbaAddr));
}
Status = LoadCapsuleImage (CapsuleInfo, CapsuleImage, CapsuleImageSize);
if (EFI_ERROR(Status)) {
Status = InitBootDevice (CapsuleInfo);
if (EFI_ERROR (Status)) {
return Status;
}
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);
if ((CapsuleInfo->DevType == OsBootDeviceUsb) && (CapsuleInfo->HwPart == 0xFF)) {
StartPart = 0;
EndPart = 0x10;
} else {
StartPart = CapsuleInfo->HwPart;
EndPart = CapsuleInfo->HwPart;
}
for (HwPart = StartPart; HwPart <= EndPart; HwPart++) {
CapsuleInfo->HwPart = HwPart;
DEBUG ((DEBUG_INFO, "Read capsule image from %a DevInstance (%4x) HwPart (%4x) SwPart (%4x) FS (%4a)",
GetBootDeviceNameString(CapsuleInfo->DevType), CapsuleInfo->DevInstance, CapsuleInfo->HwPart,
CapsuleInfo->SwPart, GetFsTypeString (CapsuleInfo->FsType)));
if (CapsuleInfo->FsType < EnumFileSystemMax) {
DEBUG ((DEBUG_INFO, " file name: %a\n", CapsuleInfo->FileName));
} else {
DEBUG ((DEBUG_INFO, " LBA offset: 0x%x \n", CapsuleInfo->LbaAddr));
}
Status = LoadCapsuleImage (CapsuleInfo, CapsuleImage, CapsuleImageSize);
if (!EFI_ERROR(Status)) {
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);
break;
}
}
return Status;
}