public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Vabhav <vabhav.sharma@nxp.com>
To: <ard.biesheuvel@linaro.org>, <leif.lindholm@linaro.org>,
	<michael.d.kinney@intel.com>, <edk2-devel@lists.01.org>
Subject: [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary
Date: Fri, 22 Dec 2017 00:18:27 +0530	[thread overview]
Message-ID: <1513882109-14295-2-git-send-email-vabhav.sharma@nxp.com> (raw)
In-Reply-To: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com>

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



  reply	other threads:[~2017-12-22  6:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2017-12-21 18:48 ` [PATCH edk2-platforms 2/3] Platform/NXP : Add " 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1513882109-14295-2-git-send-email-vabhav.sharma@nxp.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox