X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FCapsulePei%2FUefiCapsule.c;h=b224e200fe182032d6e031613d953f6f8ffca2c9;hb=0c5296153828e87a02545ccd1a4055fbd56875b4;hp=cca455ec396c6b28c73e8e470a4d484469695093;hpb=558f58e3e01a482c5a470594afd03cc4fd526345;p=mirror_edk2.git
diff --git a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
index cca455ec39..b224e200fe 100644
--- a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
+++ b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
@@ -1,17 +1,10 @@
/** @file
Capsule update PEIM for UEFI2.0
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. 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
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -133,7 +126,7 @@ Create4GPageTables (
IN EFI_PHYSICAL_ADDRESS PageTablesAddress,
IN BOOLEAN Page1GSupport
)
-{
+{
UINT8 PhysicalAddressBits;
EFI_PHYSICAL_ADDRESS PageAddress;
UINTN IndexOfPml4Entries;
@@ -172,7 +165,7 @@ Create4GPageTables (
}
//
- // Pre-allocate big pages to avoid later allocations.
+ // Pre-allocate big pages to avoid later allocations.
//
BigPageAddress = (UINTN) PageTablesAddress;
@@ -201,7 +194,7 @@ Create4GPageTables (
if (Page1GSupport) {
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
-
+
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
//
// Fill in the Page Directory entries
@@ -216,7 +209,7 @@ Create4GPageTables (
//
// Each Directory Pointer entries points to a page of Page Directory entires.
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
- //
+ //
PageDirectoryEntry = (VOID *) BigPageAddress;
BigPageAddress += SIZE_4KB;
@@ -360,7 +353,7 @@ Thunk32To64 (
if ((UINTN) ReturnContext->ReturnStatus != 0) {
Status = ENCODE_ERROR ((UINTN) ReturnContext->ReturnStatus);
}
-
+
return Status;
}
@@ -401,7 +394,7 @@ ModeSwitch (
ZeroMem (&Context, sizeof (SWITCH_32_TO_64_CONTEXT));
ZeroMem (&ReturnContext, sizeof (SWITCH_64_TO_32_CONTEXT));
-
+
MemoryBase64 = (UINT64) (UINTN) *MemoryBase;
MemorySize64 = (UINT64) (UINTN) *MemorySize;
MemoryEnd64 = MemoryBase64 + MemorySize64;
@@ -409,7 +402,7 @@ ModeSwitch (
Page1GSupport = IsPage1GSupport ();
//
- // Merge memory range reserved for stack and page table
+ // Merge memory range reserved for stack and page table
//
if (LongModeBuffer->StackBaseAddress < LongModeBuffer->PageTableAddress) {
ReservedRangeBase = LongModeBuffer->StackBaseAddress;
@@ -427,7 +420,7 @@ ModeSwitch (
if (ReservedRangeEnd < MemoryEnd64) {
MemoryBase64 = ReservedRangeEnd;
} else {
- DEBUG ((EFI_D_ERROR, "Memory is not enough to process capsule!\n"));
+ DEBUG ((DEBUG_ERROR, "Memory is not enough to process capsule!\n"));
return EFI_OUT_OF_RESOURCES;
}
} else if (ReservedRangeBase < MemoryEnd64) {
@@ -462,14 +455,14 @@ ModeSwitch (
// Will save the return status of processing capsule
//
ReturnContext.ReturnStatus = 0;
-
+
//
// Save original GDT
//
AsmReadGdtr ((IA32_DESCRIPTOR *)&ReturnContext.Gdtr);
-
+
Status = Thunk32To64 (LongModeBuffer->PageTableAddress, &Context, &ReturnContext);
-
+
if (!EFI_ERROR (Status)) {
*MemoryBase = (VOID *) (UINTN) MemoryBase64;
*MemorySize = (UINTN) MemorySize64;
@@ -525,7 +518,7 @@ FindCapsuleCoalesceImage (
&AuthenticationState
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find PE32 section in CapsuleX64 image ffs %r!\n", Status));
+ DEBUG ((DEBUG_ERROR, "Unable to find PE32 section in CapsuleX64 image ffs %r!\n", Status));
return Status;
}
*CoalesceImageMachineType = PeCoffLoaderGetMachineType ((VOID *) (UINTN) CoalesceImageAddress);
@@ -574,7 +567,7 @@ GetLongModeContext (
LongModeBuffer
);
if (EFI_ERROR (Status)) {
- DEBUG (( EFI_D_ERROR, "Error Get LongModeBuffer variable %r!\n", Status));
+ DEBUG (( DEBUG_ERROR, "Error Get LongModeBuffer variable %r!\n", Status));
}
return Status;
}
@@ -624,6 +617,82 @@ GetPhysicalAddressBits (
}
#endif
+/**
+ Sort memory resource entries based upon PhysicalStart, from low to high.
+
+ @param[in, out] MemoryResource A pointer to the memory resource entry buffer.
+
+**/
+VOID
+SortMemoryResourceDescriptor (
+ IN OUT MEMORY_RESOURCE_DESCRIPTOR *MemoryResource
+ )
+{
+ MEMORY_RESOURCE_DESCRIPTOR *MemoryResourceEntry;
+ MEMORY_RESOURCE_DESCRIPTOR *NextMemoryResourceEntry;
+ MEMORY_RESOURCE_DESCRIPTOR TempMemoryResource;
+
+ MemoryResourceEntry = MemoryResource;
+ NextMemoryResourceEntry = MemoryResource + 1;
+ while (MemoryResourceEntry->ResourceLength != 0) {
+ while (NextMemoryResourceEntry->ResourceLength != 0) {
+ if (MemoryResourceEntry->PhysicalStart > NextMemoryResourceEntry->PhysicalStart) {
+ CopyMem (&TempMemoryResource, MemoryResourceEntry, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
+ CopyMem (MemoryResourceEntry, NextMemoryResourceEntry, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
+ CopyMem (NextMemoryResourceEntry, &TempMemoryResource, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
+ }
+
+ NextMemoryResourceEntry = NextMemoryResourceEntry + 1;
+ }
+
+ MemoryResourceEntry = MemoryResourceEntry + 1;
+ NextMemoryResourceEntry = MemoryResourceEntry + 1;
+ }
+}
+
+/**
+ Merge continous memory resource entries.
+
+ @param[in, out] MemoryResource A pointer to the memory resource entry buffer.
+
+**/
+VOID
+MergeMemoryResourceDescriptor (
+ IN OUT MEMORY_RESOURCE_DESCRIPTOR *MemoryResource
+ )
+{
+ MEMORY_RESOURCE_DESCRIPTOR *MemoryResourceEntry;
+ MEMORY_RESOURCE_DESCRIPTOR *NewMemoryResourceEntry;
+ MEMORY_RESOURCE_DESCRIPTOR *NextMemoryResourceEntry;
+ MEMORY_RESOURCE_DESCRIPTOR *MemoryResourceEnd;
+
+ MemoryResourceEntry = MemoryResource;
+ NewMemoryResourceEntry = MemoryResource;
+ while (MemoryResourceEntry->ResourceLength != 0) {
+ CopyMem (NewMemoryResourceEntry, MemoryResourceEntry, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
+ NextMemoryResourceEntry = MemoryResourceEntry + 1;
+
+ while ((NextMemoryResourceEntry->ResourceLength != 0) &&
+ (NextMemoryResourceEntry->PhysicalStart == (MemoryResourceEntry->PhysicalStart + MemoryResourceEntry->ResourceLength))) {
+ MemoryResourceEntry->ResourceLength += NextMemoryResourceEntry->ResourceLength;
+ if (NewMemoryResourceEntry != MemoryResourceEntry) {
+ NewMemoryResourceEntry->ResourceLength += NextMemoryResourceEntry->ResourceLength;
+ }
+
+ NextMemoryResourceEntry = NextMemoryResourceEntry + 1;
+ }
+
+ MemoryResourceEntry = NextMemoryResourceEntry;
+ NewMemoryResourceEntry = NewMemoryResourceEntry + 1;
+ }
+
+ //
+ // Set NULL terminate memory resource descriptor after merging.
+ //
+ MemoryResourceEnd = NewMemoryResourceEntry;
+ ZeroMem (MemoryResourceEnd, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
+}
+
/**
Build memory resource descriptor from resource descriptor in HOB list.
@@ -658,7 +727,7 @@ BuildMemoryResourceDescriptor (
}
if (Index == 0) {
- DEBUG ((EFI_D_INFO | EFI_D_WARN, "No memory resource descriptor reported in HOB list before capsule Coalesce\n"));
+ DEBUG ((DEBUG_INFO | DEBUG_WARN, "No memory resource descriptor reported in HOB list before capsule Coalesce\n"));
#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
//
// Allocate memory to hold memory resource descriptor,
@@ -667,10 +736,10 @@ BuildMemoryResourceDescriptor (
Status = PeiServicesAllocatePool ((1 + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR), (VOID **) &MemoryResource);
ASSERT_EFI_ERROR (Status);
ZeroMem (MemoryResource, (1 + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR));
-
+
MemoryResource[0].PhysicalStart = 0;
MemoryResource[0].ResourceLength = LShiftU64 (1, GetPhysicalAddressBits ());
- DEBUG ((EFI_D_INFO, "MemoryResource[0x0] - Start(0x%0lx) Length(0x%0lx)\n",
+ DEBUG ((DEBUG_INFO, "MemoryResource[0x0] - Start(0x%0lx) Length(0x%0lx)\n",
MemoryResource[0x0].PhysicalStart, MemoryResource[0x0].ResourceLength));
return MemoryResource;
#else
@@ -694,7 +763,7 @@ BuildMemoryResourceDescriptor (
while (Hob.Raw != NULL) {
ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *) Hob.Raw;
if (ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
- DEBUG ((EFI_D_INFO, "MemoryResource[0x%x] - Start(0x%0lx) Length(0x%0lx)\n",
+ DEBUG ((DEBUG_INFO, "MemoryResource[0x%x] - Start(0x%0lx) Length(0x%0lx)\n",
Index, ResourceDescriptor->PhysicalStart, ResourceDescriptor->ResourceLength));
MemoryResource[Index].PhysicalStart = ResourceDescriptor->PhysicalStart;
MemoryResource[Index].ResourceLength = ResourceDescriptor->ResourceLength;
@@ -704,22 +773,100 @@ BuildMemoryResourceDescriptor (
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
}
+ SortMemoryResourceDescriptor (MemoryResource);
+ MergeMemoryResourceDescriptor (MemoryResource);
+
+ DEBUG ((DEBUG_INFO, "Dump MemoryResource[] after sorted and merged\n"));
+ for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) {
+ DEBUG ((
+ DEBUG_INFO,
+ " MemoryResource[0x%x] - Start(0x%0lx) Length(0x%0lx)\n",
+ Index,
+ MemoryResource[Index].PhysicalStart,
+ MemoryResource[Index].ResourceLength
+ ));
+ }
+
return MemoryResource;
}
/**
- Checks for the presence of capsule descriptors.
- Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
- and save to DescriptorBuffer.
+ Check if the capsules are staged.
+
+ @param UpdateCapsules A pointer to return the check result.
+
+ @retval EFI_INVALID_PARAMETER The parameter is null.
+ @retval EFI_SUCCESS The Capsules are staged.
+
+**/
+EFI_STATUS
+AreCapsulesStaged (
+ OUT BOOLEAN *UpdateCapsules
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices;
+ EFI_PHYSICAL_ADDRESS CapsuleDataPtr64 = 0;
+
+ if (UpdateCapsules == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a Invalid parameters. Inputs can't be NULL\n", __FUNCTION__));
+ ASSERT (UpdateCapsules != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *UpdateCapsules = FALSE;
+
+ Status = PeiServicesLocatePpi(
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PPIVariableServices
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to find ReadOnlyVariable2PPI\n"));
+ return Status;
+ }
+
+ //
+ // Check for Update capsule
+ //
+ Size = sizeof (CapsuleDataPtr64);
+ Status = PPIVariableServices->GetVariable (
+ PPIVariableServices,
+ EFI_CAPSULE_VARIABLE_NAME,
+ &gEfiCapsuleVendorGuid,
+ NULL,
+ &Size,
+ (VOID *)&CapsuleDataPtr64
+ );
+
+ if (!EFI_ERROR (Status)) {
+ *UpdateCapsules = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+#define MAX_SG_LIST_HEADS (20)
+
+/**
+ Check all the variables for SG list heads and get the count and addresses.
+
+ @param ListLength A pointer would return the SG list length.
+ @param HeadList A ponter to the capsule SG list.
- @param DescriptorBuffer Pointer to the capsule descriptors
+ @retval EFI_SUCCESS a valid capsule is present
+ @retval EFI_NOT_FOUND if a valid capsule is not present
+ @retval EFI_INVALID_PARAMETER the input parameter is invalid
+ @retval EFI_OUT_OF_RESOURCES fail to allocate memory
- @retval EFI_SUCCESS a valid capsule is present
- @retval EFI_NOT_FOUND if a valid capsule is not present
**/
EFI_STATUS
-GetCapsuleDescriptors (
- IN EFI_PHYSICAL_ADDRESS *DescriptorBuffer
+GetScatterGatherHeadEntries (
+ OUT UINTN *ListLength,
+ OUT EFI_PHYSICAL_ADDRESS **HeadList
)
{
EFI_STATUS Status;
@@ -732,94 +879,104 @@ GetCapsuleDescriptors (
CHAR16 *TempVarName;
EFI_PHYSICAL_ADDRESS CapsuleDataPtr64;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices;
+ EFI_PHYSICAL_ADDRESS TempList[MAX_SG_LIST_HEADS];
Index = 0;
TempVarName = NULL;
CapsuleVarName[0] = 0;
ValidIndex = 0;
CapsuleDataPtr64 = 0;
-
+
+ if ((ListLength == NULL) || (HeadList == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a Invalid parameters. Inputs can't be NULL\n", __FUNCTION__));
+ ASSERT (ListLength != NULL);
+ ASSERT (HeadList != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ListLength = 0;
+ *HeadList = NULL;
+
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
- (VOID **) &PPIVariableServices
+ (VOID **)&PPIVariableServices
);
- if (Status == EFI_SUCCESS) {
- StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPSULE_VARIABLE_NAME);
- TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to find ReadOnlyVariable2PPI\n"));
+ return Status;
+ }
+
+ //
+ // setup var name buffer for update capsules
+ //
+ StrCpyS (CapsuleVarName, sizeof (CapsuleVarName) / sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
+ TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
+ while (ValidIndex < MAX_SG_LIST_HEADS) {
+ if (Index != 0) {
+ UnicodeValueToStringS (
+ TempVarName,
+ (sizeof (CapsuleVarName) - ((StrLen (CapsuleVarName) + 1) * sizeof (CHAR16))),
+ 0,
+ Index,
+ 0
+ );
+ }
Size = sizeof (CapsuleDataPtr64);
- while (1) {
- if (Index == 0) {
- //
- // For the first Capsule Image
- //
- Status = PPIVariableServices->GetVariable (
- PPIVariableServices,
- CapsuleVarName,
- &gEfiCapsuleVendorGuid,
- NULL,
- &Size,
- (VOID *) &CapsuleDataPtr64
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "Capsule -- capsule variable not set\n"));
- return EFI_NOT_FOUND;
- }
- //
- // We have a chicken/egg situation where the memory init code needs to
- // know the boot mode prior to initializing memory. For this case, our
- // validate function will fail. We can detect if this is the case if blocklist
- // pointer is null. In that case, return success since we know that the
- // variable is set.
- //
- if (DescriptorBuffer == NULL) {
- return EFI_SUCCESS;
- }
- } else {
- UnicodeValueToStringS (
- TempVarName,
- sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
- 0,
- Index,
- 0
- );
- Status = PPIVariableServices->GetVariable (
- PPIVariableServices,
- CapsuleVarName,
- &gEfiCapsuleVendorGuid,
- NULL,
- &Size,
- (VOID *) &CapsuleDataPtr64
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- //
- // If this BlockList has been linked before, skip this variable
- //
- Flag = FALSE;
- for (TempIndex = 0; TempIndex < ValidIndex; TempIndex++) {
- if (DescriptorBuffer[TempIndex] == CapsuleDataPtr64) {
- Flag = TRUE;
- break;
- }
- }
- if (Flag) {
- Index ++;
- continue;
- }
+ Status = PPIVariableServices->GetVariable (
+ PPIVariableServices,
+ CapsuleVarName,
+ &gEfiCapsuleVendorGuid,
+ NULL,
+ &Size,
+ (VOID *)&CapsuleDataPtr64
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_NOT_FOUND) {
+ DEBUG ((DEBUG_ERROR, "Unexpected error getting Capsule Update variable. Status = %r\n"));
+ }
+ break;
+ }
+
+ //
+ // If this BlockList has been linked before, skip this variable
+ //
+ Flag = FALSE;
+ for (TempIndex = 0; TempIndex < ValidIndex; TempIndex++) {
+ if (TempList[TempIndex] == CapsuleDataPtr64) {
+ Flag = TRUE;
+ break;
}
-
- //
- // Cache BlockList which has been processed
- //
- DescriptorBuffer[ValidIndex++] = CapsuleDataPtr64;
- Index ++;
}
+ if (Flag) {
+ Index++;
+ continue;
+ }
+
+ //
+ // add it to the cached list
+ //
+ TempList[ValidIndex++] = CapsuleDataPtr64;
+ Index++;
+ }
+
+ if (ValidIndex == 0) {
+ DEBUG ((DEBUG_ERROR, "%a didn't find any SG lists in variables\n", __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+
+ *HeadList = AllocateZeroPool ((ValidIndex + 1) * sizeof (EFI_PHYSICAL_ADDRESS));
+ if (*HeadList == NULL) {
+ DEBUG ((DEBUG_ERROR, "Failed to allocate memory\n"));
+ return EFI_OUT_OF_RESOURCES;
}
-
+
+ CopyMem (*HeadList, TempList, (ValidIndex) * sizeof (EFI_PHYSICAL_ADDRESS));
+ *ListLength = ValidIndex;
+
return EFI_SUCCESS;
}
@@ -854,15 +1011,9 @@ CapsuleCoalesce (
IN OUT UINTN *MemorySize
)
{
- UINTN Index;
- UINTN Size;
- UINTN VariableCount;
- CHAR16 CapsuleVarName[30];
- CHAR16 *TempVarName;
- EFI_PHYSICAL_ADDRESS CapsuleDataPtr64;
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices;
+ UINTN ListLength;
EFI_PHYSICAL_ADDRESS *VariableArrayAddress;
MEMORY_RESOURCE_DESCRIPTOR *MemoryResource;
#ifdef MDE_CPU_IA32
@@ -872,10 +1023,8 @@ CapsuleCoalesce (
EFI_CAPSULE_LONG_MODE_BUFFER LongModeBuffer;
#endif
- Index = 0;
- VariableCount = 0;
- CapsuleVarName[0] = 0;
- CapsuleDataPtr64 = 0;
+ ListLength = 0;
+ VariableArrayAddress = NULL;
//
// Someone should have already ascertained the boot mode. If it's not
@@ -883,80 +1032,17 @@ CapsuleCoalesce (
//
Status = PeiServicesGetBootMode (&BootMode);
if (EFI_ERROR (Status) || (BootMode != BOOT_ON_FLASH_UPDATE)) {
- DEBUG ((EFI_D_ERROR, "Boot mode is not correct for capsule update path.\n"));
+ DEBUG ((DEBUG_ERROR, "Boot mode is not correct for capsule update path.\n"));
Status = EFI_NOT_FOUND;
goto Done;
}
-
- //
- // User may set the same ScatterGatherList with several different variables,
- // so cache all ScatterGatherList for check later.
- //
- Status = PeiServicesLocatePpi (
- &gEfiPeiReadOnlyVariable2PpiGuid,
- 0,
- NULL,
- (VOID **) &PPIVariableServices
- );
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- Size = sizeof (CapsuleDataPtr64);
- StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPSULE_VARIABLE_NAME);
- TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
- while (TRUE) {
- if (Index > 0) {
- UnicodeValueToStringS (
- TempVarName,
- sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
- 0,
- Index,
- 0
- );
- }
- Status = PPIVariableServices->GetVariable (
- PPIVariableServices,
- CapsuleVarName,
- &gEfiCapsuleVendorGuid,
- NULL,
- &Size,
- (VOID *) &CapsuleDataPtr64
- );
- if (EFI_ERROR (Status)) {
- //
- // There is no capsule variables, quit
- //
- DEBUG ((EFI_D_INFO,"Capsule variable Index = %d\n", Index));
- break;
- }
- VariableCount++;
- Index++;
- }
-
- DEBUG ((EFI_D_INFO,"Capsule variable count = %d\n", VariableCount));
-
- //
- // The last entry is the end flag.
- //
- Status = PeiServicesAllocatePool (
- (VariableCount + 1) * sizeof (EFI_PHYSICAL_ADDRESS),
- (VOID **)&VariableArrayAddress
- );
- if (Status != EFI_SUCCESS) {
- DEBUG ((EFI_D_ERROR, "AllocatePages Failed!, Status = %x\n", Status));
- goto Done;
- }
-
- ZeroMem (VariableArrayAddress, (VariableCount + 1) * sizeof (EFI_PHYSICAL_ADDRESS));
-
//
- // Find out if we actually have a capsule.
- // GetCapsuleDescriptors depends on variable PPI, so it should run in 32-bit environment.
+ // Get SG list entries
//
- Status = GetCapsuleDescriptors (VariableArrayAddress);
+ Status = GetScatterGatherHeadEntries (&ListLength, &VariableArrayAddress);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Fail to find capsule variables.\n"));
+ DEBUG ((DEBUG_ERROR, "%a failed to get Scatter Gather List Head Entries. Status = %r\n", __FUNCTION__, Status));
goto Done;
}
@@ -974,14 +1060,14 @@ CapsuleCoalesce (
CoalesceImageEntryPoint = 0;
Status = GetLongModeContext (&LongModeBuffer);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Fail to find the variable for long mode context!\n"));
+ DEBUG ((DEBUG_ERROR, "Fail to find the variable for long mode context!\n"));
Status = EFI_NOT_FOUND;
goto Done;
}
-
+
Status = FindCapsuleCoalesceImage (&CoalesceImageEntryPoint, &CoalesceImageMachineType);
if ((EFI_ERROR (Status)) || (CoalesceImageMachineType != EFI_IMAGE_MACHINE_X64)) {
- DEBUG ((EFI_D_ERROR, "Fail to find CapsuleX64 module in FV!\n"));
+ DEBUG ((DEBUG_ERROR, "Fail to find CapsuleX64 module in FV!\n"));
Status = EFI_NOT_FOUND;
goto Done;
}
@@ -1000,15 +1086,15 @@ CapsuleCoalesce (
//
Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);
#endif
-
- DEBUG ((EFI_D_INFO, "Capsule Coalesce Status = %r!\n", Status));
+
+ DEBUG ((DEBUG_INFO, "Capsule Coalesce Status = %r!\n", Status));
if (Status == EFI_BUFFER_TOO_SMALL) {
- DEBUG ((EFI_D_ERROR, "There is not enough memory to process capsule!\n"));
+ DEBUG ((DEBUG_ERROR, "There is not enough memory to process capsule!\n"));
}
-
+
if (Status == EFI_NOT_FOUND) {
- DEBUG ((EFI_D_ERROR, "Fail to parse capsule descriptor in memory!\n"));
+ DEBUG ((DEBUG_ERROR, "Fail to parse capsule descriptor in memory!\n"));
REPORT_STATUS_CODE (
EFI_ERROR_CODE | EFI_ERROR_MAJOR,
(EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR)
@@ -1035,13 +1121,23 @@ CheckCapsuleUpdate (
)
{
EFI_STATUS Status;
- Status = GetCapsuleDescriptors (NULL);
+ BOOLEAN Update;
+
+ Status = AreCapsulesStaged (&Update);
+
+ if (!EFI_ERROR (Status)) {
+ if (Update) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_NOT_FOUND;
+ }
+ }
return Status;
}
/**
- This function will look at a capsule and determine if it's a test pattern.
+ This function will look at a capsule and determine if it's a test pattern.
If it is, then it will verify it and emit an error message if corruption is detected.
-
+
@param PeiServices Standard pei services pointer
@param CapsuleBase Base address of coalesced capsule, which is preceeded
by private data. Very implementation specific.
@@ -1073,7 +1169,7 @@ CapsuleTestPattern (
//
if (*TestPtr == 0x54534554) {
RetValue = TRUE;
- DEBUG ((EFI_D_INFO, "Capsule test pattern mode activated...\n"));
+ DEBUG ((DEBUG_INFO, "Capsule test pattern mode activated...\n"));
TestSize = TestPtr[1] / sizeof (UINT32);
//
// Skip over the signature and the size fields in the pattern data header
@@ -1082,7 +1178,7 @@ CapsuleTestPattern (
TestCounter = 0;
while (TestSize > 0) {
if (*TestPtr != TestCounter) {
- DEBUG ((EFI_D_INFO, "Capsule test pattern mode FAILED: BaseAddr/FailAddr 0x%X 0x%X\n", (UINT32)(UINTN)(EFI_CAPSULE_PEIM_PRIVATE_DATA *)CapsuleBase, (UINT32)(UINTN)TestPtr));
+ DEBUG ((DEBUG_INFO, "Capsule test pattern mode FAILED: BaseAddr/FailAddr 0x%X 0x%X\n", (UINT32)(UINTN)(EFI_CAPSULE_PEIM_PRIVATE_DATA *)CapsuleBase, (UINT32)(UINTN)TestPtr));
return TRUE;
}
@@ -1091,7 +1187,7 @@ CapsuleTestPattern (
TestSize--;
}
- DEBUG ((EFI_D_INFO, "Capsule test pattern mode SUCCESS\n"));
+ DEBUG ((DEBUG_INFO, "Capsule test pattern mode SUCCESS\n"));
}
return RetValue;
@@ -1130,17 +1226,17 @@ CreateState (
UINT32 Index;
EFI_PHYSICAL_ADDRESS BaseAddress;
UINT64 Length;
-
+
PrivateData = (EFI_CAPSULE_PEIM_PRIVATE_DATA *) CapsuleBase;
if (PrivateData->Signature != EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE) {
return EFI_VOLUME_CORRUPTED;
}
if (PrivateData->CapsuleAllImageSize >= MAX_ADDRESS) {
- DEBUG ((EFI_D_ERROR, "CapsuleAllImageSize too big - 0x%lx\n", PrivateData->CapsuleAllImageSize));
+ DEBUG ((DEBUG_ERROR, "CapsuleAllImageSize too big - 0x%lx\n", PrivateData->CapsuleAllImageSize));
return EFI_OUT_OF_RESOURCES;
}
if (PrivateData->CapsuleNumber >= MAX_ADDRESS) {
- DEBUG ((EFI_D_ERROR, "CapsuleNumber too big - 0x%lx\n", PrivateData->CapsuleNumber));
+ DEBUG ((DEBUG_ERROR, "CapsuleNumber too big - 0x%lx\n", PrivateData->CapsuleNumber));
return EFI_OUT_OF_RESOURCES;
}
//
@@ -1158,13 +1254,13 @@ CreateState (
);
if (Status != EFI_SUCCESS) {
- DEBUG ((EFI_D_ERROR, "AllocatePages Failed!\n"));
+ DEBUG ((DEBUG_ERROR, "AllocatePages Failed!\n"));
return Status;
}
//
// Copy to our new buffer for DXE
//
- DEBUG ((EFI_D_INFO, "Capsule copy from 0x%8X to 0x%8X with size 0x%8X\n", (UINTN)((UINT8 *)PrivateData + sizeof(EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64)), (UINTN) NewBuffer, Size));
+ DEBUG ((DEBUG_INFO, "Capsule copy from 0x%8X to 0x%8X with size 0x%8X\n", (UINTN)((UINT8 *)PrivateData + sizeof(EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64)), (UINTN) NewBuffer, Size));
CopyMem ((VOID *) (UINTN) NewBuffer, (VOID *) (UINTN) ((UINT8 *)PrivateData + sizeof(EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64)), Size);
//
// Check for test data pattern. If it is the test pattern, then we'll
@@ -1186,7 +1282,7 @@ CreateState (
BuildCvHob (BaseAddress, Length);
}
-
+
return EFI_SUCCESS;
}