This patch adds the logic to decode MMIO-based PCIe ECAM accesses. If the IOREQ_TYPE_COPY request is within the ECAM address space configured by hvmloader, the ioreq type is set to XEN_DMOP_IO_RANGE_PCI and the sbdf decoded from the accessed address.
Signed-off-by: Thierry Escande <[email protected]> --- xen/arch/x86/hvm/ioreq.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c index a5fa97e149..022fe05222 100644 --- a/xen/arch/x86/hvm/ioreq.c +++ b/xen/arch/x86/hvm/ioreq.c @@ -268,6 +268,8 @@ bool arch_ioreq_server_get_type_addr(const struct domain *d, uint64_t *addr) { unsigned int cf8 = d->arch.hvm.pci_cf8; + unsigned long mmio_start = (p->type == IOREQ_TYPE_COPY) ? + ioreq_mmio_first_byte(p) : 0; if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO ) return false; @@ -298,6 +300,19 @@ bool arch_ioreq_server_get_type_addr(const struct domain *d, *addr |= CF8_ADDR_HI(cf8); } } + else if ( p->type == IOREQ_TYPE_COPY && + (mmio_start >= d->arch.ecam_addr && + mmio_start < (d->arch.ecam_addr + d->arch.ecam_size)) ) + { + pci_sbdf_t sbdf; + unsigned int reg = mmio_start & ~PAGE_MASK; + + sbdf.bdf = (((mmio_start - d->arch.ecam_addr) & 0x0ffff000) >> 12); + sbdf.seg = 0; + + *type = XEN_DMOP_IO_RANGE_PCI; + *addr = ((uint64_t)sbdf.sbdf << 32) | reg; + } else { *type = (p->type == IOREQ_TYPE_PIO) ? -- 2.51.0 -- Thierry Escande | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech
