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:
li-elvin 2010-02-23 02:33:17 +00:00
parent 235eaa63dc
commit f03ccf59ba
2 changed files with 40 additions and 12 deletions

View File

@ -5,7 +5,7 @@
# It installs the Capsule Architectural Protocol defined in PI1.0a to signify
# the capsule runtime services are ready.
#
# Copyright (c) 2006 - 2009, Intel Corporation. <BR>
# Copyright (c) 2006 - 2010, Intel Corporation. <BR>
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@ -45,6 +45,8 @@
UefiDriverEntryPoint
CapsuleLib
UefiRuntimeLib
BaseLib
PrintLib
[Guids]
gEfiCapsuleVendorGuid ## SOMETIMES_PRODUCED (Process across reset capsule image) ## Variable:L"CapsuleUpdateData" for capsule updated data

View File

@ -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;
}