Browse Source

Marvell: Armada7k8k/OcteonTx: Add multiple PCIE ports support

In order to support more than one PCIE port, PciHostBridgeLib must
generate appropriate device paths according to the board description
and assign correct segment numbers instead of a hard-coded 0.

Additionally, PciSegmentLib has to operate on a proper
config spaces base address (depending on the segment number).
Add the library constructor routine and obtain the necessary
data from the Marvell board description protocol.

Remove unused PCIE-related PCD's.

Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Kamil Koczurek 4 years ago
parent
commit
4ec5e0c887

+ 0 - 4
Platform/Marvell/Cn913xDb/Cn9130DbA.dsc.inc

@@ -93,10 +93,6 @@
   gMarvellTokenSpaceGuid.PcdPciEAhci|{ 0x1 }
   gMarvellTokenSpaceGuid.PcdPciESdhci|{ 0x1, 0x1 }
 
-  # PCIE
-  gArmTokenSpaceGuid.PcdPciIoTranslation|0xDFF00000
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xD0000000
-
   # RTC
   gMarvellTokenSpaceGuid.PcdRtcBaseAddress|0xF2284000
 

+ 0 - 4
Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc

@@ -396,10 +396,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000
 
-  # PCIE
-  gArmTokenSpaceGuid.PcdPciIoTranslation|0xEFF00000
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
-
 !if $(CAPSULE_ENABLE)
 [PcdsDynamicExDefault.common.DEFAULT]
   gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor|{0x0}|VOID*|0x100

+ 11 - 4
Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciHostBridgeLib/PciHostBridgeLib.c

@@ -9,6 +9,7 @@
 **/
 #include <PiDxe.h>
 
+#include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
 #include <Library/DevicePathLib.h>
 #include <Library/MemoryAllocationLib.h>
@@ -27,7 +28,7 @@ typedef struct {
 } EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
 #pragma pack ()
 
-STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
+STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePathTemplate = {
   {
     {
       ACPI_DEVICE_PATH,
@@ -38,7 +39,7 @@ STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
       }
     },
     EISA_PNP_ID (0x0A08), // PCI Express
-    0
+    0 // AcpiDevicePath.UID
   },
 
   {
@@ -74,6 +75,7 @@ PciHostBridgeGetRootBridges (
 {
   MV_BOARD_PCIE_DESCRIPTION CONST *BoardPcieDescription;
   MARVELL_BOARD_DESC_PROTOCOL     *BoardDescriptionProtocol;
+  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *EfiPciRootBridgeDevicePath;
   MV_PCIE_CONTROLLER CONST        *PcieController;
   PCI_ROOT_BRIDGE                 *PciRootBridges;
   PCI_ROOT_BRIDGE                 *RootBridge;
@@ -119,10 +121,15 @@ PciHostBridgeGetRootBridges (
 
   /* Fill information of all root bridge instances */
   for (Index = 0; Index < *Count; Index++, RootBridge++) {
+    EfiPciRootBridgeDevicePath = AllocateCopyPool (
+                                   sizeof (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH),
+                                   &mEfiPciRootBridgeDevicePathTemplate
+                                   );
+    EfiPciRootBridgeDevicePath->AcpiDevicePath.UID = Index;
 
     PcieController = &(BoardPcieDescription->PcieControllers[Index]);
 
-    RootBridge->Segment   = 0;
+    RootBridge->Segment   = Index;
     RootBridge->Supports  = 0;
     RootBridge->Attributes  = RootBridge->Supports;
 
@@ -168,7 +175,7 @@ PciHostBridgeGetRootBridges (
 
     RootBridge->NoExtendedConfigSpace = FALSE;
 
-    RootBridge->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath;
+    RootBridge->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)EfiPciRootBridgeDevicePath;
   }
 
   return PciRootBridges;

+ 68 - 1
Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciSegmentLib/PciSegmentLib.c

@@ -9,12 +9,20 @@
 
 **/
 
+#include <Uefi.h>
 #include <Base.h>
 
 #include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
 #include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
 #include <Library/PciSegmentLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/BoardDesc.h>
+
+UINT64 *mConfigSpaceAddresses;
+UINTN mPcieControllerCount;
 
 typedef enum {
   PciCfgWidthUint8      = 0,
@@ -34,6 +42,15 @@ typedef enum {
 #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
   ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
 
+/**
+  Extract segment number from PCI Segment address
+
+  @param  A The address to process.
+
+**/
+#define SEGMENT_INDEX(A) \
+  (((A) & 0x0000ffff00000000) >> 32)
+
 /**
   Internal worker function to obtain config space base address.
 
@@ -49,7 +66,9 @@ PciSegmentLibGetConfigBase (
   IN  UINT64      Address
   )
 {
-  return PcdGet64 (PcdPciExpressBaseAddress);
+  ASSERT (SEGMENT_INDEX (Address) < mPcieControllerCount);
+
+  return mConfigSpaceAddresses[SEGMENT_INDEX (Address)];
 }
 
 /**
@@ -1388,3 +1407,51 @@ PciSegmentWriteBuffer (
 
   return ReturnValue;
 }
+
+/**
+  Obtain base addresses of PCIe configuration spaces.
+
+  @retval EFI_SUCEESS       Routine executed properly.
+  @retval Other             Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+Armada7k8kPciSegmentLibConstructor (
+  VOID
+  )
+{
+  CONST MV_BOARD_PCIE_DESCRIPTION *PcieDesc;
+  MARVELL_BOARD_DESC_PROTOCOL *Proto;
+  EFI_STATUS Status;
+  UINTN Index;
+
+  Status = gBS->LocateProtocol (
+                  &gMarvellBoardDescProtocolGuid,
+                  NULL,
+                  (VOID **)&Proto
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = Proto->PcieDescriptionGet (Proto, &PcieDesc);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  mConfigSpaceAddresses = AllocateZeroPool (
+                            PcieDesc->PcieControllerCount * sizeof (UINT64)
+                          );
+  if (mConfigSpaceAddresses == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < PcieDesc->PcieControllerCount; Index++) {
+    mConfigSpaceAddresses[Index] = PcieDesc->PcieControllers[Index].ConfigSpaceAddress;
+  }
+
+  mPcieControllerCount = PcieDesc->PcieControllerCount;
+
+  return EFI_SUCCESS;
+}

+ 7 - 4
Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciSegmentLib/PciSegmentLib.inf

@@ -16,18 +16,21 @@
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = PciSegmentLib
+  CONSTRUCTOR                    = Armada7k8kPciSegmentLibConstructor
 
 [Sources]
   PciSegmentLib.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   Silicon/Marvell/Marvell.dec
 
 [LibraryClasses]
+  ArmadaBoardDescLib
+  ArmadaSoCDescLib
   BaseLib
-  DebugLib
-  IoLib
 
-[Pcd]
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+[Protocols]
+  gMarvellBoardDescProtocolGuid