On Wed, Oct 25, 2017 at 06:59:40PM +0100, Ard Biesheuvel wrote:
> Add support for dealing with capsules left in memory by the OS before
> reboot. This needs to be done early, before the memory is reused, which
> is why the initial handling must reside here.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> ---
>  Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c   | 59 +++++++++++++++++++-
>  Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf | 12 ++++
>  2 files changed, 70 insertions(+), 1 deletion(-)
> 
> diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c
> index 9359f7c320b7..a249210a3192 100644
> --- a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c
> +++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c
> @@ -17,12 +17,17 @@
>  
>  #include <Library/ArmLib.h>
>  #include <Library/ArmMmuLib.h>
> +#include <Library/CacheMaintenanceLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
>  
>  #include <Platform/MemoryMap.h>
>  #include <Platform/Pcie.h>
>  
> +#include <Ppi/Capsule.h>
> +
>  #define ARM_MEMORY_REGION(Base, Size) \
>    { (Base), (Base), (Size), ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK }
>  
> @@ -39,7 +44,8 @@ BuildMemoryTypeInformationHob (
>  
>  STATIC ARM_MEMORY_REGION_DESCRIPTOR mVirtualMemoryTable[] = {
>    // Memory mapped SPI NOR flash
> -  ARM_UNCACHED_REGION (SYNQUACER_SPI_NOR_BASE, SYNQUACER_SPI_NOR_BASE),
> +  ARM_UNCACHED_REGION (FixedPcdGet64 (PcdFdBaseAddress),
> +                       FixedPcdGet32 (PcdFdSize)),
>  
>    // DDR - 2 GB
>    ARM_MEMORY_REGION (SYNQUACER_SYSTEM_MEMORY_1_BASE,
> @@ -113,6 +119,12 @@ MemoryPeim (
>  {
>    EFI_RESOURCE_ATTRIBUTE_TYPE   ResourceAttributes;
>    RETURN_STATUS                 Status;
> +  EFI_PEI_SERVICES              **PeiServices;
> +  PEI_CAPSULE_PPI               *Capsule;
> +  VOID                          *CapsuleBuffer;
> +  UINTN                         CapsuleBufferLength;
> +  EFI_STATUS                    EfiStatus;
> +  BOOLEAN                       HaveCapsule;
>  
>    ResourceAttributes =
>        EFI_RESOURCE_ATTRIBUTE_PRESENT |
> @@ -140,12 +152,57 @@ MemoryPeim (
>  //    SYNQUACER_SYSTEM_MEMORY_3_BASE,
>  //    SYNQUACER_SYSTEM_MEMORY_3_SZ);
>  
> +  PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();
> +  ASSERT (PeiServices != NULL);
> +
> +  EfiStatus = PeiServicesLocatePpi (&gPeiCapsulePpiGuid, 0, NULL,
> +                (VOID **)&Capsule);
> +  ASSERT_EFI_ERROR (EfiStatus);
> +
> +  //
> +  // Check for persistent capsules
> +  //
> +  HaveCapsule = FALSE;
> +  EfiStatus = Capsule->CheckCapsuleUpdate (PeiServices);
> +  if (!EFI_ERROR (EfiStatus)) {
> +
> +    //
> +    // Coalesce the capsule into unused memory. CreateState() below will copy
> +    // it to a properly allocated buffer.
> +    //
> +    CapsuleBuffer = (VOID *)FixedPcdGet64 (PcdSystemMemoryBase);
> +    CapsuleBufferLength = UefiMemoryBase - FixedPcdGet64 (PcdSystemMemoryBase);
> +
> +    PeiServicesSetBootMode (BOOT_ON_FLASH_UPDATE);
> +
> +    EfiStatus = Capsule->Coalesce (PeiServices, &CapsuleBuffer,
> +                           &CapsuleBufferLength);
> +    if (!EFI_ERROR (EfiStatus)) {
> +      DEBUG ((DEBUG_INFO, "%a: Coalesced capsule @ %p (0x%lx)\n",
> +              __FUNCTION__, CapsuleBuffer, CapsuleBufferLength));
> +      HaveCapsule = TRUE;
> +    } else {
> +      DEBUG ((DEBUG_WARN, "%a: failed to coalesce() capsule (Status == %r)\n",
> +              __FUNCTION__, EfiStatus));
> +    }
> +  }
> +
>    Status = ArmConfigureMmu (mVirtualMemoryTable, NULL, NULL);
>    ASSERT_EFI_ERROR (Status);
>    if (EFI_ERROR (Status)) {
>      return Status;
>    }
>  
> +  if (HaveCapsule) {
> +    EfiStatus = Capsule->CreateState (PeiServices, CapsuleBuffer,
> +                           CapsuleBufferLength);
> +
> +    if (EFI_ERROR (EfiStatus)) {
> +      DEBUG ((DEBUG_WARN, "%a: Capsule->CreateState failed (Status == %r)\n",
> +              __FUNCTION__, EfiStatus));
> +    }
> +  }
> +
>    if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
>      // Optional feature that helps prevent EFI memory map fragmentation.
>      BuildMemoryTypeInformationHob ();
> diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf
> index 1ddaee8a9d45..d294c943d7f9 100644
> --- a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf
> +++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf
> @@ -36,14 +36,20 @@ [Packages]
>  [LibraryClasses]
>    ArmLib
>    ArmMmuLib
> +  CacheMaintenanceLib
>    DebugLib
> +  PeiServicesLib
> +  PeiServicesTablePointerLib
>  
>  [FeaturePcd]
>    gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
>  
>  [FixedPcd]
> +  gArmTokenSpaceGuid.PcdFdBaseAddress
> +  gArmTokenSpaceGuid.PcdFdSize
>    gArmTokenSpaceGuid.PcdGicDistributorBase
>    gArmTokenSpaceGuid.PcdGicRedistributorsBase
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
> @@ -53,3 +59,9 @@ [FixedPcd]
>    gNetsecDxeTokenSpaceGuid.PcdEepRomBase
>    gFip006DxeTokenSpaceGuid.PcdFip006DxeRegBaseAddress
>    gFip006DxeTokenSpaceGuid.PcdFip006DxeMemBaseAddress
> +
> +[Ppis]
> +  gPeiCapsulePpiGuid
> +
> +[Depex]
> +  gPeiCapsulePpiGuid
> -- 
> 2.11.0
> 
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel