@@ -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)));
@@ -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;
@@ -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);
@@ -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
#
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(-)