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: Nhi Pham <nhi@os.amperecomputing.com>
Subject: [edk2-platforms][PATCH 06/34] Platform/Ampere: Add AcpiPccLib to support ACPI PCCT Table
Date: Wed,  9 Dec 2020 16:25:03 +0700	[thread overview]
Message-ID: <20201209092531.30867-7-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20201209092531.30867-1-nhi@os.amperecomputing.com>

The AcpiPccLib provides functions to allocate and get the physical
address of PCC shared memory.

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmperePkg.dec                      |   4 +
 Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.inf |  45 +++
 Silicon/Ampere/Include/Library/AcpiPccLib.h       |  91 ++++++
 Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.c   | 322 ++++++++++++++++++++
 4 files changed, 462 insertions(+)

diff --git a/Silicon/Ampere/AmperePkg.dec b/Silicon/Ampere/AmperePkg.dec
index 47b29f508185..fa5b7074f749 100755
--- a/Silicon/Ampere/AmperePkg.dec
+++ b/Silicon/Ampere/AmperePkg.dec
@@ -22,8 +22,12 @@ [Defines]
 #
 ################################################################################
 [Includes.common]
+  Include                        # Root include for the package
 
 [LibraryClasses]
+  ##  @libraryclass  Provides functions to create the ACPI PCCT Table which which advertises PCC mailbox channel information.
+  AcpiPccLib|Silicon/Ampere/Include/Library/AcpiPccLib.h
+
 
 [Guids]
   gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
