The resource apertures that the PCI root bridge uses to assign resources to subordinate devices need to be declared in the GCD memory map before allocations can be made from it. So add the missing code to do that.
Also, declare the I/O port space as translated from its CPU visible memory offset, and take the translation into account into the I/O access routines.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org ---
Note that the 4 GB allocation limit patch is also needed for PCI to work
Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c | 38 ++++++++++++++++++-- Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h | 2 ++ Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 5 +++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 3 ++ 4 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c index 66fb27be55ad..99d4203345ba 100644 --- a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c +++ b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.c @@ -74,7 +74,7 @@ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[1][1] = { };
PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture[1][1] = { - {{ 0, 255, 0x40000000, 0x20000000, 0xEFFF0000, 0x10000}}, + {{ 0, 255, 0x40000000, 0x41FFFFFFF, 0x0, 0xFFFF, 0xEFFF0000 }}, };
EFI_HANDLE mDriverImageHandle; @@ -124,9 +124,43 @@ InitializePciHostBridge ( UINTN Loop2; PCI_HOST_BRIDGE_INSTANCE *HostBridge; PCI_ROOT_BRIDGE_INSTANCE *PrivateData; - + mDriverImageHandle = ImageHandle;
+ // + // Add IO and MMIO memory space, so that resources can be allocated in the + // EfiPciHostBridgeAllocateResources phase. + // + Status = gDS->AddIoSpace ( + EfiGcdIoTypeIo, + mResAperture[0][0].IoBase, + mResAperture[0][0].IoLimit - mResAperture[0][0].IoBase + 1 + ); + ASSERT_EFI_ERROR (Status); + + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + mResAperture[0][0].MemBase, + mResAperture[0][0].MemLimit - mResAperture[0][0].MemBase + 1, + EFI_MEMORY_UC + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: AddMemorySpace: %r\n", __FUNCTION__, Status)); + return Status; + } + + Status = gDS->SetMemorySpaceAttributes ( + mResAperture[0][0].MemBase, + mResAperture[0][0].MemLimit - mResAperture[0][0].MemBase + 1, + EFI_MEMORY_UC + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: SetMemorySpaceAttributes: %r\n", __FUNCTION__, + Status)); + return Status; + } + + DEBUG((EFI_D_ERROR, "%a () - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR 0x%x\n", __FUNCTION__, sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)));
diff --git a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h index f91b42a27572..bbd75b20bb47 100644 --- a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h +++ b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciHostBridge.h @@ -403,6 +403,7 @@ typedef struct {
UINT64 IoBase; UINT64 IoLimit; + UINT64 IoTranslation; } PCI_ROOT_BRIDGE_RESOURCE_APERTURE;
typedef enum { @@ -455,6 +456,7 @@ typedef struct { UINT64 BusLimit; UINT64 MemLimit; UINT64 IoLimit; + UINT64 IoTranslation;
//UINTN PciAddress; //UINTN PciData; diff --git a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c index 4ac89fb7548f..314a309bb010 100644 --- a/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/Platforms/AMD/Styx/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c @@ -665,6 +665,7 @@ RootBridgeConstructor ( // PrivateData->MemBase = ResAperture->MemBase; PrivateData->IoBase = ResAperture->IoBase; + PrivateData->IoTranslation = ResAperture->IoTranslation;
// // The host bridge only supports 32bit addressing for memory @@ -1005,12 +1006,16 @@ RootBridgeIoIoRW ( UINT8 OutStride; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth; UINT8 *Uint8Buffer; + PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer); if (EFI_ERROR (Status)) { return Status; }
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + Address += PrivateData->IoTranslation; + InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03); diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index cd0fe296d849..c1fea8c5361a 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -415,6 +415,9 @@ DEFINE TRANS_CODE = $(EL3_TO_EL2) # Size of the region used by UEFI in permanent memory (Reserved 64MB) gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
+ # size of the I/O port space, needed for PCI + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16 + # # ARM Pcds #