public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver
@ 2024-04-17  7:08 WangYang
  0 siblings, 0 replies; 5+ messages in thread
From: WangYang @ 2024-04-17  7:08 UTC (permalink / raw)
  To: sunilvl, git, devel; +Cc: Yang Wang, Ran Wang, Leif Lindholm, Michael D Kinney

1.Xilinx RC is XDMA
2.Support NVME storage

Nvme storage needs to be formatted to FAT32 format.

Reviewed-by: Ran Wang <wangran@bosc.ac.cn>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sunil V L <sunilvl@ventanamicro.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Signed-off-by: Yang Wang <wangyang@bosc.ac.cn>
---
 .../XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc  |   30 +-
 .../XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf  |   13 +-
 .../NanhuDev/NanhuDev.fdf.inc                 |    1 +
 .../PciHostBridgeLib/PciHostBridgeLib.c       |  273 ++++
 .../PciHostBridgeLib/PciHostBridgeLib.inf     |   48 +
 .../Library/PciSegmentLib/PciSegmentLib.c     | 1391 +++++++++++++++++
 .../Library/PciSegmentLib/PciSegmentLib.inf   |   29 +
 Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec         |   20 +
 8 files changed, 1802 insertions(+), 3 deletions(-)
 create mode 100644 Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
 create mode 100644 Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
 create mode 100755 Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c
 create mode 100755 Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf

diff --git a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc
index 7dcd7c4313..85934f66be 100644
--- a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc
+++ b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc
@@ -239,6 +239,9 @@
   PlatformBootManagerLib|Platform/RISC-V/PlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
   PlatformMemoryTestLib|Platform/RISC-V/PlatformPkg/Library/PlatformMemoryTestLibNull/PlatformMemoryTestLibNull.inf
   PlatformUpdateProgressLib|Platform/RISC-V/PlatformPkg/Library/PlatformUpdateProgressLibNull/PlatformUpdateProgressLibNull.inf
+  # Pci dependencies
+  PciSegmentLib|Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
+  PciHostBridgeLib|Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
 
 [LibraryClasses.common.UEFI_APPLICATION]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -262,6 +265,24 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
 
 [PcdsFixedAtBuild]
+  #
+  # XILINX PCI Root Complex
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x40000000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation|0x50000000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigBase|0x40000000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigSize|0x10000000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMin|0
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMax|255
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoBase|0x00000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoSize|0xf00000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Base|0x50000000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Size|0x10000000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Base|0x1000000000
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Size|0x0000000000
+
   gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
   gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
   gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
@@ -427,11 +448,13 @@
   MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
 !endif
 
-  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+  Silicon/RISC-V/ProcessorPkg/Universal/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
   MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
     <LibraryClasses>
       PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
   }
+  MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
   MdeModulePkg/Universal/Metronome/Metronome.inf
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
   MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf {
@@ -440,6 +463,11 @@
   }
   EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
 
+  #
+  # NVME Support
+  #
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
   #
   # RISC-V Platform module
   #
diff --git a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf
index d54bb73353..45c96f58a0 100644
--- a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf
+++ b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf
@@ -69,8 +69,6 @@ INF  OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
 
 INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
 INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
-INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
-INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
 INF  MdeModulePkg/Universal/Metronome/Metronome.inf
 INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
 
@@ -127,6 +125,17 @@ INF  ShellPkg/Application/Shell/Shell.inf
 
 !include NetworkPkg/Network.fdf.inc
 
+#
+# PCI Support
+#
+INF Silicon/RISC-V/ProcessorPkg/Universal/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
+INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+
+# NVMe boot devices
+#
+INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
 #
 # Usb Support
 #
diff --git a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc
index b78d25f83e..66934e5efe 100644
--- a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc
+++ b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc
@@ -60,3 +60,4 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase              = 0x310B00
 SET gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate                   = 115200
 SET gHisiTokenSpaceGuid.PcdSerialPortSendDelay                        = 50
 SET gHisiTokenSpaceGuid.PcdUartClkInHz                                = 50000000
