* [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver
@ 2017-12-21 18:48 Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary Vabhav
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Vabhav @ 2017-12-21 18:48 UTC (permalink / raw)
To: ard.biesheuvel, leif.lindholm, michael.d.kinney, edk2-devel
Following patches will add support of NXP PCI Host Bridge Driver in edk2-platforms directory 'edk2-platforms/Platform/NXP'
Updated Directory structure for added folders in 'edk2-platforms/Platform/NXP' will be:
Platform/NXP/Drivers/PciHostBridgeDxe/
|-- PciHostBridgeDxe.c
|-- PciHostBridgeDxe.inf
`-- PciRootBridgeIo.c
Platform/NXP/Library/PciHostBridgeLib/
|-- PciCntrl.c
|-- PciHostBridgeLib.inf
`-- PciRbLib.c
In Platform/NXP/Library
PciHostBridgeLib librady is added
In Platform/NXP/Drivers:
PciHostBridgeDxe driver is added
Please review and look forward for your support in upstreaming the patches in edk2-platforms.
Vabhav (3):
Platform/NXP : Add PCI Host Bridge Libary
Platform/NXP : Add PCI Host Bridge Driver
Compilation:Modify dsc,fdf files
.../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c | 967 ++++++++++++++++
.../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 61 +
.../NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 1193 ++++++++++++++++++++
Platform/NXP/Include/PciCntrlLib.h | 323 ++++++
Platform/NXP/Include/PciHostBridge.h | 466 ++++++++
Platform/NXP/Include/PciLib.h | 414 +++++++
Platform/NXP/Include/PciRootBridge.h | 674 +++++++++++
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 31 +
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 6 +
Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 +
Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 ++++++
Silicon/NXP/Chassis/Chassis.c | 11 +
Silicon/NXP/Chassis/Chassis2/SerDes.h | 11 +
Silicon/NXP/LS1043A/LS1043A.dsc | 1 +
15 files changed, 5166 insertions(+)
create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
create mode 100644 Platform/NXP/Include/PciCntrlLib.h
create mode 100644 Platform/NXP/Include/PciHostBridge.h
create mode 100644 Platform/NXP/Include/PciLib.h
create mode 100644 Platform/NXP/Include/PciRootBridge.h
create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary
2017-12-21 18:48 [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Vabhav
@ 2017-12-21 18:48 ` Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 2/3] Platform/NXP : Add PCI Host Bridge Driver Vabhav
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Vabhav @ 2017-12-21 18:48 UTC (permalink / raw)
To: ard.biesheuvel, leif.lindholm, michael.d.kinney, edk2-devel
Added PCIe Host Bridge Library to provide helper
functions which will be used by PCIe Host bridge Dxe
Driver
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Vabhav <vabhav.sharma@nxp.com>
---
Platform/NXP/Include/PciCntrlLib.h | 323 +++++++++++
Platform/NXP/Include/PciLib.h | 414 ++++++++++++++
Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++++++++++++
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 ++
Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 +++++++++++
5 files changed, 1745 insertions(+)
create mode 100644 Platform/NXP/Include/PciCntrlLib.h
create mode 100644 Platform/NXP/Include/PciLib.h
create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
diff --git a/Platform/NXP/Include/PciCntrlLib.h b/Platform/NXP/Include/PciCntrlLib.h
new file mode 100644
index 0000000..c8001d9
--- /dev/null
+++ b/Platform/NXP/Include/PciCntrlLib.h
@@ -0,0 +1,323 @@
+/** PciCntrlLib.c
+ The Header file of the Pci Controller Driver
+
+ Some part of code is inspired from EDK II, file:
+ MdePkg/Include/Library/PciLib.h
+
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI_CNTRL_H_
+#define _PCI_CNTRL_H_
+
+#include <PciRootBridge.h>
+#include <PciLib.h>
+
+#define SDRAM_BASE 0x80000000
+
+// LUT registers
+#define LS_PCIE_LUT_BASE PcdGet64 (PcdPcieLutBase)
+#define LS_PCIE_LUT_DBG PcdGet64 (PcdPcieLutDbg)
+#define PCIE_LUT_UDR(n) (0x800 + (n) * 8)
+#define PCIE_LUT_LDR(n) (0x804 + (n) * 8)
+#define PCIE_LUT_ENABLE (1 << 31)
+
+#ifndef LS_PCI_MEMORY_BUS
+#define LS_PCI_MEMORY_BUS SDRAM_BASE
+#endif
+
+#ifndef LS_PCI_MEMORY_PHYS
+#define LS_PCI_MEMORY_PHYS SDRAM_BASE
+#endif
+
+#ifndef LS_PCI_MEMORY_SIZE
+#define LS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL)
+#endif
+
+/* iATU registers */
+#define LS_PCIE_ATU_VIEWPORT 0x900
+#define LS_PCIE_ATU_REGION_INBOUND (0x1 << 31)
+#define LS_PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
+#define LS_PCIE_ATU_REGION_INDEX0 (0x0 << 0)
+#define LS_PCIE_ATU_REGION_INDEX1 (0x1 << 0)
+#define LS_PCIE_ATU_REGION_INDEX2 (0x2 << 0)
+#define LS_PCIE_ATU_REGION_INDEX3 (0x3 << 0)
+#define LS_PCIE_ATU_REGION_INDEX4 (0x4 << 0)
+#define LS_PCIE_ATU_CR1 0x904
+#define LS_PCIE_ATU_TYPE_MEM (0x0 << 0)
+#define LS_PCIE_ATU_TYPE_IO (0x2 << 0)
+#define LS_PCIE_ATU_TYPE_CFG0 (0x4 << 0)
+#define LS_PCIE_ATU_TYPE_CFG1 (0x5 << 0)
+#define LS_PCIE_ATU_CR2 0x908
+#define LS_PCIE_ATU_ENABLE (0x1 << 31)
+#define LS_PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
+#define LS_PCIE_ATU_LOWER_BASE 0x90C
+#define LS_PCIE_ATU_UPPER_BASE 0x910
+#define LS_PCIE_ATU_LIMIT 0x914
+#define LS_PCIE_ATU_LOWER_TARGET 0x918
+#define LS_PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
+#define LS_PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
+#define LS_PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
+#define LS_PCIE_ATU_UPPER_TARGET 0x91C
+
+/** DBI Read-Only Write Enable Register: Pg 1518 RM rev B
+ Set bit 0 of this register as 1.
+ Write to RO Registers Using DBI.
+ When you set this field to "1", then some RO and HwInit bits are writable
+ from the local application through the DBI.
+ **/
+#define LS_PCIE_DBI_RO_WR_EN 0x8bc
+
+#define LS_PCIE_LINK_CAP 0x7c
+#define LS_PCIE_LINK_SPEED_MASK 0xf
+#define LS_PCIE_LINK_STA 0x82
+
+#define LS_LTSSM_STATE_MASK 0x3f
+#define LS_LTSSM_PCIE_L0 0x11 // L0 state
+
+#define LS_PCIE_DBI_SIZE 0x100000 // 1M
+
+#define PCI_CLASS_REVISION 0x08 // High 24 bits are class,low 8 revision
+#define PCI_REVISION_ID 0x08 // Revision ID
+#define PCI_CLASS_PROG 0x09 // Reg. Level Programming Interface
+#define PCI_CLASS_DEVICE 0x0a // Device class
+#define PCI_CLASS_CODE 0x0b // Device class code
+#define PCI_CLASS_BRIDGE_PCI 0x0604
+
+/**
+ Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an
+ address that can be passed to the PCI Library functions.
+
+ @param Bus PCI Bus number. Range 0..255.
+ @param Device PCI Device number. Range 0..31.
+ @param Function PCI Function number. Range 0..7.
+ @param Register PCI Register number. Range 0..255 for PCI. Range 0..4095
+ for PCI Express.
+
+ @return The encoded PCI address.
+ **/
+#define PCI_LIB_ADDRESS(Bus,Device,Function,Register) \
+ (((Register) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))
+
+#define PCI_BUS_DEV(Bus,Device,Function) \
+ ((((Function) & 0x07) << 16) | (((Device) & 0x1f) << 19) | (((Bus) & 0xff) << 24))
+
+/**
+ Function to set-up PCIe region
+**/
+VOID
+PciSetRegion (
+ IN PciRegion *Reg,
+ IN PciAddrT BusStart,
+ IN PhysAddrT PhysStart,
+ IN PciSizeT Size,
+ IN UINTN Flags
+);
+
+/**
+ Function to setup PCIe space(Mem,I/O,Configuration)
+**/
+VOID
+SetLSPcieInfo (
+ IN LsPcieInfo *PcieInfo,
+ IN UINTN Num
+);
+
+/**
+ Function to check PCIe link state
+**/
+INTN
+PcieLinkState (
+ IN LsPcie *Pcie
+);
+
+/**
+ Helper Function to check PCIe link state
+ Downgrade the speed to gen1
+**/
+INTN
+PcieLinkUp (
+ IN LsPcie *pcie
+);
+
+/**
+ Function to set up PCIe (cfg0)configuration space
+**/
+VOID
+PcieCfg0SetBusdev (
+ IN LsPcie *Pcie,
+ IN UINT32 BusDev
+);
+
+/**
+ Function to set up PCIe (cfg1)configuration space
+**/
+VOID
+PcieCfg1SetBusdev (
+ IN LsPcie *Pcie,
+ IN UINT32 BusDev
+);
+
+/**
+ Function to set up iATU for outbound PCIe transactions
+**/
+VOID
+PcieIatuOutboundSet (
+ IN LsPcie *Pcie,
+ IN UINT32 Idx,
+ IN UINT32 Type,
+ IN UINT64 Phys,
+ IN UINT64 BusAddr,
+ IN UINT64 Size
+);
+
+EFI_STATUS
+PciSkipDev (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev
+);
+
+/**
+ Function to verify if PCIe address space is valid
+**/
+EFI_STATUS
+PcieAddrValid (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev
+);
+
+/**
+ Function to read value(32-bit) from PCI space
+**/
+EFI_STATUS
+PcieReadConfig (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Where,
+ IN OUT UINT32 *Val
+);
+
+/**
+ Function to read byte from PCI space
+**/
+EFI_STATUS
+PcieReadConfigByte (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ IN OUT UINT8 *Val
+);
+
+/**
+ Function to read word from PCI space
+**/
+EFI_STATUS
+PcieReadConfigWord (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ IN OUT UINT16 *Val
+);
+
+/**
+ Function to write byte in PCI space
+**/
+EFI_STATUS
+PcieWriteConfigByte (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ OUT UINT8 Val
+);
+
+/**
+ Function to write word in PCI space
+**/
+EFI_STATUS
+PcieWriteConfigWord (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ OUT UINT16 Val
+);
+
+/**
+ Function to write value(32-bit) in PCI space
+**/
+EFI_STATUS
+PcieWriteConfig (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Where,
+ IN UINT32 Val
+);
+
+/**
+ Function for setting up internal Address translation unit(ATU)
+**/
+VOID
+PcieSetupAtu (
+ IN LsPcie *Pcie,
+ IN LsPcieInfo *Info
+);
+
+/**
+ Function for setting up PCI controller
+**/
+VOID
+PcieSetupCntrl (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN LsPcie *Pcie,
+ IN LsPcieInfo *Info
+);
+
+/**
+ Internal Helper function for read and write memory space
+**/
+EFI_STATUS
+RootBridgeIoMemRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+/**
+ Internal Helper function for read and write PCI IO space
+**/
+EFI_STATUS
+RootBridgeIoIoRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+/**
+ Internal Helper function for read and write PCI configuration space
+**/
+EFI_STATUS
+RootBridgeIoPciRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+#endif
diff --git a/Platform/NXP/Include/PciLib.h b/Platform/NXP/Include/PciLib.h
new file mode 100644
index 0000000..873f0e7
--- /dev/null
+++ b/Platform/NXP/Include/PciLib.h
@@ -0,0 +1,414 @@
+/** PciLib.h
+ Pci Library containing Defines for Pci Controller configuration etc
+
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PCI_LIB_H__
+#define __PCI_LIB_H__
+
+/*
+ In PCI, devices have 256 bytes of configuration address space,
+ of which the first 64 bytes are standardized as follows:
+ **/
+#define LS_PCI_VENDOR_ID 0x00 // 16 bits
+#define LS_PCI_DEVICE_ID 0x02 // 16 bits
+#define LS_PCI_COMMAND 0x04 // 16 bits
+#define LS_PCI_COMMAND_IO 0x1 // Enable response in I/O space
+#define LS_PCI_COMMAND_MEMORY 0x2 // Enable response in Memory space
+#define LS_PCI_COMMAND_MASTER 0x4 // Enable bus mastering
+#define LS_PCI_COMMAND_SPECIAL 0x8 // Enable response to special cycles
+#define LS_PCI_COMMAND_INVALIDATE 0x10 // Use memory write and invalidate
+#define LS_PCI_COMMAND_VGA_PALETTE 0x20 // Enable palette snooping
+#define LS_PCI_COMMAND_PARITY 0x40 // Enable parity checking
+#define LS_PCI_COMMAND_WAIT 0x80 // Enable address/data stepping
+#define LS_PCI_COMMAND_SERR 0x100 // Enable SERR
+#define LS_PCI_COMMAND_FAST_BACK 0x200
+
+#define LS_PCI_STATUS 0x06 // 16 bits
+#define LS_PCI_STATUS_CAP_LIST 0x10 // Support Capability List
+#define LS_PCI_STATUS_66MHZ 0x20
+#define LS_PCI_STATUS_UDF 0x40
+#define LS_PCI_STATUS_FAST_BACK 0x80
+#define LS_PCI_STATUS_PARITY 0x100
+#define LS_PCI_STATUS_DEVSEL_MASK 0x600
+#define LS_PCI_STATUS_DEVSEL_FAST 0x000
+#define LS_PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define LS_PCI_STATUS_DEVSEL_SLOW 0x400
+#define LS_PCI_STATUS_SIG_TARGET_ABORT 0x800
+#define LS_PCI_STATUS_REC_TARGET_ABORT 0x1000
+#define LS_PCI_STATUS_REC_MASTER_ABORT 0x2000
+#define LS_PCI_STATUS_SIG_SYSTEM_ERROR 0x4000
+#define LS_PCI_STATUS_DETECTED_PARITY 0x8000
+
+#define LS_PCI_CLASS_REVISION 0x08
+#define LS_PCI_REVISION_ID 0x08 // Revision ID
+#define LS_PCI_CLASS_PROG 0x09
+#define LS_PCI_CLASS_DEVICE 0x0a // Device class
+#define LS_PCI_CLASS_CODE 0x0b // Device class code
+#define LS_PCI_CLASS_CODE_TOO_OLD 0x00
+#define LS_PCI_CLASS_CODE_STORAGE 0x01
+#define LS_PCI_CLASS_CODE_NETWORK 0x02
+#define LS_PCI_CLASS_CODE_DISPLAY 0x03
+#define LS_PCI_CLASS_CODE_MULTIMEDIA 0x04
+#define LS_PCI_CLASS_CODE_MEMORY 0x05
+#define LS_PCI_CLASS_CODE_BRIDGE 0x06
+#define LS_PCI_CLASS_CODE_COMM 0x07
+#define LS_PCI_CLASS_CODE_PERIPHERAL 0x08
+#define LS_PCI_CLASS_CODE_INPUT 0x09
+#define LS_PCI_CLASS_CODE_DOCKING 0x0A
+#define LS_PCI_CLASS_CODE_PROCESSOR 0x0B
+#define LS_PCI_CLASS_CODE_SERIAL 0x0C
+#define LS_PCI_CLASS_CODE_WIRELESS 0x0D
+#define LS_PCI_CLASS_CODE_I2O 0x0E
+#define LS_PCI_CLASS_CODE_SATELLITE 0x0F
+#define LS_PCI_CLASS_CODE_CRYPTO 0x10
+#define LS_PCI_CLASS_CODE_DATA 0x11
+// Base Class 0x12 - 0xFE is reserved
+#define LS_PCI_CLASS_CODE_OTHER 0xFF
+
+#define LS_PCI_CLASS_SUB_CODE 0x0a // Device sub-class code
+#define LS_PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA 0x00
+#define LS_PCI_CLASS_SUB_CODE_TOO_OLD_VGA 0x01
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_SCSI 0x00
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_IDE 0x01
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_FLOPPY 0x02
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_IPIBUS 0x03
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_RAID 0x04
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_ATA 0x05
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_SATA 0x06
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_SAS 0x07
+#define LS_PCI_CLASS_SUB_CODE_STORAGE_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_ETHERNET 0x00
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_TOKENRING 0x01
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_FDDI 0x02
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_ATM 0x03
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_ISDN 0x04
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP 0x05
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_PICMG 0x06
+#define LS_PCI_CLASS_SUB_CODE_NETWORK_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_DISPLAY_VGA 0x00
+#define LS_PCI_CLASS_SUB_CODE_DISPLAY_XGA 0x01
+#define LS_PCI_CLASS_SUB_CODE_DISPLAY_3D 0x02
+#define LS_PCI_CLASS_SUB_CODE_DISPLAY_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO 0x00
+#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO 0x01
+#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE 0x02
+#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_MEMORY_RAM 0x00
+#define LS_PCI_CLASS_SUB_CODE_MEMORY_FLASH 0x01
+#define LS_PCI_CLASS_SUB_CODE_MEMORY_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_HOST 0x00
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_ISA 0x01
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_EISA 0x02
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_MCA 0x03
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_LS_PCI 0x04
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA 0x05
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_NUBUS 0x06
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS 0x07
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY 0x08
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_SEMI_LS_PCI 0x09
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND 0x0A
+#define LS_PCI_CLASS_SUB_CODE_BRIDGE_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_COMM_SERIAL 0x00
+#define LS_PCI_CLASS_SUB_CODE_COMM_PARALLEL 0x01
+#define LS_PCI_CLASS_SUB_CODE_COMM_MULTIPORT 0x02
+#define LS_PCI_CLASS_SUB_CODE_COMM_MODEM 0x03
+#define LS_PCI_CLASS_SUB_CODE_COMM_GPIB 0x04
+#define LS_PCI_CLASS_SUB_CODE_COMM_SMARTCARD 0x05
+#define LS_PCI_CLASS_SUB_CODE_COMM_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_PIC 0x00
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_DMA 0x01
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER 0x02
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_RTC 0x03
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_SD 0x05
+#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_INPUT_KEYBOARD 0x00
+#define LS_PCI_CLASS_SUB_CODE_INPUT_DIGITIZER 0x01
+#define LS_PCI_CLASS_SUB_CODE_INPUT_MOUSE 0x02
+#define LS_PCI_CLASS_SUB_CODE_INPUT_SCANNER 0x03
+#define LS_PCI_CLASS_SUB_CODE_INPUT_GAMEPORT 0x04
+#define LS_PCI_CLASS_SUB_CODE_INPUT_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_DOCKING_GENERIC 0x00
+#define LS_PCI_CLASS_SUB_CODE_DOCKING_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_386 0x00
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_486 0x01
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM 0x02
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA 0x10
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC 0x20
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_MIPS 0x30
+#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_COPROC 0x40
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_1394 0x00
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS 0x01
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_SSA 0x02
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_USB 0x03
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN 0x04
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_SMBUS 0x05
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND 0x06
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_IPMI 0x07
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_SERCOS 0x08
+#define LS_PCI_CLASS_SUB_CODE_SERIAL_CANBUS 0x09
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_IRDA 0x00
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_IR 0x01
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_RF 0x10
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_80211A 0x20
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_80211B 0x21
+#define LS_PCI_CLASS_SUB_CODE_WIRELESS_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_I2O_V1_0 0x00
+#define LS_PCI_CLASS_SUB_CODE_SATELLITE_TV 0x01
+#define LS_PCI_CLASS_SUB_CODE_SATELLITE_AUDIO 0x02
+#define LS_PCI_CLASS_SUB_CODE_SATELLITE_VOICE 0x03
+#define LS_PCI_CLASS_SUB_CODE_SATELLITE_DATA 0x04
+#define LS_PCI_CLASS_SUB_CODE_CRYPTO_NETWORK 0x00
+#define LS_PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10
+#define LS_PCI_CLASS_SUB_CODE_CRYPTO_OTHER 0x80
+#define LS_PCI_CLASS_SUB_CODE_DATA_DPIO 0x00
+#define LS_PCI_CLASS_SUB_CODE_DATA_PERFCNTR 0x01
+#define LS_PCI_CLASS_SUB_CODE_DATA_COMMSYNC 0x10
+#define LS_PCI_CLASS_SUB_CODE_DATA_MGMT 0x20
+#define LS_PCI_CLASS_SUB_CODE_DATA_OTHER 0x80
+
+#define LS_PCI_CACHE_LINE_SIZE 0x0c // 8 bits
+#define LS_PCI_LATENCY_TIMER 0x0d // 8 bits
+#define LS_PCI_HEADER_TYPE 0x0e // 8 bits
+#define LS_PCI_HEADER_TYPE_NORMAL 0
+#define LS_PCI_HEADER_TYPE_BRIDGE 1
+#define LS_PCI_HEADER_TYPE_CARDBUS 2
+
+#define LS_PCI_BIST 0x0f // 8 bits
+#define LS_PCI_BIST_CODE_MASK 0x0f // Return result
+#define LS_PCI_BIST_START 0x40
+#define LS_PCI_BIST_CAPABLE 0x80
+
+#define LS_PCI_BASE_ADDRESS_0 0x10 // 32 bits
+#define LS_PCI_BASE_ADDRESS_1 0x14
+#define LS_PCI_BASE_ADDRESS_2 0x18
+#define LS_PCI_BASE_ADDRESS_3 0x1c // 32 bits
+#define LS_PCI_BASE_ADDRESS_4 0x20 // 32 bits
+#define LS_PCI_BASE_ADDRESS_5 0x24 // 32 bits
+#define LS_PCI_BASE_ADDRESS_SPACE 0x01
+#define LS_PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define LS_PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define LS_PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define LS_PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 // 32 bit address
+#define LS_PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 // Below 1M [obsolete]
+#define LS_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 // 64 bit address
+#define LS_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 // prefetchable?
+#define LS_PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL)
+#define LS_PCI_BASE_ADDRESS_IO_MASK (~0x03ULL)
+
+// Header type 0 (normal devices)
+#define LS_PCI_CARDBUS_CIS 0x28
+#define LS_PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define LS_PCI_SUBSYSTEM_ID 0x2e
+#define LS_PCI_ROM_ADDRESS 0x30
+#define LS_PCI_ROM_ADDRESS_ENABLE 0x01
+#define LS_PCI_ROM_ADDRESS_MASK (~0x7ffULL)
+
+#define LS_PCI_CAPABILITY_LIST 0x34 // Offset of first capability list entry
+
+#define LS_PCI_INTERRUPT_LINE 0x3c // 8 bits
+#define LS_PCI_INTERRUPT_PIN 0x3d // 8 bits
+#define LS_PCI_MIN_GNT 0x3e // 8 bits
+#define LS_PCI_MAX_LAT 0x3f // 8 bits
+
+// Header type 1 (PCI-to-PCI bridges)
+#define LS_PCI_PRIMARY_BUS 0x18 // Primary bus number
+#define LS_PCI_SECONDARY_BUS 0x19 // Secondary bus number
+#define LS_PCI_SUBORDINATE_BUS 0x1a
+#define LS_PCI_SEC_LATENCY_TIMER 0x1b
+#define LS_PCI_IO_BASE 0x1c // I/O range behind the bridge
+#define LS_PCI_IO_LIMIT 0x1d
+#define LS_PCI_IO_RANGE_TYPE_MASK 0x0f // I/O bridging type
+#define LS_PCI_IO_RANGE_TYPE_16 0x00
+#define LS_PCI_IO_RANGE_TYPE_32 0x01
+#define LS_PCI_IO_RANGE_MASK ~0x0f
+#define LS_PCI_SEC_STATUS 0x1e
+#define LS_PCI_MEMORY_BASE 0x20 // Memory range behind
+#define LS_PCI_MEMORY_LIMIT 0x22
+#define LS_PCI_MEMORY_RANGE_TYPE_MASK 0x0f
+#define LS_PCI_MEMORY_RANGE_MASK ~0x0f
+#define LS_PCI_PREF_MEMORY_BASE 0x24 // Prefetchable memory range behind
+#define LS_PCI_PREF_MEMORY_LIMIT 0x26
+#define LS_PCI_PREF_RANGE_TYPE_MASK 0x0f
+#define LS_PCI_PREF_RANGE_TYPE_32 0x00
+#define LS_PCI_PREF_RANGE_TYPE_64 0x01
+#define LS_PCI_PREF_RANGE_MASK ~0x0f
+#define LS_PCI_PREF_BASE_UPPER32 0x28 // Upper half of prefetchable memory range
+#define LS_PCI_PREF_LIMIT_UPPER32 0x2c
+#define LS_PCI_IO_BASE_UPPER16 0x30 // Upper half of I/O addresses
+#define LS_PCI_IO_LIMIT_UPPER16 0x32
+#define LS_PCI_ROM_ADDRESS1 0x38 // Same as LS_PCI_ROM_ADDRESS, but for htype 1
+#define LS_PCI_BRIDGE_CONTROL 0x3e
+#define LS_PCI_BRIDGE_CTL_PARITY 0x01
+#define LS_PCI_BRIDGE_CTL_SERR 0x02
+#define LS_PCI_BRIDGE_CTL_NO_ISA 0x04
+#define LS_PCI_BRIDGE_CTL_VGA 0x08
+#define LS_PCI_BRIDGE_CTL_MASTER_ABORT 0x20 // Report master aborts
+#define LS_PCI_BRIDGE_CTL_BUS_RESET 0x40 // Secondary bus reset
+#define LS_PCI_BRIDGE_CTL_FAST_BACK 0x80
+
+#define LS_PCI_ERREN 0x48 // Error Enable
+#define LS_PCI_ERRSTS 0x49 // Error Status
+#define LS_PCI_BRDGOPT1 0x4A
+#define LS_PCI_PLBSESR0 0x4C
+#define LS_PCI_PLBSESR1 0x50
+#define LS_PCI_PLBSEAR 0x54
+#define LS_PCI_CAPID 0x58
+#define LS_PCI_NEXTITEMPTR 0x59
+#define LS_PCI_PMC 0x5A
+#define LS_PCI_PMCSR 0x5C
+#define LS_PCI_PMCSRBSE 0x5E
+#define LS_PCI_BRDGOPT2 0x60 // PCI Bridge Options 2
+#define LS_PCI_PMSCRR 0x64
+
+// Header type 2 (CardBus bridges)
+#define LS_PCI_CB_CAPABILITY_LIST 0x14
+// 0x15 reserved
+#define LS_PCI_CB_SEC_STATUS 0x16 // Secondary status
+#define LS_PCI_CB_PRIMARY_BUS 0x18 // PCI bus number
+#define LS_PCI_CB_CARD_BUS 0x19
+#define LS_PCI_CB_SUBORDINATE_BUS 0x1a // Subordinate bus number
+#define LS_PCI_CB_LATENCY_TIMER 0x1b
+#define LS_PCI_CB_MEMORY_BASE_0 0x1c
+#define LS_PCI_CB_MEMORY_LIMIT_0 0x20
+#define LS_PCI_CB_MEMORY_BASE_1 0x24
+#define LS_PCI_CB_MEMORY_LIMIT_1 0x28
+#define LS_PCI_CB_IO_BASE_0 0x2c
+#define LS_PCI_CB_IO_BASE_0_HI 0x2e
+#define LS_PCI_CB_IO_LIMIT_0 0x30
+#define LS_PCI_CB_IO_LIMIT_0_HI 0x32
+#define LS_PCI_CB_IO_BASE_1 0x34
+#define LS_PCI_CB_IO_BASE_1_HI 0x36
+#define LS_PCI_CB_IO_LIMIT_1 0x38
+#define LS_PCI_CB_IO_LIMIT_1_HI 0x3a
+#define LS_PCI_CB_IO_RANGE_MASK ~0x03
+#define LS_PCI_CB_BRIDGE_CONTROL 0x3e
+#define LS_PCI_CB_BRIDGE_CTL_PARITY 0x01 // Similar to standard bridge control register
+#define LS_PCI_CB_BRIDGE_CTL_SERR 0x02
+#define LS_PCI_CB_BRIDGE_CTL_ISA 0x04
+#define LS_PCI_CB_BRIDGE_CTL_VGA 0x08
+#define LS_PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
+#define LS_PCI_CB_BRIDGE_CTL_CB_RESET 0x40 // CardBus reset
+#define LS_PCI_CB_BRIDGE_CTL_16BIT_INT 0x80
+#define LS_PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 // Prefetch enable for both memory regions
+#define LS_PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define LS_PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+#define LS_PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define LS_PCI_CB_SUBSYSTEM_ID 0x42
+#define LS_PCI_CB_LEGACY_MODE_BASE 0x44 // 16-bit PC Card legacy mode base address (ExCa)
+
+// Defines of Capability lists
+#define LS_PCI_CAP_LIST_ID 0 // Capability ID
+#define LS_PCI_CAP_ID_PM 0x01 // Power Management
+#define LS_PCI_CAP_ID_AGP 0x02
+#define LS_PCI_CAP_ID_VPD 0x03
+#define LS_PCI_CAP_ID_SLOTID 0x04
+#define LS_PCI_CAP_ID_MSI 0x05
+#define LS_PCI_CAP_ID_CHSWP 0x06
+#define LS_PCI_CAP_ID_EXP 0x10
+#define LS_PCI_CAP_LIST_NEXT 1 // Next capability in the list
+#define LS_PCI_CAP_FLAGS 2 // Capability defined flags (16 bits)
+#define LS_PCI_CAP_SIZEOF 4
+
+// Power Management Registers
+#define LS_PCI_PM_CAP_VER_MASK 0x0007
+#define LS_PCI_PM_CAP_PME_CLOCK 0x0008
+#define LS_PCI_PM_CAP_AUX_POWER 0x0010
+#define LS_PCI_PM_CAP_DSI 0x0020
+#define LS_PCI_PM_CAP_D1 0x0200
+#define LS_PCI_PM_CAP_D2 0x0400
+#define LS_PCI_PM_CAP_PME 0x0800
+#define LS_PCI_PM_CTRL 4
+#define LS_PCI_PM_CTRL_STATE_MASK 0x0003
+#define LS_PCI_PM_CTRL_PME_ENABLE 0x0100
+#define LS_PCI_PM_CTRL_DATA_SEL_MASK 0x1e00
+#define LS_PCI_PM_CTRL_DATA_SCALE_MASK 0x6000
+#define LS_PCI_PM_CTRL_PME_STATUS 0x8000
+#define LS_PCI_PM_PPB_EXTENSIONS 6
+#define LS_PCI_PM_PPB_B2_B3 0x40
+#define LS_PCI_PM_BPCC_ENABLE 0x80
+#define LS_PCI_PM_DATA_REGISTER 7
+#define LS_PCI_PM_SIZEOF 8
+
+// AGP registers defines
+#define LS_PCI_AGP_VERSION 2
+#define LS_PCI_AGP_RFU 3
+#define LS_PCI_AGP_STATUS 4
+#define LS_PCI_AGP_STATUS_RQ_MASK 0xff000000
+#define LS_PCI_AGP_STATUS_SBA 0x0200
+#define LS_PCI_AGP_STATUS_64BIT 0x0020
+#define LS_PCI_AGP_STATUS_FW 0x0010
+#define LS_PCI_AGP_STATUS_RATE4 0x0004
+#define LS_PCI_AGP_STATUS_RATE2 0x0002
+#define LS_PCI_AGP_STATUS_RATE1 0x0001
+#define LS_PCI_AGP_COMMAND 8
+#define LS_PCI_AGP_COMMAND_RQ_MASK 0xff000000
+#define LS_PCI_AGP_COMMAND_SBA 0x0200
+#define LS_PCI_AGP_COMMAND_AGP 0x0100
+#define LS_PCI_AGP_COMMAND_64BIT 0x0020
+#define LS_PCI_AGP_COMMAND_FW 0x0010
+#define LS_PCI_AGP_COMMAND_RATE4 0x0004
+#define LS_PCI_AGP_COMMAND_RATE2 0x0002
+#define LS_PCI_AGP_COMMAND_RATE1 0x0001
+#define LS_PCI_AGP_SIZEOF 12
+
+// Defines for PCI-X registers
+#define LS_PCI_X_CMD_DPERR_E 0x0001
+#define LS_PCI_X_CMD_ERO 0x0002
+#define LS_PCI_X_CMD_MAX_READ 0x0000
+#define LS_PCI_X_CMD_MAX_SPLIT 0x0030
+#define LS_PCI_X_CMD_VERSION(x) (((x) >> 12) & 3)
+
+// Register of Slot Identification
+#define LS_PCI_SID_ESR 2 // Expansion Slot Register
+#define LS_PCI_SID_ESR_NSLOTS 0x1f // Number of expansion slots available
+#define LS_PCI_SID_ESR_FIC 0x20 // First In Chassis Flag
+#define LS_PCI_SID_CHASSIS_NR 3 // Chassis Number
+
+#define LS_PCI_MSI_FLAGS 2
+#define LS_PCI_MSI_FLAGS_64BIT 0x80
+#define LS_PCI_MSI_FLAGS_QSIZE 0x70
+#define LS_PCI_MSI_FLAGS_QMASK 0x0e
+#define LS_PCI_MSI_FLAGS_ENABLE 0x01
+#define LS_PCI_MSI_RFU 3
+#define LS_PCI_MSI_ADDRESS_LO 4
+#define PCI_MSI_ADDRESS_HI 8
+#define LS_PCI_MSI_DATA_32 8
+#define LS_PCI_MSI_DATA_64 12
+
+#define LS_PCI_MAX_PCI_DEVICES 32
+#define LS_PCI_MAX_PCI_FUNCTIONS 8
+
+#define LS_PCI_FIND_CAP_TTL 0x48
+#define CAP_START_POS 0x40
+
+#define LS_PCI_REGION_MEM 0x00000000 // PCI memory space
+#define LS_PCI_REGION_IO 0x00000001 // PCI IO space
+#define LS_PCI_REGION_TYPE 0x00000001
+#define LS_PCI_REGION_PREFETCH 0x00000008 // prefetchable PCI memory
+#define LS_PCI_REGION_SYS_MEMORY 0x00000100 // System memory
+#define LS_PCI_REGION_RO 0x00000200 // Read-only memory
+
+#define PCI_BUS(Dev) (((Dev) >> 16) & 0xff)
+#define PCI_DEV(Dev) (((Dev) >> 11) & 0x1f)
+#define PCI_FUNC(Dev) (((Dev) >> 8) & 0x7)
+#define PCI_BDF(B,D,F) ((B) << 16 | (D) << 11 | (F) << 8)
+
+#define PCI_ANY_ID (~0)
+
+#define INDIRECT_TYPE_NO_PCIE_LINK 1
+
+#endif /* _PCI_LIB_H */
diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c b/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
new file mode 100644
index 0000000..942e04e
--- /dev/null
+++ b/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
@@ -0,0 +1,628 @@
+/** PciCntrl.c
+ Provides the basic interfaces to be used by PCI Root Bridge IO protocol
+
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Library/BeIoLib.h>
+#include "PciHostBridge.h"
+
+PCI_ROOT_BRIDGE_INSTANCE *RootBridgeHead;
+
+/**
+ Function for setting up PCI region
+**/
+VOID
+PciSetRegion (
+ IN PciRegion *Reg,
+ IN PciAddrT BusStart,
+ IN PhysAddrT PhysStart,
+ IN PciSizeT Size,
+ IN UINTN Flags
+)
+{
+ Reg->BusStart = BusStart;
+ Reg->PhysStart = PhysStart;
+ Reg->Size = Size;
+ Reg->Flags = Flags;
+}
+
+/**
+ Function to set PCI Space
+ - Configuration space
+ - Memory Space
+ - I/O Space
+**/
+VOID
+SetLSPcieInfo (
+ IN LsPcieInfo *PcieInfo,
+ IN UINTN Num
+)
+{
+ UINTN pciePhyAddr, pcieSysaddr;
+
+ pciePhyAddr=0;
+ pcieSysaddr=0;
+
+ switch(Num){
+ case 1:
+ pciePhyAddr = PcdGet64 (PcdPciExp1BaseAddr);
+ pcieSysaddr = PcdGet64 (PcdPciExp1SysAddr);
+ break;
+ case 2:
+ pciePhyAddr = PcdGet64 (PcdPciExp2BaseAddr);
+ pcieSysaddr = PcdGet64 (PcdPciExp2SysAddr);
+ break;
+ case 3:
+ pciePhyAddr = PcdGet64 (PcdPciExp3BaseAddr);
+ pcieSysaddr = PcdGet64 (PcdPciExp3SysAddr);
+ break;
+ case 4:
+ pciePhyAddr = PcdGet64 (PcdPciExp4BaseAddr);
+ pcieSysaddr = PcdGet64 (PcdPciExp4SysAddr);
+ break;
+ }
+
+ PcieInfo->Regs = pcieSysaddr;
+ PcieInfo->Cfg0Phys = LS_PCIE_CFG0_PHYS_OFF + pciePhyAddr;
+ PcieInfo->Cfg0Size = LS_PCIE_CFG0_SIZE;
+ PcieInfo->Cfg1Phys = LS_PCIE_CFG1_PHYS_OFF + pciePhyAddr;
+ PcieInfo->Cfg1Size = LS_PCIE_CFG1_SIZE;
+ PcieInfo->MemBus = LS_PCIE_MEM_BUS;
+ PcieInfo->MemPhys = LS_PCIE_MEM_PHYS_OFF + pciePhyAddr;
+ PcieInfo->MemSize = LS_PCIE_MEM_SIZE;
+ PcieInfo->IoBus = LS_PCIE_IO_BUS;
+ PcieInfo->IoPhys = LS_PCIE_IO_PHYS_OFF + pciePhyAddr;
+ PcieInfo->IoSize = LS_PCIE_IO_SIZE;
+ PcieInfo->PciNum = Num;
+
+ if (FeaturePcdGet (PcdPciDebug) == TRUE) {
+ DEBUG ((DEBUG_INFO, "In SET_PCIE_INFO: %d\n", Num));
+ DEBUG ((DEBUG_INFO, "PciNum:%d Info CFG Values: %016llx %016llx:%016llx %016llx %016llx\n",
+ (UINT64)PcieInfo->PciNum,
+ (UINT64)PcieInfo->Regs,
+ (UINT64)PcieInfo->Cfg0Phys,
+ (UINT64)PcieInfo->Cfg0Size,
+ (UINT64)PcieInfo->Cfg1Phys,
+ (UINT64)PcieInfo->Cfg1Size));
+ DEBUG ((DEBUG_INFO, "Info Mem Values: %016llx:%016llx %016llx\n",
+ (UINT64)PcieInfo->MemBus,
+ (UINT64)PcieInfo->MemPhys,
+ (UINT64)PcieInfo->MemSize));
+ DEBUG ((DEBUG_INFO, "Info IO Values: %016llx:%016llx %016llx\n",
+ (UINT64)PcieInfo->IoBus,
+ (UINT64)PcieInfo->IoPhys,
+ (UINT64)PcieInfo->IoSize));
+ }
+}
+
+/**
+ Function to check PCIe link state
+**/
+INTN
+PcieLinkState (
+ IN LsPcie *Pcie
+)
+{
+ UINT32 State;
+ if (FeaturePcdGet (PcdPciLutBigEndian)) {
+ State = BeMmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LUT_BASE + LS_PCIE_LUT_DBG) &
+ LS_LTSSM_STATE_MASK;
+ }
+ else {
+ State = MmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LUT_BASE + LS_PCIE_LUT_DBG) &
+ LS_LTSSM_STATE_MASK;
+ }
+
+ if (State < LS_LTSSM_PCIE_L0) {
+ DEBUG ((DEBUG_INFO," Pcie Link error. LTSSM=0x%2x\n",
+ State));
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Helper function to check PCIe link is up
+ Download the speed to gen1
+**/
+INTN
+PcieLinkUp (
+ IN LsPcie *Pcie
+)
+{
+ INTN State;
+ UINT32 Cap;
+
+ State = PcieLinkState (Pcie);
+ if (State) {
+ return State;
+ }
+
+ // Try to download speed to gen1
+ Cap = MmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LINK_CAP);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_LINK_CAP, (UINT32)(Cap & (~LS_PCIE_LINK_SPEED_MASK)) | 1);
+ State = PcieLinkState (Pcie);
+ if (State) {
+ return State;
+ }
+
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_LINK_CAP, Cap);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to set up PCI configuration(cfg0) space
+**/
+VOID
+PcieCfg0SetBusdev (
+ IN LsPcie *Pcie,
+ IN UINT32 BusDev
+)
+{
+ MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_VIEWPORT),
+ LS_PCIE_ATU_REGION_OUTBOUND | LS_PCIE_ATU_REGION_INDEX0);
+ MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET), BusDev);
+}
+
+/**
+ Function to set up PCI configuration(cfg1) space
+**/
+VOID
+PcieCfg1SetBusdev (
+ IN LsPcie *Pcie,
+ IN UINT32 BusDev
+)
+{
+ MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_VIEWPORT),
+ LS_PCIE_ATU_REGION_OUTBOUND | LS_PCIE_ATU_REGION_INDEX1);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, BusDev);
+}
+
+/**
+ Function to set up internal address translation window for inbound
+ transaction
+**/
+VOID
+PcieIatuInboundSet (
+ IN LsPcie *Pcie,
+ IN UINT32 Idx,
+ IN UINT32 Bar,
+ IN UINT64 Phys
+)
+{
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, (UINT32)(LS_PCIE_ATU_REGION_INBOUND | Idx));
+
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE, Phys);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE, (UINT32)(Phys >> 32));
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, (UINT32)Phys);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET, (UINT32)(Phys >> 32));
+
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1, LS_PCIE_ATU_TYPE_MEM);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2, LS_PCIE_ATU_ENABLE);
+}
+
+/**
+ Function to set up internal address translation window for outbound
+ transaction
+**/
+VOID
+PcieIatuOutboundSet (
+ IN LsPcie *Pcie,
+ IN UINT32 Idx,
+ IN UINT32 Type,
+ IN UINT64 Phys,
+ IN UINT64 BusAddr,
+ IN UINT64 Size
+)
+{
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, (UINT32)(LS_PCIE_ATU_REGION_OUTBOUND | Idx));
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE, Phys);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE, (UINT32)(Phys >> 32));
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LIMIT, (UINT32)(Phys + Size -1));
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, (UINT32)BusAddr);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET, (UINT32)(BusAddr >> 32));
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1, (UINT32)Type);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2, LS_PCIE_ATU_ENABLE);
+}
+
+EFI_STATUS
+PciSkipDev (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev
+)
+{
+ // Do not skip controller
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to check whether PCIe address is valid
+**/
+EFI_STATUS
+PcieAddrValid (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev
+)
+{
+ if ((((Dev >> 19)) & 0x1f) > 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // No support for multi-function
+ if ((((Dev >> 16)) & 0x07) > 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Controller does not support multi-function in RC mode
+ if (((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno) && ((((Dev) >> 16) & 0x7) > 0)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to read from PCI config space
+
+ @param Pointer to PCI_ROOT_BRIDGE_INSTANCE
+
+ @return The value(32-bit) read
+
+**/
+
+EFI_STATUS
+PcieReadConfig (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Where,
+ IN OUT UINT32 *Val
+)
+{
+ LsPcie *Pcie;
+ UINT32 BusDev, *Addr;
+
+ *Val = 0x00000000;
+ Pcie = PrivateData->Pcie;
+
+ if (PcieAddrValid (PrivateData, Dev)) {
+ *Val = 0xffffffff;
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno) {
+ Addr = Pcie->Dbi + Where;
+ } else {
+ BusDev = Dev;
+
+ if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno + 1) {
+ PcieCfg0SetBusdev (Pcie, BusDev);
+ Addr = (VOID *)Pcie->VaCfg0 + Where;
+ } else {
+ PcieCfg1SetBusdev (Pcie, BusDev);
+ Addr = (VOID *)Pcie->VaCfg1 + Where;
+ }
+ }
+
+ *Val = MmioRead32 ((UINTN)Addr);
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to read byte from PCI config space
+
+ @param Pointer to PCI_ROOT_BRIDGE_INSTANCE
+
+ @return The value(8-bit) read
+
+**/
+
+EFI_STATUS
+PcieReadConfigByte (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ IN OUT UINT8 *Val
+)
+{
+ UINT32 Val32;
+
+ if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) {
+ *Val = -1;
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Val = (Val32 >> ((Offset & (INT32)0x03) * 8));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to read word(16-bit) from PCI config space
+
+ @param Pointer to PCI_ROOT_BRIDGE_INSTANCE
+
+ @return The value(16-bit) read
+
+**/
+
+EFI_STATUS
+PcieReadConfigWord (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ IN OUT UINT16 *Val
+)
+{
+ UINT32 Val32;
+
+ if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) {
+ *Val = -1;
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Val = (UINT16)(Val32 >> ((Offset & (INT32)0x02) * 8));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to write byte to PCI config space
+
+ @param Pointer to PCI_ROOT_BRIDGE_INSTANCE
+
+ @return EFI_SUCCESS (8-bit value written)
+
+**/
+
+EFI_STATUS
+PcieWriteConfigByte (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ OUT UINT8 Val
+)
+{
+ UINT32 Val32, Mask, Ldata, Shift;
+
+ if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Shift = ((Offset & (INT32)0x03) * 8);
+ Ldata = (((UINT32)Val) & 0x000000ff) << Shift;
+ Mask = 0x000000ff << Shift;
+ Val32 = (Val32 & ~Mask) | Ldata;
+
+ if (EFI_ERROR (PcieWriteConfig (PrivateData, Dev, Offset & 0xfc, Val32))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to write word to PCI config space
+
+ @param Pointer to PCI_ROOT_BRIDGE_INSTANCE
+
+ @return EFI_SUCCESS (16-bit value written)
+
+**/
+
+EFI_STATUS
+PcieWriteConfigWord (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Offset,
+ OUT UINT16 Val
+)
+{
+ UINT32 Val32, Mask, Ldata, Shift;
+
+ if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Shift = ((Offset & (INT32)0x02) * 8);
+ Ldata = (((UINT32)Val) & 0x0000ffff) << Shift;
+ Mask = 0x0000ffff << Shift;
+ Val32 = (Val32 & ~Mask) | Ldata;
+
+ if (EFI_ERROR (PcieWriteConfig (PrivateData, Dev, Offset & 0xfc, Val32))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to write to PCI config space
+
+ @param Pointer to PCI_ROOT_BRIDGE_INSTANCE
+
+ @return EFI_SUCCESS (32-bit value written)
+
+**/
+
+EFI_STATUS
+PcieWriteConfig (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN UINT32 Dev,
+ IN INT32 Where,
+ IN UINT32 Val
+)
+{
+ LsPcie *Pcie;
+ UINT32 BusDev, *Addr;
+
+ Pcie = PrivateData->Pcie;
+
+ if (PcieAddrValid (PrivateData, Dev)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno) {
+ Addr = Pcie->Dbi + (Where & ~0x3);
+ } else {
+ BusDev = Dev;
+
+ if ((((Dev) >> 24) & 0xff) == PrivateData->FirstBusno + 1) {
+ PcieCfg0SetBusdev (Pcie, BusDev);
+ Addr = (VOID *)Pcie->VaCfg0 + (Where & ~0x3);
+ } else {
+ PcieCfg1SetBusdev (Pcie, BusDev);
+ Addr = (VOID *)Pcie->VaCfg1 + (Where & ~0x3);
+ }
+ }
+
+ MmioWrite32 ((UINTN)Addr, (UINT32)Val);
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to set up address translation unit for PCI
+ inbound transactions
+**/
+VOID
+PcieSetupAtuInbound (
+ IN LsPcie *Pcie,
+ IN LsPcieInfo *Info
+)
+{
+ UINT32 ValIn;
+ UINT32 ValOut;
+ UINT32 *Addr;
+
+ ValIn = 0x00000000;
+ ValOut = 0x28282828;
+ Addr = (UINT32 *)0x80080000;
+
+ MmioWrite32 ((UINTN)Addr, (UINT32)ValOut);
+ DEBUG ((DEBUG_INFO,"\nValue: %08lx written on Addr: %08lx\n", ValOut, Addr));
+ ValIn = MmioRead32 ((UINTN)Addr);
+ DEBUG ((DEBUG_INFO, "Value Read: %08lx from Address: %llx\n", ValIn, Addr));
+ // ATU 2 : OUTBOUND : MEM
+ PcieIatuInboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX2, 1, 0x80080000);
+
+ Addr = (VOID *)Pcie->VaCfg0 + 0x40000000;
+ ValIn = MmioRead32 ((UINTN)Addr);
+ DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", ValIn, Addr));
+ Addr = (VOID *)Pcie->VaCfg0 + 0x00000000;
+ ValIn = MmioRead32 ((UINTN)Addr);
+ DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", ValIn, Addr));
+ Addr = (UINT32 *)0x80080000;
+ ValIn = MmioRead32((UINTN)Addr);
+ DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", ValIn, Addr));
+
+}
+
+/**
+ Function to set up address translation unit for PCI
+ outbound transactions
+**/
+VOID
+PcieSetupAtu (
+ IN LsPcie *Pcie,
+ IN LsPcieInfo *Info
+)
+{
+ // ATU 0 : OUTBOUND : CFG0
+ PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX0,
+ LS_PCIE_ATU_TYPE_CFG0,
+ Info->Cfg0Phys,
+ 0,
+ Info->Cfg0Size);
+
+ // ATU 1 : OUTBOUND : CFG1
+ PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX1,
+ LS_PCIE_ATU_TYPE_CFG1,
+ Info->Cfg1Phys,
+ 0,
+ Info->Cfg1Size);
+
+ // ATU 2 : OUTBOUND : MEM
+ PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX2,
+ LS_PCIE_ATU_TYPE_MEM,
+ Info->MemPhys,
+ Info->MemBus,
+ //0x10000000,
+ Info->MemSize);
+
+ // ATU 3 : OUTBOUND : IO
+ PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX3,
+ LS_PCIE_ATU_TYPE_IO,
+ Info->IoPhys,
+ Info->IoBus,
+ Info->IoSize);
+
+ if (FeaturePcdGet (PcdPciDebug) == TRUE) {
+ INTN Cnt;
+ UINTN AddrTemp;
+ for (Cnt = 0; Cnt <= LS_PCIE_ATU_REGION_INDEX3; Cnt++) {
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT,
+ (UINT32)(LS_PCIE_ATU_REGION_OUTBOUND | Cnt));
+ DEBUG ((DEBUG_INFO,"iATU%d:\n", Cnt));
+ AddrTemp = (UINTN)((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT);
+ DEBUG((DEBUG_INFO,"iATU%d VIEWPORT REG Addr:%08lx Val:%08lx\n",
+ Cnt, AddrTemp, MmioRead32(AddrTemp)));
+ DEBUG ((DEBUG_INFO,"iATU%d VIEWPORT REG:%08lx\n", Cnt,
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT)));
+ DEBUG ((DEBUG_INFO,"\tLOWER PHYS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE)));
+ DEBUG ((DEBUG_INFO,"\tUPPER PHYS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE)));
+ DEBUG ((DEBUG_INFO,"\tLOWER BUS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET)));
+ DEBUG ((DEBUG_INFO,"\tUPPER BUS 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET)));
+ DEBUG ((DEBUG_INFO,"\tLIMIT 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LIMIT)));
+ DEBUG ((DEBUG_INFO,"\tCR1 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1)));
+ DEBUG ((DEBUG_INFO,"\tCR2 0x%08x\n",
+ MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2)));
+ }
+ }
+}
+
+/**
+ Function to set up PCI controller
+ -Setup ATU
+ -Setup Root complex class
+**/
+VOID
+PcieSetupCntrl (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN LsPcie *Pcie,
+ IN LsPcieInfo *Info
+)
+{
+ UINTN Dev;
+
+ Dev = ((PrivateData->FirstBusno) << 16 | (0) << 11 | (0) << 8);
+
+ if (FeaturePcdGet (PcdPciDebug) == TRUE) {
+ DEBUG ((DEBUG_INFO, "Going to SetUp IATU\n\n"));
+ }
+
+ PcieSetupAtu (Pcie, Info);
+
+ PcieWriteConfig (PrivateData, Dev, LS_PCI_BASE_ADDRESS_0, 0);
+
+ // program correct class for RC
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_DBI_RO_WR_EN, (UINT32)1);
+ PcieWriteConfigWord (PrivateData, Dev, LS_PCI_CLASS_DEVICE,
+ PCI_CLASS_BRIDGE_PCI);
+ MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_DBI_RO_WR_EN, (UINT32)0);
+}
diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000..f281357
--- /dev/null
+++ b/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,49 @@
+/* PciHostBridgeLib.inf
+#
+# Component description file for PCI root Bridge Library
+#
+# Copyright 2017 NXP
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+*/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = PciHostBridgeLib
+ FILE_GUID = c0f5dfa0-7599-11e0-9865-0002a5d5c61b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ Platform/NXP/NxpQoriqLs.dec
+ Silicon/NXP/Chassis/Chassis2/Chassis2.dec
+
+[Sources.common]
+ PciCntrl.c
+ PciRbLib.c
+
+[FixedPcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciDebug
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp2BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp3BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp4BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1SysAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp2SysAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp3SysAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp4SysAddr
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian
diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c b/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
new file mode 100644
index 0000000..4ebfc73
--- /dev/null
+++ b/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
@@ -0,0 +1,331 @@
+/** PciRbLib.c
+ Functions supporting PCI Root Bridge Io Protocol
+
+ Some part of code is inspired from EDK II, file:
+ PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c
+
+ Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PciHostBridge.h"
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mInStride[] = {
+ 1, // EfiPciWidthUint8
+ 2, // EfiPciWidthUint16
+ 4, // EfiPciWidthUint32
+ 8, // EfiPciWidthUint64
+ 0, // EfiPciWidthFifoUint8
+ 0, // EfiPciWidthFifoUint16
+ 0, // EfiPciWidthFifoUint32
+ 0, // EfiPciWidthFifoUint64
+ 1, // EfiPciWidthFillUint8
+ 2, // EfiPciWidthFillUint16
+ 4, // EfiPciWidthFillUint32
+ 8 // EfiPciWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mOutStride[] = {
+ 1, // EfiPciWidthUint8
+ 2, // EfiPciWidthUint16
+ 4, // EfiPciWidthUint32
+ 8, // EfiPciWidthUint64
+ 1, // EfiPciWidthFifoUint8
+ 2, // EfiPciWidthFifoUint16
+ 4, // EfiPciWidthFifoUint32
+ 8, // EfiPciWidthFifoUint64
+ 0, // EfiPciWidthFillUint8
+ 0, // EfiPciWidthFillUint16
+ 0, // EfiPciWidthFillUint32
+ 0 // EfiPciWidthFillUint64
+};
+
+/**
+ Function to validate parameters(Operation type,Supported width) for
+ root bridge io operation
+
+ @param This Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+ @param OperationType Operation type(Mem,I/O,Config)
+
+ @param Width Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH
+
+ @return EFI_SUCCESS Paramters check is ok for operation
+
+ @return EFI_INVALID_PARAMETER Inavlide parameters
+
+**/
+STATIC EFI_STATUS
+RootBridgeIoCheckParameter (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN OPERATION_TYPE OperationType,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ if ((Width >= EfiPciWidthMaximum) || (Width < EfiPciWidthUint8) || (NULL == Buffer)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal help function for read and write memory space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Write Switch value for Read or Write.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] UserAddress The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+RootBridgeIoMemRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 InStride;
+ UINT8 OutStride;
+ UINT8 *Uint8Buffer;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((Address < LS_PCIE_MEM_PHYS_OFF) ||
+ (Address >= ((UINT32)LS_PCIE_MEM_PHYS_OFF +
+ LS_PCIE_MEM_SIZE))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+ if (PrivateData == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Address += PrivateData->PciBaseAddress64;
+
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+
+ for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+ if (Write) {
+ switch (Width) {
+ case EfiPciWidthUint8:
+ MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+ break;
+ case EfiPciWidthUint16:
+ MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+ break;
+ case EfiPciWidthUint32:
+ MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+ break;
+ case EfiPciWidthUint64:
+ MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+ break;
+ default:
+ //
+ // The RootBridgeIoCheckParameter call above will ensure that this
+ // path is not taken.
+ //
+ ASSERT (FALSE);
+ break;
+ }
+ } else {
+ switch (Width) {
+ case EfiPciWidthUint8:
+ *Uint8Buffer = MmioRead8 ((UINTN)Address);
+ break;
+ case EfiPciWidthUint16:
+ *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+ break;
+ case EfiPciWidthUint32:
+ *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+ break;
+ case EfiPciWidthUint64:
+ *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+ break;
+ default:
+ //
+ // The RootBridgeIoCheckParameter call above will ensure that this
+ // path is not taken.
+ //
+ ASSERT (FALSE);
+ break;
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal help function for read and write IO space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Write Switch value for Read or Write.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] UserAddress The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+RootBridgeIoIoRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ DEBUG ((DEBUG_INFO, "PCI Root Bridge Io Io Read/Write function is not implemented yet.\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal help function for read and write PCI configuration space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Write Switch value for Read or Write.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] UserAddress The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+RootBridgeIoPciRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ INT32 Offset;
+ UINT32 BusDev;
+ UINT8 InStride;
+ UINT8 OutStride;
+ UINT8 *Uint8Buffer;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+ Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;
+
+ if (PciRbAddr->ExtendedRegister) {
+ Offset = (INT32) PciRbAddr->ExtendedRegister;
+ }
+ else {
+ Offset = (INT32) PciRbAddr->Register;
+ }
+
+ BusDev = (UINT32)PCI_BUS_DEV (
+ PciRbAddr->Bus,
+ PciRbAddr->Device,
+ PciRbAddr->Function
+ );
+
+ InStride = mInStride[Width];
+ OutStride = mOutStride[Width];
+
+ for (Uint8Buffer = Buffer; Count > 0; Offset += InStride, Uint8Buffer += OutStride, Count--) {
+ if (Write) {
+ switch (Width) {
+ case EfiPciWidthUint8:
+ Status = PcieWriteConfigByte (PrivateData, (UINT32)BusDev, Offset, *Uint8Buffer);
+ break;
+ case EfiPciWidthUint16:
+ Status = PcieWriteConfigWord (PrivateData, (UINT32)BusDev, Offset, *(UINT16 *)Uint8Buffer);
+ break;
+ case EfiPciWidthUint32:
+ Status = PcieWriteConfig (PrivateData, (UINT32)BusDev, Offset, *(UINT32 *)Uint8Buffer);
+ break;
+ default:
+ //
+ // The RootBridgeIoCheckParameter call above will ensure that this
+ // path is not taken.
+ //
+ ASSERT (FALSE);
+ break;
+ }
+ } else {
+ switch (Width) {
+ case EfiPciWidthUint8:
+ Status = PcieReadConfigByte (PrivateData, (UINT32)BusDev, Offset, Uint8Buffer);
+ break;
+ case EfiPciWidthUint16:
+ Status = PcieReadConfigWord (PrivateData, (UINT32)BusDev, Offset, (UINT16 *)Uint8Buffer);
+ break;
+ case EfiPciWidthUint32:
+ Status = PcieReadConfig (PrivateData, (UINT32)BusDev, Offset, (UINT32 *)Uint8Buffer);
+ break;
+ default:
+ //
+ // The RootBridgeIoCheckParameter call above will ensure that this
+ // path is not taken.
+ //
+ ASSERT (FALSE);
+ break;
+ }
+ }
+ }
+
+ return Status;
+}
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH edk2-platforms 2/3] Platform/NXP : Add PCI Host Bridge Driver
2017-12-21 18:48 [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary Vabhav
@ 2017-12-21 18:48 ` Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 3/3] Compilation:Modify dsc, fdf files Vabhav
2017-12-22 15:33 ` [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Ard Biesheuvel
3 siblings, 0 replies; 7+ messages in thread
From: Vabhav @ 2017-12-21 18:48 UTC (permalink / raw)
To: ard.biesheuvel, leif.lindholm, michael.d.kinney, edk2-devel
Added NXP PCI host bridge Dxe driver which install
host bridge resource allocation protocol,root bridge IO
protocol,Device path protocol and consumes MetronomeArch
Protocol.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Vabhav <vabhav.sharma@nxp.com>
---
.../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c | 967 ++++++++++++++++
.../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 61 +
.../NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 1193 ++++++++++++++++++++
Platform/NXP/Include/PciHostBridge.h | 466 ++++++++
Platform/NXP/Include/PciRootBridge.h | 674 +++++++++++
5 files changed, 3361 insertions(+)
create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
create mode 100644 Platform/NXP/Include/PciHostBridge.h
create mode 100644 Platform/NXP/Include/PciRootBridge.h
diff --git a/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c b/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
new file mode 100644
index 0000000..e9e43bc
--- /dev/null
+++ b/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
@@ -0,0 +1,967 @@
+/** PciHostBridgeDxe.c
+ Provides all functions of PCI Host Bridge Resource Allocation Protocol
+
+ Based on PCI HosttBridge implementation in
+ ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeResourceAllocation.c
+
+ Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PciHostBridge.h>
+
+/**
+ Hard code: Root Bridge Number within the host bridge
+ Root Bridge's attribute
+ Root Bridge's device path
+ Root Bridge's resource aperture
+**/
+
+UINT64 PciMemBase[NUM_PCIE_CONTROLLER];
+UINT64 PciBaseAddr[NUM_PCIE_CONTROLLER];
+
+PCI_HOST_BRIDGE_INSTANCE *HostBridge[NUM_PCIE_CONTROLLER];
+PCI_ROOT_BRIDGE_INSTANCE *PrivateData[NUM_PCIE_CONTROLLER];
+
+
+UINT64 RootBridgeAttribute[1][1] = { {EFI_PCI_HOST_BRIDGE_MEM64_DECODE | EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM} };
+
+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
+ {
+ { ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A03),
+ 0
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+EFI_HANDLE mPciDriverImageHandle;
+
+PCI_HOST_BRIDGE_INSTANCE gPciHostBridgeInstanceTemplate = {
+ PCI_HOST_BRIDGE_SIGNATURE, // Signature
+ NULL, // HostBridgeHandle
+ NULL, // ImageHandle
+ {0, 0, 0, 0}, // RootBridgeNumber
+ NULL, // RootBridgeInstance
+ {NULL, NULL}, // Head
+ FALSE, // ResourceSubiteed
+ TRUE, // CanRestarted
+ { // ResAlloc
+ PciNotifyPhase,
+ PciGetNextRootBridge,
+ PciGetAllocAttributes,
+ PciStartBusEnumeration,
+ PciSetBusNumbers,
+ PciSubmitResources,
+ PciGetProposedResources,
+ PciPreprocessController
+ }
+};
+
+/**
+ This function checks whether PCIe is enabled or not
+ depending upon board serdes protocol map
+
+ @param PcieNum PCIe number
+
+ @return The PCIe number enabled in map
+ @return FALSE PCIe number is disabled in map
+**/
+STATIC
+BOOLEAN
+IsPcieNumEnabled(
+ IN UINTN PcieNum
+ )
+{
+ UINT64 SerDes1ProtocolMap;
+
+ SerDes1ProtocolMap = 0x0;
+
+ GetSerdesProtocolMaps (&SerDes1ProtocolMap);
+
+ if (PcieNum < NUM_PCIE_CONTROLLER) {
+ return IsSerDesLaneProtocolConfigured (SerDes1ProtocolMap, (PcieNum+1));
+ }
+ else {
+ DEBUG ((DEBUG_ERROR, "Device not supported\n"));
+ }
+
+ return FALSE;
+}
+
+STATIC
+EFI_STATUS
+AddMemorySpace (
+ IN UINT64 BaseAddress,
+ IN UINTN Size
+ )
+{
+ EFI_STATUS Status;
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ BaseAddress,
+ Size,
+ 0
+ );
+
+ return Status;
+}
+
+/**
+ Entry point of this driver
+
+ @param ImageHandle Handle of driver image
+ @param SystemTable Point to EFI_SYSTEM_TABLE
+
+ @retval EFI_ABORTED PCI host bridge not present
+ @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
+ @retval EFI_DEVICE_ERROR Can not install the protocol instance
+ @retval EFI_SUCCESS Success to initialize the Pci host bridge.
+**/
+EFI_STATUS
+EFIAPI
+PciHostBridgeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Loop1;
+
+ Status = EFI_OUT_OF_RESOURCES; // error
+
+ for (Loop1 = 0; Loop1 < NUM_PCIE_CONTROLLER; Loop1++) {
+ PciMemBase[Loop1] = PcdGet64 (PcdPci1Mmio64Base) +
+ (PCI_MMIO64_BASE_DIFFERENCE * Loop1);
+ PciBaseAddr[Loop1] = PcdGet64 (PcdPciExp1BaseAddr) +
+ (PcdGet64 (PcdPciExp1BaseSize) * Loop1);
+
+ DEBUG ((DEBUG_INFO, "PciMemBase %d : 0x%p\n", Loop1, PciMemBase[Loop1]));
+ DEBUG ((DEBUG_INFO, "PciBaseAddr %d : 0x%p\n", Loop1, PciBaseAddr[Loop1]));
+ }
+
+ //
+ // Create Host Bridge Device Handle
+ //
+ for (Loop1 = 0; Loop1 < NUM_PCIE_CONTROLLER; Loop1++) {
+ if (!IsPcieNumEnabled (Loop1)) {
+ DEBUG ((DEBUG_ERROR, "PCIE%d is disabled\n", (Loop1 + 1)));
+ continue;
+ }
+
+ DEBUG ((DEBUG_INFO, "PCIE%d is Enabled\n", (Loop1 + 1)));
+
+ HostBridge[Loop1] = AllocateCopyPool (sizeof (PCI_HOST_BRIDGE_INSTANCE), &gPciHostBridgeInstanceTemplate);
+ if (HostBridge[Loop1] == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to Allocate HostBridge: %d\n", Loop1));
+ continue; // Continue with other controllers
+ }
+
+ HostBridge[Loop1]->RootBridgeNumber[Loop1] = TRUE;
+ InitializeListHead (&HostBridge[Loop1]->Head);
+ DEBUG ((DEBUG_INFO, "PCI : Install Protocol for HostBridge: %d\n", Loop1));
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &HostBridge[Loop1]->HostBridgeHandle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge[Loop1]->ResAlloc,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to install resource alloc\n", __FUNCTION__));
+ FreePool (HostBridge[Loop1]);
+ continue; // Continue with other controllers
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: Succeed to install resource allocation protocol\n", __FUNCTION__));
+ }
+
+ HostBridge[Loop1]->ImageHandle = ImageHandle;
+ //
+ // Create Root Bridge Device Handle in this Host Bridge
+ //
+ PrivateData[Loop1] = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE));
+ if (PrivateData[Loop1] == NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ HostBridge[Loop1]->HostBridgeHandle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge[Loop1]->ResAlloc,
+ NULL
+ ); // Uninstall Resource Allocation protocol
+ FreePool (HostBridge[Loop1]); // Unallocate previous memory,
+ continue; // Continue with other controllers
+ }
+
+ PrivateData[Loop1]->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
+ CopyMem (&(PrivateData[Loop1]->DevicePath), &mEfiPciRootBridgeDevicePath, sizeof (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH));
+ // Set Device Path for this Root Bridge
+
+ PrivateData[Loop1]->DevicePath.AcpiDevicePath.UID = Loop1;
+ PrivateData[Loop1]->PciMemBase64 = PciMemBase[Loop1];
+
+ PrivateData[Loop1]->Info = AllocateZeroPool (sizeof (LsPcieInfo));
+ PrivateData[Loop1]->Pcie = AllocateZeroPool (sizeof (LsPcie));
+
+ SetLSPcieInfo(PrivateData[Loop1]->Info, (Loop1+1));
+
+ HostBridge[Loop1]->RootBridge = PrivateData[Loop1];
+
+ if (FeaturePcdGet (PcdPciDebug) == TRUE) {
+ DEBUG ((DEBUG_INFO, "Installed Host Bridges successfully\n"));
+ }
+
+ Status = PciRbInitialize (
+ PrivateData[Loop1],
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *)&PrivateData[Loop1]->Io,
+ PrivateData[Loop1]->Info,
+ HostBridge[Loop1]->HostBridgeHandle,
+ RootBridgeAttribute[0][0],
+ (Loop1+1),
+ 0,
+ PciBaseAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ HostBridge[Loop1]->HostBridgeHandle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge[Loop1]->ResAlloc,
+ NULL
+ );
+
+ FreePool (PrivateData[Loop1]->Info);
+ FreePool (PrivateData[Loop1]->Pcie);
+ FreePool (PrivateData[Loop1]);
+ FreePool (HostBridge[Loop1]);
+ DEBUG ((DEBUG_INFO, "UNInstalled HostBridge ResAlloc protocol and Freed memory\n"));
+ continue; // Continue with other controllers
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &PrivateData[Loop1]->Handle,
+ &gEfiDevicePathProtocolGuid, &PrivateData[Loop1]->DevicePath,
+ &gEfiPciRootBridgeIoProtocolGuid, &PrivateData[Loop1]->Io,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to install RootBridgeIo and DevicePath protocols\n"));
+ FreePool (PrivateData[Loop1]);
+ return EFI_DEVICE_ERROR;
+ }
+
+ DEBUG ((DEBUG_INFO, "Successfully Installed RootBridgeIo and DevicePath protocols\n"));
+ InsertTailList (&HostBridge[Loop1]->Head, &PrivateData[Loop1]->Link);
+ Status = AddMemorySpace (PciMemBase[Loop1], PCI_MEM64_SIZE);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Memory Resource couldn't be added for PCI%d_MEM64\n",Loop1));
+ return EFI_DEVICE_ERROR;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Functions declarations for Host Bridge Resource allocation protocol
+
+ @param ImageHandle Handle of driver image
+ @param SystemTable Point to EFI_SYSTEM_TABLE
+
+ @retval EFI_ABORTED PCI host bridge not present
+ @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
+ @retval EFI_DEVICE_ERROR Can not install the protocol instance
+ @retval EFI_SUCCESS Success to initialize the Pci host bridge.
+**/
+EFI_STATUS
+PciNotifyPhase (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 AddrLen;
+ UINTN BitsOfAlignment;
+
+ BaseAddress = 0x0;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ RootBridgeInstance = HostBridgeInstance->RootBridge;
+
+ // Check RootBridge Signature
+ ASSERT (HostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);
+
+ // The enumeration cannot be restarted after the process has been further than the first phase
+ if (Phase == EfiPciHostBridgeBeginEnumeration) {
+ if (!HostBridgeInstance->CanRestarted) {
+ return EFI_NOT_READY;
+ }
+ } else {
+ HostBridgeInstance->CanRestarted = FALSE;
+ }
+
+ switch (Phase) {
+ case EfiPciHostBridgeBeginEnumeration:
+ RootBridgeInstance = HostBridgeInstance->RootBridge;
+ break;
+
+ case EfiPciHostBridgeBeginBusAllocation:
+ // The bus allocation phase is about to begin
+ break;
+
+ case EfiPciHostBridgeEndBusAllocation:
+ // The bus allocation and bus programming phase is complete. All the PCI-to-PCI bridges have been given and written back
+ // a bus number range into their configuration
+ break;
+
+ case EfiPciHostBridgeBeginResourceAllocation:
+ // The resource allocation phase is about to begin.
+ break;
+
+ case EfiPciHostBridgeAllocateResources:
+ // Allocates resources per previously submitted requests for all the PCI root bridges. The resources have been submitted to
+ // PciHbRaSubmitResources() before.
+
+ RootBridgeInstance = HostBridgeInstance->RootBridge;
+ if (RootBridgeInstance->ResAlloc[ResTypeIo].Length != 0) {
+ BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypeIo].Alignment) + 1; // Get the number of '1' in Alignment
+ AddrLen = RootBridgeInstance->ResAlloc[ResTypeIo].Length;
+
+ Status = gDS->AllocateIoSpace (
+ EfiGcdAllocateAnySearchBottomUp,
+ EfiGcdIoTypeIo,
+ BitsOfAlignment,
+ AddrLen,
+ &BaseAddress,
+ HostBridgeInstance->ImageHandle,
+ NULL
+ );
+ // If error then ResAlloc[n].Base ==0
+ if (!EFI_ERROR (Status)) {
+ RootBridgeInstance->ResAlloc[ResTypeIo].Base = (UINTN)BaseAddress;
+ }
+ }
+
+ if (RootBridgeInstance->ResAlloc[ResTypeMem32].Length != 0) {
+ BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypeMem32].Alignment) + 1; // Get the number of '1' in Alignment
+ AddrLen = RootBridgeInstance->ResAlloc[ResTypeMem32].Length;
+
+ // Top of the 64bit PCI Memory space
+ BaseAddress = RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ BitsOfAlignment,
+ AddrLen,
+ &BaseAddress,
+ HostBridgeInstance->ImageHandle,
+ NULL
+ );
+
+ // Ensure the allocation is in the 64bit PCI memory space
+ if (!EFI_ERROR (Status) && (BaseAddress >= RootBridgeInstance->PciMemBase64)) {
+ RootBridgeInstance->ResAlloc[ResTypeMem32].Base = (UINTN)(BaseAddress - RootBridgeInstance->PciBaseAddress64);
+ }
+ }
+
+ if (RootBridgeInstance->ResAlloc[ResTypePMem32].Length != 0) {
+ BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypePMem32].Alignment) + 1; // Get the number of '1' in Alignment
+ AddrLen = RootBridgeInstance->ResAlloc[ResTypePMem32].Length;
+
+ // Top of the 64bit PCI Memory space
+ BaseAddress = RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ BitsOfAlignment,
+ AddrLen,
+ &BaseAddress,
+ HostBridgeInstance->ImageHandle,
+ NULL
+ );
+
+ // Ensure the allocation is in the 64bit PCI memory space
+ if (!EFI_ERROR (Status) && (BaseAddress >= RootBridgeInstance->PciMemBase64)) {
+ RootBridgeInstance->ResAlloc[ResTypePMem32].Base = (UINTN)(BaseAddress - RootBridgeInstance->PciBaseAddress64);
+ }
+ }
+
+ if (RootBridgeInstance->ResAlloc[ResTypeMem64].Length != 0) {
+ BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypeMem64].Alignment) + 1; // Get the number of '1' in Alignment
+ AddrLen = RootBridgeInstance->ResAlloc[ResTypeMem64].Length;
+ // Top of the 64bit PCI Memory space
+ BaseAddress = RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ BitsOfAlignment,
+ AddrLen,
+ &BaseAddress,
+ HostBridgeInstance->ImageHandle,
+ NULL
+ );
+
+ // Ensure the allocation is in the 64bit PCI memory space
+ if (!EFI_ERROR (Status) && (BaseAddress >= RootBridgeInstance->PciMemBase64)) {
+ RootBridgeInstance->ResAlloc[ResTypeMem64].Base = (UINTN)(BaseAddress - RootBridgeInstance->PciBaseAddress64);
+ }
+ }
+ if (RootBridgeInstance->ResAlloc[ResTypePMem64].Length != 0) {
+ BitsOfAlignment = HighBitSet64 (RootBridgeInstance->ResAlloc[ResTypePMem64].Alignment) + 1; //Get the number of '1' in Alignment
+ AddrLen = RootBridgeInstance->ResAlloc[ResTypePMem64].Length;
+ // Top of the 64bit PCI Memory space
+ BaseAddress = RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ BitsOfAlignment,
+ AddrLen,
+ &BaseAddress,
+ HostBridgeInstance->ImageHandle,
+ NULL
+ );
+
+ // Ensure the allocation is in the 64bit PCI memory space
+ if (!EFI_ERROR (Status) && (BaseAddress >= RootBridgeInstance->PciMemBase64)) {
+ RootBridgeInstance->ResAlloc[ResTypePMem64].Base = (UINTN)(BaseAddress - RootBridgeInstance->PciBaseAddress64);
+ }
+ }
+
+ break;
+
+ case EfiPciHostBridgeSetResources:
+ // Programs the host bridge hardware to decode previously allocated resources (proposed resources)
+ // for all the PCI root bridges. The PCI bus driver will now program the resources
+ break;
+
+ case EfiPciHostBridgeFreeResources:
+ // Deallocates resources that were previously allocated for all the PCI root bridges and resets the
+ // I/O and memory apertures to their initial state.*/
+ break;
+
+ case EfiPciHostBridgeEndResourceAllocation:
+ break;
+
+ case EfiPciHostBridgeEndEnumeration:
+ break;
+
+ default:
+ DEBUG ((DEBUG_INFO, "PciHbRaNotifyPhase (Phase:%d)\n", Phase));
+ ASSERT (0);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+/**
+ This function returns the next root bridge attached to the
+ 'This' PCI Host Bridge.
+ There is only one PCI Root Bridge in this PCI interface, we
+ return either this root bridge if it the first time we call
+ this function (*RootBridgeHandle == NULL) or return EFI_NOT_FOUND
+ **/
+EFI_STATUS
+PciGetNextRootBridge (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN OUT EFI_HANDLE *RootBridgeHandle
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ ASSERT (HostBridgeInstance->RootBridge != NULL);
+
+ //Check RootBridge Signature
+ ASSERT (HostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);
+
+ if (*RootBridgeHandle == NULL) {
+ *RootBridgeHandle = HostBridgeInstance->RootBridge->Handle;
+ return EFI_SUCCESS;
+ } else if (*RootBridgeHandle == HostBridgeInstance->RootBridge->Handle) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ This function returns the resource allocation attributes supported
+ by this PCI Root Bridge.
+ A PCI Root bridge could support these types :
+ - EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM : does not support separate
+ windows for nonprefetchable and prefetchable memory.
+ - EFI_PCI_HOST_BRIDGE_MEM64_DECODE : supports 64-bit memory windows
+
+ @param This Pointer to host bridge resource allocation protocol
+
+ @return Attributes Attribues supported by the PCI root bridge
+ **/
+EFI_STATUS
+PciGetAllocAttributes (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT UINT64 *Attributes
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+ // Check if the RootBridgeHandle is the one managed by this PCI Host Bridge
+ ASSERT (HostBridgeInstance->RootBridge != NULL);
+ if (HostBridgeInstance->RootBridge->Handle != RootBridgeHandle) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Attributes = HostBridgeInstance->RootBridge->RootBridgeAttrib;
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function sets up the specified PCI root bridge for the
+ bus enumeration process
+
+ @param This pointer to host bridge resource allocation protocol
+**/
+EFI_STATUS
+PciStartBusEnumeration (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ )
+{
+ VOID *Buffer;
+ UINT8 *Ptr;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+ Buffer = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Ptr = (UINT8 *)Buffer;
+
+ // Fill an ACPI descriptor table with the Bus Number Range. This information will be used by the PCI Bus driver
+ // to set bus numbers to PCI-to-PCI bridge.
+
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; // QWORD Address space Descriptor
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Len = 0x2B; // Length of this descriptor in bytes not including the first two fields
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS; // Resource Type Bus Number Range
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->GenFlag = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->SpecificFlag = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrSpaceGranularity = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin = HostBridgeInstance->RootBridge->BusStart; // Bus Start
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMax = 0; // Bus Max
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrTranslationOffset = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen = FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1;
+
+ Ptr = Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc = ACPI_END_TAG_DESCRIPTOR;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum = 0x0;
+
+ *Configuration = Buffer;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function set PCI bus number(start,end for this root bridge instance
+ -Checks if ACPI descriptor is passed for supported bus range
+**/
+EFI_STATUS
+PciSetBusNumbers (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ UINT8 *Ptr;
+ UINTN BusStart;
+ UINTN BusEnd;
+ UINTN BusLen;
+
+ Ptr = Configuration;
+ if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check if the passed ACPI descriptor table define a Bus Number Range
+ if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check if the Configuration only passed one ACPI Descriptor (+ End Descriptor)
+ if (*((UINT8*)(Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR))) != ACPI_END_TAG_DESCRIPTOR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ ASSERT (HostBridgeInstance->RootBridge != NULL);
+ if (HostBridgeInstance->RootBridge->Handle != RootBridgeHandle) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
+ BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
+ BusEnd = BusStart + BusLen - 1;
+
+ ASSERT (BusStart <= BusEnd); // We should at least have PCI_BUS_ROOT and PCI_SWITCH_BUS
+ ASSERT ((BusStart >= HostBridgeInstance->RootBridge->BusStart) && (BusLen <= HostBridgeInstance->RootBridge->BusLength));
+
+ HostBridgeInstance->RootBridge->BusStart = BusStart;
+ HostBridgeInstance->RootBridge->BusLength = BusLen;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is used to submit all the I/O and memory resources
+ that are required by the specified PCI root bridge.
+ **/
+EFI_STATUS
+PciSubmitResources (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ UINT8 *Ptr;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;
+ PCI_RESOURCE_TYPE ResType;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+ if (Configuration == NULL) {
+ DEBUG((DEBUG_ERROR, "PciHbRaSubmitResources(): NULL COnf\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check if the ACPI Descriptor tables is conformed
+ Ptr = (UINT8 *)Configuration;
+ while (*Ptr == ACPI_ADDRESS_SPACE_DESCRIPTOR) { // QWORD Address Space descriptor
+ Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
+ }
+ if (*Ptr != ACPI_END_TAG_DESCRIPTOR) { // End tag
+ DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): END tag issue\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check the RootBridgeHandle
+ RootBridgeInstance = HostBridgeInstance->RootBridge;
+ ASSERT (RootBridgeInstance != NULL);
+ if (RootBridgeHandle != HostBridgeInstance->RootBridge->Handle) {
+ DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): HB/RB dont match\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ptr = (UINT8 *)Configuration;
+ while ( *Ptr == ACPI_ADDRESS_SPACE_DESCRIPTOR) { // While the entry is an ACPI Descriptor Table
+ Desc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;
+
+ // Check if the description is valid
+ if (Desc->AddrLen > 0xffffffff) {
+ DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid addr length\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Desc->AddrRangeMax >= 0xffffffff) || (Desc->AddrRangeMax != (GetPowerOfTwo64 (Desc->AddrRangeMax + 1) - 1))) {
+ DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid addr range\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Desc->ResType) {
+ case ACPI_ADDRESS_SPACE_TYPE_MEM:
+ // Check invalid Address Space Granularity
+ if ((Desc->AddrSpaceGranularity != 32) && (Desc->AddrSpaceGranularity != 64)) {
+ DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid addr space granul\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // check the memory resource request is supported by PCI root bridge
+ if (RootBridgeInstance->MemAllocAttributes == EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM && Desc->SpecificFlag == 0x06) {
+ DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid memalloc attri \n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Desc->AddrSpaceGranularity == 32) {
+ if (Desc->SpecificFlag == ACPI_SPECFLAG_PREFETCHABLE) {
+ ResType = ResTypePMem32;
+ } else {
+ ResType = ResTypeMem32;
+ }
+ } else {
+ if (Desc->SpecificFlag == ACPI_SPECFLAG_PREFETCHABLE) {
+ ResType = ResTypePMem64;
+ } else {
+ ResType = ResTypeMem64;
+ }
+ }
+ RootBridgeInstance->ResAlloc[ResType].Length = Desc->AddrLen;
+ RootBridgeInstance->ResAlloc[ResType].Alignment = Desc->AddrRangeMax;
+ RootBridgeInstance->ResAlloc[ResType].Base = Desc->AddrRangeMin;
+ break;
+ case ACPI_ADDRESS_SPACE_TYPE_IO:
+ RootBridgeInstance->ResAlloc[ResTypeIo].Length = Desc->AddrLen;
+ RootBridgeInstance->ResAlloc[ResTypeIo].Alignment = Desc->AddrRangeMax;
+ RootBridgeInstance->ResAlloc[ResTypeIo].Base = 0;
+ break;
+ default:
+ ASSERT (0); // Could be the case Desc->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS
+ break;
+ }
+ Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function Returns the proposed resource settings for the specified
+ PCI root bridge. The resources have been submitted by
+ PciHbRaSubmitResources()
+
+ @param This Pointer to host bridge resource allocation
+ instance
+ @param RootBridgeHandle Pointer to this root bridge instance
+
+ @return Configuration Pointer to resource settings
+ @return EFI_SUCCESS Successful returned requested resource
+ settings
+ @return EFI_INVALID_PARAMETER Invalid parameter for root bridge
+ @return EFI_OUT_OF_RESOURCES Resources can not be allocated
+ **/
+EFI_STATUS
+PciGetProposedResources (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ UINT32 i;
+ UINT32 ResAllocCount;
+ VOID *Buffer;
+ UINT8 *Ptr;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+ // Check the RootBridgeHandle
+ RootBridgeInstance = HostBridgeInstance->RootBridge;
+ ASSERT (RootBridgeInstance != NULL);
+ if (RootBridgeHandle != HostBridgeInstance->RootBridge->Handle) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Count the number of Resource Allocated for this Root Bridge
+ ResAllocCount = 0;
+ for (i = 0; i < ResTypeMax; i++) {
+ if (RootBridgeInstance->ResAlloc[i].Length != 0) ResAllocCount++;
+ }
+
+ if (ResAllocCount == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Buffer = AllocateZeroPool (ResAllocCount * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Ptr = Buffer;
+ for (i = 0; i < ResTypeMax; i++) {
+ // Base != 0 if the resource has been allocated
+ if (RootBridgeInstance->ResAlloc[i].Length != 0) {
+ Desc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr;
+
+ Desc->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Desc->Len = 0x2B;
+ Desc->GenFlag = 0;
+ Desc->AddrRangeMax = 0;
+
+ switch (i) {
+ case ResTypeIo:
+ Desc->Desc = 0x8A;
+ Desc->Len = 0x2B;
+ Desc->ResType = 1;
+ Desc->GenFlag = 0;
+ Desc->SpecificFlag = 0;
+ Desc->AddrSpaceGranularity = 0;
+ Desc->AddrRangeMin = RootBridgeInstance->ResAlloc[i].Base;
+ Desc->AddrLen = RootBridgeInstance->ResAlloc[i].Length;
+ break;
+ case ResTypeMem32:
+ Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Desc->Desc = 0x8A;
+ Desc->Len = 0x2B;
+ Desc->ResType = 0;
+ Desc->GenFlag = 0;
+ Desc->SpecificFlag = 0;
+ Desc->AddrSpaceGranularity = 32;
+ Desc->AddrRangeMin = RootBridgeInstance->ResAlloc[i].Base;
+ Desc->AddrLen = RootBridgeInstance->ResAlloc[i].Length;
+ break;
+ case ResTypePMem32:
+ Desc->Desc = 0x8A;
+ Desc->Len = 0x2B;
+ Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Desc->GenFlag = 0;
+ Desc->SpecificFlag = 6;
+ Desc->AddrSpaceGranularity = 32;
+ Desc->AddrRangeMin = 0;
+ Desc->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
+ Desc->AddrLen = 0;
+ break;
+ case ResTypeMem64:
+ Desc->Desc = 0x8A;
+ Desc->Len = 0x2B;
+ Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Desc->GenFlag = 0;
+ Desc->SpecificFlag = 0;
+ Desc->AddrSpaceGranularity = 64;
+ Desc->AddrRangeMin = RootBridgeInstance->ResAlloc[i].Base;
+ Desc->AddrLen = RootBridgeInstance->ResAlloc[i].Length;
+ break;
+ case ResTypePMem64:
+ Desc->Desc = 0x8A;
+ Desc->Len = 0x2B;
+ Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Desc->GenFlag = 0;
+ Desc->SpecificFlag = 6;
+ Desc->AddrSpaceGranularity = 64;
+ Desc->AddrRangeMin = 0;
+ Desc->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
+ Desc->AddrLen = 0;
+ break;
+ }
+ Desc->AddrRangeMin = RootBridgeInstance->ResAlloc[i].Base;
+ Desc->AddrTranslationOffset = EFI_RESOURCE_SATISFIED;
+ Desc->AddrLen = RootBridgeInstance->ResAlloc[i].Length;
+ Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ }
+ }
+
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc = ACPI_END_TAG_DESCRIPTOR;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum = 0x0;
+
+ *Configuration = Buffer;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function allow the host bridge driver to preinitialize individual
+ PCI controllers before enumeration
+**/
+EFI_STATUS
+PciPreprocessController (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ )
+{
+ PCI_HOST_BRIDGE_INSTANCE* HostBridge;
+ PCI_ROOT_BRIDGE_INSTANCE* RootBridge;
+ UINT32 CapabilityPtr;
+ UINT32 CapabilityEntry;
+ UINT16 CapabilityID;
+ UINT32 DeviceCapability;
+
+ if (FeaturePcdGet (PcdPciMaxPayloadFixup)) {
+ // Do Max payload fixup for every devices
+ if (Phase == EfiPciBeforeResourceCollection) {
+ // Get RootBridge Instance from Host Bridge Instance
+ HostBridge = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ RootBridge = HostBridge->RootBridge;
+
+ // Get the first PCI Capability
+ CapabilityPtr = PCI_CAPBILITY_POINTER_OFFSET;
+ RootBridge->Io.Pci.Read (
+ &RootBridge->Io,
+ EfiPciWidthUint8,
+ EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr),
+ 1,
+ &CapabilityPtr
+ );
+ CapabilityPtr &= 0x1FF;
+
+ // Get Pci Express Capability
+ while (CapabilityPtr != 0) {
+ RootBridge->Io.Pci.Read (
+ &RootBridge->Io,
+ EfiPciWidthUint16,
+ EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr),
+ 1,
+ &CapabilityEntry
+ );
+
+ CapabilityID = (UINT8)CapabilityEntry;
+
+ // Is PCIe capability ?
+ if (CapabilityID == EFI_PCI_CAPABILITY_ID_PCIEXP) {
+ // Get PCIe Device Capabilities
+ RootBridge->Io.Pci.Read (
+ &RootBridge->Io,
+ EfiPciWidthUint32,
+ EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr + 0x8),
+ 1,
+ &DeviceCapability
+ );
+
+ // Force the Max Payload to 128 Bytes (128 Bytes Max Payload Size = 0)
+ DeviceCapability &= ~ ((UINT32)(0x7 << 5 ));
+ // Max Read Request Size to 128 Bytes (128 Bytes Max Read Request Size = 0)
+ DeviceCapability &= ~ ((UINT32)(0x7 << 12));
+ // Enable all error reporting
+ DeviceCapability |= 0xF;
+
+ RootBridge->Io.Pci.Write (
+ &RootBridge->Io,
+ EfiPciWidthUint32,
+ EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.Function, CapabilityPtr + 0x8),
+ 1,
+ &DeviceCapability
+ );
+
+ return EFI_SUCCESS;
+ }
+ CapabilityPtr = (CapabilityEntry >> 8) & 0xFF;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf b/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
new file mode 100644
index 0000000..019cc63
--- /dev/null
+++ b/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -0,0 +1,61 @@
+/* PciHostBridgeDxe.inf
+#
+# Component description file for PCI Host Bridge driver
+#
+# Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+*/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = PciHostBridge
+ FILE_GUID = C62F4B20-681E-11DF-8F0D-0002A5D5C51B
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PciHostBridgeEntryPoint
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Platform/NXP/NxpQoriqLs.dec
+ Silicon/NXP/Chassis/Chassis2/Chassis2.dec
+
+[LibraryClasses]
+ DxeServicesTableLib
+ PciHostBridgeLib
+ SocLib
+ UefiDriverEntryPoint
+
+[Sources]
+ PciHostBridgeDxe.c
+ PciRootBridgeIo.c
+
+[FixedPcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdPciBusMin
+ gNxpQoriqLsTokenSpaceGuid.PcdPciBusMax
+ gNxpQoriqLsTokenSpaceGuid.PcdPci1Mmio64Base
+ gNxpQoriqLsTokenSpaceGuid.PcdPciMmio64Size
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr
+ gNxpQoriqLsTokenSpaceGuid.PcdKludgeMapPciMmioAsCached
+ gNxpQoriqLsTokenSpaceGuid.PcdPciMaxPayloadFixup
+ gNxpQoriqLsTokenSpaceGuid.PcdPciDebug
+ gNxpQoriqLsTokenSpaceGuid.PcdNumPciController
+ gNxpQoriqLsTokenSpaceGuid.PcdPciMemOneTransaction
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseSize
+
+[Protocols]
+ gEfiPciHostBridgeResourceAllocationProtocolGuid ## PRODUCES
+ gEfiPciRootBridgeIoProtocolGuid ## PRODUCES
+ gEfiMetronomeArchProtocolGuid ## CONSUMES
+ gEfiDevicePathProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
diff --git a/Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
new file mode 100644
index 0000000..9a5c238
--- /dev/null
+++ b/Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -0,0 +1,1193 @@
+/** PciRootBridgeIo.c
+ PCI Root Bridge Io Protocol implementation
+
+ Based on PCI RootBridge implementation in
+ ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciRootBridge.c
+
+ Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PciHostBridge.h>
+
+typedef struct {
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[ResTypeMax+1];
+ EFI_ACPI_END_TAG_DESCRIPTOR EndDesp;
+} RESOURCE_CONFIGURATION;
+
+RESOURCE_CONFIGURATION Configuration = {
+ {{ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_IO , 0, 0, 0, 0, 0, 0, 0},
+ {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 0, 32, 0, 0, 0, 0},
+ {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 6, 32, 0, 0, 0, 0},
+ {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 0, 64, 0, 0, 0, 0},
+ {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, 6, 64, 0, 0, 0, 0},
+ {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_BUS, 0, 0, 0, 0, 255, 0, 255}},
+ {ACPI_END_TAG_DESCRIPTOR, 0}
+};
+
+//
+// Memory Controller Pci Root Bridge Io Module Variables
+//
+EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
+
+/**
+
+ Initialize and create Pci Root Bridges for Board
+
+ @param PrvateData Driver instance of this Root Bridge IO protocol
+ @param Protocol Point to protocol instance
+ @param Info Point to Info field of this driver instance
+ @param HostBridgeHandle Handle of host bridge
+ @param Attri Attribute of host bridge
+ @param HostNo HostNo for this Host Bridge
+ @param Busno Bus Number for the Host Bridge
+
+ @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
+
+**/
+EFI_STATUS
+PciRbInitialize (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
+ IN LsPcieInfo *Info,
+ IN EFI_HANDLE HostBridgeHandle,
+ IN UINT64 Attri,
+ IN INTN HostNo,
+ IN INTN Busno,
+ IN UINT64 *PciBaseAddr
+ )
+{
+ EFI_STATUS Status;
+ LsPcie *Pcie;
+ PciDevT Pdev;
+ INTN LinkUp, EpMode;
+ UINT8 HeaderType;
+ UINT16 Temp16;
+ UINT16 VendorID16;
+ UINT16 DeviceID16;
+ UINT16 Cntr;
+
+ Pdev = ((Busno) << 16 | (0) << 11 | (0) << 8);
+ Pcie = PrivateData->Pcie;
+
+ PrivateData->FirstBusno = Busno;
+ PrivateData->Pcie->Dbi = (VOID *)Info->Regs;
+ PrivateData->Pcie->VaCfg0 = (VOID *)Info->Cfg0Phys;
+ PrivateData->Pcie->VaCfg1 = (VOID *)Info->Cfg1Phys;
+
+ LinkUp = PcieLinkUp(Pcie);
+
+ if (!LinkUp) {
+ // Let the user know there's no PCIe link
+ DEBUG ((DEBUG_INFO,"no link, regs @ 0x%lx\n", Info->Regs));
+ PrivateData->LastBusno = PrivateData->FirstBusno;
+ return EFI_ABORTED;
+ }
+ DEBUG ((DEBUG_INFO, "Passed Linkup Phase\n"));
+
+ // outbound memory
+ PciSetRegion (&PrivateData->Regions[0],
+ (PciSizeT)Info->MemBus,
+ (PhysSizeT)Info->MemPhys,
+ (PciSizeT)Info->MemSize,
+ LS_PCI_REGION_MEM);
+
+ // outbound io
+ PciSetRegion (&PrivateData->Regions[1],
+ (PciSizeT)Info->IoBus,
+ (PhysSizeT)Info->IoPhys,
+ (PciSizeT)Info->IoSize,
+ LS_PCI_REGION_IO);
+
+ // System memory space
+ PciSetRegion (&PrivateData->Regions[2],
+ LS_PCI_MEMORY_BUS,
+ LS_PCI_MEMORY_PHYS,
+ LS_PCI_MEMORY_SIZE,
+ LS_PCI_REGION_SYS_MEMORY);
+
+ PrivateData->RegionCnt = 3;
+
+ if (FeaturePcdGet (PcdPciDebug) == TRUE) {
+ for (Cntr = 0; Cntr < PrivateData->RegionCnt; Cntr++) {
+ DEBUG ((DEBUG_INFO, "PCI reg:%d %016llx:%016llx %016llx %08lx\n",
+ Cntr,
+ (UINT64)PrivateData->Regions[Cntr].PhysStart,
+ (UINT64)PrivateData->Regions[Cntr].BusStart,
+ (UINT64)PrivateData->Regions[Cntr].Size,
+ PrivateData->Regions[Cntr].Flags));
+ }
+ }
+
+ PcieReadConfigWord (PrivateData, Pdev, LS_PCI_VENDOR_ID, (UINT16 *)&VendorID16);
+ DEBUG ((DEBUG_INFO,"PCIe:VendorID: %04lx\n", VendorID16));
+ PcieReadConfigWord (PrivateData, Pdev, LS_PCI_DEVICE_ID, (UINT16 *)&DeviceID16);
+ DEBUG ((DEBUG_INFO,"PCIe Device ID: %04lx\n", DeviceID16));
+ PcieReadConfigByte (PrivateData, Pdev, LS_PCI_HEADER_TYPE, (UINT8 *)&HeaderType);
+ DEBUG ((DEBUG_INFO,"PCIe Header Type: %02lx\n", HeaderType));
+ EpMode = (HeaderType & 0x7f) == LS_PCI_HEADER_TYPE_NORMAL;
+ DEBUG ((DEBUG_INFO,"EpMode: %d\n", EpMode));
+ DEBUG ((DEBUG_INFO,"PCIe%d: %a\n", (UINT64)Info->PciNum, EpMode ? "Endpoint" : "Root Complex"));
+
+ // Print the negotiated PCIe link width
+ PcieReadConfigWord (PrivateData, Pdev, LS_PCIE_LINK_STA, (UINT16 *)&Temp16);
+ DEBUG ((DEBUG_INFO,"PCIe Link Status: %04lx\n", Temp16));
+ DEBUG ((DEBUG_INFO,"x%d gen%d, regs @ 0x%lx\n", (Temp16 & 0x3f0) >> 4,
+ (Temp16 & 0xf), Info->Regs));
+
+ if (EpMode) {
+ DEBUG ((DEBUG_INFO, "EpMode: %d\n", Busno));
+ return Busno;
+ }
+
+ PrivateData->PciBaseAddress64 = PciBaseAddr[HostNo - 1];
+ if (!PrivateData->PciBaseAddress64) {
+ DEBUG ((DEBUG_ERROR, "%a: PCI %d host bridge not present\n", __FUNCTION__, HostNo));
+ return EFI_ABORTED;
+ }
+
+ PcieSetupCntrl (PrivateData, PrivateData->Pcie, PrivateData->Info);
+
+ PrivateData->BusStart = FixedPcdGet32 (PcdPciBusMin);
+ PrivateData->BusLength = FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1;
+
+ PrivateData->RootBridgeAttrib = Attri;
+
+ PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \
+ EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \
+ EFI_PCI_ATTRIBUTE_VGA_MEMORY | \
+ EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+ PrivateData->Attributes = PrivateData->Supports;
+
+ Protocol->ParentHandle = HostBridgeHandle;
+
+ Protocol->PollMem = RootBridgeIoPollMem;
+ Protocol->PollIo = RootBridgeIoPollIo;
+
+ Protocol->Mem.Read = RootBridgeIoMemRead;
+ Protocol->Mem.Write = RootBridgeIoMemWrite;
+
+ Protocol->Io.Read = RootBridgeIoIoRead;
+ Protocol->Io.Write = RootBridgeIoIoWrite;
+
+ Protocol->CopyMem = RootBridgeIoCopyMem;
+
+ Protocol->Pci.Read = RootBridgeIoPciRead;
+ Protocol->Pci.Write = RootBridgeIoPciWrite;
+
+ Protocol->Map = RootBridgeIoMap;
+ Protocol->Unmap = RootBridgeIoUnmap;
+
+ Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
+ Protocol->FreeBuffer = RootBridgeIoFreeBuffer;
+
+ Protocol->Flush = RootBridgeIoFlush;
+
+ Protocol->GetAttributes = RootBridgeIoGetAttributes;
+ Protocol->SetAttributes = RootBridgeIoSetAttributes;
+
+ Protocol->Configuration = RootBridgeIoConfiguration;
+
+ Protocol->SegmentNumber = HostNo;
+
+ Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Polls an address in memory mapped I/O space until an exit condition is met, or
+ a timeout occurs.
+
+ This function provides a standard way to poll a PCI memory location. A PCI memory read
+ operation is performed at the PCI memory address specified by Address for the width specified
+ by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
+ read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
+ Mask) is equal to Value.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The base address of the memory operations. The caller is
+ responsible for aligning Address if required.
+ @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask
+ are ignored. The bits in the bytes below Width which are zero in
+ Mask are ignored when polling the memory address.
+ @param[in] Value The comparison value used for the polling exit criteria.
+ @param[in] Delay The number of 100 ns units to poll. Note that timer available may
+ be of poorer granularity.
+ @param[out] Result Pointer to the last value read from the memory location.
+
+ @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
+ @retval EFI_INVALID_PARAMETER Width is invalid.
+ @retval EFI_INVALID_PARAMETER Result is NULL.
+ @retval EFI_TIMEOUT Delay expired before a match occurred.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+{
+ EFI_STATUS Status;
+ UINT64 NumberOfTicks;
+ UINT32 Remainder;
+
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width > EfiPciWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // No matter what, always do a single poll.
+ Status = This->Mem.Read (This, Width, Address, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ if (Delay == 0) {
+ return EFI_SUCCESS;
+ }
+
+ NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);
+ if (Remainder != 0) {
+ NumberOfTicks += 1;
+ }
+ NumberOfTicks += 1;
+
+ while (NumberOfTicks) {
+ mMetronome->WaitForTick (mMetronome, 1);
+
+ Status = This->Mem.Read (This, Width, Address, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ NumberOfTicks -= 1;
+ }
+
+ return EFI_TIMEOUT;
+}
+
+/**
+ Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
+ satisfied or after a defined duration.
+
+ This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
+ performed at the PCI I/O address specified by Address for the width specified by Width.
+ The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
+ repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
+ to Value.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the I/O operations.
+ @param[in] Address The base address of the I/O operations. The caller is responsible
+ for aligning Address if required.
+ @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask
+ are ignored. The bits in the bytes below Width which are zero in
+ Mask are ignored when polling the I/O address.
+ @param[in] Value The comparison value used for the polling exit criteria.
+ @param[in] Delay The number of 100 ns units to poll. Note that timer available may
+ be of poorer granularity.
+ @param[out] Result Pointer to the last value read from the memory location.
+
+ @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
+ @retval EFI_INVALID_PARAMETER Width is invalid.
+ @retval EFI_INVALID_PARAMETER Result is NULL.
+ @retval EFI_TIMEOUT Delay expired before a match occurred.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+{
+ EFI_STATUS Status;
+ UINT64 NumberOfTicks;
+ UINT32 Remainder;
+
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width > EfiPciWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // No matter what, always do a single poll.
+ Status = This->Io.Read (This, Width, Address, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ if (Delay == 0) {
+ return EFI_SUCCESS;
+ }
+
+ NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);
+ if (Remainder != 0) {
+ NumberOfTicks += 1;
+ }
+ NumberOfTicks += 1;
+
+ while (NumberOfTicks) {
+ mMetronome->WaitForTick (mMetronome, 1);
+
+ Status = This->Io.Read (This, Width, Address, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ NumberOfTicks -= 1;
+ }
+
+ return EFI_TIMEOUT;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+ registers in the PCI root bridge memory space.
+ The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+ any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operation.
+ @param[in] Address The base address of the memory operation. The caller is
+ responsible for aligning the Address if required.
+ @param[in] Count The number of memory operations to perform. Bytes moved is
+ Width size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+ registers in the PCI root bridge memory space.
+ The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+ any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operation.
+ @param[in] Address The base address of the memory operation. The caller is
+ responsible for aligning the Address if required.
+ @param[in] Count The number of memory operations to perform. Bytes moved is
+ Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The base address of the I/O operation. The caller is responsible for
+ aligning the Address if required.
+ @param[in] Count The number of I/O operations to perform. Bytes moved is Width
+ size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width >= EfiPciWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The base address of the I/O operation. The caller is responsible for
+ aligning the Address if required.
+ @param[in] Count The number of I/O operations to perform. Bytes moved is Width
+ size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width >= EfiPciWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+ Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
+ root bridge memory space.
+
+ The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
+ space to another region of PCI root bridge memory space. This is especially useful for video scroll
+ operation on a memory mapped video buffer.
+ The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+ any alignment and memory width restrictions that a PCI root bridge on a platform might require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] DestAddress The destination address of the memory operation. The caller is
+ responsible for aligning the DestAddress if required.
+ @param[in] SrcAddress The source address of the memory operation. The caller is
+ responsible for aligning the SrcAddress if required.
+ @param[in] Count The number of memory operations to perform. Bytes moved is
+ Width size * Count, starting at DestAddress and SrcAddress.
+
+ @retval EFI_SUCCESS The data was copied from one memory region to another memory region.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN Direction;
+ UINTN Stride;
+ UINTN Index;
+ UINT64 Result;
+
+ if (Width > EfiPciWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DestAddress == SrcAddress) {
+ return EFI_SUCCESS;
+ }
+
+ Stride = (UINTN)(1 << Width);
+
+ Direction = TRUE;
+ if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
+ Direction = FALSE;
+ SrcAddress = SrcAddress + (Count-1) * Stride;
+ DestAddress = DestAddress + (Count-1) * Stride;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ Status = RootBridgeIoMemRead (
+ This,
+ Width,
+ SrcAddress,
+ 1,
+ &Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = RootBridgeIoMemWrite (
+ This,
+ Width,
+ DestAddress,
+ 1,
+ &Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Direction) {
+ SrcAddress += Stride;
+ DestAddress += Stride;
+ } else {
+ SrcAddress -= Stride;
+ DestAddress -= Stride;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+ The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+ registers for a PCI controller.
+ The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+ any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+ require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ )
+{
+ return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+ The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+ registers for a PCI controller.
+ The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+ any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+ require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ )
+{
+ return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+ Provides the PCI controller-specific addresses required to access system memory from a
+ DMA bus master.
+
+ The Map() function provides the PCI controller specific addresses needed to access system
+ memory. This function is used to map system memory for PCI bus master DMA accesses.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Operation Indicates if the bus master is going to read or write to system memory.
+ @param[in] HostAddress The system memory address to map to the PCI controller.
+ @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.
+ @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use
+ to access the system memory's HostAddress.
+ @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_INVALID_PARAMETER Operation is invalid.
+ @retval EFI_INVALID_PARAMETER HostAddress is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.
+ @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.
+ @retval EFI_INVALID_PARAMETER Mapping is NULL.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+ MAP_INFO *MapInfo;
+
+ if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the return values to their defaults
+ //
+ *Mapping = NULL;
+
+ //
+ // Make sure that Operation is valid
+ //
+ if ((UINT32)Operation >= EfiPciOperationMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*NumberOfBytes) > PcdGet64 (PcdPciMemOneTransaction)) {
+ DEBUG((DEBUG_INFO, "Cannot map more than 0x%x at one transaction\n",
+ PcdGet64 (PcdPciMemOneTransaction)));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If any part of the DMA transfer being mapped is above 4GB, then
+ // map the DMA transfer to a buffer below 4GB
+ //
+ PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+ if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {
+
+ //
+ // Common Buffer operations can not be remapped. If the common buffer
+ // if above 4GB, then it is not possible to generate a mapping, so return
+ // an error.
+ //
+ if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
+ // called later.
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (MAP_INFO),
+ (VOID **)&MapInfo
+ );
+ if (EFI_ERROR (Status)) {
+ *NumberOfBytes = 0;
+ return Status;
+ }
+
+ //
+ // Return a pointer to the MAP_INFO structure in Mapping
+ //
+ *Mapping = MapInfo;
+
+ //
+ // Initialize the MAP_INFO structure
+ //
+ MapInfo->Operation = Operation;
+ MapInfo->NumberOfBytes = *NumberOfBytes;
+ MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (*NumberOfBytes);
+ MapInfo->HostAddress = PhysicalAddress;
+ MapInfo->MappedHostAddress = GetPciAddressSpaceMask ();
+
+ //
+ // Allocate a buffer below 4GB to map the transfer to.
+ //
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ MapInfo->NumberOfPages,
+ &MapInfo->MappedHostAddress
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (MapInfo);
+ *NumberOfBytes = 0;
+ return Status;
+ }
+
+ //
+ // If this is a read operation from the Bus Master's point of view,
+ // then copy the contents of the real buffer into the mapped buffer
+ // so the Bus Master can read the contents of the real buffer.
+ //
+ if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
+ CopyMem (
+ (VOID *)(UINTN)MapInfo->MappedHostAddress,
+ (VOID *)(UINTN)MapInfo->HostAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+
+ //
+ // The DeviceAddress is the address of the maped buffer below 4GB
+ //
+ *DeviceAddress = MapInfo->MappedHostAddress;
+ } else {
+ //
+ // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
+ //
+ *DeviceAddress = PhysicalAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ The Unmap() function completes the Map() operation and releases any corresponding resources.
+ If the operation was an EfiPciOperationBusMasterWrite or
+ EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
+ Any resources used for the mapping are freed.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+{
+ MAP_INFO *MapInfo;
+
+ //
+ // See if the Map() operation associated with this Unmap() required a mapping buffer.
+ // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
+ //
+ if (Mapping != NULL) {
+ //
+ // Get the MAP_INFO structure from Mapping
+ //
+ MapInfo = (MAP_INFO *)Mapping;
+
+ //
+ // If this is a write operation from the Bus Master's point of view,
+ // then copy the contents of the mapped buffer into the real buffer
+ // so the processor can read the contents of the real buffer.
+ //
+ if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {
+ CopyMem (
+ (VOID *)(UINTN)MapInfo->HostAddress,
+ (VOID *)(UINTN)MapInfo->MappedHostAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+
+ //
+ // Free the mapped buffer and the MAP_INFO structure.
+ //
+ gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
+ gBS->FreePool (Mapping);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
+ EfiPciOperationBusMasterCommonBuffer64 mapping.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Type This parameter is not used and must be ignored.
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the allocated range.
+ @param Attributes The requested bit mask of attributes for the allocated range. Only
+ the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CAC HED,and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_INVALID_PARAMETER MemoryType is invalid.
+ @retval EFI_INVALID_PARAMETER HostAddress is NULL.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+ //
+ // Validate Attributes
+ //
+ if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check for invalid inputs
+ //
+ if (HostAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+ //
+ if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Limit allocations to memory below 4GB
+ //
+ PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(GetPciAddressSpaceMask ());
+
+ Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *HostAddress = (VOID *)(UINTN)PhysicalAddress;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ OUT VOID *HostAddress
+ )
+{
+
+ return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
+}
+
+/**
+ Flushes all PCI posted write transactions from a PCI host bridge to system memory.
+
+ The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
+ memory. Posted write transactions are generated by PCI bus masters when they perform write
+ transactions to target addresses in system memory.
+ This function does not flush posted write transactions from any PCI bridges. A PCI controller
+ specific action must be taken to guarantee that the posted write transactions have been flushed from
+ the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
+ a PCI read transaction from the PCI controller prior to calling Flush().
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+ @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host
+ bridge to system memory.
+ @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI
+ host bridge due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+ )
+{
+ //
+ // not supported yet
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
+ attributes that a PCI root bridge is currently using.
+
+ The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
+ and the mask of attributes that the PCI root bridge is currently using
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Supported A pointer to the mask of attributes that this PCI root bridge
+ supports setting with SetAttributes().
+ @param Attributes A pointer to the mask of attributes that this PCI root bridge is
+ currently using.
+
+ @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root
+ bridge supports is returned in Supports. If Attributes is
+ not NULL, then the attributes that the PCI root bridge is currently
+ using is returned in Attributes.
+ @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes
+ )
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (Attributes == NULL && Supported == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Set the return value for Supported and Attributes
+ //
+ if (Supported != NULL) {
+ *Supported = PrivateData->Supports;
+ }
+
+ if (Attributes != NULL) {
+ *Attributes = PrivateData->Attributes;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets attributes for a resource range on a PCI root bridge.
+
+ The SetAttributes() function sets the attributes specified in Attributes for the PCI root
+ bridge on the resource range specified by ResourceBase and ResourceLength. Since the
+ granularity of setting these attributes may vary from resource type to resource type, and from
+ platform to platform, the actual resource range and the one passed in by the caller may differ. As a
+ result, this function may set the attributes specified by Attributes on a larger resource range
+ than the caller requested. The actual range is returned in ResourceBase and
+ ResourceLength. The caller is responsible for verifying that the actual range for which the
+ attributes were set is acceptable.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Attributes The mask of attributes to set. If the attribute bit
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
+ MEMORY_DISABLE is set, then the resource range is specified by
+ ResourceBase and ResourceLength. If
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
+ MEMORY_DISABLE are not set, then ResourceBase and
+ ResourceLength are ignored, and may be NULL.
+ @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified
+ by the attributes specified by Attributes.
+ @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the
+ attributes specified by Attributes.
+
+ @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.
+ @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+ @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength
+ )
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (Attributes != 0) {
+ if ((Attributes & (~(PrivateData->Supports))) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // This is a generic driver for a PC-AT class system. It does not have any
+ // chipset specific knowlegde, so none of the attributes can be set or
+ // cleared. Any attempt to set attribute that are already set will succeed,
+ // and any attempt to set an attribute that is not supported will fail.
+ //
+ if (Attributes & (~PrivateData->Attributes)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
+ resource descriptors.
+
+ There are only two resource descriptor types from the ACPI Specification that may be used to
+ describe the current resources allocated to a PCI root bridge. These are the QWORD Address
+ Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
+ QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
+ or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
+ Address Space Descriptors followed by an End Tag.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the
+ current configuration of this PCI root bridge. The storage for the
+ ACPI 2.0 resource descriptors is allocated by this function. The
+ caller must treat the return buffer as read-only data, and the buffer
+ must not be freed by the caller.
+
+ @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.
+ @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+ @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources
+)
+{
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
+ UINTN Index;
+
+ RootBridge = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ for (Index = 0; Index < ResTypeMax; Index++) {
+ if (RootBridge->ResAlloc[Index].Length != 0) {
+ Configuration.SpaceDesp[Index].AddrRangeMin = RootBridge->ResAlloc[Index].Base;
+ Configuration.SpaceDesp[Index].AddrRangeMax = RootBridge->ResAlloc[Index].Base + RootBridge->ResAlloc[Index].Length - 1;
+ Configuration.SpaceDesp[Index].AddrLen = RootBridge->ResAlloc[Index].Length;
+ }
+ }
+
+ // Set up Configuration for the bus
+ Configuration.SpaceDesp[Index].AddrRangeMin = RootBridge->BusStart;
+ Configuration.SpaceDesp[Index].AddrLen = RootBridge->BusLength;
+
+ *Resources = &Configuration;
+ return EFI_SUCCESS;
+}
diff --git a/Platform/NXP/Include/PciHostBridge.h b/Platform/NXP/Include/PciHostBridge.h
new file mode 100644
index 0000000..cfca971
--- /dev/null
+++ b/Platform/NXP/Include/PciHostBridge.h
@@ -0,0 +1,466 @@
+/** PciHostBridge.h
+ The Header file of the Pci Host Bridge Driver
+
+ Some part of code is inspired from EDK II, File:
+ PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.h
+
+ Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved. <BR>
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI_HOST_BRIDGE_H_
+#define _PCI_HOST_BRIDGE_H_
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Metronome.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <SerDes.h>
+
+#include "PciCntrlLib.h"
+
+#define MAX_PCI_DEVICE_NUMBER 31
+#define MAX_PCI_FUNCTION_NUMBER 7
+#define MAX_PCI_REG_ADDRESS (SIZE_4KB - 1)
+
+#define LS_PCIE_CFG0_PHYS_OFF 0x00000000
+#define LS_PCIE_CFG0_SIZE 0x00001000 /* 4k */
+#define LS_PCIE_CFG1_PHYS_OFF 0x00001000
+#define LS_PCIE_CFG1_SIZE 0x00001000 /* 4k */
+
+#define LS_PCIE_IO_BUS 0x00000000
+#define LS_PCIE_IO_PHYS_OFF 0x00010000
+#define LS_PCIE_IO_SIZE 0x00010000 /* 64k */
+
+#define LS_PCIE_MEM_BUS 0x40000000
+#define LS_PCIE_MEM_PHYS_OFF 0x40000000
+#define LS_PCIE_MEM_SIZE 0x40000000 /* 1 GB */
+
+#define PCI_MEM64_SIZE FixedPcdGet64 (PcdPciMmio64Size)
+
+#define NUM_PCIE_CONTROLLER FixedPcdGet32 (PcdNumPciController)
+
+#define PCI_MMIO64_BASE_DIFFERENCE 0x800000000
+
+typedef enum {
+ IoOperation,
+ MemOperation,
+ PciOperation
+} OPERATION_TYPE;
+
+#define PCI_HOST_BRIDGE_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'h')
+typedef struct PCI_HOST_BRIDGE_INSTANCE_ST {
+ UINTN Signature;
+ EFI_HANDLE HostBridgeHandle;
+ EFI_HANDLE ImageHandle;
+ UINTN RootBridgeNumber[4];
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
+ LIST_ENTRY Head;
+ BOOLEAN ResourceSubmited;
+ BOOLEAN CanRestarted;
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL ResAlloc;
+} PCI_HOST_BRIDGE_INSTANCE;
+
+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \
+ CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
+
+//
+// HostBridge Resource Allocation interface
+//
+/**
+ These are the notifications from the PCI bus driver that it is about to enter a certain
+ phase of the PCI enumeration process.
+
+ This member function can be used to notify the host bridge driver to perform specific actions,
+ including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
+ Eight notification points are defined at this time. See belows:
+ EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures and internal data
+ structures. The PCI enumerator should issue this notification
+ before starting a fresh enumeration process. Enumeration cannot
+ be restarted after sending any other notification such as
+ EfiPciHostBridgeBeginBusAllocation.
+ EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to begin. No specific action is
+ required here. This notification can be used to perform any
+ chipset-specific programming.
+ EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming phase is complete. No
+ specific action is required here. This notification can be used to
+ perform any chipset-specific programming.
+ EfiPciHostBridgeBeginResourceAllocation
+ The resource allocation phase is about to begin. No specific
+ action is required here. This notification can be used to perform
+ any chipset-specific programming.
+ EfiPciHostBridgeAllocateResources Allocates resources per previously submitted requests for all the PCI
+ root bridges. These resource settings are returned on the next call to
+ GetProposedResources(). Before calling NotifyPhase() with a Phase of
+ EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
+ for gathering I/O and memory requests for
+ all the PCI root bridges and submitting these requests using
+ SubmitResources(). This function pads the resource amount
+ to suit the root bridge hardware, takes care of dependencies between
+ the PCI root bridges, and calls the Global Coherency Domain (GCD)
+ with the allocation request. In the case of padding, the allocated range
+ could be bigger than what was requested.
+ EfiPciHostBridgeSetResources Programs the host bridge hardware to decode previously allocated
+ resources (proposed resources) for all the PCI root bridges. After the
+ hardware is programmed, reassigning resources will not be supported.
+ The bus settings are not affected.
+ EfiPciHostBridgeFreeResources Deallocates resources that were previously allocated for all the PCI
+ root bridges and resets the I/O and memory apertures to their initial
+ state. The bus settings are not affected. If the request to allocate
+ resources fails, the PCI enumerator can use this notification to
+ deallocate previous resources, adjust the requests, and retry
+ allocation.
+ EfiPciHostBridgeEndResourceAllocation The resource allocation phase is completed. No specific action is
+ required here. This notification can be used to perform any chipsetspecific
+ programming.
+
+ @param[in] This The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ @param[in] Phase The phase during enumeration
+
+ @retval EFI_NOT_READY This phase cannot be entered at this time. For example, this error
+ is valid for a Phase of EfiPciHostBridgeAllocateResources if
+ SubmitResources() has not been called for one or more
+ PCI root bridges before this call
+ @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. This error is valid
+ for a Phase of EfiPciHostBridgeSetResources.
+ @retval EFI_INVALID_PARAMETER Invalid phase parameter
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
+ previously submitted resource requests cannot be fulfilled or
+ were only partially fulfilled.
+ @retval EFI_SUCCESS The notification was accepted without any errors.
+
+**/
+EFI_STATUS
+EFIAPI
+PciNotifyPhase(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+ );
+
+/**
+ Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
+
+ This function is called multiple times to retrieve the device handles of all the PCI root bridges that
+ are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
+ root bridges. On each call, the handle that was returned by the previous call is passed into the
+ interface, and on output the interface returns the device handle of the next PCI root bridge. The
+ caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ for that root bridge. When there are no more PCI root bridges to report, the interface returns
+ EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
+ are returned by this function.
+ For D945 implementation, there is only one root bridge in PCI host bridge.
+
+ @param[in] This The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ @param[in, out] RootBridgeHandle Returns the device handle of the next PCI root bridge.
+
+ @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
+ specific Host bridge and return EFI_SUCCESS.
+ @retval EFI_NOT_FOUND Can not find the any more root bridge in specific host bridge.
+ @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
+ returned on a previous call to GetNextRootBridge().
+**/
+EFI_STATUS
+EFIAPI
+PciGetNextRootBridge(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN OUT EFI_HANDLE *RootBridgeHandle
+ );
+
+/**
+ Returns the allocation attributes of a PCI root bridge.
+
+ The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
+ from one PCI root bridge to another. These attributes are different from the decode-related
+ attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
+ RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
+ handles of all the root bridges that are associated with this host bridge must be obtained by calling
+ GetNextRootBridge(). The attributes are static in the sense that they do not change during or
+ after the enumeration process. The hardware may provide mechanisms to change the attributes on
+ the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
+ installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
+ "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
+ For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
+ include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
+ prefetchable memory.
+ Attribute Description
+ ------------------------------------ ----------------------------------------------------------------------
+ EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root bridge does not support separate
+ windows for nonprefetchable and prefetchable memory. A PCI bus
+ driver needs to include requests for prefetchable memory in the
+ nonprefetchable memory pool.
+
+ EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root bridge supports 64-bit memory
+ windows. If this bit is not set, the PCI bus driver needs to include
+ requests for a 64-bit memory address in the corresponding 32-bit
+ memory pool.
+
+ @param[in] This The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ @param[in] RootBridgeHandle The device handle of the PCI root bridge in which the caller is interested. Type
+ EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+ @param[out] Attributes The pointer to attribte of root bridge, it is output parameter
+
+ @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
+ @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
+ @retval EFI_SUCCESS Success to get attribute of interested root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PciGetAllocAttributes(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT UINT64 *Attributes
+ );
+
+/**
+ Sets up the specified PCI root bridge for the bus enumeration process.
+
+ This member function sets up the root bridge for bus enumeration and returns the PCI bus range
+ over which the search should be performed in ACPI 2.0 resource descriptor format.
+
+ @param[in] This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
+ @param[out] Configuration Pointer to the pointer to the PCI bus resource descriptor.
+
+ @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
+ @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
+ @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
+
+**/
+EFI_STATUS
+EFIAPI
+PciStartBusEnumeration(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ );
+
+/**
+ Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
+
+ This member function programs the specified PCI root bridge to decode the bus range that is
+ specified by the input parameter Configuration.
+ The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
+
+ @param[in] This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+ @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be programmed
+ @param[in] Configuration The pointer to the PCI bus resource descriptor
+
+ @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI 2.0 resource descriptor.
+ @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI 2.0 bus resource descriptor.
+ @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource descriptors other than
+ bus descriptors.
+ @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid ACPI resource descriptors.
+ @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this root bridge.
+ @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this root bridge.
+ @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
+ @retval EFI_SUCCESS The bus range for the PCI root bridge was programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+PciSetBusNumbers(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ );
+
+/**
+ Submits the I/O and memory resource requirements for the specified PCI root bridge.
+
+ This function is used to submit all the I/O and memory resources that are required by the specified
+ PCI root bridge. The input parameter Configuration is used to specify the following:
+ - The various types of resources that are required
+ - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+ @param[in] This Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+ @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory resource requirements are being submitted.
+ @param[in] Configuration The pointer to the PCI I/O and PCI memory resource descriptor.
+
+ @retval EFI_SUCCESS The I/O and memory resource requests for a PCI root bridge were accepted.
+ @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI 2.0 resource descriptor.
+ @retval EFI_INVALID_PARAMETER Configuration includes requests for one or more resource types that are
+ not supported by this PCI root bridge. This error will happen if the caller
+ did not combine resources according to Attributes that were returned by
+ GetAllocAttributes().
+ @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
+ @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for this PCI root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PciSubmitResources(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ );
+
+/**
+ Returns the proposed resource settings for the specified PCI root bridge.
+
+ This member function returns the proposed resource settings for the specified PCI root bridge. The
+ proposed resource settings are prepared when NotifyPhase() is called with a Phase of
+ EfiPciHostBridgeAllocateResources. The output parameter Configuration
+ specifies the following:
+ - The various types of resources, excluding bus resources, that are allocated
+ - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+ @param[in] This Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+ @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+ @param[out] Configuration The pointer to the pointer to the PCI I/O and memory resource descriptor.
+
+ @retval EFI_SUCCESS The requested parameters were returned.
+ @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle.
+ @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+PciGetProposedResources(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ );
+
+/**
+ Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
+ stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
+ PCI controllers before enumeration.
+
+ This function is called during the PCI enumeration process. No specific action is expected from this
+ member function. It allows the host bridge driver to preinitialize individual PCI controllers before
+ enumeration.
+
+ @param This Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+ @param RootBridgeHandle The associated PCI root bridge handle. Type EFI_HANDLE is defined in
+ InstallProtocolInterface() in the UEFI 2.0 Specification.
+ @param PciAddress The address of the PCI device on the PCI bus. This address can be passed to the
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
+ configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
+ the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
+ @param Phase The phase of the PCI device enumeration.
+
+ @retval EFI_SUCCESS The requested parameters were returned.
+ @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle.
+ @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined in
+ EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
+ @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. The PCI enumerator should
+ not enumerate this device, including its child devices if it is a PCI-to-PCI
+ bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PciPreprocessController (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ );
+
+
+//
+// Define resource status constant
+//
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL
+
+//
+// Driver Instance Data Prototypes
+//
+
+typedef struct {
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
+ UINTN NumberOfBytes;
+ UINTN NumberOfPages;
+ EFI_PHYSICAL_ADDRESS HostAddress;
+ EFI_PHYSICAL_ADDRESS MappedHostAddress;
+} MAP_INFO;
+
+typedef enum {
+ ResNone = 0,
+ ResSubmitted,
+ ResRequested,
+ ResAllocated,
+ ResStatusMax
+} RES_STATUS;
+
+typedef struct {
+ PCI_RESOURCE_TYPE Type;
+ UINT64 Base;
+ UINT64 Length;
+ UINT64 Alignment;
+ RES_STATUS Status;
+} PCI_RES_NODE;
+
+#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32('P', 'C', 'I', '3')
+
+//
+// Driver Instance Data Macros
+//
+#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \
+ CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+
+#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \
+ CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
+
+/**
+ Initialize and create Pci Root Bridges for Board
+
+ @param PrvateData Driver instance of this Root Bridge IO protocol
+ @param Protocol Point to protocol instance
+ @param Info Point to Info field of this driver instance
+ @param HostBridgeHandle Handle of host bridge
+ @param Attri Attribute of host bridge
+ @param HostNo HostNo for this Host Bridge
+ @param Busno Bus Number for the Host Bridge
+
+ @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
+
+**/
+
+EFI_STATUS
+PciRbInitialize (
+ IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
+ IN LsPcieInfo *Info,
+ IN EFI_HANDLE HostBridgeHandle,
+ IN UINT64 Attri,
+ IN INTN HostNo,
+ IN INTN Busno,
+ IN UINT64 *PciBaseAddr
+);
+
+/**
+ Function to return PCI addess space mask
+**/
+UINT64
+GetPciAddressSpaceMask (
+ IN VOID
+ );
+
+#endif
diff --git a/Platform/NXP/Include/PciRootBridge.h b/Platform/NXP/Include/PciRootBridge.h
new file mode 100644
index 0000000..cd22e48
--- /dev/null
+++ b/Platform/NXP/Include/PciRootBridge.h
@@ -0,0 +1,674 @@
+/** PciRootBridge.h
+ The Header file of the Pci Root Bridge driver
+
+ Copyright 2017 NXP
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI_LS_H_
+#define _PCI_LS_H_
+
+#include <Library/IoLib.h>
+
+#define MAX_PCI_REGIONS 7
+
+typedef UINT64 PciAddrT;
+typedef UINT64 PciSizeT;
+typedef UINT64 PhysAddrT;
+typedef UINT64 PhysSizeT;
+typedef INTN PciDevT;
+
+//
+// Protocol Member Function Prototypes
+//
+
+/**
+ Polls an address in memory mapped I/O space until an exit condition is met, or
+ a timeout occurs.
+
+ This function provides a standard way to poll a PCI memory location. A PCI memory read
+ operation is performed at the PCI memory address specified by Address for the width specified
+ by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
+ read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
+ Mask) is equal to Value.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The base address of the memory operations. The caller is
+ responsible for aligning Address if required.
+ @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask
+ are ignored. The bits in the bytes below Width which are zero in
+ Mask are ignored when polling the memory address.
+ @param[in] Value The comparison value used for the polling exit criteria.
+ @param[in] Delay The number of 100 ns units to poll. Note that timer available may
+ be of poorer granularity.
+ @param[out] Result Pointer to the last value read from the memory location.
+
+ @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
+ @retval EFI_INVALID_PARAMETER Width is invalid.
+ @retval EFI_INVALID_PARAMETER Result is NULL.
+ @retval EFI_TIMEOUT Delay expired before a match occurred.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+/**
+ Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
+ satisfied or after a defined duration.
+
+ This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
+ performed at the PCI I/O address specified by Address for the width specified by Width.
+ The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
+ repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
+ to Value.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the I/O operations.
+ @param[in] Address The base address of the I/O operations. The caller is responsible
+ for aligning Address if required.
+ @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask
+ are ignored. The bits in the bytes below Width which are zero in
+ Mask are ignored when polling the I/O address.
+ @param[in] Value The comparison value used for the polling exit criteria.
+ @param[in] Delay The number of 100 ns units to poll. Note that timer available may
+ be of poorer granularity.
+ @param[out] Result Pointer to the last value read from the memory location.
+
+ @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.
+ @retval EFI_INVALID_PARAMETER Width is invalid.
+ @retval EFI_INVALID_PARAMETER Result is NULL.
+ @retval EFI_TIMEOUT Delay expired before a match occurred.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+ registers in the PCI root bridge memory space.
+ The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+ any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operation.
+ @param[in] Address The base address of the memory operation. The caller is
+ responsible for aligning the Address if required.
+ @param[in] Count The number of memory operations to perform. Bytes moved is
+ Width size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+ registers in the PCI root bridge memory space.
+ The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+ any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operation.
+ @param[in] Address The base address of the memory operation. The caller is
+ responsible for aligning the Address if required.
+ @param[in] Count The number of memory operations to perform. Bytes moved is
+ Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] UserAddress The base address of the I/O operation. The caller is responsible for
+ aligning the Address if required.
+ @param[in] Count The number of I/O operations to perform. Bytes moved is Width
+ size * Count, starting at Address.
+ @param[out] UserBuffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ OUT VOID *UserBuffer
+ );
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] UserAddress The base address of the I/O operation. The caller is responsible for
+ aligning the Address if required.
+ @param[in] Count The number of I/O operations to perform. Bytes moved is Width
+ size * Count, starting at Address.
+ @param[in] UserBuffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN VOID *UserBuffer
+ );
+
+/**
+ Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
+ root bridge memory space.
+
+ The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
+ space to another region of PCI root bridge memory space. This is especially useful for video scroll
+ operation on a memory mapped video buffer.
+ The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+ any alignment and memory width restrictions that a PCI root bridge on a platform might require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] DestAddress The destination address of the memory operation. The caller is
+ responsible for aligning the DestAddress if required.
+ @param[in] SrcAddress The source address of the memory operation. The caller is
+ responsible for aligning the SrcAddress if required.
+ @param[in] Count The number of memory operations to perform. Bytes moved is
+ Width size * Count, starting at DestAddress and SrcAddress.
+
+ @retval EFI_SUCCESS The data was copied from one memory region to another memory region.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count
+ );
+
+/**
+ Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+ The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+ registers for a PCI controller.
+ The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+ any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+ require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[out] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ OUT VOID *Buffer
+ );
+
+/**
+ Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+ The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+ registers for a PCI controller.
+ The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+ any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+ require.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Width Signifies the width of the memory operations.
+ @param[in] Address The address within the PCI configuration space for the PCI controller.
+ @param[in] Count The number of PCI configuration operations to perform. Bytes
+ moved is Width size * Count, starting at Address.
+ @param[in] Buffer For read operations, the destination buffer to store the results. For
+ write operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.
+ @retval EFI_INVALID_PARAMETER Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer
+ );
+
+/**
+ Provides the PCI controller-specific addresses required to access system memory from a
+ DMA bus master.
+
+ The Map() function provides the PCI controller specific addresses needed to access system
+ memory. This function is used to map system memory for PCI bus master DMA accesses.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Operation Indicates if the bus master is going to read or write to system memory.
+ @param[in] HostAddress The system memory address to map to the PCI controller.
+ @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.
+ @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use
+ to access the system memory's HostAddress.
+ @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_INVALID_PARAMETER Operation is invalid.
+ @retval EFI_INVALID_PARAMETER HostAddress is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.
+ @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.
+ @retval EFI_INVALID_PARAMETER Mapping is NULL.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Completes the Map() operation and releases any corresponding resources.
+
+ The Unmap() function completes the Map() operation and releases any corresponding resources.
+ If the operation was an EfiPciOperationBusMasterWrite or
+ EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
+ Any resources used for the mapping are freed.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Mapping The mapping value returned from Map().
+
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+/**
+ Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
+ EfiPciOperationBusMasterCommonBuffer64 mapping.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Type This parameter is not used and must be ignored.
+ @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
+ @param Pages The number of pages to allocate.
+ @param HostAddress A pointer to store the base system memory address of the allocated range.
+ @param Attributes The requested bit mask of attributes for the allocated range. Only
+ the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
+ and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_INVALID_PARAMETER MemoryType is invalid.
+ @retval EFI_INVALID_PARAMETER HostAddress is NULL.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+/**
+ Frees memory that was allocated with AllocateBuffer().
+
+ The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Pages The number of pages to free.
+ @param HostAddress The base system memory address of the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ OUT VOID *HostAddress
+ );
+
+/**
+ Flushes all PCI posted write transactions from a PCI host bridge to system memory.
+
+ The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
+ memory. Posted write transactions are generated by PCI bus masters when they perform write
+ transactions to target addresses in system memory.
+ This function does not flush posted write transactions from any PCI bridges. A PCI controller
+ specific action must be taken to guarantee that the posted write transactions have been flushed from
+ the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
+ a PCI read transaction from the PCI controller prior to calling Flush().
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+ @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host
+ bridge to system memory.
+ @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI
+ host bridge due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+ );
+
+/**
+ Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
+ attributes that a PCI root bridge is currently using.
+
+ The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
+ and the mask of attributes that the PCI root bridge is currently using.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Supported A pointer to the mask of attributes that this PCI root bridge
+ supports setting with SetAttributes().
+ @param Attributes A pointer to the mask of attributes that this PCI root bridge is
+ currently using.
+
+ @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root
+ bridge supports is returned in Supports. If Attributes is
+ not NULL, then the attributes that the PCI root bridge is currently
+ using is returned in Attributes.
+ @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes
+ );
+
+/**
+ Sets attributes for a resource range on a PCI root bridge.
+
+ The SetAttributes() function sets the attributes specified in Attributes for the PCI root
+ bridge on the resource range specified by ResourceBase and ResourceLength. Since the
+ granularity of setting these attributes may vary from resource type to resource type, and from
+ platform to platform, the actual resource range and the one passed in by the caller may differ. As a
+ result, this function may set the attributes specified by Attributes on a larger resource range
+ than the caller requested. The actual range is returned in ResourceBase and
+ ResourceLength. The caller is responsible for verifying that the actual range for which the
+ attributes were set is acceptable.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[in] Attributes The mask of attributes to set. If the attribute bit
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
+ MEMORY_DISABLE is set, then the resource range is specified by
+ ResourceBase and ResourceLength. If
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
+ MEMORY_DISABLE are not set, then ResourceBase and
+ ResourceLength are ignored, and may be NULL.
+ @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified
+ by the attributes specified by Attributes.
+ @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the
+ attributes specified by Attributes.
+
+ @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.
+ @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+ @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength
+ );
+
+/**
+ Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
+ resource descriptors.
+
+ There are only two resource descriptor types from the ACPI Specification that may be used to
+ describe the current resources allocated to a PCI root bridge. These are the QWORD Address
+ Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
+ QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
+ or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
+ Address Space Descriptors followed by an End Tag.
+
+ @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the
+ current configuration of this PCI root bridge. The storage for the
+ ACPI 2.0 resource descriptors is allocated by this function. The
+ caller must treat the return buffer as read-only data, and the buffer
+ must not be freed by the caller.
+
+ @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.
+ @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+ @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources
+ );
+
+// Structure for PCI region
+typedef struct {
+ PciAddrT BusStart; // Start on the bus
+ PhysAddrT PhysStart; // Start in physical address space
+ PciSizeT Size; // Size
+ UINT64 Flags; // Resource flags
+ PciAddrT BusLower;
+} PciRegion;
+
+// Structure for PCI space(I/O,Mem,Configuration)
+typedef struct {
+ UINT64 Regs;
+ INT32 PciNum;
+ UINT64 Cfg0Phys;
+ UINT64 Cfg0Size;
+ UINT64 Cfg1Phys;
+ UINT64 Cfg1Size;
+ UINT64 MemBus;
+ UINT64 MemPhys;
+ UINT64 MemSize;
+ UINT64 IoBus;
+ UINT64 IoPhys;
+ UINT64 IoSize;
+} LsPcieInfo;
+
+typedef struct {
+ INTN Idx;
+ VOID *Dbi;
+ UINT32 *VaCfg0;
+ UINT32 *VaCfg1;
+} LsPcie;
+
+typedef struct {
+ UINTN Vendor, Device; // Vendor and device ID or PCI_ANY_ID
+} PciDeviceId;
+
+typedef struct {
+ UINTN Vendor, Device; // Vendor and device ID or PCI_ANY_ID
+ UINTN Class; // Class ID, or PCI_ANY_ID
+ UINTN Bus; // Bus number, or PCI_ANY_ID
+ UINTN Dev; // Device number, or PCI_ANY_ID
+ UINTN Func; // Function number, or PCI_ANY_ID
+ UINTN Priv[3];
+} PciConfigTable;
+
+#define ACPI_SPECFLAG_PREFETCHABLE 0x06
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+typedef enum {
+ ResTypeIo = 0,
+ ResTypeMem32,
+ ResTypePMem32,
+ ResTypeMem64,
+ ResTypePMem64,
+ ResTypeMax
+} PCI_RESOURCE_TYPE;
+
+typedef struct {
+ UINT64 Base;
+ UINT64 Length;
+ UINT64 Alignment;
+} PCI_RESOURCE_ALLOC;
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ EFI_HANDLE Handle;
+ UINT64 RootBridgeAttrib;
+ UINT64 Attributes;
+ UINT64 Supports;
+ UINTN BusStart;
+ UINTN BusLength;
+ UINT64 MemAllocAttributes;
+ PCI_RESOURCE_ALLOC ResAlloc[ResTypeMax];
+ UINT64 PciBaseAddress64;
+ UINT64 PciMemBase64;
+ LsPcieInfo *Info;
+ LsPcie *Pcie;
+ struct PCI_ROOT_BRIDGE_INSTANCE *Next;
+ INTN FirstBusno;
+ INTN LastBusno;
+ INTN CurrentBusno;
+ UINTN *CfgAddr;
+ CHAR8 *CfgData;
+ INTN IndirectType;
+ PciRegion Regions[MAX_PCI_REGIONS];
+ INTN RegionCnt;
+ PciConfigTable *ConfigTable;
+
+ PciRegion *PciMem, *PciIo, *PciPrefetch;
+
+ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH DevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
+
+} PCI_ROOT_BRIDGE_INSTANCE;
+
+#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH edk2-platforms 3/3] Compilation:Modify dsc, fdf files
2017-12-21 18:48 [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 2/3] Platform/NXP : Add PCI Host Bridge Driver Vabhav
@ 2017-12-21 18:48 ` Vabhav
2017-12-22 15:33 ` [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Ard Biesheuvel
3 siblings, 0 replies; 7+ messages in thread
From: Vabhav @ 2017-12-21 18:48 UTC (permalink / raw)
To: ard.biesheuvel, leif.lindholm, michael.d.kinney, edk2-devel
Enabling support for compilation of PciHost Bridge Library,
PciHostBridge Dxe Driver and include respective serdes functions
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Vabhav <vabhav.sharma@nxp.com>
---
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 31 ++++++++++++++++++++++++++++
Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 6 ++++++
Silicon/NXP/Chassis/Chassis.c | 11 ++++++++++
Silicon/NXP/Chassis/Chassis2/SerDes.h | 11 ++++++++++
Silicon/NXP/LS1043A/LS1043A.dsc | 1 +
5 files changed, 60 insertions(+)
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
index 7ea791e..21f451f 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc
@@ -54,6 +54,11 @@
#
MmcLib|edk2-platforms/Platform/NXP/Library/MmcLib/MmcLib.inf
+ #
+ # Pci Library
+ #
+ PciHostBridgeLib|edk2-platforms/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+
[PcdsFixedAtBuild.common]
#
@@ -70,6 +75,7 @@
gNxpQoriqLsTokenSpaceGuid.PcdWdogBigEndian|TRUE
gNxpQoriqLsTokenSpaceGuid.PcdMmcBigEndian|TRUE
gNxpQoriqLsTokenSpaceGuid.PcdIfcBigEndian|TRUE
+ gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|TRUE
#
# NV Storage PCDs.
@@ -79,6 +85,25 @@
gNxpQoriqLsTokenSpaceGuid.PcdFlashReservedRegionBase64|0x60300000
#
+ # PCIe Pcds
+ #
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp1SysAddr|0x03400000
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp2SysAddr|0x03500000
+ gNxpQoriqLsTokenSpaceGuid.PcdPciExp3SysAddr|0x03600000
+ gNxpQoriqLsTokenSpaceGuid.PcdKludgeMapPciMmioAsCached|FALSE
+ gNxpQoriqLsTokenSpaceGuid.PcdPciMaxPayloadFixup|FALSE
+ gNxpQoriqLsTokenSpaceGuid.PcdPciBusMin|0
+ gNxpQoriqLsTokenSpaceGuid.PcdPciBusMax|255
+ gNxpQoriqLsTokenSpaceGuid.PcdPci1Mmio64Base|0x4040000000
+ gNxpQoriqLsTokenSpaceGuid.PcdPci2Mmio64Base|0x4840000000
+ gNxpQoriqLsTokenSpaceGuid.PcdPci3Mmio64Base|0x5040000000
+ gNxpQoriqLsTokenSpaceGuid.PcdPciMmio64Size|0x0040000000
+ gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x10000
+ gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x7FC
+ gNxpQoriqLsTokenSpaceGuid.PcdPciMemOneTransaction|0x10000000
+
+ #
# I2C controller Pcds
#
gNxpQoriqLsTokenSpaceGuid.PcdI2cBus|0
@@ -109,4 +134,10 @@
EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
edk2-platforms/Platform/NXP/Drivers/MmcHostDxe/MmcHostDxe.inf
+ #
+ # PCI
+ #
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ edk2-platforms/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
##
diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
index 023480b..d462ae2 100644
--- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
+++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf
@@ -127,6 +127,12 @@ READ_LOCK_STATUS = TRUE
INF edk2-platforms/Platform/NXP/Drivers/NorFlashDxe/NorFlashDxe.inf
#
+ # PCI
+ #
+ INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ INF edk2-platforms/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+ #
# Network modules
#
INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
diff --git a/Silicon/NXP/Chassis/Chassis.c b/Silicon/NXP/Chassis/Chassis.c
index a6a77c2..2a7ecbc 100644
--- a/Silicon/NXP/Chassis/Chassis.c
+++ b/Silicon/NXP/Chassis/Chassis.c
@@ -411,3 +411,14 @@ CalculateI2cClockRate (
return SocSysInfo.FreqSystemBus;
}
+
+/**
+ Return PCI address space mask
+**/
+UINT64
+GetPciAddressSpaceMask (
+ IN VOID
+ )
+{
+ return MAX_UINT32;
+}
diff --git a/Silicon/NXP/Chassis/Chassis2/SerDes.h b/Silicon/NXP/Chassis/Chassis2/SerDes.h
index 9fc60d3..fb2e728 100644
--- a/Silicon/NXP/Chassis/Chassis2/SerDes.h
+++ b/Silicon/NXP/Chassis/Chassis2/SerDes.h
@@ -66,4 +66,15 @@ SerDesProbeLanes(
IN VOID *Arg
);
+VOID
+GetSerdesProtocolMaps(
+ OUT UINT64 *SerDes1ProtocolMapPtr
+);
+
+BOOLEAN
+IsSerDesLaneProtocolConfigured(
+ IN UINT64 SerDes1ProtocolMap,
+ IN SERDES_PROTOCOL Device
+);
+
#endif /* __SERDES_H */
diff --git a/Silicon/NXP/LS1043A/LS1043A.dsc b/Silicon/NXP/LS1043A/LS1043A.dsc
index 024c09a..22cea54 100644
--- a/Silicon/NXP/LS1043A/LS1043A.dsc
+++ b/Silicon/NXP/LS1043A/LS1043A.dsc
@@ -76,5 +76,6 @@
gNxpQoriqLsTokenSpaceGuid.PcdI2c2BaseAddr|0x021A0000
gNxpQoriqLsTokenSpaceGuid.PcdI2c3BaseAddr|0x021B0000
gNxpQoriqLsTokenSpaceGuid.PcdNumI2cController|4
+ gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|3
##
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver
2017-12-21 18:48 [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Vabhav
` (2 preceding siblings ...)
2017-12-21 18:48 ` [PATCH edk2-platforms 3/3] Compilation:Modify dsc, fdf files Vabhav
@ 2017-12-22 15:33 ` Ard Biesheuvel
2017-12-27 13:02 ` Vabhav Sharma
3 siblings, 1 reply; 7+ messages in thread
From: Ard Biesheuvel @ 2017-12-22 15:33 UTC (permalink / raw)
To: Vabhav
Cc: Leif Lindholm, Kinney, Michael D, edk2-devel@lists.01.org,
Udit Kumar, Varun Sethi
On 21 December 2017 at 18:48, Vabhav <vabhav.sharma@nxp.com> wrote:
> Following patches will add support of NXP PCI Host Bridge Driver in edk2-platforms directory 'edk2-platforms/Platform/NXP'
>
Why do you need a new PciHostBridgeDxe driver? Can't you use the one
in MdeModulePkg instead?
> Updated Directory structure for added folders in 'edk2-platforms/Platform/NXP' will be:
>
> Platform/NXP/Drivers/PciHostBridgeDxe/
> |-- PciHostBridgeDxe.c
> |-- PciHostBridgeDxe.inf
> `-- PciRootBridgeIo.c
>
> Platform/NXP/Library/PciHostBridgeLib/
> |-- PciCntrl.c
> |-- PciHostBridgeLib.inf
> `-- PciRbLib.c
>
Please put these in Silicon/NXP, not Platform/NXP
> In Platform/NXP/Library
> PciHostBridgeLib librady is added
>
> In Platform/NXP/Drivers:
> PciHostBridgeDxe driver is added
>
> Please review and look forward for your support in upstreaming the patches in edk2-platforms.
>
> Vabhav (3):
> Platform/NXP : Add PCI Host Bridge Libary
> Platform/NXP : Add PCI Host Bridge Driver
> Compilation:Modify dsc,fdf files
>
> .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c | 967 ++++++++++++++++
> .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 61 +
> .../NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 1193 ++++++++++++++++++++
> Platform/NXP/Include/PciCntrlLib.h | 323 ++++++
> Platform/NXP/Include/PciHostBridge.h | 466 ++++++++
> Platform/NXP/Include/PciLib.h | 414 +++++++
> Platform/NXP/Include/PciRootBridge.h | 674 +++++++++++
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 31 +
> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 6 +
> Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 +
> Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 ++++++
> Silicon/NXP/Chassis/Chassis.c | 11 +
> Silicon/NXP/Chassis/Chassis2/SerDes.h | 11 +
> Silicon/NXP/LS1043A/LS1043A.dsc | 1 +
> 15 files changed, 5166 insertions(+)
> create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
> create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
> create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
> create mode 100644 Platform/NXP/Include/PciCntrlLib.h
> create mode 100644 Platform/NXP/Include/PciHostBridge.h
> create mode 100644 Platform/NXP/Include/PciLib.h
> create mode 100644 Platform/NXP/Include/PciRootBridge.h
> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
>
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver
2017-12-22 15:33 ` [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Ard Biesheuvel
@ 2017-12-27 13:02 ` Vabhav Sharma
2017-12-27 13:05 ` Ard Biesheuvel
0 siblings, 1 reply; 7+ messages in thread
From: Vabhav Sharma @ 2017-12-27 13:02 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Leif Lindholm, Kinney, Michael D, edk2-devel@lists.01.org,
Udit Kumar, Varun Sethi
>-----Original Message-----
>From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>Sent: Friday, December 22, 2017 9:04 PM
>To: Vabhav Sharma <vabhav.sharma@nxp.com>
>Cc: Leif Lindholm <leif.lindholm@linaro.org>; Kinney, Michael D
><michael.d.kinney@intel.com>; edk2-devel@lists.01.org; Udit Kumar
><udit.kumar@nxp.com>; Varun Sethi <V.Sethi@nxp.com>
>Subject: Re: [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host
>Bridge Driver
>
>On 21 December 2017 at 18:48, Vabhav <vabhav.sharma@nxp.com> wrote:
>> Following patches will add support of NXP PCI Host Bridge Driver in edk2-
>platforms directory 'edk2-platforms/Platform/NXP'
>>
>
>Why do you need a new PciHostBridgeDxe driver? Can't you use the one in
>MdeModulePkg instead?
Using PciHostbridge dxe driver with changes for multiple(three) host bridge instances with 1:1 mapping for HostBridge:Root bridge(Hb:Rb), I will evaluate MdeModulePkg for
Multiple host bridge support
>
>> Updated Directory structure for added folders in 'edk2-
>platforms/Platform/NXP' will be:
>>
>> Platform/NXP/Drivers/PciHostBridgeDxe/
>> |-- PciHostBridgeDxe.c
>> |-- PciHostBridgeDxe.inf
>> `-- PciRootBridgeIo.c
>>
>> Platform/NXP/Library/PciHostBridgeLib/
>> |-- PciCntrl.c
>> |-- PciHostBridgeLib.inf
>> `-- PciRbLib.c
>>
>
>Please put these in Silicon/NXP, not Platform/NXP
Reference is taken from ARM/Hisilicon directory structure , We plan to put only chassis specific code in Silicon/NXP and Drivers, Library in Platform/NXP.
Please suggest if there is any specific reason for putting them in Silicon/NXP?
>
>> In Platform/NXP/Library
>> PciHostBridgeLib librady is added
>>
>> In Platform/NXP/Drivers:
>> PciHostBridgeDxe driver is added
>>
>> Please review and look forward for your support in upstreaming the patches in
>edk2-platforms.
>>
>> Vabhav (3):
>> Platform/NXP : Add PCI Host Bridge Libary
>> Platform/NXP : Add PCI Host Bridge Driver
>> Compilation:Modify dsc,fdf files
>>
>> .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c | 967 ++++++++++++++++
>> .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 61 +
>> .../NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 1193
>++++++++++++++++++++
>> Platform/NXP/Include/PciCntrlLib.h | 323 ++++++
>> Platform/NXP/Include/PciHostBridge.h | 466 ++++++++
>> Platform/NXP/Include/PciLib.h | 414 +++++++
>> Platform/NXP/Include/PciRootBridge.h | 674 +++++++++++
>> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 31 +
>> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 6 +
>> Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++
>> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 +
>> Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 ++++++
>> Silicon/NXP/Chassis/Chassis.c | 11 +
>> Silicon/NXP/Chassis/Chassis2/SerDes.h | 11 +
>> Silicon/NXP/LS1043A/LS1043A.dsc | 1 +
>> 15 files changed, 5166 insertions(+)
>> create mode 100644
>> Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
>> create mode 100644
>> Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
>> create mode 100644
>> Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
>> create mode 100644 Platform/NXP/Include/PciCntrlLib.h
>> create mode 100644 Platform/NXP/Include/PciHostBridge.h
>> create mode 100644 Platform/NXP/Include/PciLib.h create mode 100644
>> Platform/NXP/Include/PciRootBridge.h
>> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
>> create mode 100644
>> Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
>> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
>>
>> --
>> 1.9.1
>>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver
2017-12-27 13:02 ` Vabhav Sharma
@ 2017-12-27 13:05 ` Ard Biesheuvel
0 siblings, 0 replies; 7+ messages in thread
From: Ard Biesheuvel @ 2017-12-27 13:05 UTC (permalink / raw)
To: Vabhav Sharma
Cc: Leif Lindholm, Kinney, Michael D, edk2-devel@lists.01.org,
Udit Kumar, Varun Sethi
On 27 December 2017 at 13:02, Vabhav Sharma <vabhav.sharma@nxp.com> wrote:
>
>
>>-----Original Message-----
>>From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>>Sent: Friday, December 22, 2017 9:04 PM
>>To: Vabhav Sharma <vabhav.sharma@nxp.com>
>>Cc: Leif Lindholm <leif.lindholm@linaro.org>; Kinney, Michael D
>><michael.d.kinney@intel.com>; edk2-devel@lists.01.org; Udit Kumar
>><udit.kumar@nxp.com>; Varun Sethi <V.Sethi@nxp.com>
>>Subject: Re: [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host
>>Bridge Driver
>>
>>On 21 December 2017 at 18:48, Vabhav <vabhav.sharma@nxp.com> wrote:
>>> Following patches will add support of NXP PCI Host Bridge Driver in edk2-
>>platforms directory 'edk2-platforms/Platform/NXP'
>>>
>>
>>Why do you need a new PciHostBridgeDxe driver? Can't you use the one in
>>MdeModulePkg instead?
> Using PciHostbridge dxe driver with changes for multiple(three) host bridge instances with 1:1 mapping for HostBridge:Root bridge(Hb:Rb), I will evaluate MdeModulePkg for
> Multiple host bridge support
You will need to re-implement PciSegmentLib for that. Please find an
example here:
https://git.linaro.org/leg/noupstream/edk2-platforms.git/tree/Silicon/Socionext/SynQuacer/Library/SynQuacerPciSegmentLib?h=developer-box
>>
>>> Updated Directory structure for added folders in 'edk2-
>>platforms/Platform/NXP' will be:
>>>
>>> Platform/NXP/Drivers/PciHostBridgeDxe/
>>> |-- PciHostBridgeDxe.c
>>> |-- PciHostBridgeDxe.inf
>>> `-- PciRootBridgeIo.c
>>>
>>> Platform/NXP/Library/PciHostBridgeLib/
>>> |-- PciCntrl.c
>>> |-- PciHostBridgeLib.inf
>>> `-- PciRbLib.c
>>>
>>
>>Please put these in Silicon/NXP, not Platform/NXP
> Reference is taken from ARM/Hisilicon directory structure , We plan to put only chassis specific code in Silicon/NXP and Drivers, Library in Platform/NXP.
> Please suggest if there is any specific reason for putting them in Silicon/NXP?
Yes. Platform/ contains platform specific pieces, e.g., board level
driver, device tree images, .DSC files etc. Libraries and drivers that
can be shared between different platforms using the same SoC belong in
Silicon/NXP.
>>
>>> In Platform/NXP/Library
>>> PciHostBridgeLib librady is added
>>>
>>> In Platform/NXP/Drivers:
>>> PciHostBridgeDxe driver is added
>>>
>>> Please review and look forward for your support in upstreaming the patches in
>>edk2-platforms.
>>>
>>> Vabhav (3):
>>> Platform/NXP : Add PCI Host Bridge Libary
>>> Platform/NXP : Add PCI Host Bridge Driver
>>> Compilation:Modify dsc,fdf files
>>>
>>> .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c | 967 ++++++++++++++++
>>> .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 61 +
>>> .../NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 1193
>>++++++++++++++++++++
>>> Platform/NXP/Include/PciCntrlLib.h | 323 ++++++
>>> Platform/NXP/Include/PciHostBridge.h | 466 ++++++++
>>> Platform/NXP/Include/PciLib.h | 414 +++++++
>>> Platform/NXP/Include/PciRootBridge.h | 674 +++++++++++
>>> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 31 +
>>> Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 6 +
>>> Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++
>>> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 +
>>> Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 ++++++
>>> Silicon/NXP/Chassis/Chassis.c | 11 +
>>> Silicon/NXP/Chassis/Chassis2/SerDes.h | 11 +
>>> Silicon/NXP/LS1043A/LS1043A.dsc | 1 +
>>> 15 files changed, 5166 insertions(+)
>>> create mode 100644
>>> Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c
>>> create mode 100644
>>> Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf
>>> create mode 100644
>>> Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c
>>> create mode 100644 Platform/NXP/Include/PciCntrlLib.h
>>> create mode 100644 Platform/NXP/Include/PciHostBridge.h
>>> create mode 100644 Platform/NXP/Include/PciLib.h create mode 100644
>>> Platform/NXP/Include/PciRootBridge.h
>>> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c
>>> create mode 100644
>>> Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf
>>> create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c
>>>
>>> --
>>> 1.9.1
>>>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-12-27 13:00 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-21 18:48 [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 2/3] Platform/NXP : Add PCI Host Bridge Driver Vabhav
2017-12-21 18:48 ` [PATCH edk2-platforms 3/3] Compilation:Modify dsc, fdf files Vabhav
2017-12-22 15:33 ` [PATCH edk2-platforms 0/3] Platform/NXP-Added NXP PCI Host Bridge Driver Ard Biesheuvel
2017-12-27 13:02 ` Vabhav Sharma
2017-12-27 13:05 ` Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox