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 <wangy...@bosc.ac.cn> > 发送时间: 2024-04-17 15:08:06 (星期三) > 收件人: suni...@ventanamicro.com, g...@danielschaefer.me, devel@edk2.groups.io > 抄送: "Yang Wang" <wangy...@bosc.ac.cn>, "Ran Wang" <wang...@bosc.ac.cn>, "Leif > Lindholm" <quic_llind...@quicinc.com>, "Michael D Kinney" > <michael.d.kin...@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 <wang...@bosc.ac.cn> > Cc: Leif Lindholm <quic_llind...@quicinc.com> > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Sunil V L <suni...@ventanamicro.com> > Cc: Daniel Schaefer <g...@danielschaefer.me> > Signed-off-by: Yang Wang <wangy...@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/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-