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 # It installs the Capsule Architectural Protocol defined in PI1.0a to signify
# the capsule runtime services are ready. # 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 # All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # 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 # which accompanies this distribution. The full text of the license may be found at
@ -45,6 +45,8 @@
UefiDriverEntryPoint UefiDriverEntryPoint
CapsuleLib CapsuleLib
UefiRuntimeLib UefiRuntimeLib
BaseLib
PrintLib
[Guids] [Guids]
gEfiCapsuleVendorGuid ## SOMETIMES_PRODUCED (Process across reset capsule image) ## Variable:L"CapsuleUpdateData" for capsule updated data 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/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiRuntimeLib.h> #include <Library/UefiRuntimeLib.h>
#include <Library/BaseLib.h>
#include <Library/PrintLib.h>
// //
// Handle for the installation of Capsule Architecture Protocol. // Handle for the installation of Capsule Architecture Protocol.
// //
EFI_HANDLE mNewHandle = NULL; 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 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 consumption, the firmware may process the capsule immediately. If the payload should persist
@ -72,6 +79,8 @@ UpdateCapsule (
EFI_CAPSULE_HEADER *CapsuleHeader; EFI_CAPSULE_HEADER *CapsuleHeader;
BOOLEAN NeedReset; BOOLEAN NeedReset;
BOOLEAN InitiateReset; BOOLEAN InitiateReset;
CHAR16 CapsuleVarName[30];
CHAR16 *TempVarName;
// //
// Capsule Count can't be less than one. // Capsule Count can't be less than one.
@ -83,6 +92,7 @@ UpdateCapsule (
NeedReset = FALSE; NeedReset = FALSE;
InitiateReset = FALSE; InitiateReset = FALSE;
CapsuleHeader = NULL; CapsuleHeader = NULL;
CapsuleVarName[0] = 0;
for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
// //
@ -159,19 +169,34 @@ UpdateCapsule (
return EFI_UNSUPPORTED; 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 // 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 // system reset. Set its value into NV storage to let pre-boot driver to pick it up
// after coming through a system reset. // after coming through a system reset.
// //
Status = EfiSetVariable ( Status = EfiSetVariable (
EFI_CAPSULE_VARIABLE_NAME, CapsuleVarName,
&gEfiCapsuleVendorGuid, &gEfiCapsuleVendorGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (UINTN), sizeof (UINTN),
(VOID *) &ScatterGatherList (VOID *) &ScatterGatherList
); );
if (!EFI_ERROR (Status) && InitiateReset) { 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 // 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 // will initiate a reset of the platform which is compatible with the passed-in capsule request and will
@ -179,6 +204,7 @@ UpdateCapsule (
// //
EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
} }
}
return Status; return Status;
} }