From 4f68709ffd64c14ac960670aa2891b34a0ea026c Mon Sep 17 00:00:00 2001 From: Volodymyr Babchuk Date: Fri, 16 Dec 2022 02:15:48 +0200 Subject: [PATCH 5/5] [HACK] pcie: renesas; emulate reading from ECAM under Xen If kernel is running as Xen guest, hypervisor will emulate ECAM spaces for us. Thus, we need to replace child_ops with ops that access ECAM address space. Signed-off-by: Volodymyr Babchuk --- drivers/pci/controller/dwc/pcie-renesas.c | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-renesas.c b/drivers/pci/controller/dwc/pcie-renesas.c index 12bc8b5cf559..c2ea20fde7b9 100644 --- a/drivers/pci/controller/dwc/pcie-renesas.c +++ b/drivers/pci/controller/dwc/pcie-renesas.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "../../pci.h" #include "pcie-designware.h" @@ -210,12 +211,39 @@ static const struct dw_pcie_ops dw_pcie_ops = { .link_up = renesas_pcie_link_up, }; + +void __iomem *renesas_xen_map_bus(struct pci_bus *bus, unsigned int devfn, + int where) +{ + struct pcie_port *pp = bus->sysdata; + const int bus_shift = 20; + unsigned int devfn_shift = bus_shift - 8; + unsigned int busn = bus->number; + void __iomem *base; + + busn -= 1; + + base = pp->va_cfg0_base + (busn << bus_shift); + return base + (devfn << devfn_shift) + where; +} + + +static struct pci_ops renesas_xen_child_ops = { + .map_bus = renesas_xen_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, +}; + static int renesas_pcie_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); u32 val; int ret; + /* Xen will emulate ECAM address space for us */ + if (xen_domain()) + pp->bridge->child_ops = &renesas_xen_child_ops; + dw_pcie_setup_rc(pp); dw_pcie_dbi_ro_wr_en(pci); -- 2.38.1