public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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