summaryrefslogtreecommitdiff
path: root/Platform/ARM/JunoPkg/Library
diff options
context:
space:
mode:
authorLeif Lindholm <leif.lindholm@linaro.org>2017-05-02 15:11:03 +0100
committerLeif Lindholm <leif.lindholm@linaro.org>2017-07-14 22:36:50 +0100
commit455396bda43fbf008811fdd5f549ae60c1cce877 (patch)
treebb0ba503c1720e00cd074c48c5f82edb9a8ef482 /Platform/ARM/JunoPkg/Library
parent1558779cccad9a1a552b4b0148cd390240cf5e3c (diff)
downloadedk2-platforms-455396bda43fbf008811fdd5f549ae60c1cce877.tar.xz
Platform: import ARM ltd. platforms
Import ARM Ltd. platforms Juno, FVP, TC2 at commit efd798c1eb of https://git.linaro.org/uefi/OpenPlatformPkg.git Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Diffstat (limited to 'Platform/ARM/JunoPkg/Library')
-rw-r--r--Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.c201
-rw-r--r--Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf77
-rw-r--r--Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.c182
-rw-r--r--Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.h107
4 files changed, 567 insertions, 0 deletions
diff --git a/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.c b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.c
new file mode 100644
index 0000000000..5263a2985d
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.c
@@ -0,0 +1,201 @@
+/** @file
+ PCI Host Bridge Library instance for ARM Juno
+
+ Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+
+ 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.
+
+**/
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include "ArmPlatform.h"
+
+#pragma pack(1)
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID(0x0A03), // PCI
+ 0
+ }, {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+STATIC PCI_ROOT_BRIDGE mRootBridge = {
+ 0, // Segment
+ 0, // Supports
+ 0, // Attributes
+ TRUE, // DmaAbove4G
+ FALSE, // NoExtendedConfigSpace
+ FALSE, // ResourceAssigned
+ EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes
+ EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
+ {
+ // Bus
+ FixedPcdGet32 (PcdPciBusMin),
+ FixedPcdGet32 (PcdPciBusMax)
+ }, {
+ // Io
+ FixedPcdGet64 (PcdPciIoBase),
+ FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
+ }, {
+ // Mem
+ FixedPcdGet32 (PcdPciMmio32Base),
+ FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1
+ }, {
+ // MemAbove4G
+ FixedPcdGet64 (PcdPciMmio64Base),
+ FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1
+ }, {
+ // PMem
+ MAX_UINT64,
+ 0
+ }, {
+ // PMemAbove4G
+ MAX_UINT64,
+ 0
+ },
+ (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath
+};
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+ UINTN *Count
+ )
+{
+ UINT32 JunoRevision;
+
+ //
+ // Juno R0 has no working PCIe
+ //
+ GetJunoRevision (JunoRevision);
+ if (JunoRevision < JUNO_REVISION_R1) {
+ *Count = 0;
+ return NULL;
+ }
+
+ *Count = 1;
+
+ return &mRootBridge;
+}
+
+/**
+ Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
+
+ @param Bridges The root bridge instances array.
+ @param Count The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+}
+
+
+#ifndef MDEPKG_NDEBUG
+STATIC CONST CHAR16 mPciHostBridgeLibAcpiAddressSpaceTypeStr[][4] = {
+ L"Mem", L"I/O", L"Bus"
+};
+#endif
+
+/**
+ Inform the platform that the resource conflict happens.
+
+ @param HostBridgeHandle Handle of the Host Bridge.
+ @param Configuration Pointer to PCI I/O and PCI memory resource
+ descriptors. The Configuration contains the resources
+ for all the root bridges. The resource for each root
+ bridge is terminated with END descriptor and an
+ additional END is appended indicating the end of the
+ entire resources. The resource descriptor field
+ values follow the description in
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+ EFI_HANDLE HostBridgeHandle,
+ VOID *Configuration
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN RootBridgeIndex;
+ DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+ RootBridgeIndex = 0;
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+ while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+ for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+ ASSERT (Descriptor->ResType <
+ ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr)
+ );
+ DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+ mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+ Descriptor->AddrLen, Descriptor->AddrRangeMax
+ ));
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
+ Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+ ((Descriptor->SpecificFlag &
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+ ) != 0) ? L" (Prefetchable)" : L""
+ ));
+ }
+ }
+ //
+ // Skip the END descriptor for root bridge
+ //
+ ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+ );
+ }
+}
diff --git a/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf
new file mode 100644
index 0000000000..68e22396cc
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/JunoPciHostBridgeLib.inf
@@ -0,0 +1,77 @@
+## @file
+# PCI Host Bridge Library instance for ARM Juno
+#
+# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#
+# 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 = 0x00010005
+ BASE_NAME = JunoPciHostBridgeLib
+ FILE_GUID = d92c722c-87f9-4988-843e-dffd6bc8c5e3
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib|DXE_DRIVER
+ CONSTRUCTOR = HWPciRbInit
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = AARCH64 ARM
+#
+
+[Sources]
+ JunoPciHostBridgeLib.c
+ XPressRich3.c
+
+[Packages]
+ ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+ ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ DevicePathLib
+ IoLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdPciBusMin
+ gArmTokenSpaceGuid.PcdPciBusMax
+ gArmTokenSpaceGuid.PcdPciIoBase
+ gArmTokenSpaceGuid.PcdPciIoSize
+ gArmTokenSpaceGuid.PcdPciIoTranslation
+ gArmTokenSpaceGuid.PcdPciMmio32Base
+ gArmTokenSpaceGuid.PcdPciMmio32Size
+ gArmTokenSpaceGuid.PcdPciMmio32Translation
+ gArmTokenSpaceGuid.PcdPciMmio64Base
+ gArmTokenSpaceGuid.PcdPciMmio64Size
+ gArmTokenSpaceGuid.PcdPciMmio64Translation
+
+ gArmJunoTokenSpaceGuid.PcdPcieControlBaseAddress
+ gArmJunoTokenSpaceGuid.PcdPcieRootPortBaseAddress
+ gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
+ gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceSize
+
+[Protocols]
+ gEfiCpuIo2ProtocolGuid ## CONSUMES
+
+[Depex]
+ gEfiCpuIo2ProtocolGuid
diff --git a/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.c b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.c
new file mode 100644
index 0000000000..a6d782949e
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.c
@@ -0,0 +1,182 @@
+/** @file
+* Initialize the XPress-RICH3 PCIe Root complex
+*
+* Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <IndustryStandard/Pci22.h>
+
+#include "XPressRich3.h"
+#include "ArmPlatform.h"
+
+#define PCI_BRIDGE_REVISION_ID 1
+#define CLASS_CODE_REGISTER(Class, SubClass, ProgIf) ((Class << 16) | (SubClass << 8) | ProgIf)
+#define PLDA_BRIDGE_CCR CLASS_CODE_REGISTER(PCI_CLASS_BRIDGE, \
+ PCI_CLASS_BRIDGE_P2P, \
+ PCI_IF_BRIDGE_P2P)
+
+STATIC
+VOID
+SetTranslationAddressEntry (
+ IN EFI_CPU_IO2_PROTOCOL *CpuIo,
+ IN UINTN Entry,
+ IN UINT64 SourceAddress,
+ IN UINT64 TranslatedAddress,
+ IN UINT64 TranslationSize,
+ IN UINT64 TranslationParameter
+ )
+{
+ UINTN Log2Size = HighBitSet64 (TranslationSize);
+
+ // Ensure the size is a power of two. Restriction form the AXI Translation logic
+ // Othwerwise we increase the translation size
+ if (TranslationSize != (1ULL << Log2Size)) {
+ DEBUG ((EFI_D_WARN, "PCI: The size 0x%lX of the region 0x%lx has been increased to "
+ "be a power of two for the AXI translation table.\n",
+ TranslationSize, SourceAddress));
+ Log2Size++;
+ }
+
+ PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_SRC_ADDR_LOW_SIZE,
+ (UINT32)SourceAddress | ((Log2Size - 1) << 1) | 0x1);
+ PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_SRC_ADDR_HI, SourceAddress >> 32);
+
+ PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_ADDR_LOW, (UINT32)TranslatedAddress);
+ PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_ADDR_HI, TranslatedAddress >> 32);
+
+ PCIE_ROOTPORT_WRITE32 (Entry + PCI_ATR_TRSL_PARAM, TranslationParameter);
+}
+
+EFI_STATUS
+HWPciRbInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT32 Value;
+ UINT32 Index;
+ UINTN TranslationTable;
+ EFI_CPU_IO2_PROTOCOL *CpuIo;
+ EFI_STATUS Status;
+
+ PCI_TRACE ("VExpressPciRbInit()");
+
+ PCI_TRACE ("PCIe Setting up Address Translation");
+
+ Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL,
+ (VOID **)&CpuIo);
+ ASSERT_EFI_ERROR (Status);
+
+ // The Juno PIO window is 8M, so we need full 32-bit PIO decoding.
+ PCIE_ROOTPORT_WRITE32 (PCIE_BAR_WIN, PCIE_BAR_WIN_SUPPORT_IO | PCIE_BAR_WIN_SUPPORT_IO32 |
+ PCIE_BAR_WIN_SUPPORT_MEM | PCIE_BAR_WIN_SUPPORT_MEM64);
+
+ // Setup the PCI Configuration Registers
+ // Offset 0a: SubClass 04 PCI-PCI Bridge
+ // Offset 0b: BaseClass 06 Bridge Device
+ // The Class Code register is a 24 bit and can be configured by setting up the PCIE_PCI_IDS
+ // Refer [1] Chapter 13
+ PCIE_ROOTPORT_WRITE32 (PCIE_PCI_IDS + PCIE_PCI_IDS_CLASSCODE_OFFSET, ((PLDA_BRIDGE_CCR << 8) | PCI_BRIDGE_REVISION_ID));
+
+ //
+ // PCIE Window 0 -> AXI4 Master 0 Address Translations
+ //
+ TranslationTable = VEXPRESS_ATR_PCIE_WIN0;
+
+ // MSI Support
+ SetTranslationAddressEntry (CpuIo, TranslationTable, ARM_JUNO_GIV2M_MSI_BASE, ARM_JUNO_GIV2M_MSI_BASE,
+ ARM_JUNO_GIV2M_MSI_SZ, PCI_ATR_TRSLID_AXIDEVICE);
+ TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+ // System Memory Support
+ SetTranslationAddressEntry (CpuIo, TranslationTable, PcdGet64 (PcdSystemMemoryBase), PcdGet64 (PcdSystemMemoryBase),
+ PcdGet64 (PcdSystemMemorySize), PCI_ATR_TRSLID_AXIMEMORY);
+ TranslationTable += PCI_ATR_ENTRY_SIZE;
+ SetTranslationAddressEntry (CpuIo, TranslationTable, ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE, ARM_JUNO_EXTRA_SYSTEM_MEMORY_BASE,
+ ARM_JUNO_EXTRA_SYSTEM_MEMORY_SZ, PCI_ATR_TRSLID_AXIMEMORY);
+
+ //
+ // AXI4 Slave 1 -> PCIE Window 0 Address Translations
+ //
+ TranslationTable = VEXPRESS_ATR_AXI4_SLV1;
+
+ // PCI ECAM Support
+ SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_ECAM_BASE, PCI_ECAM_BASE, PCI_ECAM_SIZE, PCI_ATR_TRSLID_PCIE_CONF);
+ TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+ // PCI IO Support, the PIO space is translated from the arm MMIO PCI_IO_BASE address to the PIO base address of 0
+ // AKA, PIO addresses used by endpoints are generally in the range of 0-64K.
+ SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_IO_BASE, 0, PCI_IO_SIZE, PCI_ATR_TRSLID_PCIE_IO);
+ TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+ // PCI MEM32 Support
+ SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_MEM32_BASE, PCI_MEM32_BASE, PCI_MEM32_SIZE, PCI_ATR_TRSLID_PCIE_MEMORY);
+ TranslationTable += PCI_ATR_ENTRY_SIZE;
+
+ // PCI MEM64 Support
+ SetTranslationAddressEntry (CpuIo, TranslationTable, PCI_MEM64_BASE, PCI_MEM64_BASE, PCI_MEM64_SIZE, PCI_ATR_TRSLID_PCIE_MEMORY);
+
+ // Add credits
+ PCIE_ROOTPORT_WRITE32 (PCIE_VC_CRED, 0x00f0b818);
+ PCIE_ROOTPORT_WRITE32 (PCIE_VC_CRED + 4, 0x1);
+
+ // Allow ECRC
+ PCIE_ROOTPORT_WRITE32 (PCIE_PEX_SPC2, 0x6006);
+
+ // Reset controller
+ PCIE_CONTROL_WRITE32 (PCIE_CONTROL_RST_CTL, PCIE_CONTROL_RST_CTL_RCPHY_REL);
+
+ // Wait for reset
+ for (Index = 0; Index < 1000; Index++) {
+ gBS->Stall (1000);
+ PCIE_CONTROL_READ32 (PCIE_CONTROL_RST_STS, Value);
+ if ((Value & PCIE_CONTROL_RST_STS_RCPHYPLL_OUT) == PCIE_CONTROL_RST_STS_RCPHYPLL_OUT) {
+ break;
+ }
+ }
+
+ // Check for reset
+ if (!(Value & PCIE_CONTROL_RST_STS_RCPHYPLL_OUT)) {
+ DEBUG ((EFI_D_ERROR, "PCIe failed to come out of reset: %x.\n", Value));
+ return EFI_NOT_READY;
+ }
+
+ gBS->Stall (1000);
+ PCI_TRACE ("Checking link Status...");
+
+ // Wait for Link Up
+ for (Index = 0; Index < 1000; Index++) {
+ gBS->Stall (1000);
+ PCIE_ROOTPORT_READ32 (VEXPRESS_BASIC_STATUS, Value);
+ if (Value & LINK_UP) {
+ break;
+ }
+ }
+
+ // Check for link up
+ if (!(Value & LINK_UP)) {
+ DEBUG ((EFI_D_ERROR, "PCIe link not up: %x.\n", Value));
+ return EFI_NOT_READY;
+ }
+
+ PCIE_ROOTPORT_WRITE32 (PCIE_IMASK_LOCAL, PCIE_INT_MSI | PCIE_INT_INTx);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.h b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.h
new file mode 100644
index 0000000000..07f52c210e
--- /dev/null
+++ b/Platform/ARM/JunoPkg/Library/JunoPciHostBridgeLib/XPressRich3.h
@@ -0,0 +1,107 @@
+/** @file
+* Header containing the Xpress-RICH3 PCIe Root Complex specific values
+*
+* Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __XPRESS_RICH3_H__
+#define __XPRESS_RICH3_H__
+
+#include <Protocol/CpuIo2.h>
+#include <Library/PcdLib.h>
+
+#define PCI_ECAM_BASE FixedPcdGet64 (PcdPciConfigurationSpaceBaseAddress)
+#define PCI_ECAM_SIZE FixedPcdGet64 (PcdPciConfigurationSpaceSize)
+#define PCI_IO_BASE FixedPcdGet64 (PcdPciIoTranslation)
+#define PCI_IO_SIZE FixedPcdGet64 (PcdPciIoSize)
+#define PCI_MEM32_BASE FixedPcdGet64 (PcdPciMmio32Base)
+#define PCI_MEM32_SIZE FixedPcdGet64 (PcdPciMmio32Size)
+#define PCI_MEM64_BASE FixedPcdGet64 (PcdPciMmio64Base)
+#define PCI_MEM64_SIZE FixedPcdGet64 (PcdPciMmio64Size)
+
+#define PCI_TRACE(txt) DEBUG((EFI_D_VERBOSE, "ARM_PCI: " txt "\n"))
+
+#define PCIE_ROOTPORT_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcieRootPortBaseAddress)+(Add)),1,&Value); }
+#define PCIE_ROOTPORT_READ32(Add, Val) { CpuIo->Mem.Read (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcieRootPortBaseAddress)+(Add)),1,&Val); }
+
+#define PCIE_CONTROL_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcieControlBaseAddress)+(Add)),1,&Value); }
+#define PCIE_CONTROL_READ32(Add, Val) { CpuIo->Mem.Read (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcieControlBaseAddress)+(Add)),1,&Val); }
+
+/*
+ * Bridge Internal Registers
+ */
+
+// PCIe Available Credit Settings
+#define PCIE_VC_CRED 0x090
+// PCIe PCI Standard Configuration Identification Settings registers
+#define PCIE_PCI_IDS 0x098
+#define PCIE_PCI_IDS_CLASSCODE_OFFSET 0x4
+// PCIe Specific 2 Capabilities Settings
+#define PCIE_PEX_SPC2 0x0d8
+// PCIe Windows Settings register
+#define PCIE_BAR_WIN 0x0FC
+// Local Processor Interrupt Mask
+#define PCIE_IMASK_LOCAL 0x180
+
+#define PCIE_BAR_WIN_SUPPORT_IO BIT0
+#define PCIE_BAR_WIN_SUPPORT_IO32 BIT1
+#define PCIE_BAR_WIN_SUPPORT_MEM BIT2
+#define PCIE_BAR_WIN_SUPPORT_MEM64 BIT3
+
+#define PCIE_INT_MSI BIT28
+#define PCIE_INT_A BIT24
+#define PCIE_INT_B BIT25
+#define PCIE_INT_C BIT26
+#define PCIE_INT_D BIT27
+#define PCIE_INT_INTx (PCIE_INT_A | PCIE_INT_B |\
+ PCIE_INT_C | PCIE_INT_D)
+
+/*
+ * PCIe Control Registers
+ */
+#define PCIE_CONTROL_RST_CTL 0x1004
+#define PCIE_CONTROL_RST_STS 0x1008
+
+/*
+ * PCI Express Address Translation registers
+ * All are offsets from PcdPcieControlBaseAddress
+ */
+#define VEXPRESS_ATR_PCIE_WIN0 0x600
+#define VEXPRESS_ATR_AXI4_SLV0 0x800
+#define VEXPRESS_ATR_AXI4_SLV1 0x820
+
+#define PCI_ATR_ENTRY_SIZE 0x20
+#define PCI_ATR_SRC_ADDR_LOW_SIZE 0
+#define PCI_ATR_SRC_ADDR_HI 0x4
+#define PCI_ATR_TRSL_ADDR_LOW 0x8
+#define PCI_ATR_TRSL_ADDR_HI 0xc
+#define PCI_ATR_TRSL_PARAM 0x10
+
+#define PCI_ATR_TRSLID_AXIDEVICE 0x420004
+#define PCI_ATR_TRSLID_AXIMEMORY 0x4e0004
+#define PCI_ATR_TRSLID_PCIE_CONF 0x000001
+#define PCI_ATR_TRSLID_PCIE_IO 0x020000
+#define PCI_ATR_TRSLID_PCIE_MEMORY 0x000000
+
+#define PCIE_CONTROL_RST_CTL_RC_REL (1 << 1)
+#define PCIE_CONTROL_RST_CTL_PHY_REL (1 << 0)
+#define PCIE_CONTROL_RST_CTL_RCPHY_REL (PCIE_CONTROL_RST_CTL_RC_REL | PCIE_CONTROL_RST_CTL_PHY_REL)
+
+#define PCIE_CONTROL_RST_STS_RC_ST (1 << 2)
+#define PCIE_CONTROL_RST_STS_PHY_ST (1 << 1)
+#define PCIE_CONTROL_RST_STS_PLL_ST (1 << 0)
+#define PCIE_CONTROL_RST_STS_RCPHYPLL_OUT (PCIE_CONTROL_RST_STS_RC_ST | PCIE_CONTROL_RST_STS_PHY_ST | PCIE_CONTROL_RST_STS_PLL_ST)
+
+#define VEXPRESS_BASIC_STATUS 0x18
+#define LINK_UP 0xff
+
+#endif