FmpSetImage() will receive untrusted input and do basic validation.\r
\r
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
@param[in] ConfigData Points to the component configuration structure.\r
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] Progress A function used by the driver to report the progress of the firmware update.\r
+ @param[in] StartPercentage The start completion percentage value that may be used to report progress during the flash write operation.\r
+ @param[in] EndPercentage The end completion percentage value that may be used to report progress during the flash write operation.\r
\r
@retval EFI_SUCCESS The System Firmware image is updated.\r
@retval EFI_WRITE_PROTECTED The flash device is read only.\r
**/\r
EFI_STATUS\r
PerformUpdate (\r
- IN VOID *SystemFirmwareImage,\r
- IN UINTN SystemFirmwareImageSize,\r
- IN UPDATE_CONFIG_DATA *ConfigData,\r
- OUT UINT32 *LastAttemptVersion,\r
- OUT UINT32 *LastAttemptStatus\r
+ IN VOID *SystemFirmwareImage,\r
+ IN UINTN SystemFirmwareImageSize,\r
+ IN UPDATE_CONFIG_DATA *ConfigData,\r
+ OUT UINT32 *LastAttemptVersion,\r
+ OUT UINT32 *LastAttemptStatus,\r
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,\r
+ IN UINTN StartPercentage,\r
+ IN UINTN EndPercentage\r
)\r
{\r
EFI_STATUS Status;\r
DEBUG((DEBUG_INFO, " BaseAddress - 0x%lx,", ConfigData->BaseAddress));\r
DEBUG((DEBUG_INFO, " ImageOffset - 0x%x,", ConfigData->ImageOffset));\r
DEBUG((DEBUG_INFO, " Legnth - 0x%x\n", ConfigData->Length));\r
- Status = PerformFlashWrite (\r
+ if (Progress != NULL) {\r
+ Progress (StartPercentage);\r
+ }\r
+ Status = PerformFlashWriteWithProgress (\r
ConfigData->FirmwareType,\r
ConfigData->BaseAddress,\r
ConfigData->AddressType,\r
(VOID *)((UINTN)SystemFirmwareImage + (UINTN)ConfigData->ImageOffset),\r
- ConfigData->Length\r
+ ConfigData->Length,\r
+ Progress,\r
+ StartPercentage,\r
+ EndPercentage\r
);\r
+ if (Progress != NULL) {\r
+ Progress (EndPercentage);\r
+ }\r
if (!EFI_ERROR(Status)) {\r
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
if (ConfigData->FirmwareType == PlatformFirmwareTypeNvRam) {\r
@param[in] ConfigImageSize The length of the config file image in bytes.\r
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] Progress A function used by the driver to report the progress of the firmware update.\r
\r
@retval EFI_SUCCESS The System Firmware image is updated.\r
@retval EFI_WRITE_PROTECTED The flash device is read only.\r
**/\r
EFI_STATUS\r
UpdateImage (\r
- IN VOID *SystemFirmwareImage,\r
- IN UINTN SystemFirmwareImageSize,\r
- IN VOID *ConfigImage,\r
- IN UINTN ConfigImageSize,\r
- OUT UINT32 *LastAttemptVersion,\r
- OUT UINT32 *LastAttemptStatus\r
+ IN VOID *SystemFirmwareImage,\r
+ IN UINTN SystemFirmwareImageSize,\r
+ IN VOID *ConfigImage,\r
+ IN UINTN ConfigImageSize,\r
+ OUT UINT32 *LastAttemptVersion,\r
+ OUT UINT32 *LastAttemptStatus,\r
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress\r
)\r
{\r
EFI_STATUS Status;\r
UPDATE_CONFIG_DATA *UpdateConfigData;\r
CONFIG_HEADER ConfigHeader;\r
UINTN Index;\r
+ UINTN TotalSize;\r
+ UINTN BytesWritten;\r
+ UINTN StartPercentage;\r
+ UINTN EndPercentage;\r
\r
if (ConfigImage == NULL) {\r
DEBUG((DEBUG_INFO, "PlatformUpdate (NoConfig):"));\r
DEBUG((DEBUG_INFO, " BaseAddress - 0x%x,", 0));\r
DEBUG((DEBUG_INFO, " Length - 0x%x\n", SystemFirmwareImageSize));\r
// ASSUME the whole System Firmware include NVRAM region.\r
- Status = PerformFlashWrite (\r
+ StartPercentage = 0;\r
+ EndPercentage = 100;\r
+ if (Progress != NULL) {\r
+ Progress (StartPercentage);\r
+ }\r
+ Status = PerformFlashWriteWithProgress (\r
PlatformFirmwareTypeNvRam,\r
0,\r
FlashAddressTypeRelativeAddress,\r
SystemFirmwareImage,\r
- SystemFirmwareImageSize\r
+ SystemFirmwareImageSize,\r
+ Progress,\r
+ StartPercentage,\r
+ EndPercentage\r
);\r
+ if (Progress != NULL) {\r
+ Progress (EndPercentage);\r
+ }\r
if (!EFI_ERROR(Status)) {\r
*LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
mNvRamUpdated = TRUE;\r
DEBUG((DEBUG_INFO, "ConfigHeader.NumOfUpdates - 0x%x\n", ConfigHeader.NumOfUpdates));\r
DEBUG((DEBUG_INFO, "PcdEdkiiSystemFirmwareFileGuid - %g\n", PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid)));\r
\r
+ TotalSize = 0;\r
+ for (Index = 0; Index < ConfigHeader.NumOfUpdates; Index++) {\r
+ if (CompareGuid(&ConfigData[Index].FileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid))) {\r
+ TotalSize = TotalSize + ConfigData[Index].Length;\r
+ }\r
+ }\r
+\r
+ BytesWritten = 0;\r
Index = 0;\r
UpdateConfigData = ConfigData;\r
while (Index < ConfigHeader.NumOfUpdates) {\r
if (CompareGuid(&UpdateConfigData->FileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid))) {\r
DEBUG((DEBUG_INFO, "FileGuid - %g (processing)\n", &UpdateConfigData->FileGuid));\r
+ StartPercentage = (BytesWritten * 100) / TotalSize;\r
+ EndPercentage = ((BytesWritten + UpdateConfigData->Length) * 100) / TotalSize;\r
Status = PerformUpdate (\r
SystemFirmwareImage,\r
SystemFirmwareImageSize,\r
UpdateConfigData,\r
LastAttemptVersion,\r
- LastAttemptStatus\r
+ LastAttemptStatus,\r
+ Progress,\r
+ StartPercentage,\r
+ EndPercentage\r
);\r
//\r
// Shall updates be serialized so that if an update is not successfully completed,\r
DEBUG((DEBUG_INFO, "FileGuid - %g (ignored)\n", &UpdateConfigData->FileGuid));\r
}\r
\r
+ BytesWritten += UpdateConfigData->Length;\r
+\r
Index++;\r
UpdateConfigData++;\r
}\r
@param[in] ImageSize The size of the EDKII system FMP capsule image in bytes.\r
@param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
@param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] Progress A function used by the driver to report the progress of the firmware update.\r
\r
@retval EFI_SUCCESS EDKII system FMP capsule passes authentication and the System Firmware image is updated.\r
@retval EFI_SECURITY_VIOLATION EDKII system FMP capsule fails authentication and the System Firmware image is not updated.\r
**/\r
EFI_STATUS\r
SystemFirmwareAuthenticatedUpdate (\r
- IN VOID *Image,\r
- IN UINTN ImageSize,\r
- OUT UINT32 *LastAttemptVersion,\r
- OUT UINT32 *LastAttemptStatus\r
+ IN VOID *Image,\r
+ IN UINTN ImageSize,\r
+ OUT UINT32 *LastAttemptVersion,\r
+ OUT UINT32 *LastAttemptStatus,\r
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress\r
)\r
{\r
EFI_STATUS Status;\r
ExtractConfigImage(AuthenticatedImage, AuthenticatedImageSize, &ConfigImage, &ConfigImageSize);\r
\r
DEBUG((DEBUG_INFO, "UpdateImage ...\n"));\r
- Status = UpdateImage(SystemFirmwareImage, SystemFirmwareImageSize, ConfigImage, ConfigImageSize, LastAttemptVersion, LastAttemptStatus);\r
+ Status = UpdateImage(SystemFirmwareImage, SystemFirmwareImageSize, ConfigImage, ConfigImageSize, LastAttemptVersion, LastAttemptStatus, Progress);\r
if (EFI_ERROR(Status)) {\r
DEBUG((DEBUG_INFO, "UpdateImage - %r\n", Status));\r
return Status;\r
@retval EFI_ABORTED The operation is aborted.\r
@retval EFI_INVALID_PARAMETER The Image was NULL.\r
@retval EFI_UNSUPPORTED The operation is not supported.\r
- @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure.\r
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.\r
\r
**/\r
EFI_STATUS\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Status = SystemFirmwareAuthenticatedUpdate((VOID *)Image, ImageSize, &SystemFmpPrivate->LastAttempt.LastAttemptVersion, &SystemFmpPrivate->LastAttempt.LastAttemptStatus);\r
- DEBUG((DEBUG_INFO, "SetImage - LastAttemp Version - 0x%x, State - 0x%x\n", SystemFmpPrivate->LastAttempt.LastAttemptVersion, SystemFmpPrivate->LastAttempt.LastAttemptStatus));\r
+ Status = SystemFirmwareAuthenticatedUpdate((VOID *)Image, ImageSize, &SystemFmpPrivate->LastAttempt.LastAttemptVersion, &SystemFmpPrivate->LastAttempt.LastAttemptStatus, Progress);\r
+ DEBUG((DEBUG_INFO, "SetImage - LastAttempt Version - 0x%x, State - 0x%x\n", SystemFmpPrivate->LastAttempt.LastAttemptVersion, SystemFmpPrivate->LastAttempt.LastAttemptStatus));\r
\r
//\r
// If NVRAM is updated, we should no longer touch variable services, because\r
// the current variable driver may not manage the new NVRAM region.\r
//\r
if (mNvRamUpdated) {\r
- DEBUG ((DEBUG_INFO, "NvRamUpdated, Update Variable Serivces\n"));\r
+ DEBUG ((DEBUG_INFO, "NvRamUpdated, Update Variable Services\n"));\r
gRT->GetVariable = GetVariableHook;\r
gRT->GetNextVariableName = GetNextVariableNameHook;\r
gRT->SetVariable = SetVariableHook;\r
sizeof(SystemFmpPrivate->LastAttempt),\r
&SystemFmpPrivate->LastAttempt\r
);\r
- DEBUG((DEBUG_INFO, "SetLastAttemp - %r\n", VarStatus));\r
+ DEBUG((DEBUG_INFO, "SetLastAttempt - %r\n", VarStatus));\r
\r
return Status;\r
}\r
)\r
{\r
EFI_STATUS Status;\r
+ UINTN TempHandleCount;\r
EFI_HANDLE *HandleBuffer;\r
UINTN Index;\r
UINTN Index2;\r
BOOLEAN MatchFound;\r
\r
*HandleCount = 0;\r
+ TempHandleCount = 0;\r
HandleBuffer = NULL;\r
Status = gBS->LocateHandleBuffer (\r
ByProtocol,\r
ProtocolGuid,\r
NULL,\r
- HandleCount,\r
+ &TempHandleCount,\r
&HandleBuffer\r
);\r
if (EFI_ERROR (Status)) {\r
- *HandleCount = 0;\r
return NULL;\r
}\r
\r
- for (Index = 0; Index < *HandleCount; Index++) {\r
+ for (Index = 0; Index < TempHandleCount; Index++) {\r
OriginalFmpImageInfoBuf = GetFmpImageDescriptors (\r
HandleBuffer[Index],\r
ProtocolGuid,\r
//\r
FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);\r
}\r
- if (!MatchFound) {\r
- HandleBuffer[Index] = NULL;\r
+ if (MatchFound) {\r
+ HandleBuffer[*HandleCount] = HandleBuffer[Index];\r
+ (*HandleCount)++;\r
}\r
\r
FreePool (OriginalFmpImageInfoBuf);\r
}\r
+\r
+ if ((*HandleCount) == 0) {\r
+ //\r
+ // No any matching handle.\r
+ //\r
+ FreePool (HandleBuffer);\r
+ return NULL;\r
+ }\r
return HandleBuffer;\r
}\r
\r
// Install System FMP protocol onto handle with matching FMP Protocol\r
//\r
DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Install System FMP onto matching FMP handle\n"));\r
+ mSystemFmpPrivate->Handle = HandleBuffer[0];\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&HandleBuffer[0],\r
&gSystemFmpProtocolGuid,\r