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
next prev parent 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