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; }