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
This commit is contained in:
lgao4 2009-08-18 01:23:29 +00:00
parent bdb140d76b
commit 409d47b49e
1 changed files with 47 additions and 51 deletions

View File

@ -63,6 +63,7 @@ UpdateCapsule (
UINTN ArrayNumber; UINTN ArrayNumber;
EFI_STATUS Status; EFI_STATUS Status;
EFI_CAPSULE_HEADER *CapsuleHeader; EFI_CAPSULE_HEADER *CapsuleHeader;
BOOLEAN NeedReset;
// //
// Capsule Count can't be less than one. // Capsule Count can't be less than one.
@ -70,8 +71,8 @@ UpdateCapsule (
if (CapsuleCount < 1) { if (CapsuleCount < 1) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
NeedReset = FALSE;
CapsuleHeader = NULL; CapsuleHeader = NULL;
for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
// //
@ -92,71 +93,66 @@ UpdateCapsule (
} }
// //
// Assume that capsules have the same flags on reseting or not. // Walk through all capsules, record whether there is a capsule
// needs reset. And then process capsules which has no reset flag directly.
// //
CapsuleHeader = CapsuleHeaderArray[0]; for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {
CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
//
// 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 // Here should be in the boot-time for non-reset capsule image
// Platform specific update for the non-reset capsule image.
// //
if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) { if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {
return EFI_UNSUPPORTED; if (EfiAtRuntime ()) {
} Status = EFI_UNSUPPORTED;
// } else {
// ScatterGatherList is only referenced if the capsules are defined to persist across Status = ProcessCapsuleImage(CapsuleHeader);
// system reset. }
// if (EFI_ERROR(Status)) {
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) {
return Status; return Status;
} }
// } else {
// Successfully set the capsule image address into EFI variable. NeedReset = TRUE;
//
return EFI_SUCCESS;
} }
} }
//
// 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 ()) { if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
// return EFI_INVALID_PARAMETER;
// Runtime mode doesn't support the non-reset capsule image. }
//
//
// Check if the platform supports update capsule across a system reset
//
if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
// //
// Here should be in the boot-time for non-reset capsule image // ScatterGatherList is only referenced if the capsules are defined to persist across
// Platform specific update for the non-reset capsule image. // system reset. Set its value into NV storage to let pre-boot driver to pick it up
// after coming through a system reset.
// //
for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { Status = gRT->SetVariable (
Status = ProcessCapsuleImage (CapsuleHeaderArray[ArrayNumber]); EFI_CAPSULE_VARIABLE_NAME,
if (EFI_ERROR (Status)) { &gEfiCapsuleVendorGuid,
return Status; EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
} sizeof (UINTN),
} (VOID *) &ScatterGatherList
);
return EFI_SUCCESS; return Status;
} }
/** /**