From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: eric.jin@intel.com) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by groups.io with SMTP; Sun, 11 Aug 2019 19:00:49 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Aug 2019 19:00:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,375,1559545200"; d="scan'208";a="375082863" Received: from unknown (HELO jjin9-MOBL.ccr.corp.intel.com) ([10.239.192.132]) by fmsmga005.fm.intel.com with ESMTP; 11 Aug 2019 19:00:47 -0700 From: "Eric Jin" To: devel@edk2.groups.io Cc: Sean Brogan , Bret Barkelew , Liming Gao , Michael D Kinney Subject: [PATCH V2 05/10] FmpDevicePkg/FmpDxe: Different variable for each FMP Descriptor Date: Mon, 12 Aug 2019 10:00:44 +0800 Message-Id: <20190812020044.46044-1-eric.jin@intel.com> X-Mailer: git-send-email 2.20.1.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1525 Cc: Sean Brogan Cc: Bret Barkelew Cc: Liming Gao Signed-off-by: Michael D Kinney Signed-off-by: Eric Jin --- FmpDevicePkg/FmpDxe/FmpDxe.c | 124 +++- FmpDevicePkg/FmpDxe/FmpDxe.h | 8 +- FmpDevicePkg/FmpDxe/VariableSupport.c | 824 ++++++++++++++++++-------- FmpDevicePkg/FmpDxe/VariableSupport.h | 135 ++++- 4 files changed, 786 insertions(+), 305 deletions(-) diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index dab3310834..1574425fd6 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -11,6 +11,7 @@ **/ #include "FmpDxe.h" +#include "VariableSupport.h" /// /// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the @@ -73,7 +74,13 @@ const FIRMWARE_MANAGEMENT_PRIVATE_DATA mFirmwareManagementPrivateDataTemplate = NULL, // VersionName TRUE, // RuntimeVersionSupported NULL, // FmpDeviceLockEvent - FALSE // FmpDeviceLocked + FALSE, // FmpDeviceLocked + NULL, // FmpDeviceContext + NULL, // VersionVariableName + NULL, // LsvVariableName + NULL, // LastAttemptStatusVariableName + NULL, // LastAttemptVersionVariableName + NULL // FmpStateVariableName }; /// @@ -193,7 +200,7 @@ GetImageTypeNameString ( **/ UINT32 GetLowestSupportedVersion ( - VOID + FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { EFI_STATUS Status; @@ -230,7 +237,7 @@ GetLowestSupportedVersion ( // // Check the lowest supported version UEFI variable for this device // - VariableLowestSupportedVersion = GetLowestSupportedVersionFromVariable(); + VariableLowestSupportedVersion = GetLowestSupportedVersionFromVariable (Private); if (VariableLowestSupportedVersion > ReturnLsv) { ReturnLsv = VariableLowestSupportedVersion; } @@ -265,6 +272,20 @@ PopulateDescriptor ( Private->Descriptor.ImageId = Private->Descriptor.ImageIndex; Private->Descriptor.ImageIdName = GetImageTypeNameString(); + // + // Get the hardware instance from FmpDeviceLib + // + Status = FmpDeviceGetHardwareInstance (&Private->Descriptor.HardwareInstance); + if (Status == EFI_UNSUPPORTED) { + Private->Descriptor.HardwareInstance = 0; + } + + // + // Generate UEFI Variable names used to store status information for this + // FMP instance. + // + GenerateFmpVariableNames (Private); + // // Get the version. Some devices don't support getting the firmware version // at runtime. If FmpDeviceLib does not support returning a version, then @@ -273,7 +294,7 @@ PopulateDescriptor ( Status = FmpDeviceGetVersion (&Private->Descriptor.Version); if (Status == EFI_UNSUPPORTED) { Private->RuntimeVersionSupported = FALSE; - Private->Descriptor.Version = GetVersionFromVariable(); + Private->Descriptor.Version = GetVersionFromVariable (Private); } else if (EFI_ERROR (Status)) { // // Unexpected error. Use default version. @@ -309,7 +330,7 @@ PopulateDescriptor ( ); } - Private->Descriptor.LowestSupportedImageVersion = GetLowestSupportedVersion(); + Private->Descriptor.LowestSupportedImageVersion = GetLowestSupportedVersion (Private); // // Get attributes from the FmpDeviceLib @@ -341,16 +362,8 @@ PopulateDescriptor ( Private->Descriptor.Size = 0; } - Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (); - Private->Descriptor.LastAttemptStatus = GetLastAttemptStatusFromVariable (); - - // - // Get the hardware instance from FmpDeviceLib - // - Status = FmpDeviceGetHardwareInstance (&Private->Descriptor.HardwareInstance); - if (Status == EFI_UNSUPPORTED) { - Private->Descriptor.HardwareInstance = 0; - } + Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (Private); + Private->Descriptor.LastAttemptStatus = GetLastAttemptStatusFromVariable (Private); Private->DescriptorPopulated = TRUE; } @@ -453,7 +466,7 @@ GetTheImageInfo ( *ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR); // - // make sure the descriptor has already been loaded + // Make sure the descriptor has already been loaded or refreshed // PopulateDescriptor (Private); @@ -696,7 +709,7 @@ CheckTheImage ( FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext); // - // make sure the descriptor has already been loaded + // Make sure the descriptor has already been loaded or refreshed // PopulateDescriptor (Private); @@ -949,7 +962,15 @@ SetTheImage ( Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This); FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext); - SetLastAttemptVersionInVariable (IncommingFwVersion); //set to 0 to clear any previous results. + // + // Make sure the descriptor has already been loaded or refreshed + // + PopulateDescriptor (Private); + + // + // Set to 0 to clear any previous results. + // + SetLastAttemptVersionInVariable (Private, IncommingFwVersion); // // if we have locked the device, then skip the set operation. @@ -988,7 +1009,7 @@ SetTheImage ( // // Set to actual value // - SetLastAttemptVersionInVariable (IncommingFwVersion); + SetLastAttemptVersionInVariable (Private, IncommingFwVersion); } @@ -1080,7 +1101,7 @@ SetTheImage ( // Save LastAttemptStatus as error so that if SetImage never returns the error // state is recorded. // - SetLastAttemptStatusInVariable (LastAttemptStatus); + SetLastAttemptStatusInVariable (Private, LastAttemptStatus); // // Strip off all the headers so the device can process its firmware @@ -1132,23 +1153,21 @@ SetTheImage ( if (!Private->RuntimeVersionSupported) { Version = DEFAULT_VERSION; GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &Version); - SetVersionInVariable (Version); + SetVersionInVariable (Private, Version); } // // Update lowest supported variable // - { - LowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION; - GetFmpPayloadHeaderLowestSupportedVersion (FmpHeader, FmpPayloadSize, &LowestSupportedVersion); - SetLowestSupportedVersionInVariable (LowestSupportedVersion); - } + LowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION; + GetFmpPayloadHeaderLowestSupportedVersion (FmpHeader, FmpPayloadSize, &LowestSupportedVersion); + SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion); LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; cleanup: mProgressFunc = NULL; - SetLastAttemptStatusInVariable (LastAttemptStatus); + SetLastAttemptStatusInVariable (Private, LastAttemptStatus); if (Progress != NULL) { // @@ -1359,13 +1378,18 @@ InstallFmpInstance ( goto cleanup; } + // + // Make sure the descriptor has already been loaded or refreshed + // + PopulateDescriptor (Private); + DEBUG ((DEBUG_ERROR, "InstallFmpInstance: Lock events\n")); if (IsLockFmpDeviceAtLockEventGuidRequired ()) { // // Lock all UEFI Variables used by this module. // - Status = LockAllFmpVariables (); + Status = LockAllFmpVariables (Private); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to lock variables. Status = %r.\n", Status)); } else { @@ -1417,6 +1441,27 @@ cleanup: if (Private->FmpDeviceLockEvent != NULL) { gBS->CloseEvent (Private->FmpDeviceLockEvent); } + if (Private->Descriptor.VersionName != NULL) { + FreePool (Private->Descriptor.VersionName); + } + if (Private->FmpDeviceContext != NULL) { + FmpDeviceSetContext (NULL, &Private->FmpDeviceContext); + } + if (Private->VersionVariableName != NULL) { + FreePool (Private->VersionVariableName); + } + if (Private->LsvVariableName != NULL) { + FreePool (Private->LsvVariableName); + } + if (Private->LastAttemptStatusVariableName != NULL) { + FreePool (Private->LastAttemptStatusVariableName); + } + if (Private->LastAttemptVersionVariableName != NULL) { + FreePool (Private->LastAttemptVersionVariableName); + } + if (Private->FmpStateVariableName != NULL) { + FreePool (Private->FmpStateVariableName); + } FreePool (Private); } } @@ -1473,8 +1518,27 @@ UninstallFmpInstance ( return Status; } - FmpDeviceSetContext (NULL, &Private->FmpDeviceContext); - + if (Private->Descriptor.VersionName != NULL) { + FreePool (Private->Descriptor.VersionName); + } + if (Private->FmpDeviceContext != NULL) { + FmpDeviceSetContext (NULL, &Private->FmpDeviceContext); + } + if (Private->VersionVariableName != NULL) { + FreePool (Private->VersionVariableName); + } + if (Private->LsvVariableName != NULL) { + FreePool (Private->LsvVariableName); + } + if (Private->LastAttemptStatusVariableName != NULL) { + FreePool (Private->LastAttemptStatusVariableName); + } + if (Private->LastAttemptVersionVariableName != NULL) { + FreePool (Private->LastAttemptVersionVariableName); + } + if (Private->FmpStateVariableName != NULL) { + FreePool (Private->FmpStateVariableName); + } FreePool (Private); return EFI_SUCCESS; diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h index c2ffc439d1..06514c67c8 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.h +++ b/FmpDevicePkg/FmpDxe/FmpDxe.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -26,9 +27,9 @@ #include #include #include +#include #include #include -#include "VariableSupport.h" #define VERSION_STRING_NOT_SUPPORTED L"VERSION STRING NOT SUPPORTED" #define VERSION_STRING_NOT_AVAILABLE L"VERSION STRING NOT AVAILABLE" @@ -57,6 +58,11 @@ typedef struct { // BOOLEAN FmpDeviceLocked; VOID *FmpDeviceContext; + CHAR16 *VersionVariableName; + CHAR16 *LsvVariableName; + CHAR16 *LastAttemptStatusVariableName; + CHAR16 *LastAttemptVersionVariableName; + CHAR16 *FmpStateVariableName; } FIRMWARE_MANAGEMENT_PRIVATE_DATA; /// diff --git a/FmpDevicePkg/FmpDxe/VariableSupport.c b/FmpDevicePkg/FmpDxe/VariableSupport.c index 57f4388df2..d06d6b36c7 100644 --- a/FmpDevicePkg/FmpDxe/VariableSupport.c +++ b/FmpDevicePkg/FmpDxe/VariableSupport.c @@ -3,81 +3,339 @@ firmware updates. Copyright (c) 2016, Microsoft Corporation. All rights reserved.
- Copyright (c) 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include -#include -#include -#include -#include -#include -#include +#include "FmpDxe.h" #include "VariableSupport.h" -/// -/// Array of UEFI variable names that are locked in LockAllFmpVariables(). -/// -const CHAR16 *mFmpVariableLockList[] = { - VARNAME_VERSION, - VARNAME_LSV, - VARNAME_LASTATTEMPTSTATUS, - VARNAME_LASTATTEMPTVERSION -}; +/** + Retrieve the value of a 32-bit UEFI Variable specified by VariableName and + a GUID of gEfiCallerIdGuid. + + @param[in] VariableName Pointer to the UEFI Variable name to retrieve. + @param[out] Valid Set to TRUE if UEFI Variable is present and the size + of the UEFI Variable value is 32-bits. Otherwise + FALSE. + @param[out] Value If Valid is set to TRUE, then the 32-bit value of + the UEFI Variable. Otherwise 0. +**/ +static +VOID +GetFmpVariable ( + IN CHAR16 *VariableName, + OUT BOOLEAN *Valid, + OUT UINT32 *Value + ) +{ + EFI_STATUS Status; + UINTN Size; + UINT32 *Buffer; + + *Valid = FALSE; + *Value = 0; + Size = 0; + Buffer = NULL; + Status = GetVariable2 ( + VariableName, + &gEfiCallerIdGuid, + (VOID **)&Buffer, + &Size + ); + if (!EFI_ERROR (Status) && Size == sizeof (*Value) && Buffer != NULL) { + *Valid = TRUE; + *Value = *Buffer; + } + if (Buffer != NULL) { + FreePool (Buffer); + } +} /** - Returns the value used to fill in the Version field of the - EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo() - service of the Firmware Management Protocol. The value is read from a UEFI - variable. If the UEFI variables does not exist, then a default version value - is returned. + Delete the UEFI Variable with name specified by VariableName and GUID of + gEfiCallerIdGuid. If the variable can not be deleted, then print a + DEBUG_ERROR message. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpVersion" + @param[in] VariableName Pointer to the UEFI Variable name to delete. +**/ +static +VOID +DeleteFmpVariable ( + IN CHAR16 *VariableName + ) +{ + EFI_STATUS Status; + BOOLEAN Valid; + UINT32 Value; - @return The version of the firmware image in the firmware device. + GetFmpVariable (VariableName, &Valid, &Value); + if (Valid) { + Status = gRT->SetVariable (VariableName, &gEfiCallerIdGuid, 0, 0, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to delete FMP Variable %s. Status = %r\n", VariableName, Status)); + } else { + DEBUG ((DEBUG_INFO, "Deleted FMP Variable %s\n", VariableName)); + } + } +} + +/** + Retrieve the FMP Controller State UEFI Variable value. Return NULL if + the variable does not exist or if the size of the UEFI Variable is not the + size of FMP_CONTROLLER_STATE. The buffer for the UEFI Variable value + if allocated using the UEFI Boot Service AllocatePool(). + @param[in] Private Private context structure for the managed controller. + + @return Pointer to the allocated FMP Controller State. Returns NULL + if the variable does not exist or is a different size than expected. **/ -UINT32 -GetVersionFromVariable ( - VOID +static +FMP_CONTROLLER_STATE * +GetFmpControllerState ( + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; - UINT32 *Value; - UINTN Size; - UINT32 Version; + EFI_STATUS Status; + FMP_CONTROLLER_STATE *FmpControllerState; + UINTN Size; + + FmpControllerState = NULL; + Size = 0; + Status = GetVariable2 ( + Private->FmpStateVariableName, + &gEfiCallerIdGuid, + (VOID **)&FmpControllerState, + &Size + ); + if (EFI_ERROR (Status) || FmpControllerState == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to get the FMP Controller State. Status = %r\n", Status)); + } else { + if (Size == sizeof (*FmpControllerState)) { + return FmpControllerState; + } + DEBUG ((DEBUG_ERROR, "Getting FMP Controller State returned a size different than expected. Size = 0x%x\n", Size)); + } + if (FmpControllerState != NULL) { + FreePool (FmpControllerState); + } + return NULL; +} - Value = NULL; - Size = 0; - Version = DEFAULT_VERSION; +/** + Generates a Null-terminated Unicode string UEFI Variable name from a base name + and a hardware instance. If the hardware instance value is 0, then the base + name is returned. If the hardware instance value is non-zero, then the 64-bit + hardware instance value is converted to a 16 character hex string and appended + to base name. The UEFI Variable name returned is allocated using the UEFI + Boot Service AllocatePool(). + + @param[in] HardwareInstance 64-bit hardware instance value. + @param[in] BaseVariableName Null-terminated Unicode string that is the base + name of the UEFI Variable. + + @return Pointer to the allocated UEFI Variable name. Returns NULL if the + UEFI Variable can not be allocated. +**/ +static +CHAR16 * +GenerateFmpVariableName ( + IN UINT64 HardwareInstance, + IN CHAR16 *BaseVariableName + ) +{ + CHAR16 *VariableName; + + VariableName = CatSPrint (NULL, BaseVariableName); + if (VariableName == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to generate FMP variable name %s.\n", BaseVariableName)); + return VariableName; + } + if (HardwareInstance == 0) { + return VariableName; + } + VariableName = CatSPrint (VariableName, L"%016lx", HardwareInstance); + if (VariableName == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to generate FMP variable name %s.\n", BaseVariableName)); + } + return VariableName; +} + +/** + Generate the names of the UEFI Variables used to store state information for + a managed controller. The UEFI Variables names are a combination of a base + name and an optional hardware instance value as a 16 character hex value. If + the hardware instance value is 0, then the 16 character hex value is not + included. These storage for the UEFI Variable names are allocated using the + UEFI Boot Service AllocatePool() and the pointers are stored in the Private. + The following are examples of variable names produces for hardware instance + value 0 and value 0x1234567812345678. + + FmpVersion + FmpLsv + LastAttemptStatus + LastAttemptVersion + FmpState + + FmpVersion1234567812345678 + FmpLsv1234567812345678 + LastAttemptStatus1234567812345678 + LastAttemptVersion1234567812345678 + FmpState1234567812345678 + + @param[in,out] Private Private context structure for the managed controller. +**/ +VOID +GenerateFmpVariableNames ( + IN OUT FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + VOID *Buffer; + FMP_CONTROLLER_STATE FmpControllerState; + + if (Private->VersionVariableName != NULL) { + FreePool (Private->VersionVariableName); + } + if (Private->LsvVariableName != NULL) { + FreePool (Private->LsvVariableName); + } + if (Private->LastAttemptStatusVariableName != NULL) { + FreePool (Private->LastAttemptStatusVariableName); + } + if (Private->LastAttemptVersionVariableName != NULL) { + FreePool (Private->LastAttemptVersionVariableName); + } + if (Private->FmpStateVariableName != NULL) { + FreePool (Private->FmpStateVariableName); + } - Status = GetVariable2 (VARNAME_VERSION, &gEfiCallerIdGuid, (VOID **)&Value, &Size); - if (EFI_ERROR (Status) || (Value == NULL)) { - DEBUG ((DEBUG_ERROR, "Failed to get the Version from variable. Status = %r\n", Status)); - return Version; + Private->VersionVariableName = GenerateFmpVariableName ( + Private->Descriptor.HardwareInstance, + VARNAME_VERSION + ); + Private->LsvVariableName = GenerateFmpVariableName ( + Private->Descriptor.HardwareInstance, + VARNAME_LSV + ); + Private->LastAttemptStatusVariableName = GenerateFmpVariableName ( + Private->Descriptor.HardwareInstance, + VARNAME_LASTATTEMPTSTATUS + ); + Private->LastAttemptVersionVariableName = GenerateFmpVariableName ( + Private->Descriptor.HardwareInstance, + VARNAME_LASTATTEMPTVERSION + ); + Private->FmpStateVariableName = GenerateFmpVariableName ( + Private->Descriptor.HardwareInstance, + VARNAME_FMPSTATE + ); + + DEBUG ((DEBUG_INFO, "FmpDxe Variable %g %s\n", &gEfiCallerIdGuid, Private->VersionVariableName)); + DEBUG ((DEBUG_INFO, "FmpDxe Variable %g %s\n", &gEfiCallerIdGuid, Private->LsvVariableName)); + DEBUG ((DEBUG_INFO, "FmpDxe Variable %g %s\n", &gEfiCallerIdGuid, Private->LastAttemptStatusVariableName)); + DEBUG ((DEBUG_INFO, "FmpDxe Variable %g %s\n", &gEfiCallerIdGuid, Private->LastAttemptVersionVariableName)); + DEBUG ((DEBUG_INFO, "FmpDxe Variable %g %s\n", &gEfiCallerIdGuid, Private->FmpStateVariableName)); + + Buffer = GetFmpControllerState (Private); + if (Buffer != NULL) { + // + // FMP Controller State was found with correct size. + // Delete old variables if they exist. + // + FreePool (Buffer); + DeleteFmpVariable (Private->VersionVariableName); + DeleteFmpVariable (Private->LsvVariableName); + DeleteFmpVariable (Private->LastAttemptStatusVariableName); + DeleteFmpVariable (Private->LastAttemptVersionVariableName); + return; } // - // No error from call + // FMP Controller State was either not found or is wrong size. + // Create a new FMP Controller State variable with the correct size. // - if (Size == sizeof (*Value)) { + DEBUG ((DEBUG_INFO, "Create FMP Controller State\n")); + GetFmpVariable ( + Private->VersionVariableName, + &FmpControllerState.VersionValid, + &FmpControllerState.Version + ); + GetFmpVariable ( + Private->LsvVariableName, + &FmpControllerState.LsvValid, + &FmpControllerState.Lsv + ); + GetFmpVariable ( + Private->LastAttemptStatusVariableName, + &FmpControllerState.LastAttemptStatusValid, + &FmpControllerState.LastAttemptStatus + ); + GetFmpVariable ( + Private->LastAttemptVersionVariableName, + &FmpControllerState.LastAttemptVersionValid, + &FmpControllerState.LastAttemptVersion + ); + Status = gRT->SetVariable ( + Private->FmpStateVariableName, + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (FmpControllerState), + &FmpControllerState + ); + if (EFI_ERROR (Status)) { // - // Successful read + // Failed to create FMP Controller State. In this case, do not + // delete the individual variables. They can be used again on next boot + // to create the FMP Controller State. // - Version = *Value; + DEBUG ((DEBUG_ERROR, "Failed to create FMP Controller State. Status = %r\n", Status)); } else { - // - // Return default since size was unknown - // - DEBUG ((DEBUG_ERROR, "Getting version Variable returned a size different than expected. Size = 0x%x\n", Size)); + DeleteFmpVariable (Private->VersionVariableName); + DeleteFmpVariable (Private->LsvVariableName); + DeleteFmpVariable (Private->LastAttemptStatusVariableName); + DeleteFmpVariable (Private->LastAttemptVersionVariableName); } +} - FreePool (Value); +/** + Returns the value used to fill in the Version field of the + EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo() + service of the Firmware Management Protocol. The value is read from a UEFI + variable. If the UEFI variables does not exist, then a default version value + is returned. + + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" - return Version; + @param[in] Private Private context structure for the managed controller. + + @return The version of the firmware image in the firmware device. +**/ +UINT32 +GetVersionFromVariable ( + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private + ) +{ + FMP_CONTROLLER_STATE *FmpControllerState; + UINT32 Value; + + Value = DEFAULT_VERSION; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState != NULL) { + if (FmpControllerState->VersionValid) { + Value = FmpControllerState->Version; + DEBUG ((DEBUG_INFO, "Get FMP Variable %g %s Version %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + Value + )); + } + FreePool (FmpControllerState); + } + return Value; } /** @@ -87,50 +345,35 @@ GetVersionFromVariable ( variable. If the UEFI variables does not exist, then a default lowest supported version value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpLsv" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" + + @param[in] Private Private context structure for the managed controller. @return The lowest supported version of the firmware image in the firmware device. - **/ UINT32 GetLowestSupportedVersionFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; - UINT32 *Value; - UINTN Size; - UINT32 Version; - - Value = NULL; - Size = 0; - Version = DEFAULT_LOWESTSUPPORTEDVERSION; - - Status = GetVariable2 (VARNAME_LSV, &gEfiCallerIdGuid, (VOID **)&Value, &Size); - if (EFI_ERROR (Status) || (Value == NULL)) { - DEBUG ((DEBUG_WARN, "Warning: Failed to get the Lowest Supported Version from variable. Status = %r\n", Status)); - return Version; - } - - // - // No error from call - // - if (Size == sizeof (*Value)) { - // - // Successful read - // - Version = *Value; - } else { - // - // Return default since size was unknown - // - DEBUG ((DEBUG_ERROR, "Getting LSV Variable returned a size different than expected. Size = 0x%x\n", Size)); + FMP_CONTROLLER_STATE *FmpControllerState; + UINT32 Value; + + Value = DEFAULT_LOWESTSUPPORTEDVERSION; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState != NULL) { + if (FmpControllerState->LsvValid) { + Value = FmpControllerState->Lsv; + DEBUG ((DEBUG_INFO, "Get FMP Variable %g %s LowestSupportedVersion %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + Value + )); + } + FreePool (FmpControllerState); } - - FreePool (Value); - - return Version; + return Value; } /** @@ -140,53 +383,34 @@ GetLowestSupportedVersionFromVariable ( variable. If the UEFI variables does not exist, then a default last attempt status value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptStatus" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" - @return The last attempt status value for the most recent capsule update. + @param[in] Private Private context structure for the managed controller. + @return The last attempt status value for the most recent capsule update. **/ UINT32 GetLastAttemptStatusFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; - UINT32 *Value; - UINTN Size; - UINT32 LastAttemptStatus; - - Value = NULL; - Size = 0; - LastAttemptStatus = DEFAULT_LASTATTEMPT; - - Status = GetVariable2 (VARNAME_LASTATTEMPTSTATUS, &gEfiCallerIdGuid, (VOID **)&Value, &Size); - if (EFI_ERROR (Status) || (Value == NULL)) { - DEBUG ((DEBUG_WARN, "Warning: Failed to get the Last Attempt Status from variable. Status = %r\n", Status)); - return LastAttemptStatus; - } - - // - // No error from call - // - if (Size == sizeof (*Value)) { - // - // Successful read - // - LastAttemptStatus = *Value; - } else { - // - // Return default since size was unknown - // - DEBUG ( - (DEBUG_ERROR, - "Getting Last Attempt Status Variable returned a size different than expected. Size = 0x%x\n", - Size) - ); + FMP_CONTROLLER_STATE *FmpControllerState; + UINT32 Value; + + Value = DEFAULT_LASTATTEMPTSTATUS; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState != NULL) { + if (FmpControllerState->LastAttemptStatusValid) { + Value = FmpControllerState->LastAttemptStatus; + DEBUG ((DEBUG_INFO, "Get FMP Variable %g %s LastAttemptStatus %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + Value + )); + } + FreePool (FmpControllerState); } - - FreePool (Value); - - return LastAttemptStatus; + return Value; } /** @@ -196,219 +420,343 @@ GetLastAttemptStatusFromVariable ( variable. If the UEFI variables does not exist, then a default last attempt version value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" - @return The last attempt version value for the most recent capsule update. + @param[in] Private Private context structure for the managed controller. + @return The last attempt version value for the most recent capsule update. **/ UINT32 GetLastAttemptVersionFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; - UINT32 *Value; - UINTN Size; - UINT32 Version; - - Value = NULL; - Size = 0; - Version = DEFAULT_LASTATTEMPT; - - Status = GetVariable2 (VARNAME_LASTATTEMPTVERSION, &gEfiCallerIdGuid, (VOID **)&Value, &Size); - if (EFI_ERROR (Status) || (Value == NULL)) { - DEBUG ((DEBUG_WARN, "Warning: Failed to get the Last Attempt Version from variable. Status = %r\n", Status)); - return Version; - } - - // - // No error from call - // - if (Size == sizeof (*Value)) { - // - // Successful read - // - Version = *Value; - } else { - // - // Return default since size was unknown - // - DEBUG ( - (DEBUG_ERROR, - "Getting Last Attempt Version variable returned a size different than expected. Size = 0x%x\n", - Size) - ); + FMP_CONTROLLER_STATE *FmpControllerState; + UINT32 Value; + + Value = DEFAULT_LASTATTEMPTVERSION; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState != NULL) { + if (FmpControllerState->LastAttemptVersionValid) { + Value = FmpControllerState->LastAttemptVersion; + DEBUG ((DEBUG_INFO, "Get FMP Variable %g %s LastAttemptVersion %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + Value + )); + } + FreePool (FmpControllerState); } - - FreePool (Value); - - return Version; + return Value; } - /** Saves the version current of the firmware image in the firmware device to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" + @param[in] Private Private context structure for the managed controller. @param[in] Version The version of the firmware image in the firmware device. - **/ VOID SetVersionInVariable ( - UINT32 Version + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 Version ) { - EFI_STATUS Status; - UINT32 Current; + EFI_STATUS Status; + FMP_CONTROLLER_STATE *FmpControllerState; + BOOLEAN Update; - Status = EFI_SUCCESS; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState == NULL) { + // + // Can not update value if FMP Controller State does not exist. + // This variable is guaranteed to be created by GenerateFmpVariableNames(). + // + return; + } - Current = GetVersionFromVariable(); - if (Current != Version) { + Update = FALSE; + if (!FmpControllerState->VersionValid) { + Update = TRUE; + } + if (FmpControllerState->Version != Version) { + Update = TRUE; + } + if (!Update) { + DEBUG ((DEBUG_INFO, "No need to update FMP Controller State. Same value as before.\n")); + } else { + FmpControllerState->VersionValid = TRUE; + FmpControllerState->Version = Version; Status = gRT->SetVariable ( - VARNAME_VERSION, + Private->FmpStateVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (Version), - &Version + sizeof (*FmpControllerState), + FmpControllerState ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to set the Version into a variable. Status = %r\n", Status)); + DEBUG ((DEBUG_ERROR, "Failed to update FMP Controller State. Status = %r\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "Set FMP Variable %g %s Version %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + Version + )); } - } else { - DEBUG ((DEBUG_INFO, "Version variable doesn't need to update. Same value as before.\n")); } + FreePool (FmpControllerState); } /** Saves the lowest supported version current of the firmware image in the firmware device to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpLsv" - - @param[in] LowestSupportedVersion The lowest supported version of the firmware image - in the firmware device. + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" + @param[in] Private Private context structure for the managed + controller. + @param[in] LowestSupportedVersion The lowest supported version of the + firmware image in the firmware device. **/ VOID SetLowestSupportedVersionInVariable ( - UINT32 LowestSupportedVersion + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 LowestSupportedVersion ) { - EFI_STATUS Status; - UINT32 Current; + EFI_STATUS Status; + FMP_CONTROLLER_STATE *FmpControllerState; + BOOLEAN Update; - Status = EFI_SUCCESS; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState == NULL) { + // + // Can not update value if FMP Controller State does not exist. + // This variable is guaranteed to be created by GenerateFmpVariableNames(). + // + return; + } - Current = GetLowestSupportedVersionFromVariable(); - if (LowestSupportedVersion > Current) { + Update = FALSE; + if (!FmpControllerState->LsvValid) { + Update = TRUE; + } + if (FmpControllerState->Lsv < LowestSupportedVersion) { + Update = TRUE; + } + if (!Update) { + DEBUG ((DEBUG_INFO, "No need to update FMP Controller State. Same value as before.\n")); + } else { + FmpControllerState->LsvValid = TRUE; + FmpControllerState->Lsv = LowestSupportedVersion; Status = gRT->SetVariable ( - VARNAME_LSV, + Private->FmpStateVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (LowestSupportedVersion), &LowestSupportedVersion + sizeof (*FmpControllerState), + FmpControllerState ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to set the LSV into a variable. Status = %r\n", Status)); + DEBUG ((DEBUG_ERROR, "Failed to update FMP Controller State. Status = %r\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "Set FMP Variable %g %s LowestSupportedVersion %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + LowestSupportedVersion + )); } - } else { - DEBUG ((DEBUG_INFO, "LSV variable doesn't need to update. Same value as before.\n")); } + FreePool (FmpControllerState); } /** Saves the last attempt status value of the most recent FMP capsule update to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptStatus" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" + @param[in] Private Private context structure for the managed + controller. @param[in] LastAttemptStatus The last attempt status of the most recent FMP capsule update. - **/ VOID SetLastAttemptStatusInVariable ( - UINT32 LastAttemptStatus + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 LastAttemptStatus ) { - EFI_STATUS Status; - UINT32 Current; + EFI_STATUS Status; + FMP_CONTROLLER_STATE *FmpControllerState; + BOOLEAN Update; - Status = EFI_SUCCESS; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState == NULL) { + // + // Can not update value if FMP Controller State does not exist. + // This variable is guaranteed to be created by GenerateFmpVariableNames(). + // + return; + } - Current = GetLastAttemptStatusFromVariable(); - if (Current != LastAttemptStatus) { + Update = FALSE; + if (!FmpControllerState->LastAttemptStatusValid) { + Update = TRUE; + } + if (FmpControllerState->LastAttemptStatus != LastAttemptStatus) { + Update = TRUE; + } + if (!Update) { + DEBUG ((DEBUG_INFO, "No need to update FMP Controller State. Same value as before.\n")); + } else { + FmpControllerState->LastAttemptStatusValid = TRUE; + FmpControllerState->LastAttemptStatus = LastAttemptStatus; Status = gRT->SetVariable ( - VARNAME_LASTATTEMPTSTATUS, + Private->FmpStateVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (LastAttemptStatus), - &LastAttemptStatus + sizeof (*FmpControllerState), + FmpControllerState ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to set the LastAttemptStatus into a variable. Status = %r\n", Status)); + DEBUG ((DEBUG_ERROR, "Failed to update FMP Controller State. Status = %r\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "Set FMP Variable %g %s LastAttemptStatus %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + LastAttemptStatus + )); } - } else { - DEBUG ((DEBUG_INFO, "LastAttemptStatus variable doesn't need to update. Same value as before.\n")); } + FreePool (FmpControllerState); } /** Saves the last attempt version value of the most recent FMP capsule update to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState" + @param[in] Private Private context structure for the managed + controller. @param[in] LastAttemptVersion The last attempt version value of the most recent FMP capsule update. - **/ VOID SetLastAttemptVersionInVariable ( - UINT32 LastAttemptVersion + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 LastAttemptVersion ) { - EFI_STATUS Status; - UINT32 Current; + EFI_STATUS Status; + FMP_CONTROLLER_STATE *FmpControllerState; + BOOLEAN Update; - Status = EFI_SUCCESS; + FmpControllerState = GetFmpControllerState (Private); + if (FmpControllerState == NULL) { + // + // Can not update value if FMP Controller State does not exist. + // This variable is guaranteed to be created by GenerateFmpVariableNames(). + // + return; + } - Current = GetLastAttemptVersionFromVariable(); - if (Current != LastAttemptVersion) { + Update = FALSE; + if (!FmpControllerState->LastAttemptVersionValid) { + Update = TRUE; + } + if (FmpControllerState->LastAttemptVersion != LastAttemptVersion) { + Update = TRUE; + } + if (!Update) { + DEBUG ((DEBUG_INFO, "No need to update FMP Controller State. Same value as before.\n")); + } else { + FmpControllerState->LastAttemptVersionValid = TRUE; + FmpControllerState->LastAttemptVersion = LastAttemptVersion; Status = gRT->SetVariable ( - VARNAME_LASTATTEMPTVERSION, + Private->FmpStateVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (LastAttemptVersion), - &LastAttemptVersion + sizeof (*FmpControllerState), + FmpControllerState ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to set the LastAttemptVersion into a variable. Status = %r\n", Status)); + DEBUG ((DEBUG_ERROR, "Failed to update FMP Controller State. Status = %r\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "Set FMP Variable %g %s LastAttemptVersion %08x\n", + &gEfiCallerIdGuid, + Private->FmpStateVariableName, + LastAttemptVersion + )); } - } else { - DEBUG ((DEBUG_INFO, "LastAttemptVersion variable doesn't need to update. Same value as before.\n")); } + FreePool (FmpControllerState); } /** - Locks all the UEFI Variables used by this module. + Attempts to lock a single UEFI Variable propagating the error state of the + first lock attempt that fails. Uses gEfiCallerIdGuid as the variable GUID. + + @param[in] PreviousStatus The previous UEFI Variable lock attempt status. + @param[in] VariableLock The EDK II Variable Lock Protocol instance. + @param[in] VariableName The name of the UEFI Variable to lock. + + @retval EFI_SUCCESS The UEFI Variable was locked and the previous variable + lock attempt also succeeded. + @retval Other The UEFI Variable could not be locked or the previous + variable lock attempt failed. +**/ +static +EFI_STATUS +LockFmpVariable ( + IN EFI_STATUS PreviousStatus, + IN EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock, + IN CHAR16 *VariableName + ) +{ + EFI_STATUS Status; + + Status = VariableLock->RequestToLock ( + VariableLock, + VariableName, + &gEfiCallerIdGuid + ); + if (!EFI_ERROR (Status)) { + return PreviousStatus; + } + + DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to lock variable %g %s. Status = %r\n", + &gEfiCallerIdGuid, + VariableName, + Status + )); + + if (EFI_ERROR (PreviousStatus)) { + return PreviousStatus; + } + return Status; +} + +/** + Locks all the UEFI Variables that use gEfiCallerIdGuid of the currently + executing module. + + @param[in] Private Private context structure for the managed controller. @retval EFI_SUCCESS All UEFI variables are locked. @retval EFI_UNSUPPORTED Variable Lock Protocol not found. @retval Other One of the UEFI variables could not be locked. - **/ EFI_STATUS LockAllFmpVariables ( - VOID + FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { EFI_STATUS Status; EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; - EFI_STATUS ReturnStatus; - UINTN Index; VariableLock = NULL; Status = gBS->LocateProtocol ( @@ -416,29 +764,17 @@ LockAllFmpVariables ( NULL, (VOID **)&VariableLock ); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || VariableLock == NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to locate Variable Lock Protocol (%r).\n", Status)); return EFI_UNSUPPORTED; } - ReturnStatus = EFI_SUCCESS; - for (Index = 0; Index < ARRAY_SIZE (mFmpVariableLockList); Index++) { - Status = VariableLock->RequestToLock ( - VariableLock, - (CHAR16 *)mFmpVariableLockList[Index], - &gEfiCallerIdGuid - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to lock variable %g %s. Status = %r\n", - &gEfiCallerIdGuid, - mFmpVariableLockList[Index], - Status - )); - if (!EFI_ERROR (ReturnStatus)) { - ReturnStatus = Status; - } - } - } + Status = EFI_SUCCESS; + Status = LockFmpVariable (Status, VariableLock, Private->VersionVariableName); + Status = LockFmpVariable (Status, VariableLock, Private->LsvVariableName); + Status = LockFmpVariable (Status, VariableLock, Private->LastAttemptStatusVariableName); + Status = LockFmpVariable (Status, VariableLock, Private->LastAttemptVersionVariableName); + Status = LockFmpVariable (Status, VariableLock, Private->FmpStateVariableName); - return ReturnStatus; + return Status; } diff --git a/FmpDevicePkg/FmpDxe/VariableSupport.h b/FmpDevicePkg/FmpDxe/VariableSupport.h index b5079a9900..23f24f2a13 100644 --- a/FmpDevicePkg/FmpDxe/VariableSupport.h +++ b/FmpDevicePkg/FmpDxe/VariableSupport.h @@ -3,7 +3,7 @@ firmware updates. Copyright (c) 2016, Microsoft Corporation. All rights reserved.
- Copyright (c) 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -12,16 +12,75 @@ #ifndef __VARIABLE_SUPPORT_H__ #define __VARIABLE_SUPPORT_H__ +/// +/// Default values for FMP Controller State information +/// #define DEFAULT_VERSION 0x1 #define DEFAULT_LOWESTSUPPORTEDVERSION 0x0 -#define DEFAULT_LASTATTEMPT 0x0 +#define DEFAULT_LASTATTEMPTSTATUS 0x0 +#define DEFAULT_LASTATTEMPTVERSION 0x0 +/// +/// Base UEFI Variable names for FMP Controller State information stored in +/// separate variables. +/// #define VARNAME_VERSION L"FmpVersion" #define VARNAME_LSV L"FmpLsv" - #define VARNAME_LASTATTEMPTSTATUS L"LastAttemptStatus" #define VARNAME_LASTATTEMPTVERSION L"LastAttemptVersion" +/// +/// Base UEFI Variable name for FMP Controller State information stored in a +/// merged UEFI Variable. If the separate UEFI Variables above are detected, +/// then they are merged into a single variable and the separate variables are +/// deleted. +/// +#define VARNAME_FMPSTATE L"FmpState" + +/// +/// FMP Controller State structure that is used to store the state of +/// a controller in one combined UEFI Variable. +/// +typedef struct { + BOOLEAN VersionValid; + BOOLEAN LsvValid; + BOOLEAN LastAttemptStatusValid; + BOOLEAN LastAttemptVersionValid; + UINT32 Version; + UINT32 Lsv; + UINT32 LastAttemptStatus; + UINT32 LastAttemptVersion; +} FMP_CONTROLLER_STATE; + +/** + Generate the names of the UEFI Variables used to store state information for + a managed controller. The UEFI Variables names are a combination of a base + name and an optional hardware instance value as a 16 character hex value. If + the hardware instance value is 0, then the 16 character hex value is not + included. These storage for the UEFI Variable names are allocated using the + UEFI Boot Service AllocatePool() and the pointers are stored in the Private. + The following are examples of variable names produces for hardware instance + value 0 and value 0x1234567812345678. + + FmpVersion + FmpLsv + LastAttemptStatus + LastAttemptVersion + FmpDxe + + FmpVersion1234567812345678 + FmpLsv1234567812345678 + LastAttemptStatus1234567812345678 + LastAttemptVersion1234567812345678 + FmpDxe1234567812345678 + + @param[in,out] Private Private context structure for the managed controller. +**/ +VOID +GenerateFmpVariableNames ( + IN OUT FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private + ); + /** Returns the value used to fill in the Version field of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo() @@ -29,14 +88,15 @@ variable. If the UEFI variables does not exist, then a default version value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" - @return The version of the firmware image in the firmware device. + @param[in] Private Private context structure for the managed controller. + @return The version of the firmware image in the firmware device. **/ UINT32 GetVersionFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ); /** @@ -46,15 +106,16 @@ GetVersionFromVariable ( variable. If the UEFI variables does not exist, then a default lowest supported version value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpLsv" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" + + @param[in] Private Private context structure for the managed controller. @return The lowest supported version of the firmware image in the firmware device. - **/ UINT32 GetLowestSupportedVersionFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ); /** @@ -64,14 +125,15 @@ GetLowestSupportedVersionFromVariable ( variable. If the UEFI variables does not exist, then a default last attempt status value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptStatus" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" - @return The last attempt status value for the most recent capsule update. + @param[in] Private Private context structure for the managed controller. + @return The last attempt status value for the most recent capsule update. **/ UINT32 GetLastAttemptStatusFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ); /** @@ -81,83 +143,96 @@ GetLastAttemptStatusFromVariable ( variable. If the UEFI variables does not exist, then a default last attempt version value is returned. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" - @return The last attempt version value for the most recent capsule update. + @param[in] Private Private context structure for the managed controller. + @return The last attempt version value for the most recent capsule update. **/ UINT32 GetLastAttemptVersionFromVariable ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ); /** Saves the version current of the firmware image in the firmware device to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" + @param[in] Private Private context structure for the managed controller. @param[in] Version The version of the firmware image in the firmware device. - **/ VOID SetVersionInVariable ( - UINT32 Version + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 Version ); /** Saves the lowest supported version current of the firmware image in the firmware device to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpLsv" - - @param[in] LowestSupportedVersion The lowest supported version of the firmware image - in the firmware device. + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" + @param[in] Private Private context structure for the managed + controller. + @param[in] LowestSupportedVersion The lowest supported version of the + firmware image in the firmware device. **/ VOID SetLowestSupportedVersionInVariable ( - UINT32 LowestSupportedVersion + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 LowestSupportedVersion ); /** Saves the last attempt status value of the most recent FMP capsule update to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptStatus" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" + @param[in] Private Private context structure for the managed + controller. @param[in] LastAttemptStatus The last attempt status of the most recent FMP capsule update. - **/ VOID SetLastAttemptStatusInVariable ( - UINT32 LastAttemptStatus + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 LastAttemptStatus ); /** Saves the last attempt version value of the most recent FMP capsule update to a UEFI variable. - UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion" + UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe" + @param[in] Private Private context structure for the managed + controller. @param[in] LastAttemptVersion The last attempt version value of the most recent FMP capsule update. - **/ VOID SetLastAttemptVersionInVariable ( - UINT32 LastAttemptVersion + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private, + IN UINT32 LastAttemptVersion ); /** Locks all the UEFI Variables that use gEfiCallerIdGuid of the currently executing module. + @param[in] Private Private context structure for the managed controller. + + @retval EFI_SUCCESS All UEFI variables are locked. + @retval EFI_UNSUPPORTED Variable Lock Protocol not found. + @retval Other One of the UEFI variables could not be locked. **/ EFI_STATUS LockAllFmpVariables ( - VOID + IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ); #endif -- 2.20.1.windows.1