[edk2,edk2-platforms,v4,17/34] SynQuacer/SynQuacerMemoryInitPeiLib: add capsule support

Message ID 20171110142127.12018-18-ard.biesheuvel@linaro.org
State New
Headers show
Series
  • add support for Socionext SynQuacer
Related show

Commit Message

Ard Biesheuvel Nov. 10, 2017, 2:21 p.m.
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   | 52 ++++++++++++++++++++
 Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf |  4 +-
 2 files changed, 55 insertions(+), 1 deletion(-)

-- 
2.11.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Patch

diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c
index b682d631d0c2..b44c58d61062 100644
--- a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.c
@@ -22,10 +22,12 @@ 
 #include <Library/HobLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
 
 #include <Platform/MemoryMap.h>
 #include <Platform/Pcie.h>
 
+#include <Ppi/Capsule.h>
 #include <Ppi/DramInfo.h>
 
 #define ARM_MEMORY_REGION(Base, Size) \
@@ -177,6 +179,11 @@  MemoryPeim (
 {
   EFI_STATUS                    Status;
   ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+  EFI_PEI_SERVICES              **PeiServices;
+  PEI_CAPSULE_PPI               *Capsule;
+  VOID                          *CapsuleBuffer;
+  UINTN                         CapsuleBufferLength;
+  BOOLEAN                       HaveCapsule;
 
   Status = DeclareDram (&VirtualMemoryTable);
   ASSERT_EFI_ERROR (Status);
@@ -184,12 +191,57 @@  MemoryPeim (
     return Status;
   }
 
+  PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();
+  ASSERT (PeiServices != NULL);
+
+  Status = PeiServicesLocatePpi (&gPeiCapsulePpiGuid, 0, NULL,
+             (VOID **)&Capsule);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Check for persistent capsules
+  //
+  HaveCapsule = FALSE;
+  Status = Capsule->CheckCapsuleUpdate (PeiServices);
+  if (!EFI_ERROR (Status)) {
+
+    //
+    // Coalesce the capsule into unused memory. CreateState() below will copy
+    // it to a properly allocated buffer.
+    //
+    CapsuleBuffer = (VOID *)PcdGet64 (PcdSystemMemoryBase);
+    CapsuleBufferLength = UefiMemoryBase - PcdGet64 (PcdSystemMemoryBase);
+
+    PeiServicesSetBootMode (BOOT_ON_FLASH_UPDATE);
+
+    Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer,
+                           &CapsuleBufferLength);
+    if (!EFI_ERROR (Status)) {
+      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__, Status));
+    }
+  }
+
   Status = ArmConfigureMmu (VirtualMemoryTable, NULL, NULL);
   ASSERT_EFI_ERROR (Status);
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
+  if (HaveCapsule) {
+    Status = Capsule->CreateState (PeiServices, CapsuleBuffer,
+                        CapsuleBufferLength);
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_WARN, "%a: Capsule->CreateState failed (Status == %r)\n",
+        __FUNCTION__, Status));
+    }
+  }
+
   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 db3e3b3792e4..6c3420a525d6 100644
--- a/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerMemoryInitPeiLib/SynQuacerMemoryInitPeiLib.inf
@@ -39,6 +39,7 @@  [LibraryClasses]
   DebugLib
   MemoryAllocationLib
   PeiServicesLib
+  PeiServicesTablePointerLib
 
 [FeaturePcd]
   gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
@@ -62,7 +63,8 @@  [Pcd]
   gArmTokenSpaceGuid.PcdSystemMemoryBase
 
 [Ppis]
+  gPeiCapsulePpiGuid                    ## CONSUMES
   gSynQuacerDramInfoPpiGuid             ## CONSUMES
 
 [Depex]
-  gSynQuacerDramInfoPpiGuid
+  gPeiCapsulePpiGuid AND gSynQuacerDramInfoPpiGuid