From 409d47b49e23ae429723419528ea75633808381e Mon Sep 17 00:00:00 2001 From: lgao4 Date: Tue, 18 Aug 2009 01:23:29 +0000 Subject: Enhance Capsule driver to update capsule one by one. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9082 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/CapsuleRuntimeDxe/CapsuleService.c | 98 +++++++++++----------- 1 file changed, 47 insertions(+), 51 deletions(-) (limited to 'MdeModulePkg/Universal/CapsuleRuntimeDxe') diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c index 2bf456cd97..2a45bf37fe 100644 --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c @@ -63,6 +63,7 @@ UpdateCapsule ( UINTN ArrayNumber; EFI_STATUS Status; EFI_CAPSULE_HEADER *CapsuleHeader; + BOOLEAN NeedReset; // // Capsule Count can't be less than one. @@ -70,8 +71,8 @@ UpdateCapsule ( if (CapsuleCount < 1) { return EFI_INVALID_PARAMETER; } - - CapsuleHeader = NULL; + NeedReset = FALSE; + CapsuleHeader = NULL; for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { // @@ -92,71 +93,66 @@ UpdateCapsule ( } // - // Assume that capsules have the same flags on reseting or not. - // - CapsuleHeader = CapsuleHeaderArray[0]; - + // Walk through all capsules, record whether there is a capsule + // needs reset. And then process capsules which has no reset flag directly. // - // Process across reset capsule image. - // - if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) { - // - // Check if the platform supports update capsule across a system reset - // - if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) { - return EFI_UNSUPPORTED; - } + for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) { + CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; // - // ScatterGatherList is only referenced if the capsules are defined to persist across - // system reset. + // Here should be in the boot-time for non-reset capsule image + // Platform specific update for the non-reset capsule image. // - if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) { - return EFI_INVALID_PARAMETER; - } else { - // - // 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 = gRT->SetVariable ( - EFI_CAPSULE_VARIABLE_NAME, - &gEfiCapsuleVendorGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof (UINTN), - (VOID *) &ScatterGatherList - ); - if (Status != EFI_SUCCESS) { + if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) { + if (EfiAtRuntime ()) { + Status = EFI_UNSUPPORTED; + } else { + Status = ProcessCapsuleImage(CapsuleHeader); + } + if (EFI_ERROR(Status)) { return Status; } - // - // Successfully set the capsule image address into EFI variable. - // - return EFI_SUCCESS; + } else { + NeedReset = TRUE; } } + + // + // After launching all capsules who has no reset flag, if no more capsules claims + // for a system reset just return. + // + if (!NeedReset) { + return EFI_SUCCESS; + } // - // Process the non-reset capsule image. + // ScatterGatherList is only referenced if the capsules are defined to persist across + // system reset. // - if (EfiAtRuntime ()) { - // - // Runtime mode doesn't support the non-reset capsule image. - // - return EFI_UNSUPPORTED; + if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) { + return EFI_INVALID_PARAMETER; } // - // Here should be in the boot-time for non-reset capsule image - // Platform specific update for the non-reset capsule image. + // Check if the platform supports update capsule across a system reset // - for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { - Status = ProcessCapsuleImage (CapsuleHeaderArray[ArrayNumber]); - if (EFI_ERROR (Status)) { - return Status; - } + if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) { + return EFI_UNSUPPORTED; } - return EFI_SUCCESS; + // + // 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 = gRT->SetVariable ( + EFI_CAPSULE_VARIABLE_NAME, + &gEfiCapsuleVendorGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINTN), + (VOID *) &ScatterGatherList + ); + + return Status; } /** -- cgit v1.2.3