diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciHostBridge.h b/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciHostBridge.h index 6e9bd84c47..cbceca4bcf 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciHostBridge.h +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciHostBridge.h @@ -457,6 +457,7 @@ typedef struct { UINT64 BusLimit; UINT64 MemLimit; UINT64 IoLimit; + UINT64 IoTranslation; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io; diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciRootBridgeIo.c b/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciRootBridgeIo.c index 7c35e85c63..85048b2f74 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciRootBridgeIo.c +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PciHostBridgeDxe/PciRootBridgeIo.c @@ -640,11 +640,13 @@ RootBridgeConstructor ( PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol); // - // The host to pci bridge, the host memory and io addresses are - // direct mapped to pci addresses, so no need translate, set bases to 0. + // The host to PCI bridge. The host memory addresses are direct mapped to PCI + // addresses, so there's no need to translate them. IO addresses need + // translation however. // - PrivateData->MemBase = ResAperture->MemBase; - PrivateData->IoBase = ResAperture->IoBase; + PrivateData->MemBase = ResAperture->MemBase; + PrivateData->IoBase = ResAperture->IoBase; + PrivateData->IoTranslation = ResAperture->IoTranslation; // // The host bridge only supports 32bit addressing for memory @@ -978,6 +980,7 @@ RootBridgeIoIoRW ( ) { EFI_STATUS Status; + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; UINT8 InStride; UINT8 OutStride; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth; @@ -988,6 +991,15 @@ RootBridgeIoIoRW ( return Status; } + PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + // + // The addition below is performed in UINT64 modular arithmetic, in + // accordance with the definition of PcdPciIoTranslation in + // "ArmPlatformPkg.dec". Meaning, the addition below may in fact *decrease* + // Address, implementing a negative offset translation. + // + Address += PrivateData->IoTranslation; + InStride = mInStride[Width]; OutStride = mOutStride[Width]; OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);