diff --git a/Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.inf b/Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.inf
new file mode 100755
index 000000000000..d4b48e0fa248
--- /dev/null
+++ b/Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.inf
@@ -0,0 +1,45 @@
+## @file
+#
+# Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                   = 0x0001001B
+  BASE_NAME                     = AcpiPccLib
+  FILE_GUID                     = 790519F0-F344-11E3-AC10-0800200C9A66
+  MODULE_TYPE                   = BASE
+  VERSION_STRING                = 1.0
+  LIBRARY_CLASS                 = AcpiPccLib
+
+[Sources.common]
+  AcpiPccLib.c
+
+[FeaturePcd]
+
+[Pcd]
+
+[FixedPcd]
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Silicon/Ampere/AmperePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/Ac01Pkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  DebugLib
+  IoLib
+  PrintLib
+  TimerLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+
+[Pcd]
+  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
+  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
diff --git a/Silicon/Ampere/Include/Library/AcpiPccLib.h b/Silicon/Ampere/Include/Library/AcpiPccLib.h
new file mode 100755
index 000000000000..7ec761adaec1
--- /dev/null
+++ b/Silicon/Ampere/Include/Library/AcpiPccLib.h
@@ -0,0 +1,91 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _ACPI_PCC_LIB_H_
+#define _ACPI_PCC_LIB_H_
+
+struct ACPI_PCCT_SHARED_MEMORY {
+  UINT32 Signature;
+  union {
+    UINT16 Command;
+    struct PCC_COMMAND {
+      UINT16 CommandCode:8;
+      UINT16 Reserved:7;
+      UINT16 Interrupt:1;
+    } __attribute__ ((packed)) CmdT;
+  } CmdData;
+  union {
+    UINT16 Status;
+    struct PCC_STATUS {
+      UINT16 CommandComplete:1;
+      UINT16 SciDb:1;
+      UINT16 Error:1;
+      UINT16 PlatformNotification:1;
+      UINT16 Reserved:12;
+    } __attribute__ ((packed)) StatusT;
+  } StatusData;
+} __attribute__((packed));
+
+EFI_STATUS
+EFIAPI
+AcpiPccSendMsg (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace,
+  IN VOID                        *MsgBuf,
+  IN UINT32                      Length
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiPccUnmaskInt (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiPccSyncSharedMemAddr (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiPccSharedMemInit (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiPccSharedMemInitV2 (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiIppPccIsSupported (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiPccAllocSharedMemory (
+  OUT UINT64                     *PccSharedMemPointer,
+  IN UINT32                      SubspaceNum
+  );
+
+VOID
+EFIAPI
+AcpiPccFreeSharedMemory (
+  OUT UINT64                     *PccSharedMemPointer,
+  IN UINT32                      SubspaceNum
+  );
+
+#endif /* _ACPI_PCC_LIB_H_*/
diff --git a/Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.c b/Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.c
new file mode 100755
index 000000000000..94e55ce34505
--- /dev/null
+++ b/Platform/Ampere/Library/AcpiPccLib/AcpiPccLib.c
@@ -0,0 +1,322 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Platform/Ac01.h>
+#include <Library/AcpiPccLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#define PCC_NULL_MSG             0x0F000000
+
+STATIC UINT64 PccSharedMemAddr = 0;
+
+STATIC EFI_STATUS
+AcpiPccGetSharedMemAddr (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace,
+  OUT VOID                       **AcpiPcct
+  )
+{
+  if ((Subspace >= PCC_MAX_SUBSPACES_PER_SOCKET)
+    || (Socket >= PLATFORM_CPU_MAX_SOCKET)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PccSharedMemAddr == 0) {
+    return EFI_NOT_READY;
+  }
+
+  *AcpiPcct = (VOID *) (PccSharedMemAddr + PCC_SUBSPACE_SHARED_MEM_SIZE *
+                       (Subspace + PCC_MAX_SUBSPACES_PER_SOCKET * Socket));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPccSendMsg (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace,
+  IN VOID                        *MsgBuf,
+  IN UINT32                      Length
+  )
+{
+  INTN TimeoutCnt                = PCC_NOMINAL_LATENCY / PCC_CMD_POLL_UDELAY;
+  VOID                           *CommunicationSpacePtr;
+  struct ACPI_PCCT_SHARED_MEMORY *AcpiPcct;
+  EFI_STATUS                     Status;
+  UINT32                         PccMsg;
+
+  if ((Subspace >= PCC_MAX_SUBSPACES_PER_SOCKET)
+    || (Socket >= PLATFORM_CPU_MAX_SOCKET)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = AcpiPccGetSharedMemAddr (Socket, Subspace, (VOID **) &AcpiPcct);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  CommunicationSpacePtr = AcpiPcct + 1;
+
+  /* Write Data into Communication Space Region */
+  CopyMem (CommunicationSpacePtr, MsgBuf, Length);
+  /* Flip CMD_COMPLETE bit */
+  AcpiPcct->StatusData.StatusT.CommandComplete = 0;
+  /* PCC signature */
+  AcpiPcct->Signature = PCC_SIGNATURE_MASK | Subspace;
+  /* Ring the Doorbell */
+  PccMsg = PCC_MSG;
+  /* Store the upper address (Bit 40-43) of PCC shared memory */
+  PccMsg |= ((UINT64) AcpiPcct >> 40) & PCP_MSG_UPPER_ADDR_MASK;
+  if (Subspace < PMPRO_MAX_DB) {
+    MmioWrite32 (PMPRO_DBx_REG (Socket, Subspace, DB_OUT), PccMsg);
+  } else {
+    MmioWrite32 (SMPRO_DBx_REG (Socket, Subspace - PMPRO_MAX_DB, DB_OUT),
+                PccMsg);
+  }
+
+  /* Polling CMD_COMPLETE bit */
+  while (AcpiPcct->StatusData.StatusT.CommandComplete != 1) {
+    if (--TimeoutCnt <= 0) {
+      return EFI_TIMEOUT;
+    }
+    MicroSecondDelay (PCC_CMD_POLL_UDELAY);
+  };
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPccUnmaskInt (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  )
+{
+  if ((Subspace >= PCC_MAX_SUBSPACES_PER_SOCKET)
+    || (Socket >= PLATFORM_CPU_MAX_SOCKET)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  /* Unmask Interrupt */
+  if (Subspace < PMPRO_MAX_DB) {
+    MmioWrite32 (
+      PMPRO_DBx_REG (Socket, Subspace, DB_STATUSMASK),
+      ~DB_AVAIL_MASK
+      );
+  } else {
+    MmioWrite32 (
+      SMPRO_DBx_REG (Socket, Subspace - PMPRO_MAX_DB, DB_STATUSMASK),
+      ~DB_AVAIL_MASK
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPccSyncSharedMemAddr (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  )
+{
+  UINT32 PccData;
+
+  if ((Subspace >= PCC_MAX_SUBSPACES_PER_SOCKET)
+    || (Socket >= PLATFORM_CPU_MAX_SOCKET)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  /*
+   * Advertise shared memory address to Platform (SMPro/PMPro)
+   * by ring the doorbell with dummy PCC message
+   */
+  PccData = PCC_NULL_MSG;
+
+  return AcpiPccSendMsg (Socket, Subspace, &PccData, 4);
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPccSharedMemInit (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  )
+{
+  struct ACPI_PCCT_SHARED_MEMORY *AcpiPcct;
+  EFI_STATUS                     Status;
+
+  if ((Subspace >= PCC_MAX_SUBSPACES_PER_SOCKET)
+    || (Socket >= PLATFORM_CPU_MAX_SOCKET)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = AcpiPccGetSharedMemAddr (Socket, Subspace, (VOID **) &AcpiPcct);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  /* Set Shared Memory address into DB OUT register */
+  if (Subspace < PMPRO_MAX_DB) {
+    MmioWrite32 (
+      PMPRO_DBx_REG (Socket, Subspace, DB_OUT0),
+      (UINT32) ((UINT64) AcpiPcct >> 8)
+      );
+  } else {
+    MmioWrite32 (
+      SMPRO_DBx_REG(Socket, Subspace - PMPRO_MAX_DB, DB_OUT0),
+      (UINT32) ((UINT64) AcpiPcct >> 8)
+      );
+  }
+
+  /* Init shared memory for each PCC subspaces */
+  SetMem (
+    (VOID *) AcpiPcct,
+    sizeof (struct ACPI_PCCT_SHARED_MEMORY) + PCC_MSG_SIZE,
+    0x0
+    );
+  AcpiPcct->StatusData.StatusT.CommandComplete = 1;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPccSharedMemInitV2 (
+  IN UINT32                      Socket,
+  IN UINT32                      Subspace
+  )
+{
+  struct ACPI_PCCT_SHARED_MEMORY *AcpiPcct;
+  EFI_STATUS                     Status;
+  UINT32                         AlignBit;
+
+  if ((Subspace >= PCC_MAX_SUBSPACES_PER_SOCKET)
+    || (Socket >= PLATFORM_CPU_MAX_SOCKET)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = AcpiPccGetSharedMemAddr (Socket, Subspace, (VOID **) &AcpiPcct);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((PCC_MSG & PCC_256_ALIGN_ADDR) != 0) {
+    AlignBit = 8;
+  }
+
+  /* Set Shared Memory address into DB OUT register */
+  if (Subspace < PMPRO_MAX_DB) {
+    MmioWrite32 (
+      PMPRO_DBx_REG (Socket, Subspace, DB_OUT0),
+      (UINT32) ((UINT64) AcpiPcct >> AlignBit)
+      );
+
+    MmioWrite32 (
+      (PMPRO_DBx_REG (Socket, Subspace, DB_OUT1)),
+      (UINT32) ((UINT64) AcpiPcct >> (32 + AlignBit))
+      );
+  } else {
+    MmioWrite32 (
+      SMPRO_DBx_REG (Socket, Subspace - PMPRO_MAX_DB, DB_OUT0),
+      (UINT32) ((UINT64) AcpiPcct >> AlignBit)
+      );
+
+    MmioWrite32 (
+      SMPRO_DBx_REG (Socket, Subspace - PMPRO_MAX_DB, DB_OUT1),
+      (UINT32) ((UINT64) AcpiPcct >> (32 + AlignBit))
+      );
+  }
+
+  /* Init shared memory for each PCC subspaces */
+  SetMem (
+    (VOID *) AcpiPcct,
+    sizeof (struct ACPI_PCCT_SHARED_MEMORY) + PCC_MSG_SIZE,
+    0x0
+    );
+  AcpiPcct->StatusData.StatusT.CommandComplete = 1;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiIppPccIsSupported (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+
+  /* Send a PCC NULL command to check if IPP supports PCC request */
+  AcpiPccSharedMemInit (0, 0);
+
+  Status = AcpiPccSyncSharedMemAddr (0, 0);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPccAllocSharedMemory (
+  OUT UINT64                     *PccSharedMemPointer,
+  IN UINT32                      SubspaceNum
+  )
+{
+  EFI_STATUS                     Status;
+
+  if (SubspaceNum > PCC_MAX_SUBSPACES) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gBS->AllocatePages (
+                  AllocateAnyPages,
+                  EfiRuntimeServicesData,
+                  EFI_SIZE_TO_PAGES (PCC_SUBSPACE_SHARED_MEM_SIZE * SubspaceNum),
+                  &PccSharedMemAddr
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to allocate PCC shared memory\n"));
+    return Status;
+  }
+
+  *PccSharedMemPointer = PccSharedMemAddr;
+
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+AcpiPccFreeSharedMemory (
+  OUT UINT64                     *PccSharedMemPointer,
+  IN UINT32                      SubspaceNum
+  )
+{
+  if (SubspaceNum > PCC_MAX_SUBSPACES) {
+    return;
+  }
+
+  gBS->FreePages (
+         *PccSharedMemPointer,
+         EFI_SIZE_TO_PAGES (PCC_SUBSPACE_SHARED_MEM_SIZE * SubspaceNum)
+         );
+
+  PccSharedMemAddr = 0;
+}
-- 
2.17.1


  parent reply	other threads:[~2020-12-09  9:24 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-09  9:24 [edk2-platforms][PATCH 00/34] Add new Ampere Mt. Jade platform Nhi Pham
2020-12-09  9:24 ` [edk2-platforms][PATCH 01/34] Initial support for Ampere Altra and " Nhi Pham
2021-01-07 23:57   ` [edk2-devel] " Leif Lindholm
2021-01-15  4:59     ` Vu Nguyen
2020-12-09  9:24 ` [edk2-platforms][PATCH 02/34] Platform/Ampere: Implement FailSafe library Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 03/34] Platform/Ampere: Add FailSafe and WDT support Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 04/34] AmpereAltraPkg: Implement GpioLib and I2cLib modules Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 05/34] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2020-12-09  9:25 ` Nhi Pham [this message]
2020-12-09  9:25 ` [edk2-platforms][PATCH 07/34] Platform/Ampere: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 08/34] JadePkg: Initial support for static ACPI tables Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 09/34] JadePkg: Install some ACPI tables at runtime Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 10/34] Silicon/Ampere: Support Non Volatile storage for Variable service Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 11/34] Silicon/Ampere: Support PlatformManagerUiLib Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 12/34] AmpereAltraPkg: Add PcieCore Library Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 13/34] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 14/34] JadePkg: Add implementation for PcieBoardLib Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 15/34] JadePkg: Enable PCIe support Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 16/34] JadePkg: Add ASpeed GOP driver Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 17/34] Silicon/Ampere: Add Random Number Generator Support Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 18/34] Silicon/Ampere: Fixup runtime memory attribute Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 19/34] JadePkg: Add SMBIOS tables support Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 20/34] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 21/34] Silicon/Ampere: Add platform info screen Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 22/34] Silicon/Ampere: Add Memory " Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 23/34] AmpereAltraPkg: Add CPU Configuration for SubNUMA Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 24/34] AmpereAltraPkg: Add ACPI configuration screen Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 25/34] AmpereAltraPkg: Implement PlatformFlashAccessLib instance Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 26/34] JadePkg: Add implementation for UEFI Capsule Update Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 27/34] JadePkg: Add Capsule Update support Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 28/34] Silicon/Ampere: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 29/34] Platform/Ampere: Add LinuxBoot image Nhi Pham
2020-12-10 12:40   ` [edk2-devel] " Leif Lindholm
2020-12-11  2:38     ` Nhi Pham
2020-12-11 11:15       ` Leif Lindholm
2020-12-09  9:25 ` [edk2-platforms][PATCH 30/34] JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 31/34] AmpereAltraPkg: Add BootProgress support Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 32/34] JadePkg: Add ACPI/APEI tables Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 33/34] Platform/Ampere: Add AcpiApeiLib Nhi Pham
2020-12-09  9:25 ` [edk2-platforms][PATCH 34/34] AmpereAltraPkg, JadePkg: Add RAS setting screen 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=20201209092531.30867-7-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