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: [PATCH v3 03/28] AmperePlatformPkg: Implement FailSafe library
Date: Wed, 15 Sep 2021 22:55:02 +0700	[thread overview]
Message-ID: <20210915155527.8176-4-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20210915155527.8176-1-nhi@os.amperecomputing.com>

The Ampere Altra System Firmware provides a fail-safe feature to help
recover the system if there are setting changes such as Core voltage,
DRAM parameters that cause the UEFI failed to boot.

The FailSafeLib supports API calls to Secure World to:
* Get the FailSafe region information.
* Get the current FailSafe status.
* Inform to FailSafe monitor that the system boots successfully.
* Simulate UEFI boot failure due to config wrong NVPARAM for
  testing failsafe feature.

This library will be consumed by FailSafe DXE driver.

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>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
---
 Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec               |   3 +
 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf |  41 +++
 Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h       |  62 ++++
 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c   | 313 ++++++++++++++++++++
 4 files changed, 419 insertions(+)

diff --git a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
index 7c1d1f84f780..6e33d96c7ea5 100644
--- a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
+++ b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
@@ -22,7 +22,10 @@ [Defines]
 #
 ################################################################################
 [Includes]
+  Include                        # Root include for the package
 
 [LibraryClasses]
+  ##  @libraryclass  Provides functions to support FailSafe operations.
+  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
 
 [Guids]
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
new file mode 100644
index 000000000000..456b9d5fc85b
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
@@ -0,0 +1,41 @@
+## @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                      = FailSafeLib
+  FILE_GUID                      = 3403D080-6D76-11E7-907B-A6006AD3DBA0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FailSafeLib
+
+[Sources]
+  FailSafeLib.c
+
+[Protocols]
+  gEfiMmCommunicationProtocolGuid        ## CONSUMES
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  IoLib
+  NVParamLib
+
+[Guids]
+  gSpiNorMmGuid
diff --git a/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
new file mode 100644
index 000000000000..7ebd1c8a74a2
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
@@ -0,0 +1,62 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FAILSAFE_LIB_H_
+#define FAILSAFE_LIB_H_
+
+enum {
+  MM_SPINOR_FUNC_GET_INFO,
+  MM_SPINOR_FUNC_READ,
+  MM_SPINOR_FUNC_WRITE,
+  MM_SPINOR_FUNC_ERASE,
+  MM_SPINOR_FUNC_GET_NVRAM_INFO,
+  MM_SPINOR_FUNC_GET_NVRAM2_INFO,
+  MM_SPINOR_FUNC_GET_FAILSAFE_INFO
+};
+
+#define MM_SPINOR_RES_SUCCESS           0xAABBCC00
+#define MM_SPINOR_RES_FAIL              0xAABBCCFF
+
+enum {
+  FAILSAFE_BOOT_NORMAL = 0,
+  FAILSAFE_BOOT_LAST_KNOWN_SETTINGS,
+  FAILSAFE_BOOT_DEFAULT_SETTINGS,
+  FAILSAFE_BOOT_DDR_DOWNGRADE,
+  FAILSAFE_BOOT_SUCCESSFUL
+};
+
+/**
+  Get the FailSafe region information.
+**/
+EFI_STATUS
+EFIAPI
+FailSafeGetRegionInfo (
+  UINT64 *Offset,
+  UINT64 *Size
+  );
+
+/**
+  Inform to FailSafe monitor that the system boots successfully.
+**/
+EFI_STATUS
+EFIAPI
+FailSafeBootSuccessfully (
+  VOID
+  );
+
+/**
+  Simulate UEFI boot failure due to config wrong NVPARAM for
+  testing failsafe feature
+**/
+EFI_STATUS
+EFIAPI
+FailSafeTestBootFailure (
+  VOID
+  );
+
+#endif /* FAILSAFE_LIB_H_ */
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
new file mode 100644
index 000000000000..d74962d73396
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
@@ -0,0 +1,313 @@
+/** @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/FailSafeLib.h>
+#include <Library/HobLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Platform/Ac01.h>
+#include <Protocol/MmCommunication.h>
+
+#define EFI_MM_MAX_PAYLOAD_U64_E  10
+#define EFI_MM_MAX_PAYLOAD_SIZE   (EFI_MM_MAX_PAYLOAD_U64_E * sizeof (UINT64))
+
+EFI_MM_COMMUNICATION_PROTOCOL *mFlashLibMmCommProtocol = NULL;
+
+typedef struct {
+  /* Allows for disambiguation of the message format */
+  EFI_GUID HeaderGuid;
+  /*
+   * Describes the size of Data (in bytes) and does not include the size
+   * of the header
+   */
+  UINTN MsgLength;
+} EFI_MM_COMM_HEADER_NOPAYLOAD;
+
+typedef struct {
+  UINT64 Data[EFI_MM_MAX_PAYLOAD_U64_E];
+} EFI_MM_COMM_SPINOR_PAYLOAD;
+
+typedef struct {
+  EFI_MM_COMM_HEADER_NOPAYLOAD EfiMmHdr;
+  EFI_MM_COMM_SPINOR_PAYLOAD   PayLoad;
+} EFI_MM_COMM_REQUEST;
+
+typedef struct {
+  UINT64 Status;
+} EFI_MM_COMMUNICATE_SPINOR_RES;
+
+typedef struct {
+  UINT64 Status;
+  UINT64 FailSafeBase;
+  UINT64 FailSafeSize;
+} EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES;
+
+EFI_MM_COMM_REQUEST mEfiMmSpiNorReq;
+
+#pragma pack(1)
+typedef struct {
+  UINT8  ImgMajorVer;
+  UINT8  ImgMinorVer;
+  UINT32 NumRetry1;
+  UINT32 NumRetry2;
+  UINT32 MaxRetry;
+  UINT8  Status;
+  /*
+   * Byte[3]: Reserved
+   * Byte[2]: Slave MCU Failure Mask
+   * Byte[1]: Reserved
+   * Byte[0]: Master MCU Failure Mask
+   */
+  UINT32 MCUFailsMask;
+  UINT16 CRC16;
+  UINT8  Reserved[3];
+} FAIL_SAFE_CONTEXT;
+
+#pragma pack()
+
+STATIC
+EFI_STATUS
+UefiMmCreateSpiNorReq (
+  VOID   *Data,
+  UINT64 Size
+  )
+{
+  CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
+  mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size;
+
+  if (Size != 0) {
+    ASSERT (Data);
+    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
+
+    CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+INTN
+CheckCrc16 (
+  UINT8 *Pointer,
+  INTN  Count
+  )
+{
+  INTN Crc = 0;
+  INTN Index;
+
+  while (--Count >= 0) {
+    Crc = Crc ^ (INTN)*Pointer++ << 8;
+    for (Index = 0; Index < 8; ++Index) {
+      if ((Crc & 0x8000) != 0) {
+        Crc = Crc << 1 ^ 0x1021;
+      } else {
+        Crc = Crc << 1;
+      }
+    }
+  }
+
+  return Crc & 0xFFFF;
+}
+
+BOOLEAN
+FailSafeValidCRC (
+  FAIL_SAFE_CONTEXT *FailSafeBuf
+  )
+{
+  UINT8  Valid;
+  UINT16 Crc;
+  UINT32 Len;
+
+  Len = sizeof (FAIL_SAFE_CONTEXT);
+  Crc = FailSafeBuf->CRC16;
+  FailSafeBuf->CRC16 = 0;
+
+  Valid = (Crc == CheckCrc16 ((UINT8 *)FailSafeBuf, Len));
+  FailSafeBuf->CRC16 = Crc;
+
+  return Valid;
+}
+
+BOOLEAN
+FailSafeFailureStatus (
+  UINT8 Status
+  )
+{
+  if ((Status == FAILSAFE_BOOT_LAST_KNOWN_SETTINGS) ||
+      (Status == FAILSAFE_BOOT_DEFAULT_SETTINGS) ||
+      (Status == FAILSAFE_BOOT_DDR_DOWNGRADE))
+  {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeGetRegionInfo (
+  UINT64 *Offset,
+  UINT64 *Size
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *MmSpiNorFailSafeInfoRes;
+  UINT64                                      MmData[5];
+  UINTN                                       DataSize;
+  EFI_STATUS                                  Status;
+
+  if (mFlashLibMmCommProtocol == NULL) {
+    Status = gBS->LocateProtocol (
+                    &gEfiMmCommunicationProtocolGuid,
+                    NULL,
+                    (VOID **)&mFlashLibMmCommProtocol
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: Can't locate gEfiMmCommunicationProtocolGuid\n", __FUNCTION__));
+      return Status;
+    }
+  }
+
+  MmData[0] = MM_SPINOR_FUNC_GET_FAILSAFE_INFO;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  DataSize = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = mFlashLibMmCommProtocol->Communicate (
+                                      mFlashLibMmCommProtocol,
+                                      (VOID *)&mEfiMmSpiNorReq,
+                                      &DataSize
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorFailSafeInfoRes = (EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorFailSafeInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Get flash information failed: 0x%llx\n",
+      __FUNCTION__,
+      MmSpiNorFailSafeInfoRes->Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  *Offset = MmSpiNorFailSafeInfoRes->FailSafeBase;
+  *Size   = MmSpiNorFailSafeInfoRes->FailSafeSize;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeBootSuccessfully (
+  VOID
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
+  UINT64                        MmData[5];
+  UINTN                         Size;
+  EFI_STATUS                    Status;
+  UINT64                        FailSafeStartOffset;
+  UINT64                        FailSafeSize;
+  FAIL_SAFE_CONTEXT             FailSafeBuf;
+
+  Status = FailSafeGetRegionInfo (&FailSafeStartOffset, &FailSafeSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get context region information\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  MmData[0] = MM_SPINOR_FUNC_READ;
+  MmData[1] = FailSafeStartOffset;
+  MmData[2] = (UINT64)sizeof (FAIL_SAFE_CONTEXT);
+  MmData[3] = (UINT64)&FailSafeBuf;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = mFlashLibMmCommProtocol->Communicate (
+                                      mFlashLibMmCommProtocol,
+                                      (VOID *)&mEfiMmSpiNorReq,
+                                      &Size
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Read context failed: 0x%llx\n",
+      __FUNCTION__,
+      MmSpiNorRes->Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  /*
+   * If failsafe context is valid, and:
+   *    - The status indicate non-failure, then don't clear it
+   *    - The status indicate a failure, then go and clear it
+   */
+  if (FailSafeValidCRC (&FailSafeBuf)
+      && !FailSafeFailureStatus (FailSafeBuf.Status)) {
+    return EFI_SUCCESS;
+  }
+
+  MmData[0] = MM_SPINOR_FUNC_ERASE;
+  MmData[1] = FailSafeStartOffset;
+  MmData[2] = FailSafeSize;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = mFlashLibMmCommProtocol->Communicate (
+                                      mFlashLibMmCommProtocol,
+                                      (VOID *)&mEfiMmSpiNorReq,
+                                      &Size
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Erase context failed: 0x%llx\n",
+      __FUNCTION__,
+      MmSpiNorRes->Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeTestBootFailure (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value = 0;
+
+  /*
+   * Simulate UEFI boot failure due to config wrong NVPARAM for
+   * testing failsafe feature
+   */
+  Status = NVParamGet (NV_UEFI_FAILURE_FAILSAFE_OFFSET, NV_PERM_ALL, &Value);
+  if (!EFI_ERROR (Status) && (Value == 1)) {
+    while (1) {
+    }
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


  parent reply	other threads:[~2021-09-15 15:59 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-15 15:54 [PATCH v3 00/28] Add new Ampere Mt. Jade platform Nhi Pham
2021-09-15 15:55 ` [PATCH v3 01/28] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-09-16 10:40   ` Leif Lindholm
2021-09-16 10:46     ` Leif Lindholm
2021-09-17  6:19       ` Nhi Pham
2021-09-23 13:54   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 02/28] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
2021-09-15 15:55 ` Nhi Pham [this message]
2021-09-15 15:55 ` [PATCH v3 04/28] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
2021-09-16 11:22   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 05/28] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
2021-09-15 15:55 ` [PATCH v3 06/28] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
2021-09-15 15:55 ` [PATCH v3 07/28] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-09-15 15:55 ` [PATCH v3 08/28] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 09/28] AmpereAltraPkg: Support UEFI non-volatile variable Nhi Pham
2021-09-23 11:49   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 10/28] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-09-15 15:55 ` [PATCH v3 11/28] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 12/28] AmpereAltraPkg: Add Ac01PcieLib library instance Nhi Pham
2021-09-23 13:49   ` Leif Lindholm
2021-09-27 14:33     ` Nhi Pham
2021-10-04 12:03     ` Nhi Pham
2021-10-05 19:59       ` Leif Lindholm
2021-10-06 12:55         ` [edk2-devel] " Nhi Pham
2021-10-07  9:06           ` Leif Lindholm
2021-10-07  9:13             ` Nhi Pham
2021-09-28 10:34   ` Leif Lindholm
2021-10-04 11:36     ` Nhi Pham
2021-09-15 15:55 ` [PATCH v3 13/28] JadePkg: Add BoardPcieLib " Nhi Pham
2021-09-24 12:35   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 14/28] Ampere: PCIe: Add PciHostBridgeLib " Nhi Pham
2021-09-24 13:12   ` Ard Biesheuvel
2021-09-15 15:55 ` [PATCH v3 15/28] Ampere: PCIe: Add PciSegmentLib " Nhi Pham
2021-09-24 13:16   ` Ard Biesheuvel
2021-09-28 10:26     ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 16/28] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
2021-09-15 15:55 ` [PATCH v3 17/28] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-09-15 15:55 ` [PATCH v3 18/28] Ampere: PCIe: Add PciPlatformDxe driver Nhi Pham
2021-09-24 12:59   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 19/28] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 20/28] JadePkg: Add SMBIOS tables support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 21/28] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-09-24 12:43   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 22/28] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-09-15 15:55 ` [PATCH v3 23/28] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
2021-09-24 12:50   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 24/28] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-09-24 12:51   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 25/28] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-09-24 12:53   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 26/28] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-09-24 12:54   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 27/28] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-09-24 12:55   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 28/28] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
2021-09-24 12:57   ` Leif Lindholm
2021-09-16 10:09 ` [PATCH v3 00/28] Add new Ampere Mt. Jade platform Leif Lindholm
2021-09-17  6:10   ` 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=20210915155527.8176-4-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