ArmVirtualizationPkg/PciHostBridgeDxe: translate addresses for IO

Unlike the one in PcAtChipsetPkg, our PciHostBridgeDxe module must handle
address space translation. IO addresses expressed in the respective
aperture are mapped to a different base in CPU address space.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16899 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Laszlo Ersek 2015-02-23 16:03:16 +00:00 committed by lersek
parent 120a25c287
commit 1275aaf430
2 changed files with 17 additions and 4 deletions

View File

@ -457,6 +457,7 @@ typedef struct {
UINT64 BusLimit; UINT64 BusLimit;
UINT64 MemLimit; UINT64 MemLimit;
UINT64 IoLimit; UINT64 IoLimit;
UINT64 IoTranslation;
EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;

View File

@ -640,11 +640,13 @@ RootBridgeConstructor (
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol); PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
// //
// The host to pci bridge, the host memory and io addresses are // The host to PCI bridge. The host memory addresses are direct mapped to PCI
// direct mapped to pci addresses, so no need translate, set bases to 0. // addresses, so there's no need to translate them. IO addresses need
// translation however.
// //
PrivateData->MemBase = ResAperture->MemBase; PrivateData->MemBase = ResAperture->MemBase;
PrivateData->IoBase = ResAperture->IoBase; PrivateData->IoBase = ResAperture->IoBase;
PrivateData->IoTranslation = ResAperture->IoTranslation;
// //
// The host bridge only supports 32bit addressing for memory // The host bridge only supports 32bit addressing for memory
@ -978,6 +980,7 @@ RootBridgeIoIoRW (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
UINT8 InStride; UINT8 InStride;
UINT8 OutStride; UINT8 OutStride;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
@ -988,6 +991,15 @@ RootBridgeIoIoRW (
return Status; 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]; InStride = mInStride[Width];
OutStride = mOutStride[Width]; OutStride = mOutStride[Width];
OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03); OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);