Enhance UpdateCapsule () to support calling multiple times.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10044 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -27,12 +27,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
//
|
||||
// Handle for the installation of Capsule Architecture Protocol.
|
||||
//
|
||||
EFI_HANDLE mNewHandle = NULL;
|
||||
|
||||
//
|
||||
// The times of calling UpdateCapsule ()
|
||||
//
|
||||
UINTN mTimes = 0;
|
||||
|
||||
/**
|
||||
Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
|
||||
consumption, the firmware may process the capsule immediately. If the payload should persist
|
||||
@ -72,6 +79,8 @@ UpdateCapsule (
|
||||
EFI_CAPSULE_HEADER *CapsuleHeader;
|
||||
BOOLEAN NeedReset;
|
||||
BOOLEAN InitiateReset;
|
||||
CHAR16 CapsuleVarName[30];
|
||||
CHAR16 *TempVarName;
|
||||
|
||||
//
|
||||
// Capsule Count can't be less than one.
|
||||
@ -80,9 +89,10 @@ UpdateCapsule (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
NeedReset = FALSE;
|
||||
InitiateReset = FALSE;
|
||||
CapsuleHeader = NULL;
|
||||
NeedReset = FALSE;
|
||||
InitiateReset = FALSE;
|
||||
CapsuleHeader = NULL;
|
||||
CapsuleVarName[0] = 0;
|
||||
|
||||
for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
|
||||
//
|
||||
@ -159,25 +169,41 @@ UpdateCapsule (
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
|
||||
// if user calls UpdateCapsule multiple times.
|
||||
//
|
||||
StrCpy (CapsuleVarName, EFI_CAPSULE_VARIABLE_NAME);
|
||||
TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
|
||||
if (mTimes > 0) {
|
||||
UnicodeValueToString (TempVarName, 0, mTimes, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// ScatterGatherList is only referenced if the capsules are defined to persist across
|
||||
// system reset. Set its value into NV storage to let pre-boot driver to pick it up
|
||||
// after coming through a system reset.
|
||||
//
|
||||
Status = EfiSetVariable (
|
||||
EFI_CAPSULE_VARIABLE_NAME,
|
||||
CapsuleVarName,
|
||||
&gEfiCapsuleVendorGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||||
sizeof (UINTN),
|
||||
(VOID *) &ScatterGatherList
|
||||
);
|
||||
if (!EFI_ERROR (Status) && InitiateReset) {
|
||||
//
|
||||
// Firmware that encounters a capsule which has the CAPSULE_FLAGS_INITIATE_RESET Flag set in its header
|
||||
// will initiate a reset of the platform which is compatible with the passed-in capsule request and will
|
||||
// not return back to the caller.
|
||||
//
|
||||
EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Variable has been set successfully, increase variable index.
|
||||
//
|
||||
mTimes++;
|
||||
if(InitiateReset) {
|
||||
//
|
||||
// Firmware that encounters a capsule which has the CAPSULE_FLAGS_INITIATE_RESET Flag set in its header
|
||||
// will initiate a reset of the platform which is compatible with the passed-in capsule request and will
|
||||
// not return back to the caller.
|
||||
//
|
||||
EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
Reference in New Issue
Block a user