[edk2] [staging/cadence-aarch64 PATCH v3 3/6] CadencePkg: Add PCI host bridge library for Cadence PCIe Root Complex.

Scott Telford posted 6 patches 8 years, 7 months ago
[edk2] [staging/cadence-aarch64 PATCH v3 3/6] CadencePkg: Add PCI host bridge library for Cadence PCIe Root Complex.
Posted by Scott Telford 8 years, 7 months ago
Add PciHostBridgeLib implementation for the Cadence PCIe Root Complex.
This library is derived from
Platforms/ARM/Juno/Library/JunoPciHostBridgeLib in OpenPlatformPkg.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Telford <stelford@cadence.com>
---
 .../Library/CadencePciHostBridgeLib/CdnsPci.c      | 149 ++++++++++++++++
 .../Library/CadencePciHostBridgeLib/CdnsPci.h      |  88 ++++++++++
 .../CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c | 188 +++++++++++++++++++++
 .../CdnsPciHostBridgeLib.inf                       |  73 ++++++++
 4 files changed, 498 insertions(+)
 create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
 create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
 create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
 create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf

diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
new file mode 100644
index 0000000..3114843
--- /dev/null
+++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
@@ -0,0 +1,149 @@
+/** @file
+*  Initialize the Cadence PCIe Root complex
+*
+*  Copyright (c) 2017, Cadence Design Systems. 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 <Library/BaseLib.h>
+#include <Library/CspSysReg.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+
+#include "CdnsPci.h"
+
+STATIC
+VOID
+CdnsPciConfigRegion (
+  EFI_CPU_IO2_PROTOCOL *CpuIo,
+  IN UINT32 Region,
+  IN UINT32 Descriptor,
+  IN UINT32 TransAddr,
+  IN UINT32 TransAddrBits,
+  IN UINT32 BaseAddr,
+  IN UINT32 BaseAddrBits
+  )
+{
+  UINTN RegionBaseAddr = PCIE_AXI + (Region * PCIE_AXI_REGION_OFF);
+
+  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_TRANS0_OFF,
+                         TransAddr | TransAddrBits);
+  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_DESC_OFF,
+                         Descriptor);
+  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_BASE0_OFF,
+                         BaseAddr | BaseAddrBits);
+}
+
+STATIC
+VOID
+CdnsPciRegInit(
+  EFI_CPU_IO2_PROTOCOL    *CpuIo
+)
+{
+  UINT32                  Value;
+
+  // Setup the class code as PCIe Host Bridge.
+  PCIE_ROOTPORT_WRITE32 (PCIE_RP + PCIE_PCI_CLASSCODE, PCIE_BRIDGE_CLASSCODE);
+
+  // Set up the BARs via the Root Port registers
+  PCIE_ROOTPORT_READ32 (PCIE_LM + PCIE_RP_BAR_CONFIG, Value);
+  PCIE_ROOTPORT_WRITE32 (PCIE_LM + PCIE_RP_BAR_CONFIG, Value | (1 << PCIE_RCBARPIE));
+
+  // Allow incoming writes
+  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_BAR0_IB, PCIE_AXI_BITS_32);
+  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_BAR1_IB, PCIE_AXI_BITS_32);
+  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_NO_BAR_IB, PCIE_AXI_BITS_32);
+
+  // Set up region 0 for Type 0 write (bus 0 and 1), size 2MB
+  CdnsPciConfigRegion (
+          CpuIo,
+          0,
+          PCIE_AXI_DESC_TYPE0,
+          PCIE_ECAM_BASE,
+          PCIE_AXI_BITS_25,
+          0,
+          PCIE_AXI_BITS_21
+          );
+
+  // Set up region 1 for Type 1 writes (bus 2 upwards), size (32-2)MB
+  CdnsPciConfigRegion(
+          CpuIo,
+          1,
+          PCIE_AXI_DESC_TYPE1,
+          PCIE_ECAM_BASE + (2*PCIE_BUS_SIZE),
+          PCIE_AXI_BITS_25,
+          2*PCIE_BUS_SIZE,
+          PCIE_AXI_BITS_25
+          );
+
+  // Set up region 2 for memory write, size 16MB
+  CdnsPciConfigRegion(
+          CpuIo,
+          2,
+          PCIE_AXI_DESC_MEM,
+          PCIE_MEM32_BASE,
+          PCIE_AXI_BITS_25,
+          (PCIE_MEM32_BASE - PCIE_ECAM_BASE),
+          PCIE_AXI_BITS_24
+          );
+
+  // Set up region 3 for IO write, size 16MB
+  CdnsPciConfigRegion(
+          CpuIo,
+          3,
+          PCIE_AXI_DESC_IO,
+          PCIE_IO_BASE,
+          PCIE_AXI_BITS_25,
+          (PCIE_IO_BASE - PCIE_ECAM_BASE),
+          PCIE_AXI_BITS_24
+          );
+}
+
+EFI_STATUS
+HWPciRbInit (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  UINT32                  Count;
+  EFI_CPU_IO2_PROTOCOL    *CpuIo;
+  EFI_STATUS              Status;
+  UINT32                  Value;
+
+  PCI_TRACE ("HWPciRbInit()");
+
+  PCI_TRACE ("PCIe Setting up Address Translation");
+
+  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL,
+                  (VOID **)&CpuIo);
+  ASSERT_EFI_ERROR (Status);
+
+  // Check for link up
+  for (Count = 0; Count < PCIE_LINK_TIMEOUT_COUNT; Count++) {
+    gBS->Stall (PCIE_LINK_TIMEOUT_WAIT_US);
+    PCIE_ROOTPORT_READ32 (PCIE_LM + PCIE_LINK_CTRL_STATUS, Value);
+    if (Value & PCIE_LINK_UP) {
+      break;
+    }
+  }
+  if (!(Value & PCIE_LINK_UP)) {
+    DEBUG ((DEBUG_ERROR, "PCIe link not up: %x.\n", Value));
+    return EFI_NOT_READY;
+  }
+
+  // Initialise configuration registers
+  CdnsPciRegInit(CpuIo);
+
+  return EFI_SUCCESS;
+}
diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
new file mode 100644
index 0000000..08faece
--- /dev/null
+++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
@@ -0,0 +1,88 @@
+/** @file
+*  Header for Cadence PCIe Root Complex
+*
+*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*  Copyright (c) 2017, Cadence Design Systems. 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 __CDNS_PCI_H__
+#define __CDNS_PCI_H__
+
+#include <Protocol/CpuIo2.h>
+
+#define PCIE_ECAM_BASE       FixedPcdGet64 (PcdPciConfigurationSpaceBaseAddress)
+#define PCIE_ECAM_SIZE       FixedPcdGet64 (PcdPciConfigurationSpaceSize)
+#define PCIE_IO_BASE         (FixedPcdGet64(PcdPciIoTranslation) + FixedPcdGet64 (PcdPciIoBase))
+#define PCIE_IO_SIZE         FixedPcdGet64 (PcdPciIoSize)
+#define PCIE_MEM32_BASE      FixedPcdGet64 (PcdPciMmio32Base)
+#define PCIE_MEM32_SIZE      FixedPcdGet64 (PcdPciMmio32Size)
+
+#define PCIE_BUS_SIZE        SIZE_1MB
+
+#define PCIE_LINK_TIMEOUT_WAIT_US 1000 // microseconds
+#define PCIE_LINK_TIMEOUT_COUNT 1000
+
+#define PCI_TRACE(txt)  DEBUG((DEBUG_VERBOSE, "CDNS_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); }
+#ifdef CDNS_B2B
+#define PCIE1_ROOTPORT_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcie1RootPortBaseAddress)+(Add)),1,&Value); }
+#define PCIE1_ROOTPORT_READ32(Add, Val) { CpuIo->Mem.Read (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcie1RootPortBaseAddress)+(Add)),1,&Val); }
+#endif
+
+/*
+ * PCIe Core Configuration Register offsets
+ */
+
+// Root Port Configuration
+#define PCIE_RP                   0x00200000
+#define PCIE_PCI_CLASSCODE        0x8
+
+// Local Management
+#define PCIE_LM                   0x00100000
+#define PCIE_LINK_CTRL_STATUS     0x00
+#define PCIE_RP_BAR_CONFIG        0x300
+
+// AXI Configuration
+#define PCIE_AXI                   0x00400000
+
+#define PCIE_AXI_REGION_OFF        0x020
+#define PCIE_AXI_REGION_TRANS0_OFF 0x000
+#define PCIE_AXI_REGION_DESC_OFF   0x008
+#define PCIE_AXI_REGION_BASE0_OFF  0x018
+
+#define PCIE_AXI_BAR0_IB         0x800
+#define PCIE_AXI_BAR1_IB         0x808
+#define PCIE_AXI_NO_BAR_IB       0x810
+
+/*
+ * PCIe Core Configuration Register values
+ */
+
+#define PCIE_BRIDGE_CLASSCODE    0x06040000
+#define PCIE_LINK_UP             0x01
+#define PCIE_RCBARPIE            0x19
+
+// AXI Region Address Translation/Base Address bits values
+#define PCIE_AXI_BITS_21         20
+#define PCIE_AXI_BITS_24         23
+#define PCIE_AXI_BITS_25         24
+#define PCIE_AXI_BITS_32         31
+
+// AXI Region Outbound PCIe Descriptor Register values
+#define PCIE_AXI_DESC_TYPE0      0x80000A
+#define PCIE_AXI_DESC_TYPE1      0x80000B
+#define PCIE_AXI_DESC_MEM        0x800002
+#define PCIE_AXI_DESC_IO         0x800006
+
+#endif
diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
new file mode 100644
index 0000000..f58cac3
--- /dev/null
+++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
@@ -0,0 +1,188 @@
+/** @file
+  PCI Host Bridge support for the Cadence PCIe Root Complex
+
+  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2017, Cadence Design Systems. 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 <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+
+#include <PiDxe.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.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
+  {
+    // Bus
+    FixedPcdGet32 (PcdPciBusMin),
+    FixedPcdGet32 (PcdPciBusMax)
+  }, {
+    // Io
+    FixedPcdGet64 (PcdPciIoBase),
+    FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
+  }, {
+    // Mem
+    FixedPcdGet32 (PcdPciMmio32Base),
+    FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1
+  }, {
+    // MemAbove4G
+    MAX_UINT64,
+    0
+  }, {
+    // 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
+  )
+{
+  *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 ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+  RootBridgeIndex = 0;
+  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+      ASSERT (Descriptor->ResType <
+              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr)
+              );
+      DEBUG ((DEBUG_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 ((DEBUG_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/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
new file mode 100644
index 0000000..b17a96c
--- /dev/null
+++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
@@ -0,0 +1,73 @@
+## @file
+#  PCI Host Bridge Library instance for Cadence PCIe Root Complex
+#
+#  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2017, Cadence Design Systems. All rights reserved.
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 1.25
+  BASE_NAME                      = CdnsPciHostBridgeLib
+  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]
+  CdnsPciHostBridgeLib.c
+  CdnsPci.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  CadencePkg/CadenceCspPkg.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
+  gCadenceCspTokenSpaceGuid.PcdPcieRootPortBaseAddress
+  gCadenceCspTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
+  gCadenceCspTokenSpaceGuid.PcdPciConfigurationSpaceSize
+
+[Protocols]
+  gEfiCpuIo2ProtocolGuid          ## CONSUMES
+
+[Depex]
+  gEfiCpuIo2ProtocolGuid
-- 
2.2.2

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [staging/cadence-aarch64 PATCH v3 3/6] CadencePkg: Add PCI host bridge library for Cadence PCIe Root Complex.
Posted by Leif Lindholm 8 years, 7 months ago
On Thu, Jun 22, 2017 at 10:31:58AM +0100, Scott Telford wrote:
> Add PciHostBridgeLib implementation for the Cadence PCIe Root Complex.
> This library is derived from
> Platforms/ARM/Juno/Library/JunoPciHostBridgeLib in OpenPlatformPkg.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Scott Telford <stelford@cadence.com>
> ---
>  .../Library/CadencePciHostBridgeLib/CdnsPci.c      | 149 ++++++++++++++++
>  .../Library/CadencePciHostBridgeLib/CdnsPci.h      |  88 ++++++++++
>  .../CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c | 188 +++++++++++++++++++++
>  .../CdnsPciHostBridgeLib.inf                       |  73 ++++++++
>  4 files changed, 498 insertions(+)
>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
> 
> diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
> new file mode 100644
> index 0000000..3114843
> --- /dev/null
> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
> @@ -0,0 +1,149 @@
> +/** @file
> +*  Initialize the Cadence PCIe Root complex
> +*
> +*  Copyright (c) 2017, Cadence Design Systems. 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 <Library/BaseLib.h>
> +#include <Library/CspSysReg.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <Protocol/Cpu.h>
> +
> +#include "CdnsPci.h"
> +
> +STATIC
> +VOID
> +CdnsPciConfigRegion (
> +  EFI_CPU_IO2_PROTOCOL *CpuIo,
> +  IN UINT32 Region,
> +  IN UINT32 Descriptor,
> +  IN UINT32 TransAddr,
> +  IN UINT32 TransAddrBits,
> +  IN UINT32 BaseAddr,
> +  IN UINT32 BaseAddrBits
> +  )
> +{
> +  UINTN RegionBaseAddr = PCIE_AXI + (Region * PCIE_AXI_REGION_OFF);
> +
> +  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_TRANS0_OFF,
> +                         TransAddr | TransAddrBits);
> +  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_DESC_OFF,
> +                         Descriptor);
> +  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_BASE0_OFF,
> +                         BaseAddr | BaseAddrBits);
> +}
> +
> +STATIC
> +VOID
> +CdnsPciRegInit(
> +  EFI_CPU_IO2_PROTOCOL    *CpuIo
> +)
> +{
> +  UINT32                  Value;
> +
> +  // Setup the class code as PCIe Host Bridge.
> +  PCIE_ROOTPORT_WRITE32 (PCIE_RP + PCIE_PCI_CLASSCODE, PCIE_BRIDGE_CLASSCODE);
> +
> +  // Set up the BARs via the Root Port registers
> +  PCIE_ROOTPORT_READ32 (PCIE_LM + PCIE_RP_BAR_CONFIG, Value);
> +  PCIE_ROOTPORT_WRITE32 (PCIE_LM + PCIE_RP_BAR_CONFIG, Value | (1 << PCIE_RCBARPIE));
> +
> +  // Allow incoming writes
> +  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_BAR0_IB, PCIE_AXI_BITS_32);
> +  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_BAR1_IB, PCIE_AXI_BITS_32);
> +  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_NO_BAR_IB, PCIE_AXI_BITS_32);
> +
> +  // Set up region 0 for Type 0 write (bus 0 and 1), size 2MB
> +  CdnsPciConfigRegion (
> +          CpuIo,
> +          0,
> +          PCIE_AXI_DESC_TYPE0,
> +          PCIE_ECAM_BASE,
> +          PCIE_AXI_BITS_25,
> +          0,
> +          PCIE_AXI_BITS_21
> +          );
> +
> +  // Set up region 1 for Type 1 writes (bus 2 upwards), size (32-2)MB
> +  CdnsPciConfigRegion(
> +          CpuIo,
> +          1,
> +          PCIE_AXI_DESC_TYPE1,
> +          PCIE_ECAM_BASE + (2*PCIE_BUS_SIZE),
> +          PCIE_AXI_BITS_25,
> +          2*PCIE_BUS_SIZE,
> +          PCIE_AXI_BITS_25
> +          );
> +
> +  // Set up region 2 for memory write, size 16MB
> +  CdnsPciConfigRegion(
> +          CpuIo,
> +          2,
> +          PCIE_AXI_DESC_MEM,
> +          PCIE_MEM32_BASE,
> +          PCIE_AXI_BITS_25,
> +          (PCIE_MEM32_BASE - PCIE_ECAM_BASE),
> +          PCIE_AXI_BITS_24
> +          );
> +
> +  // Set up region 3 for IO write, size 16MB
> +  CdnsPciConfigRegion(
> +          CpuIo,
> +          3,
> +          PCIE_AXI_DESC_IO,
> +          PCIE_IO_BASE,
> +          PCIE_AXI_BITS_25,
> +          (PCIE_IO_BASE - PCIE_ECAM_BASE),
> +          PCIE_AXI_BITS_24
> +          );

Thanks - this is exactly what I was hoping for!
I'll leave for Ard to comment on hos bits, but:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> +}
> +
> +EFI_STATUS
> +HWPciRbInit (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  UINT32                  Count;
> +  EFI_CPU_IO2_PROTOCOL    *CpuIo;
> +  EFI_STATUS              Status;
> +  UINT32                  Value;
> +
> +  PCI_TRACE ("HWPciRbInit()");
> +
> +  PCI_TRACE ("PCIe Setting up Address Translation");
> +
> +  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL,
> +                  (VOID **)&CpuIo);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  // Check for link up
> +  for (Count = 0; Count < PCIE_LINK_TIMEOUT_COUNT; Count++) {
> +    gBS->Stall (PCIE_LINK_TIMEOUT_WAIT_US);
> +    PCIE_ROOTPORT_READ32 (PCIE_LM + PCIE_LINK_CTRL_STATUS, Value);
> +    if (Value & PCIE_LINK_UP) {
> +      break;
> +    }
> +  }
> +  if (!(Value & PCIE_LINK_UP)) {
> +    DEBUG ((DEBUG_ERROR, "PCIe link not up: %x.\n", Value));
> +    return EFI_NOT_READY;
> +  }
> +
> +  // Initialise configuration registers
> +  CdnsPciRegInit(CpuIo);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
> new file mode 100644
> index 0000000..08faece
> --- /dev/null
> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
> @@ -0,0 +1,88 @@
> +/** @file
> +*  Header for Cadence PCIe Root Complex
> +*
> +*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
> +*  Copyright (c) 2017, Cadence Design Systems. 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 __CDNS_PCI_H__
> +#define __CDNS_PCI_H__
> +
> +#include <Protocol/CpuIo2.h>
> +
> +#define PCIE_ECAM_BASE       FixedPcdGet64 (PcdPciConfigurationSpaceBaseAddress)
> +#define PCIE_ECAM_SIZE       FixedPcdGet64 (PcdPciConfigurationSpaceSize)
> +#define PCIE_IO_BASE         (FixedPcdGet64(PcdPciIoTranslation) + FixedPcdGet64 (PcdPciIoBase))
> +#define PCIE_IO_SIZE         FixedPcdGet64 (PcdPciIoSize)
> +#define PCIE_MEM32_BASE      FixedPcdGet64 (PcdPciMmio32Base)
> +#define PCIE_MEM32_SIZE      FixedPcdGet64 (PcdPciMmio32Size)
> +
> +#define PCIE_BUS_SIZE        SIZE_1MB
> +
> +#define PCIE_LINK_TIMEOUT_WAIT_US 1000 // microseconds
> +#define PCIE_LINK_TIMEOUT_COUNT 1000
> +
> +#define PCI_TRACE(txt)  DEBUG((DEBUG_VERBOSE, "CDNS_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); }
> +#ifdef CDNS_B2B
> +#define PCIE1_ROOTPORT_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcie1RootPortBaseAddress)+(Add)),1,&Value); }
> +#define PCIE1_ROOTPORT_READ32(Add, Val) { CpuIo->Mem.Read (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcie1RootPortBaseAddress)+(Add)),1,&Val); }
> +#endif
> +
> +/*
> + * PCIe Core Configuration Register offsets
> + */
> +
> +// Root Port Configuration
> +#define PCIE_RP                   0x00200000
> +#define PCIE_PCI_CLASSCODE        0x8
> +
> +// Local Management
> +#define PCIE_LM                   0x00100000
> +#define PCIE_LINK_CTRL_STATUS     0x00
> +#define PCIE_RP_BAR_CONFIG        0x300
> +
> +// AXI Configuration
> +#define PCIE_AXI                   0x00400000
> +
> +#define PCIE_AXI_REGION_OFF        0x020
> +#define PCIE_AXI_REGION_TRANS0_OFF 0x000
> +#define PCIE_AXI_REGION_DESC_OFF   0x008
> +#define PCIE_AXI_REGION_BASE0_OFF  0x018
> +
> +#define PCIE_AXI_BAR0_IB         0x800
> +#define PCIE_AXI_BAR1_IB         0x808
> +#define PCIE_AXI_NO_BAR_IB       0x810
> +
> +/*
> + * PCIe Core Configuration Register values
> + */
> +
> +#define PCIE_BRIDGE_CLASSCODE    0x06040000
> +#define PCIE_LINK_UP             0x01
> +#define PCIE_RCBARPIE            0x19
> +
> +// AXI Region Address Translation/Base Address bits values
> +#define PCIE_AXI_BITS_21         20
> +#define PCIE_AXI_BITS_24         23
> +#define PCIE_AXI_BITS_25         24
> +#define PCIE_AXI_BITS_32         31
> +
> +// AXI Region Outbound PCIe Descriptor Register values
> +#define PCIE_AXI_DESC_TYPE0      0x80000A
> +#define PCIE_AXI_DESC_TYPE1      0x80000B
> +#define PCIE_AXI_DESC_MEM        0x800002
> +#define PCIE_AXI_DESC_IO         0x800006
> +
> +#endif
> diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
> new file mode 100644
> index 0000000..f58cac3
> --- /dev/null
> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
> @@ -0,0 +1,188 @@
> +/** @file
> +  PCI Host Bridge support for the Cadence PCIe Root Complex
> +
> +  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
> +  Copyright (c) 2017, Cadence Design Systems. 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 <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.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
> +  {
> +    // Bus
> +    FixedPcdGet32 (PcdPciBusMin),
> +    FixedPcdGet32 (PcdPciBusMax)
> +  }, {
> +    // Io
> +    FixedPcdGet64 (PcdPciIoBase),
> +    FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
> +  }, {
> +    // Mem
> +    FixedPcdGet32 (PcdPciMmio32Base),
> +    FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1
> +  }, {
> +    // MemAbove4G
> +    MAX_UINT64,
> +    0
> +  }, {
> +    // 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
> +  )
> +{
> +  *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 ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
> +
> +  RootBridgeIndex = 0;
> +  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
> +  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> +    DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
> +    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
> +      ASSERT (Descriptor->ResType <
> +              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr)
> +              );
> +      DEBUG ((DEBUG_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 ((DEBUG_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/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
> new file mode 100644
> index 0000000..b17a96c
> --- /dev/null
> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
> @@ -0,0 +1,73 @@
> +## @file
> +#  PCI Host Bridge Library instance for Cadence PCIe Root Complex
> +#
> +#  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2017, Cadence Design Systems. All rights reserved.
> +#
> +#  This program and the accompanying materials are licensed and made available
> +#  under the terms and conditions of the BSD License which accompanies this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> +#  IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 1.25
> +  BASE_NAME                      = CdnsPciHostBridgeLib
> +  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]
> +  CdnsPciHostBridgeLib.c
> +  CdnsPci.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  CadencePkg/CadenceCspPkg.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
> +  gCadenceCspTokenSpaceGuid.PcdPcieRootPortBaseAddress
> +  gCadenceCspTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
> +  gCadenceCspTokenSpaceGuid.PcdPciConfigurationSpaceSize
> +
> +[Protocols]
> +  gEfiCpuIo2ProtocolGuid          ## CONSUMES
> +
> +[Depex]
> +  gEfiCpuIo2ProtocolGuid
> -- 
> 2.2.2
> 
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [staging/cadence-aarch64 PATCH v3 3/6] CadencePkg: Add PCI host bridge library for Cadence PCIe Root Complex.
Posted by Ard Biesheuvel 8 years, 7 months ago
On 22 June 2017 at 15:12, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Thu, Jun 22, 2017 at 10:31:58AM +0100, Scott Telford wrote:
>> Add PciHostBridgeLib implementation for the Cadence PCIe Root Complex.
>> This library is derived from
>> Platforms/ARM/Juno/Library/JunoPciHostBridgeLib in OpenPlatformPkg.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Scott Telford <stelford@cadence.com>
>> ---
>>  .../Library/CadencePciHostBridgeLib/CdnsPci.c      | 149 ++++++++++++++++
>>  .../Library/CadencePciHostBridgeLib/CdnsPci.h      |  88 ++++++++++
>>  .../CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c | 188 +++++++++++++++++++++
>>  .../CdnsPciHostBridgeLib.inf                       |  73 ++++++++
>>  4 files changed, 498 insertions(+)
>>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
>>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
>>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
>>  create mode 100644 CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
>>
>> diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
>> new file mode 100644
>> index 0000000..3114843
>> --- /dev/null
>> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.c
>> @@ -0,0 +1,149 @@
>> +/** @file
>> +*  Initialize the Cadence PCIe Root complex
>> +*
>> +*  Copyright (c) 2017, Cadence Design Systems. 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 <Library/BaseLib.h>
>> +#include <Library/CspSysReg.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +
>> +#include <Protocol/Cpu.h>
>> +
>> +#include "CdnsPci.h"
>> +
>> +STATIC
>> +VOID
>> +CdnsPciConfigRegion (
>> +  EFI_CPU_IO2_PROTOCOL *CpuIo,
>> +  IN UINT32 Region,
>> +  IN UINT32 Descriptor,
>> +  IN UINT32 TransAddr,
>> +  IN UINT32 TransAddrBits,
>> +  IN UINT32 BaseAddr,
>> +  IN UINT32 BaseAddrBits
>> +  )
>> +{
>> +  UINTN RegionBaseAddr = PCIE_AXI + (Region * PCIE_AXI_REGION_OFF);
>> +
>> +  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_TRANS0_OFF,
>> +                         TransAddr | TransAddrBits);
>> +  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_DESC_OFF,
>> +                         Descriptor);
>> +  PCIE_ROOTPORT_WRITE32 (RegionBaseAddr + PCIE_AXI_REGION_BASE0_OFF,
>> +                         BaseAddr | BaseAddrBits);
>> +}
>> +
>> +STATIC
>> +VOID
>> +CdnsPciRegInit(
>> +  EFI_CPU_IO2_PROTOCOL    *CpuIo
>> +)
>> +{
>> +  UINT32                  Value;
>> +
>> +  // Setup the class code as PCIe Host Bridge.
>> +  PCIE_ROOTPORT_WRITE32 (PCIE_RP + PCIE_PCI_CLASSCODE, PCIE_BRIDGE_CLASSCODE);
>> +
>> +  // Set up the BARs via the Root Port registers
>> +  PCIE_ROOTPORT_READ32 (PCIE_LM + PCIE_RP_BAR_CONFIG, Value);
>> +  PCIE_ROOTPORT_WRITE32 (PCIE_LM + PCIE_RP_BAR_CONFIG, Value | (1 << PCIE_RCBARPIE));
>> +
>> +  // Allow incoming writes
>> +  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_BAR0_IB, PCIE_AXI_BITS_32);
>> +  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_BAR1_IB, PCIE_AXI_BITS_32);
>> +  PCIE_ROOTPORT_WRITE32 (PCIE_AXI + PCIE_AXI_NO_BAR_IB, PCIE_AXI_BITS_32);
>> +
>> +  // Set up region 0 for Type 0 write (bus 0 and 1), size 2MB
>> +  CdnsPciConfigRegion (
>> +          CpuIo,
>> +          0,
>> +          PCIE_AXI_DESC_TYPE0,
>> +          PCIE_ECAM_BASE,
>> +          PCIE_AXI_BITS_25,
>> +          0,
>> +          PCIE_AXI_BITS_21
>> +          );
>> +
>> +  // Set up region 1 for Type 1 writes (bus 2 upwards), size (32-2)MB
>> +  CdnsPciConfigRegion(
>> +          CpuIo,
>> +          1,
>> +          PCIE_AXI_DESC_TYPE1,
>> +          PCIE_ECAM_BASE + (2*PCIE_BUS_SIZE),
>> +          PCIE_AXI_BITS_25,
>> +          2*PCIE_BUS_SIZE,
>> +          PCIE_AXI_BITS_25
>> +          );
>> +

It is still not fully clear to me how this works, i.e., how type0
cycles for bus 1 get routed correctly. But if it works, I'm fine with
it. (Obviously, you know the IP best)

>> +  // Set up region 2 for memory write, size 16MB
>> +  CdnsPciConfigRegion(
>> +          CpuIo,
>> +          2,
>> +          PCIE_AXI_DESC_MEM,
>> +          PCIE_MEM32_BASE,
>> +          PCIE_AXI_BITS_25,
>> +          (PCIE_MEM32_BASE - PCIE_ECAM_BASE),
>> +          PCIE_AXI_BITS_24
>> +          );
>> +
>> +  // Set up region 3 for IO write, size 16MB
>> +  CdnsPciConfigRegion(
>> +          CpuIo,
>> +          3,
>> +          PCIE_AXI_DESC_IO,
>> +          PCIE_IO_BASE,
>> +          PCIE_AXI_BITS_25,
>> +          (PCIE_IO_BASE - PCIE_ECAM_BASE),
>> +          PCIE_AXI_BITS_24
>> +          );
>
> Thanks - this is exactly what I was hoping for!
> I'll leave for Ard to comment on hos bits, but:
> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
>

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> +}
>> +
>> +EFI_STATUS
>> +HWPciRbInit (
>> +  IN EFI_HANDLE        ImageHandle,
>> +  IN EFI_SYSTEM_TABLE  *SystemTable
>> +  )
>> +{
>> +  UINT32                  Count;
>> +  EFI_CPU_IO2_PROTOCOL    *CpuIo;
>> +  EFI_STATUS              Status;
>> +  UINT32                  Value;
>> +
>> +  PCI_TRACE ("HWPciRbInit()");
>> +
>> +  PCI_TRACE ("PCIe Setting up Address Translation");
>> +
>> +  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL,
>> +                  (VOID **)&CpuIo);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  // Check for link up
>> +  for (Count = 0; Count < PCIE_LINK_TIMEOUT_COUNT; Count++) {
>> +    gBS->Stall (PCIE_LINK_TIMEOUT_WAIT_US);
>> +    PCIE_ROOTPORT_READ32 (PCIE_LM + PCIE_LINK_CTRL_STATUS, Value);
>> +    if (Value & PCIE_LINK_UP) {
>> +      break;
>> +    }
>> +  }
>> +  if (!(Value & PCIE_LINK_UP)) {
>> +    DEBUG ((DEBUG_ERROR, "PCIe link not up: %x.\n", Value));
>> +    return EFI_NOT_READY;
>> +  }
>> +
>> +  // Initialise configuration registers
>> +  CdnsPciRegInit(CpuIo);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
>> new file mode 100644
>> index 0000000..08faece
>> --- /dev/null
>> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPci.h
>> @@ -0,0 +1,88 @@
>> +/** @file
>> +*  Header for Cadence PCIe Root Complex
>> +*
>> +*  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
>> +*  Copyright (c) 2017, Cadence Design Systems. 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 __CDNS_PCI_H__
>> +#define __CDNS_PCI_H__
>> +
>> +#include <Protocol/CpuIo2.h>
>> +
>> +#define PCIE_ECAM_BASE       FixedPcdGet64 (PcdPciConfigurationSpaceBaseAddress)
>> +#define PCIE_ECAM_SIZE       FixedPcdGet64 (PcdPciConfigurationSpaceSize)
>> +#define PCIE_IO_BASE         (FixedPcdGet64(PcdPciIoTranslation) + FixedPcdGet64 (PcdPciIoBase))
>> +#define PCIE_IO_SIZE         FixedPcdGet64 (PcdPciIoSize)
>> +#define PCIE_MEM32_BASE      FixedPcdGet64 (PcdPciMmio32Base)
>> +#define PCIE_MEM32_SIZE      FixedPcdGet64 (PcdPciMmio32Size)
>> +
>> +#define PCIE_BUS_SIZE        SIZE_1MB
>> +
>> +#define PCIE_LINK_TIMEOUT_WAIT_US 1000 // microseconds
>> +#define PCIE_LINK_TIMEOUT_COUNT 1000
>> +
>> +#define PCI_TRACE(txt)  DEBUG((DEBUG_VERBOSE, "CDNS_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); }
>> +#ifdef CDNS_B2B
>> +#define PCIE1_ROOTPORT_WRITE32(Add, Val) { UINT32 Value = (UINT32)(Val); CpuIo->Mem.Write (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcie1RootPortBaseAddress)+(Add)),1,&Value); }
>> +#define PCIE1_ROOTPORT_READ32(Add, Val) { CpuIo->Mem.Read (CpuIo,EfiCpuIoWidthUint32,(UINT64)(PcdGet64 (PcdPcie1RootPortBaseAddress)+(Add)),1,&Val); }
>> +#endif
>> +
>> +/*
>> + * PCIe Core Configuration Register offsets
>> + */
>> +
>> +// Root Port Configuration
>> +#define PCIE_RP                   0x00200000
>> +#define PCIE_PCI_CLASSCODE        0x8
>> +
>> +// Local Management
>> +#define PCIE_LM                   0x00100000
>> +#define PCIE_LINK_CTRL_STATUS     0x00
>> +#define PCIE_RP_BAR_CONFIG        0x300
>> +
>> +// AXI Configuration
>> +#define PCIE_AXI                   0x00400000
>> +
>> +#define PCIE_AXI_REGION_OFF        0x020
>> +#define PCIE_AXI_REGION_TRANS0_OFF 0x000
>> +#define PCIE_AXI_REGION_DESC_OFF   0x008
>> +#define PCIE_AXI_REGION_BASE0_OFF  0x018
>> +
>> +#define PCIE_AXI_BAR0_IB         0x800
>> +#define PCIE_AXI_BAR1_IB         0x808
>> +#define PCIE_AXI_NO_BAR_IB       0x810
>> +
>> +/*
>> + * PCIe Core Configuration Register values
>> + */
>> +
>> +#define PCIE_BRIDGE_CLASSCODE    0x06040000
>> +#define PCIE_LINK_UP             0x01
>> +#define PCIE_RCBARPIE            0x19
>> +
>> +// AXI Region Address Translation/Base Address bits values
>> +#define PCIE_AXI_BITS_21         20
>> +#define PCIE_AXI_BITS_24         23
>> +#define PCIE_AXI_BITS_25         24
>> +#define PCIE_AXI_BITS_32         31
>> +
>> +// AXI Region Outbound PCIe Descriptor Register values
>> +#define PCIE_AXI_DESC_TYPE0      0x80000A
>> +#define PCIE_AXI_DESC_TYPE1      0x80000B
>> +#define PCIE_AXI_DESC_MEM        0x800002
>> +#define PCIE_AXI_DESC_IO         0x800006
>> +
>> +#endif
>> diff --git a/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
>> new file mode 100644
>> index 0000000..f58cac3
>> --- /dev/null
>> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.c
>> @@ -0,0 +1,188 @@
>> +/** @file
>> +  PCI Host Bridge support for the Cadence PCIe Root Complex
>> +
>> +  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
>> +  Copyright (c) 2017, Cadence Design Systems. 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 <Library/DebugLib.h>
>> +#include <Library/DevicePathLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/PciHostBridgeLib.h>
>> +
>> +#include <PiDxe.h>
>> +
>> +#include <Protocol/PciHostBridgeResourceAllocation.h>
>> +#include <Protocol/PciRootBridgeIo.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
>> +  {
>> +    // Bus
>> +    FixedPcdGet32 (PcdPciBusMin),
>> +    FixedPcdGet32 (PcdPciBusMax)
>> +  }, {
>> +    // Io
>> +    FixedPcdGet64 (PcdPciIoBase),
>> +    FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1
>> +  }, {
>> +    // Mem
>> +    FixedPcdGet32 (PcdPciMmio32Base),
>> +    FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1
>> +  }, {
>> +    // MemAbove4G
>> +    MAX_UINT64,
>> +    0
>> +  }, {
>> +    // 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
>> +  )
>> +{
>> +  *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 ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));
>> +
>> +  RootBridgeIndex = 0;
>> +  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
>> +  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
>> +    DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
>> +    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
>> +      ASSERT (Descriptor->ResType <
>> +              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr)
>> +              );
>> +      DEBUG ((DEBUG_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 ((DEBUG_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/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
>> new file mode 100644
>> index 0000000..b17a96c
>> --- /dev/null
>> +++ b/CadencePkg/Library/CadencePciHostBridgeLib/CdnsPciHostBridgeLib.inf
>> @@ -0,0 +1,73 @@
>> +## @file
>> +#  PCI Host Bridge Library instance for Cadence PCIe Root Complex
>> +#
>> +#  Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
>> +#  Copyright (c) 2017, Cadence Design Systems. All rights reserved.
>> +#
>> +#  This program and the accompanying materials are licensed and made available
>> +#  under the terms and conditions of the BSD License which accompanies this
>> +#  distribution. The full text of the license may be found at
>> +#  http://opensource.org/licenses/bsd-license.php
>> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
>> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
>> +#  IMPLIED.
>> +#
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 1.25
>> +  BASE_NAME                      = CdnsPciHostBridgeLib
>> +  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]
>> +  CdnsPciHostBridgeLib.c
>> +  CdnsPci.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  CadencePkg/CadenceCspPkg.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
>> +  gCadenceCspTokenSpaceGuid.PcdPcieRootPortBaseAddress
>> +  gCadenceCspTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
>> +  gCadenceCspTokenSpaceGuid.PcdPciConfigurationSpaceSize
>> +
>> +[Protocols]
>> +  gEfiCpuIo2ProtocolGuid          ## CONSUMES
>> +
>> +[Depex]
>> +  gEfiCpuIo2ProtocolGuid
>> --
>> 2.2.2
>>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel