From: li-elvin Date: Tue, 23 Feb 2010 02:33:17 +0000 (+0000) Subject: Enhance UpdateCapsule () to support calling multiple times. X-Git-Tag: edk2-stable201903~16292 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=f03ccf59badd0e2c7296542cdb2631cdbb8c0eae;p=mirror_edk2.git 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 --- diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf index 2ab29ba339..c627e9b8d6 100644 --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf @@ -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.
+# Copyright (c) 2006 - 2010, Intel Corporation.
# 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 diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c index fc9fc0e78f..774730e6f8 100644 --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c @@ -27,12 +27,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include +#include // // 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; }