+
diff --git a/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..a25728affc
--- /dev/null
+++ b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,273 @@
+/** @file
+  PCI host bridge library instance for NanHuDev SOC.
+
+  Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.<BR>
+  Copyright (c) 2024, Bosc. All rights reserved.<BR>ved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/IoLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH     AcpiDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+#pragma pack ()
+
+#define BIT(nr)         (1UL << (nr))
+#define GENMASK(h, l) \
+    (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+/* Register definitions */
+#define XILINX_PCIE_REG_VSEC		0x0000012c
+#define XILINX_PCIE_REG_BIR		0x00000130
+#define XILINX_PCIE_REG_IDR		0x00000138
+#define XILINX_PCIE_REG_IMR		0x0000013c
+#define XILINX_PCIE_REG_PSCR		0x00000144
+#define XILINX_PCIE_REG_RPSC		0x00000148
+#define XILINX_PCIE_REG_MSIBASE1	0x0000014c
+#define XILINX_PCIE_REG_MSIBASE2	0x00000150
+#define XILINX_PCIE_REG_RPEFR		0x00000154
+#define XILINX_PCIE_REG_RPIFR1		0x00000158
+#define XILINX_PCIE_REG_RPIFR2		0x0000015c
+#define XILINX_PCIE_REG_IDRN            0x00000160
+#define XILINX_PCIE_REG_IDRN_MASK       0x00000164
+#define XILINX_PCIE_REG_MSI_LOW		0x00000170
+#define XILINX_PCIE_REG_MSI_HI		0x00000174
+#define XILINX_PCIE_REG_MSI_LOW_MASK	0x00000178
+#define XILINX_PCIE_REG_MSI_HI_MASK	0x0000017c
+
+/* Interrupt registers definitions */
+#define XILINX_PCIE_INTR_LINK_DOWN	BIT(0)
+#define XILINX_PCIE_INTR_HOT_RESET	BIT(3)
+#define XILINX_PCIE_INTR_CFG_TIMEOUT	BIT(8)
+#define XILINX_PCIE_INTR_CORRECTABLE	BIT(9)
+#define XILINX_PCIE_INTR_NONFATAL	BIT(10)
+#define XILINX_PCIE_INTR_FATAL		BIT(11)
+#define XILINX_PCIE_INTR_INTX		BIT(16)
+#define XILINX_PCIE_INTR_MSI		BIT(17)
+#define XILINX_PCIE_INTR_SLV_UNSUPP	BIT(20)
+#define XILINX_PCIE_INTR_SLV_UNEXP	BIT(21)
+#define XILINX_PCIE_INTR_SLV_COMPL	BIT(22)
+#define XILINX_PCIE_INTR_SLV_ERRP	BIT(23)
+#define XILINX_PCIE_INTR_SLV_CMPABT	BIT(24)
+#define XILINX_PCIE_INTR_SLV_ILLBUR	BIT(25)
+#define XILINX_PCIE_INTR_MST_DECERR	BIT(26)
+#define XILINX_PCIE_INTR_MST_SLVERR	BIT(27)
+#define XILINX_PCIE_IMR_ALL_MASK	0x0FF30FE9
+#define XILINX_PCIE_IDR_ALL_MASK	0xFFFFFFFF
+#define XILINX_PCIE_IDRN_MASK           GENMASK(19, 16)
+
+/* Root Port Error FIFO Read Register definitions */
+#define XILINX_PCIE_RPEFR_ERR_VALID	BIT(18)
+#define XILINX_PCIE_RPEFR_REQ_ID	GENMASK(15, 0)
+#define XILINX_PCIE_RPEFR_ALL_MASK	0xFFFFFFFF
+
+/* Root Port Interrupt FIFO Read Register 1 definitions */
+#define XILINX_PCIE_RPIFR1_INTR_VALID	BIT(31)
+#define XILINX_PCIE_RPIFR1_MSI_INTR	BIT(30)
+#define XILINX_PCIE_RPIFR1_INTR_MASK	GENMASK(28, 27)
+#define XILINX_PCIE_RPIFR1_ALL_MASK	0xFFFFFFFF
+#define XILINX_PCIE_RPIFR1_INTR_SHIFT	27
+#define XILINX_PCIE_IDRN_SHIFT          16
+#define XILINX_PCIE_VSEC_REV_MASK	GENMASK(19, 16)
+#define XILINX_PCIE_VSEC_REV_SHIFT	16
+#define XILINX_PCIE_FIFO_SHIFT		5
+
+/* Bridge Info Register definitions */
+#define XILINX_PCIE_BIR_ECAM_SZ_MASK	GENMASK(18, 16)
+#define XILINX_PCIE_BIR_ECAM_SZ_SHIFT	16
+
+/* Root Port Interrupt FIFO Read Register 2 definitions */
+#define XILINX_PCIE_RPIFR2_MSG_DATA	GENMASK(15, 0)
+
+/* Root Port Status/control Register definitions */
+#define XILINX_PCIE_REG_RPSC_BEN	BIT(0)
+
+/* Phy Status/Control Register definitions */
+#define XILINX_PCIE_REG_PSCR_LNKUP	BIT(11)
+
+/* ECAM definitions */
+#define ECAM_BUS_NUM_SHIFT		20
+#define ECAM_DEV_NUM_SHIFT		12
+
+/* Number of MSI IRQs */
+#define XILINX_NUM_MSI_IRQS		64
+#define INTX_NUM                        4
+
+#define DMA_BRIDGE_BASE_OFF		0xCD8
+
+
+#define END_DEVICE_PATH_DEF { END_DEVICE_PATH_TYPE, \
+                              END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+                              { END_DEVICE_PATH_LENGTH, 0 } \
+                            }
+
+#define ACPI_DEVICE_PATH_DEF(UID) {{ ACPI_DEVICE_PATH, ACPI_DP, \
+                                     { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+                                       (UINT8) (sizeof (ACPI_HID_DEVICE_PATH) >> 8)} \
+                                     }, \
+                                     EISA_PNP_ID (0x0A03), UID \
+                                  }
+
+STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[] = {
+  {
+    ACPI_DEVICE_PATH_DEF (0),
+    END_DEVICE_PATH_DEF
+  },
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+  L"Mem", L"I/O", L"Bus"
+};
+
+STATIC PCI_ROOT_BRIDGE mRootBridge = {
+  0,                                              // Segment
+  0,                                              // Supports
+  0,                                              // Attributes
+  FALSE,                                           // DmaAbove4G
+  FALSE,                                          // NoExtendedConfigSpace
+  FALSE,                                          // ResourceAssigned
+  0,           // AllocationAttributes
+  {
+    // Bus
+    FixedPcdGet32 (PcdPciBusMin),
+    FixedPcdGet32 (PcdPciBusMax)
+  }, {
+    // Io
+    FixedPcdGet64 (PcdPciIoBase),
+    FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
+  }, {
+    // Mem
+    FixedPcdGet32 (PcdPciMmio32Base),
+    FixedPcdGet32 (PcdPciMmio32Base) + (FixedPcdGet32 (PcdPciMmio32Size) - 1)
+    //0x7FFFFFFF
+  }, {
+    // MemAbove4G
+    FixedPcdGet64 (PcdPciMmio64Base),
+    FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1
+  }, {
+    // PMem
+    MAX_UINT64,
+    0
+  }, {
+    // PMemAbove4G
+    MAX_UINT64,
+    0
+  },
+  (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath
+};
+
+/**
+  Return all the root bridge instances in an array.
+
+  @param[out] Count  Return the count of root bridge instances.
+
+  @return All the root bridge instances in an array.
+          The array should be passed into PciHostBridgeFreeRootBridges()
+          when it's not used.
+
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+  OUT UINTN     *Count
+  )
+{
+  /* Enable the Bridge enable bit */
+  UINT64 PciConfigBase = FixedPcdGet64 (PcdPciConfigBase);
+  UINT32 Rpsc = MmioRead32 (PciConfigBase + XILINX_PCIE_REG_RPSC);
+  MmioWrite32 (PciConfigBase + XILINX_PCIE_REG_RPSC, Rpsc | XILINX_PCIE_REG_RPSC_BEN);
+  DEBUG ((DEBUG_INFO, "PciHostBridgeGetRootBridges():%d PciConfigBase:0x%x Rpsc:0x%x XILINX_PCIE_REG_RPSC_BEN:0x%x\n", \
+              __LINE__, PciConfigBase, Rpsc, Rpsc | XILINX_PCIE_REG_RPSC_BEN));
+
+  *Count = 1;
+  return &mRootBridge;
+}
+
+
+/**
+  Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
+
+  @param[in] Bridges The root bridge instances array.
+  @param[in] Count   The count of the array.
+
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+  IN PCI_ROOT_BRIDGE *Bridges,
+  IN UINTN           Count
+  )
+{
+
+}
+
+
+/**
+  Inform the platform that the resource conflict happens.
+
+  @param[in] HostBridgeHandle Handle of the Host Bridge.
+  @param[in] Configuration    Pointer to PCI I/O and PCI memory resource
+                          descriptors. The Configuration contains the resources
+                          for all the root bridges. The resource for each root
+                          bridge is terminated with END descriptor and an
+                          additional END is appended indicating the end of the
+                          entire resources. The resource descriptor field
+                          values follow the description in
+                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+                          SubmitResources().
+
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+  IN EFI_HANDLE                        HostBridgeHandle,
+  IN VOID                              *Configuration
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+  BOOLEAN IsPrefetchable;
+
+  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+      ASSERT (Descriptor->ResType <
+              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr));
+      DEBUG ((DEBUG_INFO, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+              mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+              Descriptor->AddrLen,
+              Descriptor->AddrRangeMax
+              ));
+      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+
+        IsPrefetchable = (Descriptor->SpecificFlag &
+          EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0;
+
+        DEBUG ((DEBUG_INFO, "     Granularity/SpecificFlag = %ld / %02x%s\n",
+          Descriptor->AddrSpaceGranularity,
+          Descriptor->SpecificFlag,
+          (IsPrefetchable) ? L" (Prefetchable)" : L""
+          ));
+      }
+    }
+    //
+    // Skip the end descriptor for root bridge
+    //
+    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (
+                   (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+                   );
+  }
+}
diff --git a/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..1620936736
--- /dev/null
+++ b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,48 @@
+#/** @file
+#  PCI Host Bridge Library instance for Bosc SOC.
+#
+#  Copyright (C) 2020, Bosc Technology Co, Ltd. All rights reserved.<BR>
+#  Copyright (c) 2024, Bosc. All rights reserved.<BR>ved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = PciHostBridgeLib
+  FILE_GUID                      = 7F418E45-0127-454E-9CBB-F5FCF237E383
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciHostBridgeLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = RISCV64
+#
+
+[Sources]
+  PciHostBridgeLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
+
+[LibraryClasses]
+  DebugLib
+
+[Guids]
+
+[FixedPcd]
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMin
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMax
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoBase
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoSize
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Base
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Size
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Base
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Size
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigBase
diff --git a/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c
new file mode 100755
index 0000000000..8e463fcc79
--- /dev/null
+++ b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c
@@ -0,0 +1,1391 @@
+/** @file
+  PCI Segment Library for SoC with multiple RCs.
+
+  Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.<BR>
+  Copyright (c) 2024, Bosc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+#define PCI_SEG_CONFIG_BASE       0x40000000
+
+typedef enum {
+  PciCfgWidthUint8 = 0,
+  PciCfgWidthUint16,
+  PciCfgWidthUint32,
+  PciCfgWidthMax
+} PCI_CFG_WIDTH;
+
+/**
+  Assert the validity of a PCI Segment address.
+  A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
+
+  @param[in]  A The address to validate.
+  @param[in]  M Additional bits to assert to be zero.
+
+**/
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
+ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
+
+
+#define EXTRACT_PCIE_ADDRESS(Address, Bus, Device, Function) \
+{ \
+  (Bus)      = (((Address) >> 20) & 0xff);   \
+  (Device)   = (((Address) >> 15) & 0x1f);   \
+  (Function) = (((Address) >> 12) & 0x07);   \
+}
+
+
+/**
+  This function  geted the config base of PCI device.
+  @param[in]  Address  The address that encodes the PCI Bus, Device, Function and
+                       Register.
+
+  @return The value of the config base of PCI device.
+
+**/
+STATIC
+UINT64
+PciSegmentLibGetConfigBase (
+  IN  UINT64      Address
+  )
+{
+  UINT8 Bus;
+  UINT8 Device;
+  UINT8 Function;
+
+  EXTRACT_PCIE_ADDRESS (Address, Bus, Device, Function);
+  if ((Bus == 1) || (Bus == 2) || (Bus == 3) || (Bus == 4)) {
+    return PCI_SEG_CONFIG_BASE;
+  }
+
+  return PCI_SEG_CONFIG_BASE;
+}
+
+/**
+  Internal worker function to read a PCI configuration register.
+
+  @param[in]  Address The address that encodes the PCI Bus, Device, Function and
+                      Register.
+  @param[in]  Width   The width of data to read
+
+  @return The value read from the PCI configuration register.
+
+**/
+STATIC
+UINT32
+PciSegmentLibReadWorker (
+  IN  UINT64                      Address,
+  IN  PCI_CFG_WIDTH               Width
+  )
+{
+  UINT64    Base;
+
+  Base = PciSegmentLibGetConfigBase (Address);
+  if (Base == 0xFFFFFFFF) {
+    return 0xFFFFFFFF;
+  }
+
+  switch (Width) {
+  case PciCfgWidthUint8:
+    return MmioRead8 (Base + (UINT32)Address);
+  case PciCfgWidthUint16:
+    return MmioRead16 (Base + (UINT32)Address);
+  case PciCfgWidthUint32:
+    return MmioRead32 (Base + (UINT32)Address);
+  default:
+    ASSERT (FALSE);
+  }
+
+  return 0;
+}
+
+
+/**
+  Internal worker function to writes a PCI configuration register.
+
+  @param[in]  Address The address that encodes the PCI Bus, Device, Function and
+                  Register.
+  @param[in]  Width   The width of data to write
+  @param[in]  Data    The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+STATIC
+UINT32
+PciSegmentLibWriteWorker (
+  IN  UINT64                      Address,
+  IN  PCI_CFG_WIDTH               Width,
+  IN  UINT32                      Data
+  )
+{
+  UINT64    Base;
+
+  Base = PciSegmentLibGetConfigBase (Address);
+  if (Base == 0xFFFFFFFF) {
+    return 0xFFFFFFFF;
+  }
+
+  switch (Width) {
+  case PciCfgWidthUint8:
+    MmioWrite8 (Base + (UINT32)Address, Data);
+    break;
+  case PciCfgWidthUint16:
+    MmioWrite16 (Base + (UINT32)Address, Data);
+    break;
+  case PciCfgWidthUint32:
+    MmioWrite32 (Base + (UINT32)Address, Data);
+    break;
+  default:
+    ASSERT (FALSE);
+  }
+
+  return Data;
+}
+
+/**
+  Register a PCI device so PCI configuration registers may be accessed after
+  SetVirtualAddressMap().
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param[in]      Address          The address that encodes the PCI Bus, Device, Function and
+                                   Register.
+
+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
+                                   after ExitBootServices().
+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device
+                                   at runtime could not be mapped.
+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to
+                                   complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciSegmentRegisterForRuntimeAccess (
+  IN UINTN  Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  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[in]  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 (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
+}
+
+/**
+  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[in]  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  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 (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  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 PciSegmentWrite8 (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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  AndData    The value to AND with the PCI configuration register.
+  @param[in]  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 bit field of a PCI configuration register.
+
+  Reads the bit field in an 8-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to read.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldRead8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit
+  )
+{
+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  8-bit register is returned.
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldWrite8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     Value
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 8-bit port.
+
+  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. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldOr8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 8-bit register.
+
+  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. Extra left bits in AndData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldAnd8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     AndData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR 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. Extra left bits in both AndData and
+  OrData are stripped.
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+  @param[in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldAndThenOr8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     AndData,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, 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[in]  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 (UINT16) PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
+}
+
+/**
+  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[in]  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  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 (UINT16) PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, 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[in]  Address The address that encodes the PCI Segment, Bus, Device, Function and
+                  Register.
+  @param[in]  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.
+
+  Reads the 16-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 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentAnd16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData
+  )
+{
+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));
+}
+
+/**
+  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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+  @param[in]  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 bit field of a PCI configuration register.
+
+  Reads the bit field in a 16-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to read.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldRead16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit
+  )
+{
+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  16-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldWrite16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    Value
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, 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.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldOr16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
+  and writes the result back to the bit field in the 16-bit port.
+
+  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.
+  Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    The ordinal of the least significant bit in a byte is bit 0.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    The ordinal of the most significant bit in a byte is bit 7.
+  @param[in]  AndData   The value to AND with the read value from the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldAnd16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    AndData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, 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. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+  @param[in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldAndThenOr16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    AndData,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, 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[in]  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 PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
+}
+
+/**
+  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[in]  Address     The address that encodes the PCI Segment, Bus, Device,
+                      Function, and Register.
+  @param[in]  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 PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param[in]  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.
+
+  Reads the 32-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 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentAnd32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData
+  )
+{
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);
+}
+
+/**
+  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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function,
+                    and Register.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+  @param[in]  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 bit field of a PCI configuration register.
+
+  Reads the bit field in a 32-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to read.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldRead32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit
+  )
+{
+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  32-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldWrite32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    Value
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 32-bit port.
+
+  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. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldOr32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 32-bit register.
+
+
+  Reads the 32-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 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.  Extra left bits in AndData are stripped.
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldAnd32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    AndData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, 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. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param[in]  Address   The PCI configuration register to write.
+  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param[in]  AndData   The value to AND with the PCI configuration register.
+  @param[in]  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldAndThenOr32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    AndData,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, 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[in]  StartAddress  The starting address that encodes the PCI Segment, Bus,
+                        Device, Function and Register.
+  @param[in]  Size          The size in bytes of the transfer.
+  @param[in]  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);
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Read a byte if StartAddress is byte aligned,
+    //
+    MmioWrite8 ((UINTN)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
+    //
+    MmioWrite8 ((UINTN)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[in]  StartAddress  The starting address that encodes the PCI Segment, Bus,
+                        Device, Function and Register.
+  @param[in]  Size          The size in bytes of the transfer.
+  @param[in]  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);
+
+  //
+  // 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/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
new file mode 100755
index 0000000000..29d1758410
--- /dev/null
+++ b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
@@ -0,0 +1,29 @@
+#/** @file
+#  PCI Segment Library for Bosc NanHuDev platform with Xilinx XDMA RCs.
+#
+#  Copyright (C) 2020, Phytium Technology Co, Ltd. All rights reser
+#  Copyright (c) 2024, Bosc. All rights reserved.<BR>ved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = PciSegmentLib
+  FILE_GUID                      = B0DD53D5-30C6-48CB-849D-BEB935B57D78
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciSegmentLib
+
+[Sources]
+  PciSegmentLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
diff --git a/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec b/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
index e975ae42d0..9f553a5b0a 100644
--- a/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
+++ b/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
@@ -20,6 +20,7 @@
 [Protocols]
 
 [Guids]
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid  = { 0x245C5C80, 0x7945, 0x43BE, { 0xB4, 0x01, 0xC9, 0x92, 0x8A, 0x13, 0xDD, 0x0A }}
 
 [PcdsFixedAtBuild]
   gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0|UINT64|0x00001004
@@ -27,5 +28,24 @@
   gHisiTokenSpaceGuid.PcdSerialPortSendDelay|0x0|UINT32|0x00001006
   gHisiTokenSpaceGuid.PcdUartClkInHz|0x0|UINT32|0x00001007
 
+  #
+  # PCI configuration address space
+  #
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigBase|0x0|UINT64|0x00000008
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigSize|0x0|UINT64|0x00000009
+
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x0000000a
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x0000000b
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT32|0x0000000c
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT32|0x0000000d
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x0000000e
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x0000000f
+
+  #
+  # Inclusive range of allowed PCI buses.
+  #
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMin|0x0|UINT32|0x00000010
+  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMax|0x0|UINT32|0x00000011
+
 [UserExtensions.TianoCore."ExtraFiles"]
   NanHuPkgExtra.uni
-- 
2.34.1



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



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver
       [not found] <17C6FF8EBB82206B.20815@groups.io>
@ 2024-05-15  7:40 ` WangYang
  2024-05-15  8:36   ` Ni, Ray
  0 siblings, 1 reply; 5+ messages in thread
From: WangYang @ 2024-05-15  7:40 UTC (permalink / raw)
  To: devel; +Cc: sunilvl, git, Ran Wang, Leif Lindholm, Michael D Kinney

Hi,Sunil V L

   Thank you very much for your attention.
   How about this status.
   This patch is based on  https://edk2.groups.io/g/devel/topic/105437172#msg118579.   
   I also want to know the status of this patch(https://edk2.groups.io/g/devel/topic/105437172#msg118579).  
   
Best Regards,
Yang Wang

> -----原始邮件-----
> 发件人: WangYang <wangyang@bosc.ac.cn>
> 发送时间: 2024-04-17 15:08:06 (星期三)
> 收件人: sunilvl@ventanamicro.com, git@danielschaefer.me, devel@edk2.groups.io
> 抄送: "Yang Wang" <wangyang@bosc.ac.cn>, "Ran Wang" <wangran@bosc.ac.cn>, "Leif Lindholm" <quic_llindhol@quicinc.com>, "Michael D Kinney" <michael.d.kinney@intel.com>
> 主题: [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver
> 
> 1.Xilinx RC is XDMA
> 2.Support NVME storage
> 
> Nvme storage needs to be formatted to FAT32 format.
> 
> Reviewed-by: Ran Wang <wangran@bosc.ac.cn>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Sunil V L <sunilvl@ventanamicro.com>
> Cc: Daniel Schaefer <git@danielschaefer.me>
> Signed-off-by: Yang Wang <wangyang@bosc.ac.cn>
> ---
>  .../XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc  |   30 +-
>  .../XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf  |   13 +-
>  .../NanhuDev/NanhuDev.fdf.inc                 |    1 +
>  .../PciHostBridgeLib/PciHostBridgeLib.c       |  273 ++++
>  .../PciHostBridgeLib/PciHostBridgeLib.inf     |   48 +
>  .../Library/PciSegmentLib/PciSegmentLib.c     | 1391 +++++++++++++++++
>  .../Library/PciSegmentLib/PciSegmentLib.inf   |   29 +
>  Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec         |   20 +
>  8 files changed, 1802 insertions(+), 3 deletions(-)
>  create mode 100644 Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
>  create mode 100644 Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
>  create mode 100755 Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c
>  create mode 100755 Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
> 
> diff --git a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc
> index 7dcd7c4313..85934f66be 100644
> --- a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc
> +++ b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.dsc
> @@ -239,6 +239,9 @@
>    PlatformBootManagerLib|Platform/RISC-V/PlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
>    PlatformMemoryTestLib|Platform/RISC-V/PlatformPkg/Library/PlatformMemoryTestLibNull/PlatformMemoryTestLibNull.inf
>    PlatformUpdateProgressLib|Platform/RISC-V/PlatformPkg/Library/PlatformUpdateProgressLibNull/PlatformUpdateProgressLibNull.inf
> +  # Pci dependencies
> +  PciSegmentLib|Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
> +  PciHostBridgeLib|Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
>  
>  [LibraryClasses.common.UEFI_APPLICATION]
>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> @@ -262,6 +265,24 @@
>    gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
>  
>  [PcdsFixedAtBuild]
> +  #
> +  # XILINX PCI Root Complex
> +  #
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x40000000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdPciIoTranslation|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdPciMmio32Translation|0x50000000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigBase|0x40000000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigSize|0x10000000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMin|0
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMax|255
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoBase|0x00000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoSize|0xf00000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Base|0x50000000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Size|0x10000000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Base|0x1000000000
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Size|0x0000000000
> +
>    gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
>    gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
>    gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
> @@ -427,11 +448,13 @@
>    MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
>  !endif
>  
> -  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +  Silicon/RISC-V/ProcessorPkg/Universal/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>    MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
>      <LibraryClasses>
>        PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
>    }
> +  MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
>    MdeModulePkg/Universal/Metronome/Metronome.inf
>    MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
>    MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf {
> @@ -440,6 +463,11 @@
>    }
>    EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>  
> +  #
> +  # NVME Support
> +  #
> +  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
>    #
>    # RISC-V Platform module
>    #
> diff --git a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf
> index d54bb73353..45c96f58a0 100644
> --- a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf
> +++ b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf
> @@ -69,8 +69,6 @@ INF  OvmfPkg/Fdt/HighMemDxe/HighMemDxe.inf
>  
>  INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>  INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> -INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> -INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
>  INF  MdeModulePkg/Universal/Metronome/Metronome.inf
>  INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>  
> @@ -127,6 +125,17 @@ INF  ShellPkg/Application/Shell/Shell.inf
>  
>  !include NetworkPkg/Network.fdf.inc
>  
> +#
> +# PCI Support
> +#
> +INF Silicon/RISC-V/ProcessorPkg/Universal/PciCpuIo2Dxe/PciCpuIo2Dxe.inf
> +INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +
> +# NVMe boot devices
> +#
> +INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
>  #
>  # Usb Support
>  #
> diff --git a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc
> index b78d25f83e..66934e5efe 100644
> --- a/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc
> +++ b/Platform/Bosc/XiangshanSeriesPkg/NanhuDev/NanhuDev.fdf.inc
> @@ -60,3 +60,4 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase              = 0x310B00
>  SET gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate                   = 115200
>  SET gHisiTokenSpaceGuid.PcdSerialPortSendDelay                        = 50
>  SET gHisiTokenSpaceGuid.PcdUartClkInHz                                = 50000000
> +
> diff --git a/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 0000000000..a25728affc
> --- /dev/null
> +++ b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
> @@ -0,0 +1,273 @@
> +/** @file
> +  PCI host bridge library instance for NanHuDev SOC.
> +
> +  Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.<BR>
> +  Copyright (c) 2024, Bosc. All rights reserved.<BR>ved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Library/IoLib.h>
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH     AcpiDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
> +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +
> +#pragma pack ()
> +
> +#define BIT(nr)         (1UL << (nr))
> +#define GENMASK(h, l) \
> +    (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
> +
> +/* Register definitions */
> +#define XILINX_PCIE_REG_VSEC		0x0000012c
> +#define XILINX_PCIE_REG_BIR		0x00000130
> +#define XILINX_PCIE_REG_IDR		0x00000138
> +#define XILINX_PCIE_REG_IMR		0x0000013c
> +#define XILINX_PCIE_REG_PSCR		0x00000144
> +#define XILINX_PCIE_REG_RPSC		0x00000148
> +#define XILINX_PCIE_REG_MSIBASE1	0x0000014c
> +#define XILINX_PCIE_REG_MSIBASE2	0x00000150
> +#define XILINX_PCIE_REG_RPEFR		0x00000154
> +#define XILINX_PCIE_REG_RPIFR1		0x00000158
> +#define XILINX_PCIE_REG_RPIFR2		0x0000015c
> +#define XILINX_PCIE_REG_IDRN            0x00000160
> +#define XILINX_PCIE_REG_IDRN_MASK       0x00000164
> +#define XILINX_PCIE_REG_MSI_LOW		0x00000170
> +#define XILINX_PCIE_REG_MSI_HI		0x00000174
> +#define XILINX_PCIE_REG_MSI_LOW_MASK	0x00000178
> +#define XILINX_PCIE_REG_MSI_HI_MASK	0x0000017c
> +
> +/* Interrupt registers definitions */
> +#define XILINX_PCIE_INTR_LINK_DOWN	BIT(0)
> +#define XILINX_PCIE_INTR_HOT_RESET	BIT(3)
> +#define XILINX_PCIE_INTR_CFG_TIMEOUT	BIT(8)
> +#define XILINX_PCIE_INTR_CORRECTABLE	BIT(9)
> +#define XILINX_PCIE_INTR_NONFATAL	BIT(10)
> +#define XILINX_PCIE_INTR_FATAL		BIT(11)
> +#define XILINX_PCIE_INTR_INTX		BIT(16)
> +#define XILINX_PCIE_INTR_MSI		BIT(17)
> +#define XILINX_PCIE_INTR_SLV_UNSUPP	BIT(20)
> +#define XILINX_PCIE_INTR_SLV_UNEXP	BIT(21)
> +#define XILINX_PCIE_INTR_SLV_COMPL	BIT(22)
> +#define XILINX_PCIE_INTR_SLV_ERRP	BIT(23)
> +#define XILINX_PCIE_INTR_SLV_CMPABT	BIT(24)
> +#define XILINX_PCIE_INTR_SLV_ILLBUR	BIT(25)
> +#define XILINX_PCIE_INTR_MST_DECERR	BIT(26)
> +#define XILINX_PCIE_INTR_MST_SLVERR	BIT(27)
> +#define XILINX_PCIE_IMR_ALL_MASK	0x0FF30FE9
> +#define XILINX_PCIE_IDR_ALL_MASK	0xFFFFFFFF
> +#define XILINX_PCIE_IDRN_MASK           GENMASK(19, 16)
> +
> +/* Root Port Error FIFO Read Register definitions */
> +#define XILINX_PCIE_RPEFR_ERR_VALID	BIT(18)
> +#define XILINX_PCIE_RPEFR_REQ_ID	GENMASK(15, 0)
> +#define XILINX_PCIE_RPEFR_ALL_MASK	0xFFFFFFFF
> +
> +/* Root Port Interrupt FIFO Read Register 1 definitions */
> +#define XILINX_PCIE_RPIFR1_INTR_VALID	BIT(31)
> +#define XILINX_PCIE_RPIFR1_MSI_INTR	BIT(30)
> +#define XILINX_PCIE_RPIFR1_INTR_MASK	GENMASK(28, 27)
> +#define XILINX_PCIE_RPIFR1_ALL_MASK	0xFFFFFFFF
> +#define XILINX_PCIE_RPIFR1_INTR_SHIFT	27
> +#define XILINX_PCIE_IDRN_SHIFT          16
> +#define XILINX_PCIE_VSEC_REV_MASK	GENMASK(19, 16)
> +#define XILINX_PCIE_VSEC_REV_SHIFT	16
> +#define XILINX_PCIE_FIFO_SHIFT		5
> +
> +/* Bridge Info Register definitions */
> +#define XILINX_PCIE_BIR_ECAM_SZ_MASK	GENMASK(18, 16)
> +#define XILINX_PCIE_BIR_ECAM_SZ_SHIFT	16
> +
> +/* Root Port Interrupt FIFO Read Register 2 definitions */
> +#define XILINX_PCIE_RPIFR2_MSG_DATA	GENMASK(15, 0)
> +
> +/* Root Port Status/control Register definitions */
> +#define XILINX_PCIE_REG_RPSC_BEN	BIT(0)
> +
> +/* Phy Status/Control Register definitions */
> +#define XILINX_PCIE_REG_PSCR_LNKUP	BIT(11)
> +
> +/* ECAM definitions */
> +#define ECAM_BUS_NUM_SHIFT		20
> +#define ECAM_DEV_NUM_SHIFT		12
> +
> +/* Number of MSI IRQs */
> +#define XILINX_NUM_MSI_IRQS		64
> +#define INTX_NUM                        4
> +
> +#define DMA_BRIDGE_BASE_OFF		0xCD8
> +
> +
> +#define END_DEVICE_PATH_DEF { END_DEVICE_PATH_TYPE, \
> +                              END_ENTIRE_DEVICE_PATH_SUBTYPE, \
> +                              { END_DEVICE_PATH_LENGTH, 0 } \
> +                            }
> +
> +#define ACPI_DEVICE_PATH_DEF(UID) {{ ACPI_DEVICE_PATH, ACPI_DP, \
> +                                     { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
> +                                       (UINT8) (sizeof (ACPI_HID_DEVICE_PATH) >> 8)} \
> +                                     }, \
> +                                     EISA_PNP_ID (0x0A03), UID \
> +                                  }
> +
> +STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[] = {
> +  {
> +    ACPI_DEVICE_PATH_DEF (0),
> +    END_DEVICE_PATH_DEF
> +  },
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
> +  L"Mem", L"I/O", L"Bus"
> +};
> +
> +STATIC PCI_ROOT_BRIDGE mRootBridge = {
> +  0,                                              // Segment
> +  0,                                              // Supports
> +  0,                                              // Attributes
> +  FALSE,                                           // DmaAbove4G
> +  FALSE,                                          // NoExtendedConfigSpace
> +  FALSE,                                          // ResourceAssigned
> +  0,           // AllocationAttributes
> +  {
> +    // Bus
> +    FixedPcdGet32 (PcdPciBusMin),
> +    FixedPcdGet32 (PcdPciBusMax)
> +  }, {
> +    // Io
> +    FixedPcdGet64 (PcdPciIoBase),
> +    FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
> +  }, {
> +    // Mem
> +    FixedPcdGet32 (PcdPciMmio32Base),
> +    FixedPcdGet32 (PcdPciMmio32Base) + (FixedPcdGet32 (PcdPciMmio32Size) - 1)
> +    //0x7FFFFFFF
> +  }, {
> +    // MemAbove4G
> +    FixedPcdGet64 (PcdPciMmio64Base),
> +    FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1
> +  }, {
> +    // PMem
> +    MAX_UINT64,
> +    0
> +  }, {
> +    // PMemAbove4G
> +    MAX_UINT64,
> +    0
> +  },
> +  (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath
> +};
> +
> +/**
> +  Return all the root bridge instances in an array.
> +
> +  @param[out] Count  Return the count of root bridge instances.
> +
> +  @return All the root bridge instances in an array.
> +          The array should be passed into PciHostBridgeFreeRootBridges()
> +          when it's not used.
> +
> +**/
> +PCI_ROOT_BRIDGE *
> +EFIAPI
> +PciHostBridgeGetRootBridges (
> +  OUT UINTN     *Count
> +  )
> +{
> +  /* Enable the Bridge enable bit */
> +  UINT64 PciConfigBase = FixedPcdGet64 (PcdPciConfigBase);
> +  UINT32 Rpsc = MmioRead32 (PciConfigBase + XILINX_PCIE_REG_RPSC);
> +  MmioWrite32 (PciConfigBase + XILINX_PCIE_REG_RPSC, Rpsc | XILINX_PCIE_REG_RPSC_BEN);
> +  DEBUG ((DEBUG_INFO, "PciHostBridgeGetRootBridges():%d PciConfigBase:0x%x Rpsc:0x%x XILINX_PCIE_REG_RPSC_BEN:0x%x\n", \
> +              __LINE__, PciConfigBase, Rpsc, Rpsc | XILINX_PCIE_REG_RPSC_BEN));
> +
> +  *Count = 1;
> +  return &mRootBridge;
> +}
> +
> +
> +/**
> +  Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
> +
> +  @param[in] Bridges The root bridge instances array.
> +  @param[in] Count   The count of the array.
> +
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeRootBridges (
> +  IN PCI_ROOT_BRIDGE *Bridges,
> +  IN UINTN           Count
> +  )
> +{
> +
> +}
> +
> +
> +/**
> +  Inform the platform that the resource conflict happens.
> +
> +  @param[in] HostBridgeHandle Handle of the Host Bridge.
> +  @param[in] Configuration    Pointer to PCI I/O and PCI memory resource
> +                          descriptors. The Configuration contains the resources
> +                          for all the root bridges. The resource for each root
> +                          bridge is terminated with END descriptor and an
> +                          additional END is appended indicating the end of the
> +                          entire resources. The resource descriptor field
> +                          values follow the description in
> +                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +                          SubmitResources().
> +
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeResourceConflict (
> +  IN EFI_HANDLE                        HostBridgeHandle,
> +  IN VOID                              *Configuration
> +  )
> +{
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
> +  BOOLEAN IsPrefetchable;
> +
> +  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
> +  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> +    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
> +      ASSERT (Descriptor->ResType <
> +              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr));
> +      DEBUG ((DEBUG_INFO, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
> +              mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
> +              Descriptor->AddrLen,
> +              Descriptor->AddrRangeMax
> +              ));
> +      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
> +
> +        IsPrefetchable = (Descriptor->SpecificFlag &
> +          EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0;
> +
> +        DEBUG ((DEBUG_INFO, "     Granularity/SpecificFlag = %ld / %02x%s\n",
> +          Descriptor->AddrSpaceGranularity,
> +          Descriptor->SpecificFlag,
> +          (IsPrefetchable) ? L" (Prefetchable)" : L""
> +          ));
> +      }
> +    }
> +    //
> +    // Skip the end descriptor for root bridge
> +    //
> +    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
> +    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (
> +                   (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
> +                   );
> +  }
> +}
> diff --git a/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 0000000000..1620936736
> --- /dev/null
> +++ b/Silicon/Bosc/NanHuPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> @@ -0,0 +1,48 @@
> +#/** @file
> +#  PCI Host Bridge Library instance for Bosc SOC.
> +#
> +#  Copyright (C) 2020, Bosc Technology Co, Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2024, Bosc. All rights reserved.<BR>ved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001b
> +  BASE_NAME                      = PciHostBridgeLib
> +  FILE_GUID                      = 7F418E45-0127-454E-9CBB-F5FCF237E383
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PciHostBridgeLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build
> +# tools.
> +#
> +#  VALID_ARCHITECTURES           = RISCV64
> +#
> +
> +[Sources]
> +  PciHostBridgeLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +
> +[Guids]
> +
> +[FixedPcd]
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMin
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMax
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoBase
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoSize
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Base
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Size
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Base
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Size
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigBase
> diff --git a/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c
> new file mode 100755
> index 0000000000..8e463fcc79
> --- /dev/null
> +++ b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.c
> @@ -0,0 +1,1391 @@
> +/** @file
> +  PCI Segment Library for SoC with multiple RCs.
> +
> +  Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.<BR>
> +  Copyright (c) 2024, Bosc. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +
> +#define PCI_SEG_CONFIG_BASE       0x40000000
> +
> +typedef enum {
> +  PciCfgWidthUint8 = 0,
> +  PciCfgWidthUint16,
> +  PciCfgWidthUint32,
> +  PciCfgWidthMax
> +} PCI_CFG_WIDTH;
> +
> +/**
> +  Assert the validity of a PCI Segment address.
> +  A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
> +
> +  @param[in]  A The address to validate.
> +  @param[in]  M Additional bits to assert to be zero.
> +
> +**/
> +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> +ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> +
> +
> +#define EXTRACT_PCIE_ADDRESS(Address, Bus, Device, Function) \
> +{ \
> +  (Bus)      = (((Address) >> 20) & 0xff);   \
> +  (Device)   = (((Address) >> 15) & 0x1f);   \
> +  (Function) = (((Address) >> 12) & 0x07);   \
> +}
> +
> +
> +/**
> +  This function  geted the config base of PCI device.
> +  @param[in]  Address  The address that encodes the PCI Bus, Device, Function and
> +                       Register.
> +
> +  @return The value of the config base of PCI device.
> +
> +**/
> +STATIC
> +UINT64
> +PciSegmentLibGetConfigBase (
> +  IN  UINT64      Address
> +  )
> +{
> +  UINT8 Bus;
> +  UINT8 Device;
> +  UINT8 Function;
> +
> +  EXTRACT_PCIE_ADDRESS (Address, Bus, Device, Function);
> +  if ((Bus == 1) || (Bus == 2) || (Bus == 3) || (Bus == 4)) {
> +    return PCI_SEG_CONFIG_BASE;
> +  }
> +
> +  return PCI_SEG_CONFIG_BASE;
> +}
> +
> +/**
> +  Internal worker function to read a PCI configuration register.
> +
> +  @param[in]  Address The address that encodes the PCI Bus, Device, Function and
> +                      Register.
> +  @param[in]  Width   The width of data to read
> +
> +  @return The value read from the PCI configuration register.
> +
> +**/
> +STATIC
> +UINT32
> +PciSegmentLibReadWorker (
> +  IN  UINT64                      Address,
> +  IN  PCI_CFG_WIDTH               Width
> +  )
> +{
> +  UINT64    Base;
> +
> +  Base = PciSegmentLibGetConfigBase (Address);
> +  if (Base == 0xFFFFFFFF) {
> +    return 0xFFFFFFFF;
> +  }
> +
> +  switch (Width) {
> +  case PciCfgWidthUint8:
> +    return MmioRead8 (Base + (UINT32)Address);
> +  case PciCfgWidthUint16:
> +    return MmioRead16 (Base + (UINT32)Address);
> +  case PciCfgWidthUint32:
> +    return MmioRead32 (Base + (UINT32)Address);
> +  default:
> +    ASSERT (FALSE);
> +  }
> +
> +  return 0;
> +}
> +
> +
> +/**
> +  Internal worker function to writes a PCI configuration register.
> +
> +  @param[in]  Address The address that encodes the PCI Bus, Device, Function and
> +                  Register.
> +  @param[in]  Width   The width of data to write
> +  @param[in]  Data    The value to write.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +STATIC
> +UINT32
> +PciSegmentLibWriteWorker (
> +  IN  UINT64                      Address,
> +  IN  PCI_CFG_WIDTH               Width,
> +  IN  UINT32                      Data
> +  )
> +{
> +  UINT64    Base;
> +
> +  Base = PciSegmentLibGetConfigBase (Address);
> +  if (Base == 0xFFFFFFFF) {
> +    return 0xFFFFFFFF;
> +  }
> +
> +  switch (Width) {
> +  case PciCfgWidthUint8:
> +    MmioWrite8 (Base + (UINT32)Address, Data);
> +    break;
> +  case PciCfgWidthUint16:
> +    MmioWrite16 (Base + (UINT32)Address, Data);
> +    break;
> +  case PciCfgWidthUint32:
> +    MmioWrite32 (Base + (UINT32)Address, Data);
> +    break;
> +  default:
> +    ASSERT (FALSE);
> +  }
> +
> +  return Data;
> +}
> +
> +/**
> +  Register a PCI device so PCI configuration registers may be accessed after
> +  SetVirtualAddressMap().
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +
> +  @param[in]      Address          The address that encodes the PCI Bus, Device, Function and
> +                                   Register.
> +
> +  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.
> +  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
> +                                   after ExitBootServices().
> +  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device
> +                                   at runtime could not be mapped.
> +  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to
> +                                   complete the registration.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +PciSegmentRegisterForRuntimeAccess (
> +  IN UINTN  Address
> +  )
> +{
> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> +
> +  return RETURN_UNSUPPORTED;
> +}
> +
> +/**
> +  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[in]  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 (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);
> +}
> +
> +/**
> +  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[in]  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  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 (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  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 PciSegmentWrite8 (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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  AndData    The value to AND with the PCI configuration register.
> +  @param[in]  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 bit field of a PCI configuration register.
> +
> +  Reads the bit field in an 8-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to read.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..7.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldRead8 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit
> +  )
> +{
> +  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  8-bit register is returned.
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldWrite8 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT8                     Value
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 8-bit port.
> +
> +  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. Extra left bits in OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldOr8 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT8                     OrData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 8-bit register.
> +
> +  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. Extra left bits in AndData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldAnd8 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT8                     AndData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  8-bit port.
> +
> +  Reads the 8-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR 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. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..7.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +  @param[in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciSegmentBitFieldAndThenOr8 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT8                     AndData,
> +  IN UINT8                     OrData
> +  )
> +{
> +  return PciSegmentWrite8 (
> +           Address,
> +           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, 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[in]  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 (UINT16) PciSegmentLibReadWorker (Address, PciCfgWidthUint16);
> +}
> +
> +/**
> +  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[in]  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  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 (UINT16) PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, 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[in]  Address The address that encodes the PCI Segment, Bus, Device, Function and
> +                  Register.
> +  @param[in]  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.
> +
> +  Reads the 16-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 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentAnd16 (
> +  IN UINT64                    Address,
> +  IN UINT16                    AndData
> +  )
> +{
> +  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));
> +}
> +
> +/**
> +  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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +  @param[in]  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 bit field of a PCI configuration register.
> +
> +  Reads the bit field in a 16-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is
> +  returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to read.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..15.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldRead16 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit
> +  )
> +{
> +  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  16-bit register is returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldWrite16 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT16                    Value
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, 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.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldOr16 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT16                    OrData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
> +  and writes the result back to the bit field in the 16-bit port.
> +
> +  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.
> +  Extra left bits in OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> +  If StartBit is greater than 7, then ASSERT().
> +  If EndBit is greater than 7, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    The ordinal of the least significant bit in a byte is bit 0.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    The ordinal of the most significant bit in a byte is bit 7.
> +  @param[in]  AndData   The value to AND with the read value from the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldAnd16 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT16                    AndData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  16-bit port.
> +
> +  Reads the 16-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, 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. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 15, then ASSERT().
> +  If EndBit is greater than 15, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..15.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +  @param[in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciSegmentBitFieldAndThenOr16 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT16                    AndData,
> +  IN UINT16                    OrData
> +  )
> +{
> +  return PciSegmentWrite16 (
> +           Address,
> +           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, 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[in]  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 PciSegmentLibReadWorker (Address, PciCfgWidthUint32);
> +}
> +
> +/**
> +  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[in]  Address     The address that encodes the PCI Segment, Bus, Device,
> +                      Function, and Register.
> +  @param[in]  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 PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
> +  @param[in]  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.
> +
> +  Reads the 32-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 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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function,
> +                    and Register.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentAnd32 (
> +  IN UINT64                    Address,
> +  IN UINT32                    AndData
> +  )
> +{
> +  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);
> +}
> +
> +/**
> +  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[in]  Address   The address that encodes the PCI Segment, Bus, Device, Function,
> +                    and Register.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +  @param[in]  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 bit field of a PCI configuration register.
> +
> +  Reads the bit field in a 32-bit PCI configuration register. The bit field is
> +  specified by the StartBit and the EndBit. The value of the bit field is returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to read.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..31.
> +
> +  @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldRead32 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit
> +  )
> +{
> +  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);
> +}
> +
> +/**
> +  Writes a bit field to a PCI configuration register.
> +
> +  Writes Value to the bit field of the PCI configuration register. The bit
> +  field is specified by the StartBit and the EndBit. All other bits in the
> +  destination PCI configuration register are preserved. The new value of the
> +  32-bit register is returned.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  Value     The new value of the bit field.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldWrite32 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT32                    Value
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
> +  writes the result back to the bit field in the 32-bit port.
> +
> +  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. Extra left bits in OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  OrData    The value to OR with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldOr32 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT32                    OrData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
> +  AND, and writes the result back to the bit field in the 32-bit register.
> +
> +
> +  Reads the 32-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 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.  Extra left bits in AndData are stripped.
> +  If any reserved bits in Address are set, then ASSERT().
> +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldAnd32 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT32                    AndData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)
> +           );
> +}
> +
> +/**
> +  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
> +  bitwise OR, and writes the result back to the bit field in the
> +  32-bit port.
> +
> +  Reads the 32-bit PCI configuration register specified by Address, performs a
> +  bitwise AND followed by a bitwise OR between the read result and
> +  the value specified by AndData, 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. Extra left bits in both AndData and
> +  OrData are stripped.
> +
> +  If any reserved bits in Address are set, then ASSERT().
> +  If StartBit is greater than 31, then ASSERT().
> +  If EndBit is greater than 31, then ASSERT().
> +  If EndBit is less than StartBit, then ASSERT().
> +  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
> +
> +  @param[in]  Address   The PCI configuration register to write.
> +  @param[in]  StartBit  The ordinal of the least significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  EndBit    The ordinal of the most significant bit in the bit field.
> +                    Range 0..31.
> +  @param[in]  AndData   The value to AND with the PCI configuration register.
> +  @param[in]  OrData    The value to OR with the result of the AND operation.
> +
> +  @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciSegmentBitFieldAndThenOr32 (
> +  IN UINT64                    Address,
> +  IN UINTN                     StartBit,
> +  IN UINTN                     EndBit,
> +  IN UINT32                    AndData,
> +  IN UINT32                    OrData
> +  )
> +{
> +  return PciSegmentWrite32 (
> +           Address,
> +           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, 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[in]  StartAddress  The starting address that encodes the PCI Segment, Bus,
> +                        Device, Function and Register.
> +  @param[in]  Size          The size in bytes of the transfer.
> +  @param[in]  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);
> +
> +  //
> +  // Save Size for return
> +  //
> +  ReturnValue = Size;
> +
> +  if ((StartAddress & BIT0) != 0) {
> +    //
> +    // Read a byte if StartAddress is byte aligned,
> +    //
> +    MmioWrite8 ((UINTN)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
> +    //
> +    MmioWrite8 ((UINTN)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[in]  StartAddress  The starting address that encodes the PCI Segment, Bus,
> +                        Device, Function and Register.
> +  @param[in]  Size          The size in bytes of the transfer.
> +  @param[in]  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);
> +
> +  //
> +  // 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/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
> new file mode 100755
> index 0000000000..29d1758410
> --- /dev/null
> +++ b/Silicon/Bosc/NanHuPkg/Library/PciSegmentLib/PciSegmentLib.inf
> @@ -0,0 +1,29 @@
> +#/** @file
> +#  PCI Segment Library for Bosc NanHuDev platform with Xilinx XDMA RCs.
> +#
> +#  Copyright (C) 2020, Phytium Technology Co, Ltd. All rights reser
> +#  Copyright (c) 2024, Bosc. All rights reserved.<BR>ved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001b
> +  BASE_NAME                      = PciSegmentLib
> +  FILE_GUID                      = B0DD53D5-30C6-48CB-849D-BEB935B57D78
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PciSegmentLib
> +
> +[Sources]
> +  PciSegmentLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  IoLib
> diff --git a/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec b/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
> index e975ae42d0..9f553a5b0a 100644
> --- a/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
> +++ b/Silicon/Bosc/NanHuPkg/NanHuDevPkg.dec
> @@ -20,6 +20,7 @@
>  [Protocols]
>  
>  [Guids]
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid  = { 0x245C5C80, 0x7945, 0x43BE, { 0xB4, 0x01, 0xC9, 0x92, 0x8A, 0x13, 0xDD, 0x0A }}
>  
>  [PcdsFixedAtBuild]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x0|UINT64|0x00001004
> @@ -27,5 +28,24 @@
>    gHisiTokenSpaceGuid.PcdSerialPortSendDelay|0x0|UINT32|0x00001006
>    gHisiTokenSpaceGuid.PcdUartClkInHz|0x0|UINT32|0x00001007
>  
> +  #
> +  # PCI configuration address space
> +  #
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigBase|0x0|UINT64|0x00000008
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciConfigSize|0x0|UINT64|0x00000009
> +
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x0000000a
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x0000000b
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT32|0x0000000c
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT32|0x0000000d
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x0000000e
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x0000000f
> +
> +  #
> +  # Inclusive range of allowed PCI buses.
> +  #
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMin|0x0|UINT32|0x00000010
> +  gBoscNanHuDdevPlatformPkgTokenSpaceGuid.PcdPciBusMax|0x0|UINT32|0x00000011
> +
>  [UserExtensions.TianoCore."ExtraFiles"]
>    NanHuPkgExtra.uni
> -- 
> 2.34.1
> 
> 
> 
> 
> 


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



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver
  2024-05-15  7:40 ` [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver WangYang
@ 2024-05-15  8:36   ` Ni, Ray
  2024-05-16  2:54     ` WangYang
  0 siblings, 1 reply; 5+ messages in thread
From: Ni, Ray @ 2024-05-15  8:36 UTC (permalink / raw)
  To: devel@edk2.groups.io, wangyang@bosc.ac.cn
  Cc: sunilvl@ventanamicro.com, git@danielschaefer.me, Ran Wang,
	Leif Lindholm, Kinney, Michael D

[-- Attachment #1: Type: text/plain, Size: 915 bytes --]

  1.  The patch is too big. Can you split it to multiple smaller patches?

> +STATIC
> +UINT64
> +PciSegmentLibGetConfigBase (
> +  IN  UINT64      Address
> +  )
> +{
> +  UINT8 Bus;
> +  UINT8 Device;
> +  UINT8 Function;
> +
> +  EXTRACT_PCIE_ADDRESS (Address, Bus, Device, Function);
> +  if ((Bus == 1) || (Bus == 2) || (Bus == 3) || (Bus == 4)) {
> +    return PCI_SEG_CONFIG_BASE;
> +  }
> +
> +  return PCI_SEG_CONFIG_BASE;


  1.
Both paths return the same PCI_SEG_CONFIG_BASE. Then why do you check the Bus number?



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



[-- Attachment #2: Type: text/html, Size: 6467 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver
  2024-05-15  8:36   ` Ni, Ray
@ 2024-05-16  2:54     ` WangYang
  2024-05-17  2:41       ` suijingfeng
  0 siblings, 1 reply; 5+ messages in thread
From: WangYang @ 2024-05-16  2:54 UTC (permalink / raw)
  To: Ni, Ray
  Cc: devel@edk2.groups.io, sunilvl@ventanamicro.com,
	git@danielschaefer.me, Ran Wang, Leif Lindholm, Kinney, Michael D

[-- Attachment #1: Type: text/plain, Size: 1773 bytes --]

Hi,Ray

   Thank you very much for your attention.



-----原始邮件-----
发件人:"Ni, Ray" <ray.ni@intel.com>
发送时间:2024-05-15 16:36:02 (星期三)
收件人: "devel@edk2.groups.io" <devel@edk2.groups.io>, "wangyang@bosc.ac.cn" <wangyang@bosc.ac.cn>
抄送: "sunilvl@ventanamicro.com" <sunilvl@ventanamicro.com>, "git@danielschaefer.me" <git@danielschaefer.me>, "Ran Wang" <wangran@bosc.ac.cn>, "Leif Lindholm" <quic_llindhol@quicinc.com>, "Kinney, Michael D" <michael.d.kinney@intel.com>
主题: Re: [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver



The patch is too big. Can you split it to multiple smaller patches?

        

        As you said, this patch is indeed a bit big.  The main reference is file “./Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.c” .




> +STATIC
> +UINT64
> +PciSegmentLibGetConfigBase (
> +  IN  UINT64      Address
> +  )

> +{







> +  UINT8 Bus;
> +  UINT8 Device;
> +  UINT8 Function;
> +
> +  EXTRACT_PCIE_ADDRESS (Address, Bus, Device, Function);
> +  if ((Bus == 1) || (Bus == 2) || (Bus == 3) || (Bus == 4)) {
> +    return PCI_SEG_CONFIG_BASE;
> +  }

> +




This part of the code is redundant and should be deleted​

> +  return PCI_SEG_CONFIG_BASE;


Both paths return the same PCI_SEG_CONFIG_BASE. Then why do you check the Bus number?
This part of the code is redundant and should be deleted.​


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



[-- Attachment #2: Type: text/html, Size: 8521 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver
  2024-05-16  2:54     ` WangYang
@ 2024-05-17  2:41       ` suijingfeng
  0 siblings, 0 replies; 5+ messages in thread
From: suijingfeng @ 2024-05-17  2:41 UTC (permalink / raw)
  To: WangYang, devel

On Thu, May 16, 2024 at 10:54 AM, WangYang wrote:

Hi,

>
> Hi,Ray
> 
> Thank you very much for your attention.
>

The reviewer Ray told you that  you patch has some small problems, 
For example, the clause "if ((Bus == 1) || (Bus == 2) || (Bus == 3) || (Bus == 4)) "  is useless.
As both code path returns same value. 

You should solve this small problems, also cut this big patch into smaller pieces as smaller patch is easier to review.
and when all problem solved, you should send the updated patch as V2. Since this version is V1 as far as I know.





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



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-05-17 17:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <17C6FF8EBB82206B.20815@groups.io>
2024-05-15  7:40 ` [edk2-devel] [PATCH] XiangshanSeriesPkg:Add Support for Xilinx RC(PCIE) Driver WangYang
2024-05-15  8:36   ` Ni, Ray
2024-05-16  2:54     ` WangYang
2024-05-17  2:41       ` suijingfeng
2024-04-17  7:08 WangYang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox