public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chuang, Rosen" <rosen.chuang@intel.com>
To: "Kasbekar, Saloni" <saloni.kasbekar@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
	"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
	"Oram, Isaac W" <isaac.w.oram@intel.com>
Subject: Re: [edk2-devel] [PATCH v2 1/7] AlderlakeSiliconPkg: Add package and library instances
Date: Wed, 16 Aug 2023 02:42:04 +0000	[thread overview]
Message-ID: <PH0PR11MB562611AEF9A29D03AD20B99A9215A@PH0PR11MB5626.namprd11.prod.outlook.com> (raw)
In-Reply-To: <fd4a711ecdae4eb6451fda15a92cb603f69d7539.1691170619.git.saloni.kasbekar@intel.com>

Reviewed-by: Rosen Chuang < rosen.chuang@intel.com>


Thanks,
Rosen

-----Original Message-----
From: Kasbekar, Saloni <saloni.kasbekar@intel.com> 
Sent: Saturday, August 5, 2023 1:38 AM
To: devel@edk2.groups.io
Cc: Kasbekar, Saloni <saloni.kasbekar@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Oram, Isaac W <isaac.w.oram@intel.com>; Chuang, Rosen <rosen.chuang@intel.com>
Subject: [PATCH v2 1/7] AlderlakeSiliconPkg: Add package and library instances

Create the AlderlakeSiliconPkg to provide an initial package for silicon initialization code for Alder Lake (ADL) products. Add the following libraries -
- BasePciSegmentMultiSegLibPci
- BaseSiConfigBlockLib
- PeiPostMemSiliconPolicyInitLib
- PeiPreMemSiliconPolicyInitLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Isaac Oram <isaac.w.oram@intel.com>
Cc: Rosen Chuang <rosen.chuang@intel.com>
Signed-off-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
---
 .../BasePciSegmentMultiSegLibPci.inf          |  37 ++
 .../BasePciSegmentMultiSegLibPci.uni          |  14 +
 .../PciSegmentLib.c                           | 597 ++++++++++++++++++
 .../BaseSiConfigBlockLib.c                    |  87 +++
 .../BaseSiConfigBlockLib.inf                  |  32 +
 .../PeiPostMemSiliconPolicyInitLib.c          |  94 +++
 .../PeiPostMemSiliconPolicyInitLib.inf        |  36 ++
 .../PeiPreMemSiliconPolicyInitLib.c           |  98 +++
 .../PeiPreMemSiliconPolicyInitLib.inf         |  36 ++
 9 files changed, 1031 insertions(+)
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf

diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf
new file mode 100644
index 0000000000..f3764d0187
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLi
+++ bPci/BasePciSegmentMultiSegLibPci.inf
@@ -0,0 +1,37 @@
+## @file
+# Instance of PCI Segment Library based on PCI Library.
+#
+# PCI Segment Library that layers on top of the PCI Library which only 
+#  supports segment 0 and segment 1 PCI configuration access.
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BasePciSegmentMultiSegLibPci
+  MODULE_UNI_FILE                = BasePciSegmentMultiSegLibPci.uni
+  FILE_GUID                      = AC65B409-DF03-466e-8D2B-6FCE1079F0B2
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciSegmentLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  PciSegmentLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  AlderlakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PciLib
+  DebugLib
+  PcdLib
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni
new file mode 100644
index 0000000000..dd8d74bee8
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLi
+++ bPci/BasePciSegmentMultiSegLibPci.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Instance of PCI Segment Library based on PCI Library.
+//
+// PCI Segment Library that layers on top of the PCI Library which only 
+//  supports segment 0 and segment 1 PCI configuration access.
+//
+//   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+//   SPDX-License-Identifier: BSD-2-Clause-Patent
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of PCI Segment Library based on PCI Library."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "PCI Segment Library that layers on top of the PCI Library which only supports segment 0 and segment 1 PCI configuration access."
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c
new file mode 100644
index 0000000000..9bcb388016
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLi
+++ bPci/PciSegmentLib.c
@@ -0,0 +1,597 @@
+/** @file
+  PCI Segment Library that layers on top of the PCI Library which only
+   supports segment 0 and segment 1 PCI configuration access.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PciSegmentLib.h>
+
+/**
+  Assert the validity of a PCI Segment address.
+  A valid PCI Segment address should not contain 1's in bits 28..31 and 
+33..63
+  and the segment should be 0 or 1.
+
+  @param  A The address to validate.
+  @param  M Additional bits to assert to be zero.
+
+**/
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
+  ASSERT (((A) & (0xfffffffef0000000ULL | (M))) == 0)
+
+/**
+  Convert the PCI Segment library address to PCI library address.
+  From ICL generation support the multiple segment, and the segment 
+number start from BIT28,
+  So we convert the Segment Number offset from BIT32 to BIT28
+
+  @param A The address to convert.
+**/
+#define PCI_SEGMENT_TO_PCI_ADDRESS(A) ((UINTN) (UINT32) ((A) | 
+((RShiftU64 ((A) & BIT32, 4)))))
+
+
+
+/**
+  Reads an 8-bit PCI configuration register.
+
+  Reads and returns the 8-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 8-bit PCI configuration register specified by Address.
+
+**/
+UINT8
+EFIAPI
+PciSegmentRead8 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return PciRead8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address)); }
+
+/**
+  Writes an 8-bit PCI configuration register.
+
+  Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentWrite8 (
+  IN UINT64                    Address,
+  IN UINT8                     Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value); }
+
+/**
+  Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,  
+ performs a bitwise OR between the read result and the value specified 
+ by OrData,  and writes the result to the 8-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     OrData
+  )
+{
+  return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), (UINT8) 
+(PciSegmentRead8 (Address) | OrData)); }
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,  
+ performs a bitwise AND between the read result and the value specified 
+ by AndData,  and writes the result to the 8-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentAnd8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData
+  )
+{
+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) 
+& AndData)); }
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 
+8-bit value,
+  followed a  bitwise OR with another 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,  
+ performs a bitwise AND between the read result and the value specified 
+ by AndData,  performs a bitwise OR between the result of the AND 
+ operation and the value specified by OrData,  and writes the result to the 8-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData    The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentAndThenOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) 
+& AndData) | OrData)); }
+
+/**
+  Reads a 16-bit PCI configuration register.
+
+  Reads and returns the 16-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 16-bit PCI configuration register specified by Address.
+
+**/
+UINT16
+EFIAPI
+PciSegmentRead16 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address)); }
+
+/**
+  Writes a 16-bit PCI configuration register.
+
+  Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+PciSegmentWrite16 (
+  IN UINT64                    Address,
+  IN UINT16                    Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value); }
+
+/**
+  Performs a bitwise OR of a 16-bit PCI configuration register with
+  a 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address, 
+ performs a  bitwise OR between the read result and the value specified 
+ by  OrData, and writes the result to the 16-bit PCI configuration 
+ register  specified by Address. The value written to the PCI 
+ configuration register is  returned. This function must guarantee that 
+ all PCI read and write operations  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address The address that encodes the PCI Segment, Bus, Device, Function and
+                  Register.
+  @param  OrData  The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 
+(Address) | OrData)); }
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 
+16-bit value,
+  followed a  bitwise OR with another 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address,  
+ performs a bitwise AND between the read result and the value specified 
+ by AndData,  performs a bitwise OR between the result of the AND 
+ operation and the value specified by OrData,  and writes the result to the 16-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData    The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentAndThenOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 
+(Address) & AndData) | OrData)); }
+
+/**
+  Reads a 32-bit PCI configuration register.
+
+  Reads and returns the 32-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 32-bit PCI configuration register specified by Address.
+
+**/
+UINT32
+EFIAPI
+PciSegmentRead32 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address)); }
+
+/**
+  Writes a 32-bit PCI configuration register.
+
+  Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT32
+EFIAPI
+PciSegmentWrite32 (
+  IN UINT64                    Address,
+  IN UINT32                    Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value); }
+
+/**
+  Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,  
+ performs a bitwise OR between the read result and the value specified 
+ by OrData,  and writes the result to the 32-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | 
+OrData); }
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 
+32-bit value,
+  followed a  bitwise OR with another 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,  
+ performs a bitwise AND between the read result and the value specified 
+ by AndData,  performs a bitwise OR between the result of the AND 
+ operation and the value specified by OrData,  and writes the result to the 32-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentAndThenOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & 
+AndData) | OrData); }
+/**
+  Reads a range of PCI configuration registers into a caller supplied buffer.
+
+  Reads the range of PCI configuration registers specified by 
+ StartAddress and  Size into the buffer specified by Buffer. This 
+ function only allows the PCI  configuration registers from a single 
+ PCI function to be read. Size is  returned. When possible 32-bit PCI 
+ configuration read cycles are used to read  from StartAdress to 
+ StartAddress + Size. Due to alignment restrictions, 8-bit  and 16-bit 
+ PCI configuration read cycles may be used at the beginning and the  end of the range.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, Device,
+                        Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  Buffer        The pointer to a buffer receiving the data read.
+
+  @return Size
+
+**/
+UINTN
+EFIAPI
+PciSegmentReadBuffer (
+  IN  UINT64                   StartAddress,
+  IN  UINTN                    Size,
+  OUT VOID                     *Buffer
+  )
+{
+  UINTN                                ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);  ASSERT 
+ (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return Size;
+  }
+
+  ASSERT (Buffer != NULL);
+  if (Buffer == NULL) {
+    return 0;
+  }
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Read a byte if StartAddress is byte aligned
+    //
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+    StartAddress += sizeof (UINT8);
+    Size -= sizeof (UINT8);
+    Buffer = (UINT8*)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+    //
+    // Read a word if StartAddress is word aligned
+    //
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    //
+    // Read as many double words as possible
+    //
+    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
+    StartAddress += sizeof (UINT32);
+    Size -= sizeof (UINT32);
+    Buffer = (UINT32*)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    //
+    // Read the last remaining word if exist
+    //
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    //
+    // Read the last remaining byte if exist
+    //
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);  }
+
+  return ReturnValue;
+}
+
+/**
+  Copies the data in a caller supplied buffer to a specified range of 
+PCI
+  configuration space.
+
+  Writes the range of PCI configuration registers specified by 
+ StartAddress and  Size from the buffer specified by Buffer. This 
+ function only allows the PCI  configuration registers from a single 
+ PCI function to be written. Size is  returned. When possible 32-bit 
+ PCI configuration write cycles are used to  write from StartAdress to 
+ StartAddress + Size. Due to alignment restrictions,  8-bit and 16-bit 
+ PCI configuration write cycles may be used at the beginning  and the end of the range.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, Device,
+                        Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  Buffer        The pointer to a buffer containing the data to write.
+
+  @return The parameter of Size.
+
+**/
+UINTN
+EFIAPI
+PciSegmentWriteBuffer (
+  IN UINT64                    StartAddress,
+  IN UINTN                     Size,
+  IN VOID                      *Buffer
+  )
+{
+  UINTN                                ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);  ASSERT 
+ (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return 0;
+  }
+
+  ASSERT (Buffer != NULL);
+  if (Buffer == NULL) {
+    return 0;
+  }
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Write a byte if StartAddress is byte aligned
+    //
+    PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer);
+    StartAddress += sizeof (UINT8);
+    Size -= sizeof (UINT8);
+    Buffer = (UINT8*) Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+    //
+    // Write a word if StartAddress is word aligned
+    //
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*) Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    //
+    // Write as many double words as possible
+    //
+    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
+    StartAddress += sizeof (UINT32);
+    Size -= sizeof (UINT32);
+    Buffer = (UINT32*) Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    //
+    // Write the last remaining word if exist
+    //
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*) Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    //
+    // Write the last remaining byte if exist
+    //
+    PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer);  }
+
+  return ReturnValue;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
new file mode 100644
index 0000000000..93290d8371
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/Bas
+++ eSiConfigBlockLib.c
@@ -0,0 +1,87 @@
+/** @file
+  This file is BaseSiConfigBlockLib library is used to add config 
+blocks
+  to config block header.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include 
+<ConfigBlock.h> #include <Library/DebugLib.h> #include 
+<Library/IoLib.h> #include <Library/BaseMemoryLib.h> #include 
+<Library/ConfigBlockLib.h> #include <Library/SiConfigBlockLib.h>
+
+
+/**
+  GetComponentConfigBlockTotalSize get config block table total size.
+
+  @param[in] ComponentBlocks    Component blocks array
+  @param[in] TotalBlockCount    Number of blocks
+
+  @retval                       Size of config block table
+**/
+UINT16
+EFIAPI
+GetComponentConfigBlockTotalSize (
+  IN COMPONENT_BLOCK_ENTRY *ComponentBlocks,
+  IN UINT16                TotalBlockCount
+  )
+{
+  UINT16            TotalBlockSize;
+  UINT16            BlockCount;
+
+  TotalBlockSize = 0;
+  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
+    TotalBlockSize += (UINT32) ComponentBlocks[BlockCount].Size;  }
+
+  return TotalBlockSize;
+}
+
+/**
+  AddComponentConfigBlocks add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+  @param[in] ComponentBlocks            Config blocks array
+  @param[in] TotalBlockCount            Number of blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+AddComponentConfigBlocks (
+  IN VOID                  *ConfigBlockTableAddress,
+  IN COMPONENT_BLOCK_ENTRY *ComponentBlocks,
+  IN UINT16                TotalBlockCount
+  )
+{
+  UINT16            BlockCount;
+  VOID              *ConfigBlockPointer;
+  CONFIG_BLOCK      ConfigBlockBuf;
+  EFI_STATUS        Status;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Initialize ConfigBlockPointer to NULL
+  //
+  ConfigBlockPointer = NULL;
+  //
+  // Loop to identify each config block from ComponentBlocks[] Table 
+and add each of them
+  //
+  for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) {
+    ZeroMem (&ConfigBlockBuf, sizeof (CONFIG_BLOCK));
+    CopyMem (&(ConfigBlockBuf.Header.GuidHob.Name), ComponentBlocks[BlockCount].Guid, sizeof (EFI_GUID));
+    ConfigBlockBuf.Header.GuidHob.Header.HobLength = ComponentBlocks[BlockCount].Size;
+    ConfigBlockBuf.Header.Revision                 = ComponentBlocks[BlockCount].Revision;
+    ConfigBlockPointer = (VOID *)&ConfigBlockBuf;
+    Status = AddConfigBlock ((VOID *)ConfigBlockTableAddress, (VOID *)&ConfigBlockPointer);
+    ASSERT_EFI_ERROR (Status);
+    if (ComponentBlocks[BlockCount].LoadDefault != NULL) {
+      ComponentBlocks[BlockCount].LoadDefault (ConfigBlockPointer);
+    }
+  }
+  return Status;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
new file mode 100644
index 0000000000..097095ef0d
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/Bas
+++ eSiConfigBlockLib.inf
@@ -0,0 +1,32 @@
+## @file
+# Component description file for the BaseSiConfigBlockLib library.
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSiConfigBlockLib
+FILE_GUID = 6C068D0F-F48E-48CB-B369-433E507AF4A2
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SiConfigBlockLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+ConfigBlockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseSiConfigBlockLib.c
+
+
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c
new file mode 100644
index 0000000000..a9d6c7e265
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyI
+++ nitLib/PeiPostMemSiliconPolicyInitLib.c
@@ -0,0 +1,94 @@
+/** @file
+  This library initialize Silicon Policy for PostMemory.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include 
+<Ppi/SiPolicy.h> #include <Ppi/PeiSiDefaultPolicy.h> #include 
+<Library/PcdLib.h> #include <Library/DebugLib.h> #include 
+<Library/PeiServicesLib.h> #include <Library/SiPolicyLib.h>
+
+/**
+  Performs silicon post-mem policy initialization.
+
+  The returned data must be used as input data for 
+ SiliconPolicyDonePostMem (),  and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem ().
+
+  @param[in, out] Policy       Pointer to policy.
+  @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPostMem (
+  IN OUT VOID *Policy
+  )
+{
+  EFI_STATUS                        Status;
+  SI_POLICY_PPI                     *SiPolicyPpi;
+  PEI_SI_DEFAULT_POLICY_INIT_PPI    *PeiSiDefaultPolicyInitPpi;
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in 
+ Post-Memory...\n"));
+
+  ASSERT (Policy == NULL);
+  SiPolicyPpi = NULL;
+  PeiSiDefaultPolicyInitPpi = NULL;
+
+  //
+  // Locate Policy init PPI to install default silicon policy  //  
+ Status = PeiServicesLocatePpi (
+             &gSiDefaultPolicyInitPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiSiDefaultPolicyInitPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+  if (PeiSiDefaultPolicyInitPpi != NULL) {
+    Status = PeiSiDefaultPolicyInitPpi->PeiPolicyInit ();
+    ASSERT_EFI_ERROR (Status);
+    if (Status == EFI_SUCCESS) {
+      Status = PeiServicesLocatePpi (
+                 &gSiPolicyPpiGuid,
+                 0,
+                 NULL,
+                 (VOID **) &SiPolicyPpi
+                 );
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  if (SiPolicyPpi == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create default policy!\n"));
+    return NULL;
+  }
+
+
+  return SiPolicyPpi;
+}
+
+/**
+  The silicon post-mem policy is finalized.
+  Silicon code can do initialization based upon the policy data.
+
+  The input Policy must be returned by SiliconPolicyInitPostMem().
+
+  @param[in] Policy       Pointer to policy.
+  @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+**/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePostMem (
+  IN VOID *Policy
+  )
+{
+  EFI_STATUS                   Status;
+
+  Status = SiInstallPolicyReadyPpi ();
+  ASSERT_EFI_ERROR (Status);
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in 
+ Post-Memory\n"));
+
+  return Status;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..b13d63d337
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyI
+++ nitLib/PeiPostMemSiliconPolicyInitLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Component information file for Silicon Policy Init Library # This 
+library implements Silicon Policy Initialization for PostMemory.
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiPostMemSiliconPolicyInitLib
+  FILE_GUID                      = 20B51FFB-93D3-4546-9F13-2C91AEEF9212
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyInitLib
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  PeiServicesLib
+  DebugLib
+  SiPolicyLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  AlderlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiPostMemSiliconPolicyInitLib.c
+
+[Ppis]
+  gSiDefaultPolicyInitPpiGuid
+  gEfiPeiMpServicesPpiGuid
+
+[Depex]
+  gSiDefaultPolicyInitPpiGuid
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c
new file mode 100644
index 0000000000..74fb47a73d
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyIn
+++ itLib/PeiPreMemSiliconPolicyInitLib.c
@@ -0,0 +1,98 @@
+/** @file
+  This library initialize Silicon Policy for PreMemory.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include 
+<Ppi/SiPolicy.h> #include <Ppi/PeiPreMemSiDefaultPolicy.h> #include 
+<Library/DebugLib.h> #include <Library/PeiServicesLib.h> #include 
+<Library/SiPolicyLib.h>
+
+
+/**
+  Performs silicon pre-mem policy initialization.
+
+  The returned data must be used as input data for 
+ SiliconPolicyDonePreMem (),  and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem ().
+
+  @param[in, out] Policy       Pointer to policy.
+  @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPreMem (
+  IN OUT VOID *Policy
+  )
+{
+  EFI_STATUS                             Status;
+  SI_PREMEM_POLICY_PPI                   *SiPreMemPolicyPpi;
+  PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI  
+*PeiPreMemSiDefaultPolicyInitPpi;
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in 
+ Pre-Memory...\n"));
+
+  ASSERT (Policy == NULL);
+  SiPreMemPolicyPpi = NULL;
+  PeiPreMemSiDefaultPolicyInitPpi = NULL;
+
+  //
+  // Locate Policy init PPI to install default silicon policy  //  
+ Status = PeiServicesLocatePpi (
+             &gSiPreMemDefaultPolicyInitPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiPreMemSiDefaultPolicyInitPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+  if (PeiPreMemSiDefaultPolicyInitPpi != NULL) {
+    Status = PeiPreMemSiDefaultPolicyInitPpi->PeiPreMemPolicyInit ();
+    ASSERT_EFI_ERROR (Status);
+    if (Status == EFI_SUCCESS) {
+      Status = PeiServicesLocatePpi (
+                 &gSiPreMemPolicyPpiGuid,
+                 0,
+                 NULL,
+                 (VOID **) &SiPreMemPolicyPpi
+                 );
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  if (SiPreMemPolicyPpi == NULL) {
+    DEBUG ((DEBUG_ERROR, "Fail to create default policy!\n"));
+    return NULL;
+  }
+
+  return SiPreMemPolicyPpi;
+}
+
+/**
+  The silicon pre-mem policy is finalized.
+  Silicon code can do initialization based upon the policy data.
+
+  The input Policy must be returned by SiliconPolicyInitPreMem().
+
+  @param[in] Policy       Pointer to policy.
+  @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+**/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePreMem (
+  IN VOID *Policy
+  )
+{
+  EFI_STATUS                   Status;
+  //
+  // Install PreMem Policy Ready PPI
+  // While installs PreMemPolicyReadyPpi, RC assumes the Policy is 
+ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SiPreMemInstallPolicyReadyPpi ();
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in 
+ Pre-Memory\n"));
+
+  return Status;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..d5ce714ce5
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyIn
+++ itLib/PeiPreMemSiliconPolicyInitLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Component information file for Silicon Policy Init Library # This 
+library implements Silicon Policy Initialization for PreMemory.
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiPreMemSiliconPolicyInitLib
+  FILE_GUID                      = 1FB4B175-0BB6-4137-A4AC-EA48FCE83862
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyInitLib
+
+[LibraryClasses]
+  BaseLib
+  PeiServicesLib
+  DebugLib
+  SiPolicyLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  AlderlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiPreMemSiliconPolicyInitLib.c
+
+[Pcd]
+
+[Ppis]
+  gSiPreMemDefaultPolicyInitPpiGuid
+
+[Depex]
+  gSiPreMemDefaultPolicyInitPpiGuid
--
2.36.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107779): https://edk2.groups.io/g/devel/message/107779
Mute This Topic: https://groups.io/mt/100551000/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



      parent reply	other threads:[~2023-08-16  2:42 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-04 17:37 [edk2-devel] [PATCH v2 1/7] AlderlakeSiliconPkg: Add package and library instances Saloni Kasbekar
2023-08-04 17:37 ` [edk2-devel] [PATCH v2 2/7] AlderlakeSiliconPkg: Add Cpu modules Saloni Kasbekar
2023-08-16  2:45   ` Chuang, Rosen
2023-08-04 17:37 ` [edk2-devel] [PATCH v2 3/7] AlderlakeSiliconPkg/Pch: Add include headers Saloni Kasbekar
2023-08-16  2:44   ` Chuang, Rosen
2023-08-04 17:37 ` [edk2-devel] [PATCH v2 4/7] AlderlakeSiliconPkg/Pch: Add libraries Saloni Kasbekar
2023-08-16  2:42   ` Chuang, Rosen
2023-08-04 17:37 ` [edk2-devel] [PATCH v2 5/7] AlderlakeSiliconPkg/Pch: Add drivers Saloni Kasbekar
2023-08-16  2:46   ` Chuang, Rosen
2023-08-04 17:37 ` [edk2-devel] [PATCH v2 6/7] AlderlakeSiliconPkg/SystemAgent: Add include headers Saloni Kasbekar
2023-08-16  2:45   ` Chuang, Rosen
2023-08-04 17:37 ` [edk2-devel] [PATCH v2 7/7] AlderlakeSiliconPkg/SystemAgent: Add library and driver modules Saloni Kasbekar
2023-08-16  2:45   ` Chuang, Rosen
2023-08-16  2:42 ` Chuang, Rosen [this message]

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=PH0PR11MB562611AEF9A29D03AD20B99A9215A@PH0PR11MB5626.namprd11.prod.outlook.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