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