public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Nhi Pham" <nhi@os.amperecomputing.com>
To: devel@edk2.groups.io
Cc: patches@amperecomputing.com, nhi@os.amperecomputing.com,
	vunguyen@os.amperecomputing.com,
	Thang Nguyen <thang@os.amperecomputing.com>,
	Chuong Tran <chuong@os.amperecomputing.com>,
	Phong Vo <phong@os.amperecomputing.com>,
	Leif Lindholm <leif@nuviainc.com>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Nate DeSimone <nathaniel.l.desimone@intel.com>
Subject: [edk2-platforms][PATCH v4 08/31] AmpereAltraPkg: Support UEFI non-volatile variable
Date: Fri, 22 Oct 2021 13:17:46 +0700	[thread overview]
Message-ID: <20211022061809.31087-9-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20211022061809.31087-1-nhi@os.amperecomputing.com>

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This change supports storing the UEFI non-volatile varibles on the
Flash through below modules:
* FlashPei driver helps to restore the saved variables from
  flash on each boot.
* FlashFvbDxe driver provides the implementation for the
  gEfiFirmwareVolumeBlock protocol

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec              |   5 +
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc              |   6 +-
 Platform/Ampere/JadePkg/Jade.dsc                                  |   5 +
 Platform/Ampere/JadePkg/Jade.fdf                                  |  62 ++-
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf |  54 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf       |  49 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c   | 525 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c         | 125 +++++
 8 files changed, 827 insertions(+), 4 deletions(-)

diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
index 6ebdf7db0a57..c6827d0cad7e 100644
--- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -31,6 +31,11 @@ [Guids]
 [Ppis]
 
 [PcdsFixedAtBuild]
+  #
+  # NVRAM
+  #
+  gAmpereTokenSpaceGuid.PcdPlatformConfigUuid|"C416535D-970B-41B9-859A-3CAF0FAF198C"|VOID*|0x00000010
+
   #
   # SMpro PMpro Pcds
   #
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index cd982e987745..69bf00ee56c4 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -523,8 +523,10 @@ [Components.common]
   ArmPlatformPkg/PlatformPei/PlatformPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
   ArmPkg/Drivers/CpuPei/CpuPei.inf
   UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
   MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
   MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
     <LibraryClasses>
@@ -578,9 +580,9 @@ [Components.common]
   #
   # Environment Variables Protocol
   #
+  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
   MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
-    <PcdsFixedAtBuild>
-      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
     <LibraryClasses>
       BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
       TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 7b70c5d6b5fb..0dd30dc14841 100644
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -51,6 +51,7 @@ [Defines]
   DEFINE FIRMWARE_VER            = 0.01.001
   DEFINE SECURE_BOOT_ENABLE      = FALSE
   DEFINE INCLUDE_TFTP_COMMAND    = TRUE
+  DEFINE PLATFORM_CONFIG_UUID    = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5
 
   #
   # Network definition
@@ -83,6 +84,10 @@ [LibraryClasses]
 ################################################################################
 [PcdsFeatureFlag.common]
 [PcdsFixedAtBuild.common]
+  #
+  # Platform config UUID
+  #
+  gAmpereTokenSpaceGuid.PcdPlatformConfigUuid|"$(PLATFORM_CONFIG_UUID)"
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
   # Override the default values from SecurityPkg to ensure images
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index bbee31c3fc99..5727d8706240 100644
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -26,7 +26,7 @@ [FD.BL33_JADE_UEFI]
 ErasePolarity = 1
 
 # This one is tricky, it must be: BlockSize * NumBlocks = Size
-BlockSize     = 0x10000
+BlockSize     = 0x10000|gAmpereTokenSpaceGuid.PcdFvBlockSize
 NumBlocks     = 0x7C
 
 ################################################################################
@@ -56,8 +56,61 @@ [FD.BL33_JADE_UEFI]
 
 #
 # NV Variables
-# Placeholder
+# Offset: 0x00740000
+# Size:   0x00080000
 #
+0x00740000|0x00030000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
+  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x80000
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # Signature "_FVH"       # Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x2D, 0x09, 0x00, 0x00, 0x00, 0x02,
+  # Blockmap[0]: 0x2 Blocks * 0x40000 Bytes / Block
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+  # Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+  # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.
+  # Signature: gEfiAuthenticatedVariableGuid =
+  #   { 0xaaf32c78, 0x947b, 0x439a,
+  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+  # Size: 0x30000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x2FFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xFF, 0x02, 0x00,
+  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00770000|0x00010000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 Size: 0x10000 - 0x20 (FTW_WORKING_HEADER) = 0xFFE0
+  0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00780000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
 
 ################################################################################
 #
