Clarification needed for PCI address translation


Ni, Ray
 

I don't think the assumption is valid that host address be "always" greater than device address.

-----Original Message-----
From: Pankaj Bansal <pankaj.bansal@nxp.com>
Sent: Sunday, May 10, 2020 12:10 PM
To: Heyi Guo <heyi.guo@linaro.org>; Yi Li <phoenix.liyi@huawei.com>; Ni, Ray
<ray.ni@intel.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: discuss@edk2.groups.io
Subject: Clarification needed for PCI address translation

Hi Heyi Guo et al,

I have a question about the patch that you submitted in edk2:

commit dc080d3b61e570e7a3163fc24afa6f8388d0c0bf
Author: Heyi Guo <heyi.guo@linaro.org>
Date: Thu Feb 8 11:13:27 2018 +0800

MdeModulePkg/PciBus: return CPU address for GetBarAttributes

According to UEFI spec 2.7, PciIo->GetBarAttributes should return host
address (CPU view ddress) rather than device address (PCI view
address), and
device address = host address + address translation offset,
so we subtract translation from device address before returning.

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index fef3eceb7f62..62179eb44bbd 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
@@ -1972,6 +1972,10 @@ PciIoGetBarAttributes (
return EFI_UNSUPPORTED;
}
}
+
+ // According to UEFI spec 2.7, we need return host address for
+ // PciIo->GetBarAttributes, and host address = device address - translation.
+ Descriptor->AddrRangeMin -= Descriptor->AddrTranslationOffset;
}

return EFI_SUCCESS;

Now I have a question about this statement : "host address = device address -
translation"
Won't the host address be "always" greater than device address ?

As I see the PCI controller integration in out ARM64 based SOC (LX2160), the
PCI address space
of a controller starts at > 4 GB offset in HOST address space. E.g. :

Start address | End address | Size | Allocation
0x3600000 | 0x360FFFF | 64K | PCI controller registers
0x80000000 | 0xFFFFFFFF | 2GB | DDR
0x8000000000 | 0x87FFFFFFFF | 32GB | PCI Express

All the BAR allocations (IO/MEM32/MEM64) are done from 32 GB PCI express
space (i.e. 0x8000000000 - 0x87FFFFFFFF)
The corresponding PCI addresses for devices are in 32 GB range i.e. 0x0 -
0x7FFFFFFFF.
If I take translation = 0x8000000000, So for this case :

host address = device address + translation.

Regards,
Pankaj Bansal


Pankaj Bansal
 

But won't it?

There can be only two scenarios :
1. PCI address space coincides with CPU address space.
In this case host address = device address and translation = 0
2. PCI address space lies at some offset in CPU address space. Like the example I mention in LX2160A
In this case host address = device address + translation, where translation > 0

Can there be a scenario where translation < 0 ? I don't think so

Regards,
Pankaj Bansal

-----Original Message-----
From: Ni, Ray <ray.ni@intel.com>
Sent: Monday, May 11, 2020 7:37 AM
To: Pankaj Bansal <pankaj.bansal@nxp.com>; Heyi Guo <heyi.guo@linaro.org>;
Yi Li <phoenix.liyi@huawei.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: discuss@edk2.groups.io
Subject: RE: Clarification needed for PCI address translation

I don't think the assumption is valid that host address be "always" greater than
device address.

-----Original Message-----
From: Pankaj Bansal <pankaj.bansal@nxp.com>
Sent: Sunday, May 10, 2020 12:10 PM
To: Heyi Guo <heyi.guo@linaro.org>; Yi Li <phoenix.liyi@huawei.com>; Ni,
Ray
<ray.ni@intel.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: discuss@edk2.groups.io
Subject: Clarification needed for PCI address translation

Hi Heyi Guo et al,

I have a question about the patch that you submitted in edk2:

commit dc080d3b61e570e7a3163fc24afa6f8388d0c0bf
Author: Heyi Guo <heyi.guo@linaro.org>
Date: Thu Feb 8 11:13:27 2018 +0800

MdeModulePkg/PciBus: return CPU address for GetBarAttributes

According to UEFI spec 2.7, PciIo->GetBarAttributes should return host
address (CPU view ddress) rather than device address (PCI view
address), and
device address = host address + address translation offset,
so we subtract translation from device address before returning.

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index fef3eceb7f62..62179eb44bbd 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
@@ -1972,6 +1972,10 @@ PciIoGetBarAttributes (
return EFI_UNSUPPORTED;
}
}
+
+ // According to UEFI spec 2.7, we need return host address for
+ // PciIo->GetBarAttributes, and host address = device address - translation.
+ Descriptor->AddrRangeMin -= Descriptor->AddrTranslationOffset;
}

return EFI_SUCCESS;

Now I have a question about this statement : "host address = device address -
translation"
Won't the host address be "always" greater than device address ?

As I see the PCI controller integration in out ARM64 based SOC (LX2160), the
PCI address space
of a controller starts at > 4 GB offset in HOST address space. E.g. :

Start address | End address | Size | Allocation
0x3600000 | 0x360FFFF | 64K | PCI controller registers
0x80000000 | 0xFFFFFFFF | 2GB | DDR
0x8000000000 | 0x87FFFFFFFF | 32GB | PCI Express

All the BAR allocations (IO/MEM32/MEM64) are done from 32 GB PCI express
space (i.e. 0x8000000000 - 0x87FFFFFFFF)
The corresponding PCI addresses for devices are in 32 GB range i.e. 0x0 -
0x7FFFFFFFF.
If I take translation = 0x8000000000, So for this case :

host address = device address + translation.

Regards,
Pankaj Bansal


Pankaj Bansal
 

On Mon, 11 May 2020 at 05:36, Pankaj Bansal <pankaj.bansal@nxp.com> wrote:

But won't it?

There can be only two scenarios :
1. PCI address space coincides with CPU address space.
In this case host address = device address and translation = 0
2. PCI address space lies at some offset in CPU address space. Like the
example I mention in LX2160A
In this case host address = device address + translation, where translation >
0

Can there be a scenario where translation < 0 ? I don't think so
I don't see how this matters.

Translation uses unsigned 64-bit integer arithmetic, so if you need
the translation to go the other way, just subtract from
0x1_0000_0000_0000_0000.
That is what confuses me. Why is this convoluted logic needed altogether ?
Why can't we use direct translation values (instead of MAX_UINT64 + 1 - translation) ?

Regards,
Pankaj Bansal