@@ -101,9 +154,11 @@ [FV.FVMAIN_COMPACT]
   INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
   INF ArmPkg/Drivers/CpuPei/CpuPei.inf
   INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
   INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
   INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
   INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
@@ -144,6 +199,7 @@ [FV.FvMain]
   INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
   INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
   INF ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
 }
 
   INF MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -173,6 +229,8 @@ [FV.FvMain]
   # Environment Variables Protocol
   #
   INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
 
   #
   # Multiple Console IO support
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
new file mode 100644
index 000000000000..008fd2315ffe
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
@@ -0,0 +1,54 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = FlashFvbDxe
+  FILE_GUID                      = 9E6EA240-DF80-11EA-8B6E-0800200C9A66
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 0.1
+  ENTRY_POINT                    = FlashFvbDxeInitialize
+
+[Sources]
+  FlashFvbDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  FlashLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiRuntimeLib
+
+[FixedPcd]
+  gAmpereTokenSpaceGuid.PcdFvBlockSize
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+  gSpiNorMmGuid
+
+[Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid             ## PRODUCES
+  gEfiMmCommunication2ProtocolGuid                ## CONSUMES
+
+[Depex]
+  gEfiMmCommunication2ProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
new file mode 100644
index 000000000000..2b329c5d0987
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
@@ -0,0 +1,49 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = FlashPei
+  FILE_GUID                      = 967CFBD0-DF81-11EA-8B6E-0800200C9A66
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FlashPeiEntryPoint
+
+[Sources]
+  FlashPei.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  BaseMemoryLib
+  DebugLib
+  FlashLib
+  MmCommunicationLib
+  PcdLib
+  PeimEntryPoint
+
+[FixedPcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
+
+  gAmpereTokenSpaceGuid.PcdPlatformConfigUuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
new file mode 100644
index 000000000000..009694703ddd
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
@@ -0,0 +1,525 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/FlashLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+//
+// These temporary buffers are used to calculate and convert linear virtual
+// to physical address
+//
+STATIC UINT64 mNvFlashBase;
+STATIC UINT32 mNvFlashSize;
+STATIC UINT32 mFlashBlockSize;
+STATIC UINT64 mNvStorageBase;
+STATIC UINT64 mNvStorageSize;
+
+/**
+  Fixup internal data so that EFI can be call in virtual mode.
+  Call the passed in Child Notify event and convert any pointers in
+  lib to virtual mode.
+
+  @param[in]    Event   The Event that is being processed
+  @param[in]    Context Event Context
+**/
+VOID
+EFIAPI
+FlashFvbAddressChangeEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EfiConvertPointer (0x0, (VOID **)&mNvStorageBase);
+}
+
+/**
+  The GetAttributes() function retrieves the attributes and
+  current settings of the block.
+
+  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
+                    attributes and current settings are
+                    returned. Type EFI_FVB_ATTRIBUTES_2 is defined
+                    in EFI_FIRMWARE_VOLUME_HEADER.
+
+  @retval EFI_SUCCESS The firmware volume attributes were
+                      returned.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  OUT      EFI_FVB_ATTRIBUTES_2                *Attributes
+  )
+{
+  ASSERT (Attributes != NULL);
+
+  *Attributes = EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
+                EFI_FVB2_READ_STATUS        | // Reads are currently enabled
+                EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
+                EFI_FVB2_WRITE_ENABLED_CAP  | // Writes may be enabled
+                EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+                EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
+                EFI_FVB2_ALIGNMENT          |
+                EFI_FVB2_ERASE_POLARITY;      // After erasure all bits take this value (i.e. '1')
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The SetAttributes() function sets configurable firmware volume
+  attributes and returns the new settings of the firmware volume.
+
+  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Attributes   On input, Attributes is a pointer to
+                      EFI_FVB_ATTRIBUTES_2 that contains the
+                      desired firmware volume settings. On
+                      successful return, it contains the new
+                      settings of the firmware volume. Type
+                      EFI_FVB_ATTRIBUTES_2 is defined in
+                      EFI_FIRMWARE_VOLUME_HEADER.
+
+  @retval EFI_SUCCESS           The firmware volume attributes were returned.
+
+  @retval EFI_INVALID_PARAMETER The attributes requested are in
+                                conflict with the capabilities
+                                as declared in the firmware
+                                volume header.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN OUT   EFI_FVB_ATTRIBUTES_2                *Attributes
+  )
+{
+  return EFI_SUCCESS;  // ignore for now
+}
+
+/**
+  The GetPhysicalAddress() function retrieves the base address of
+  a memory-mapped firmware volume. This function should be called
+  only for memory-mapped firmware volumes.
+
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Address  Pointer to a caller-allocated
+                  EFI_PHYSICAL_ADDRESS that, on successful
+                  return from GetPhysicalAddress(), contains the
+                  base address of the firmware volume.
+
+  @retval EFI_SUCCESS       The firmware volume base address was returned.
+
+  @retval EFI_UNSUPPORTED   The firmware volume is not memory mapped.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  OUT      EFI_PHYSICAL_ADDRESS                *Address
+  )
+{
+  ASSERT (Address != NULL);
+
+  *Address = (EFI_PHYSICAL_ADDRESS)mNvStorageBase;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The GetBlockSize() function retrieves the size of the requested
+  block. It also returns the number of additional blocks with
+  the identical size. The GetBlockSize() function is used to
+  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
+
+
+  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Lba            Indicates the block for which to return the size.
+
+  @param BlockSize      Pointer to a caller-allocated UINTN in which
+                        the size of the block is returned.
+
+  @param NumberOfBlocks Pointer to a caller-allocated UINTN in
+                        which the number of consecutive blocks,
+                        starting with Lba, is returned. All
+                        blocks in this range have a size of
+                        BlockSize.
+
+
+  @retval EFI_SUCCESS             The firmware volume base address was returned.
+
+  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeGetBlockSize (
+  IN  CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN        EFI_LBA                             Lba,
+  OUT       UINTN                               *BlockSize,
+  OUT       UINTN                               *NumberOfBlocks
+  )
+{
+  UINTN TotalNvStorageBlocks;
+
+  ASSERT (BlockSize != NULL);
+  ASSERT (NumberOfBlocks != NULL);
+
+  TotalNvStorageBlocks = mNvStorageSize / mFlashBlockSize;
+
+  if (TotalNvStorageBlocks <= (UINTN)Lba) {
+    DEBUG ((DEBUG_ERROR, "The requested LBA is out of range\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *NumberOfBlocks = TotalNvStorageBlocks - (UINTN)Lba;
+  *BlockSize = mFlashBlockSize;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads the specified number of bytes into a buffer from the specified block.
+
+  The Read() function reads the requested number of bytes from the
+  requested block and stores them in the provided buffer.
+  Implementations should be mindful that the firmware volume
+  might be in the ReadDisabled state. If it is in this state,
+  the Read() function must return the status code
+  EFI_ACCESS_DENIED without modifying the contents of the
+  buffer. The Read() function must also prevent spanning block
+  boundaries. If a read is requested that would span a block
+  boundary, the read must read up to the boundary but not
+  beyond. The output parameter NumBytes must be set to correctly
+  indicate the number of bytes actually read. The caller must be
+  aware that a read may be partially completed.
+
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Lba      The starting logical block index
+                  from which to read.
+
+  @param Offset   Offset into the block at which to begin reading.
+
+  @param NumBytes Pointer to a UINTN. At entry, *NumBytes
+                  contains the total size of the buffer. At
+                  exit, *NumBytes contains the total number of
+                  bytes read.
+
+  @param Buffer   Pointer to a caller-allocated buffer that will
+                  be used to hold the data that is read.
+
+  @retval EFI_SUCCESS         The firmware volume was read successfully,
+                              and contents are in Buffer.
+
+  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
+                              boundary. On output, NumBytes
+                              contains the total number of bytes
+                              returned in Buffer.
+
+  @retval EFI_ACCESS_DENIED   The firmware volume is in the
+                              ReadDisabled state.
+
+  @retval EFI_DEVICE_ERROR    The block device is not
+                              functioning correctly and could
+                              not be read.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN       EFI_LBA                             Lba,
+  IN       UINTN                               Offset,
+  IN OUT   UINTN                               *NumBytes,
+  IN OUT   UINT8                               *Buffer
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (NumBytes != NULL);
+  ASSERT (Buffer != NULL);
+
+  if (Offset + *NumBytes > mFlashBlockSize) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  Status = FlashReadCommand (
+             mNvFlashBase + Lba * mFlashBlockSize + Offset,
+             Buffer,
+             *NumBytes
+             );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to do flash read\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes the specified number of bytes from the input buffer to the block.
+
+  The Write() function writes the specified number of bytes from
+  the provided buffer to the specified block and offset. If the
+  firmware volume is sticky write, the caller must ensure that
+  all the bits of the specified range to write are in the
+  EFI_FVB_ERASE_POLARITY state before calling the Write()
+  function, or else the result will be unpredictable. This
+  unpredictability arises because, for a sticky-write firmware
+  volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
+  state but cannot flip it back again.  Before calling the
+  Write() function,  it is recommended for the caller to first call
+  the EraseBlocks() function to erase the specified block to
+  write. A block erase cycle will transition bits from the
+  (NOT)EFI_FVB_ERASE_POLARITY state back to the
+  EFI_FVB_ERASE_POLARITY state. Implementations should be
+  mindful that the firmware volume might be in the WriteDisabled
+  state. If it is in this state, the Write() function must
+  return the status code EFI_ACCESS_DENIED without modifying the
+  contents of the firmware volume. The Write() function must
+  also prevent spanning block boundaries. If a write is
+  requested that spans a block boundary, the write must store up
+  to the boundary but not beyond. The output parameter NumBytes
+  must be set to correctly indicate the number of bytes actually
+  written. The caller must be aware that a write may be
+  partially completed. All writes, partial or otherwise, must be
+  fully flushed to the hardware before the Write() service
+  returns.
+
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Lba      The starting logical block index to write to.
+
+  @param Offset   Offset into the block at which to begin writing.
+
+  @param NumBytes The pointer to a UINTN. At entry, *NumBytes
+                  contains the total size of the buffer. At
+                  exit, *NumBytes contains the total number of
+                  bytes actually written.
+
+  @param Buffer   The pointer to a caller-allocated buffer that
+                  contains the source for the write.
+
+  @retval EFI_SUCCESS         The firmware volume was written successfully.
+
+  @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
+                              LBA boundary. On output, NumBytes
+                              contains the total number of bytes
+                              actually written.
+
+  @retval EFI_ACCESS_DENIED   The firmware volume is in the
+                              WriteDisabled state.
+
+  @retval EFI_DEVICE_ERROR    The block device is malfunctioning
+                              and could not be written.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN       EFI_LBA                             Lba,
+  IN       UINTN                               Offset,
+  IN OUT   UINTN                               *NumBytes,
+  IN       UINT8                               *Buffer
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (NumBytes != NULL);
+  ASSERT (Buffer != NULL);
+
+  if (Offset + *NumBytes > mFlashBlockSize) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  Status = FlashWriteCommand (
+             mNvFlashBase + Lba * mFlashBlockSize + Offset,
+             Buffer,
+             *NumBytes
+             );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to do flash write\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return Status;
+}
+
+/**
+  Erases and initializes a firmware volume block.
+
+  The EraseBlocks() function erases one or more blocks as denoted
+  by the variable argument list. The entire parameter list of
+  blocks must be verified before erasing any blocks. If a block is
+  requested that does not exist within the associated firmware
+  volume (it has a larger index than the last block of the
+  firmware volume), the EraseBlocks() function must return the
+  status code EFI_INVALID_PARAMETER without modifying the contents
+  of the firmware volume. Implementations should be mindful that
+  the firmware volume might be in the WriteDisabled state. If it
+  is in this state, the EraseBlocks() function must return the
+  status code EFI_ACCESS_DENIED without modifying the contents of
+  the firmware volume. All calls to EraseBlocks() must be fully
+  flushed to the hardware before the EraseBlocks() service
+  returns.
+
+  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
+                instance.
+
+  @param ...    The variable argument list is a list of tuples.
+                Each tuple describes a range of LBAs to erase
+                and consists of the following:
+                - An EFI_LBA that indicates the starting LBA
+                - A UINTN that indicates the number of blocks to
+                  erase.
+
+                The list is terminated with an
+                EFI_LBA_LIST_TERMINATOR. For example, the
+                following indicates that two ranges of blocks
+                (5-7 and 10-11) are to be erased: EraseBlocks
+                (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
+
+  @retval EFI_SUCCESS The erase request successfully
+                      completed.
+
+  @retval EFI_ACCESS_DENIED   The firmware volume is in the
+                              WriteDisabled state.
+  @retval EFI_DEVICE_ERROR  The block device is not functioning
+                            correctly and could not be written.
+                            The firmware device may have been
+                            partially erased.
+  @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
+                                in the variable argument list do
+                                not exist in the firmware volume.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeErase (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  ...
+  )
+{
+  VA_LIST    Args;
+  EFI_LBA    Start;
+  UINTN      Length;
+  EFI_STATUS Status;
+
+  Status = EFI_SUCCESS;
+
+  VA_START (Args, This);
+
+  for (Start = VA_ARG (Args, EFI_LBA);
+       Start != EFI_LBA_LIST_TERMINATOR;
+       Start = VA_ARG (Args, EFI_LBA))
+  {
+    Length = VA_ARG (Args, UINTN);
+    Status = FlashEraseCommand (
+               mNvFlashBase + Start * mFlashBlockSize,
+               Length * mFlashBlockSize
+               );
+  }
+
+  VA_END (Args);
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to do flash erase\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFlashFvbProtocol = {
+  FlashFvbDxeGetAttributes,
+  FlashFvbDxeSetAttributes,
+  FlashFvbDxeGetPhysicalAddress,
+  FlashFvbDxeGetBlockSize,
+  FlashFvbDxeRead,
+  FlashFvbDxeWrite,
+  FlashFvbDxeErase
+};
+
+EFI_STATUS
+EFIAPI
+FlashFvbDxeInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_HANDLE FvbHandle = NULL;
+  EFI_EVENT  VirtualAddressChangeEvent;
+
+  // Get NV store FV info
+  mFlashBlockSize = FixedPcdGet32 (PcdFvBlockSize);
+  mNvStorageBase = PcdGet64 (PcdFlashNvStorageVariableBase64);
+  mNvStorageSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+                   FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+                   FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: Using NV store FV in-memory copy at 0x%lx with size 0x%x\n",
+    __FUNCTION__,
+    mNvStorageBase,
+    mNvStorageSize
+    ));
+
+  // Get NV Flash information
+  Status = FlashGetNvRamInfo (&mNvFlashBase, &mNvFlashSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get Flash info\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (mNvFlashSize >= (mNvStorageSize * 2)) {
+    DEBUG ((DEBUG_INFO, "%a: NV store on Flash is valid\n", __FUNCTION__));
+  } else {
+    DEBUG ((DEBUG_ERROR, "%a: NV store on Flash is invalid\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  FlashFvbAddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &VirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &FvbHandle,
+                  &gEfiFirmwareVolumeBlockProtocolGuid,
+                  &mFlashFvbProtocol,
+                  NULL
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to install Firmware Volume Block protocol\n"));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
new file mode 100644
index 000000000000..3da7df3907dc
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
@@ -0,0 +1,125 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FlashLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+
+/**
+  Entry point function for the PEIM
+
+  @param FileHandle      Handle of the file being invoked.
+  @param PeiServices     Describes the list of possible PEI Services.
+
+  @return EFI_SUCCESS    If we installed our PPI
+
+**/
+EFI_STATUS
+EFIAPI
+FlashPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  CHAR8               BuildUuid[PcdGetSize (PcdPlatformConfigUuid)];
+  CHAR8               StoredUuid[PcdGetSize (PcdPlatformConfigUuid)];
+  EFI_STATUS          Status;
+  UINTN               FWNvRamStartOffset;
+  UINT32              FWNvRamSize;
+  UINTN               NvRamAddress;
+  UINT32              NvRamSize;
+
+  CopyMem ((VOID *)BuildUuid, PcdGetPtr (PcdPlatformConfigUuid), sizeof (BuildUuid));
+
+  NvRamAddress = PcdGet64 (PcdFlashNvStorageVariableBase64);
+  NvRamSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+              FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+              FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: Using NV store FV in-memory copy at 0x%lx with size 0x%x\n",
+    __FUNCTION__,
+    NvRamAddress,
+    NvRamSize
+    ));
+
+  Status = FlashGetNvRamInfo (&FWNvRamStartOffset, &FWNvRamSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get Flash NVRAM info %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  if (FWNvRamSize < (NvRamSize * 2 + sizeof (BuildUuid))) {
+    //
+    // NVRAM size provided by FW is not enough
+    //
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // We stored BUILD UUID build at the offset NVRAM_SIZE * 2
+  //
+  Status = FlashReadCommand (
+             FWNvRamStartOffset + NvRamSize * 2,
+             (UINT8 *)StoredUuid,
+             sizeof (StoredUuid)
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (CompareMem ((VOID *)StoredUuid, (VOID *)BuildUuid, sizeof (BuildUuid)) != 0) {
+    DEBUG ((DEBUG_INFO, "BUILD UUID Changed, Update Storage with NVRAM FV\n"));
+
+    Status = FlashEraseCommand (FWNvRamStartOffset, NvRamSize * 2 + sizeof (BuildUuid));
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Status = FlashWriteCommand (
+               FWNvRamStartOffset,
+               (UINT8 *)NvRamAddress,
+               NvRamSize
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    //
+    // Write new BUILD UUID to the Flash
+    //
+    Status = FlashWriteCommand (
+               FWNvRamStartOffset + NvRamSize * 2,
+               (UINT8 *)BuildUuid,
+               sizeof (BuildUuid)
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "Identical UUID, copy stored NVRAM to RAM\n"));
+
+    Status = FlashReadCommand (
+               FWNvRamStartOffset,
+               (UINT8 *)NvRamAddress,
+               NvRamSize
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


  parent reply	other threads:[~2021-10-22  6:19 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-22  6:17 [edk2-platforms][PATCH v4 00/31] Add new Ampere Mt. Jade platform Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 01/31] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-10-26 11:14   ` Leif Lindholm
2021-11-03  9:31     ` Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 02/31] AmpereAltraPkg: Add FlashLib library instance Nhi Pham
2021-10-26 11:25   ` Leif Lindholm
2021-11-03  9:32     ` Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 03/31] AmpereAltraPkg: Add FailSafe and WDT support Nhi Pham
2021-10-26 12:15   ` Leif Lindholm
2021-11-03  9:35     ` Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 04/31] AmpereAltraPkg: Add DwI2cLib library instance Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 05/31] AmpereAltraPkg: Add DwGpioLib " Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 06/31] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 07/31] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-10-22  6:17 ` Nhi Pham [this message]
2021-10-26 12:21   ` [edk2-platforms][PATCH v4 08/31] AmpereAltraPkg: Support UEFI non-volatile variable Leif Lindholm
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 09/31] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 10/31] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 11/31] AmpereAltraPkg: Add Root Complex HOB data structures Nhi Pham
2021-10-26 12:23   ` Leif Lindholm
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 12/31] AmpereAltraPkg: Add Ac01PcieLib library instance Nhi Pham
2021-10-26 12:45   ` Leif Lindholm
2021-11-03  9:33     ` Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 13/31] JadePkg: Add BoardPcieLib " Nhi Pham
2021-10-26 12:46   ` Leif Lindholm
2021-11-03  9:33     ` Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 14/31] AmpereAltraPkg: Add driver to initialize PCIe Root Complex Nhi Pham
2021-10-26 12:49   ` Leif Lindholm
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 15/31] AmpereAltraPkg: Add PciHostBridgeLib library instance Nhi Pham
2021-10-26 12:49   ` Leif Lindholm
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 16/31] AmpereAltraPkg: Add PciSegmentLib " Nhi Pham
2021-10-26 12:53   ` Leif Lindholm
2021-11-03  9:35     ` Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 17/31] JadePkg: Enable PciHostBridgeDxe driver Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 18/31] JadePkg: Add PciPlatformDxe driver Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 19/31] JadePkg: Add ACPI tables to support PCIe Nhi Pham
2021-10-26 12:54   ` Leif Lindholm
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 20/31] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-10-22  6:17 ` [edk2-platforms][PATCH v4 21/31] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 22/31] JadePkg: Add SMBIOS tables support Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 23/31] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 24/31] AmpereAltraPkg: Add configuration screen for PCIe Nhi Pham
2021-10-26 12:56   ` Leif Lindholm
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 25/31] Ampere: Utilize the PCIe User setting Nhi Pham
2021-10-26 12:57   ` Leif Lindholm
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 26/31] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 27/31] AmpereAltraPkg: Add configuration screen for Memory Nhi Pham
2021-10-26 12:58   ` Leif Lindholm
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 28/31] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 29/31] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 30/31] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-10-22  6:18 ` [edk2-platforms][PATCH v4 31/31] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-10-26 13:03   ` Leif Lindholm
2021-11-03  9:36     ` Nhi Pham
2021-10-26 13:08 ` [edk2-platforms][PATCH v4 00/31] Add new Ampere Mt. Jade platform Leif Lindholm
2021-11-03  9:37   ` Nhi Pham

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211022061809.31087-9-nhi@os.amperecomputing.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox