diff --git a/sys/arm64/apple/apple_pcie.c b/sys/arm64/apple/apple_pcie.c index 19c3d221aaaf..c8e78891c2bc 100644 --- a/sys/arm64/apple/apple_pcie.c +++ b/sys/arm64/apple/apple_pcie.c @@ -1260,6 +1265,50 @@ device_printf(dev, "bst %p bsh %lx\n", sc->base.base.bst, sc->base.base.bsh); return (bus_generic_attach(dev)); } +static int +apple_pcie_activate_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + rman_res_t start, end; + int res; + + if ((res = rman_activate_resource(r)) != 0) + return (res); + + start = rman_get_start(r); + end = rman_get_end(r); + res = pci_host_generic_translate_resource(dev, type, start, end, + &start, &end); + if (res != 0) { + rman_deactivate_resource(r); + return (res); + } + + rman_set_start(r, start); + rman_set_end(r, end); + + /* Hijack memory requests and map them nGnRE */ + if (type == SYS_RES_MEMORY && (rman_get_flags(r) & RF_UNMAPPED) == 0) { + struct resource_map_request req; + struct resource_map map; + + resource_init_map_request(&req); + req.memattr = VM_MEMATTR_DEVICE_nGnRE; + res = bus_map_resource(child, type, r, &req, &map); + if (res != 0) { + rman_deactivate_resource(r); + return (res); + } + + rman_set_mapping(r, &map); + + return (0); + } + + return (BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, + rid, r)); +} + /* * Device method table. */ @@ -1268,6 +1317,8 @@ static device_method_t apple_pcie_methods[] = { DEVMETHOD(device_probe, apple_pcie_probe), DEVMETHOD(device_attach, apple_pcie_attach), + DEVMETHOD(bus_activate_resource, apple_pcie_activate_resource), + /* PCIB interface. */ DEVMETHOD(pcib_read_config, apple_pcie_read_config), DEVMETHOD(pcib_write_config, apple_pcie_write_config), diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c index fbc9c2e1d3c2..cef9cf23d4ef 100644 --- a/sys/dev/pci/pci_host_generic.c +++ b/sys/dev/pci/pci_host_generic.c @@ -362,8 +386,8 @@ pci_host_generic_core_release_resource(device_t dev, device_t child, int type, return (bus_generic_release_resource(dev, child, type, rid, res)); } -static int -generic_pcie_translate_resource_common(device_t dev, int type, rman_res_t start, +int +pci_host_generic_translate_resource(device_t dev, int type, rman_res_t start, rman_res_t end, rman_res_t *new_start, rman_res_t *new_end) { struct generic_pcie_core_softc *sc; @@ -425,7 +449,7 @@ generic_pcie_translate_resource(device_t bus, int type, { rman_res_t newend; /* unused */ - return (generic_pcie_translate_resource_common( + return (pci_host_generic_translate_resource( bus, type, start, 0, newstart, &newend)); } @@ -491,7 +519,7 @@ generic_pcie_activate_resource(device_t dev, device_t child, int type, start = rman_get_start(r); end = rman_get_end(r); - res = generic_pcie_translate_resource_common(dev, type, start, end, + res = pci_host_generic_translate_resource(dev, type, start, end, &start, &end); if (res != 0) { rman_deactivate_resource(r); diff --git a/sys/dev/pci/pci_host_generic.h b/sys/dev/pci/pci_host_generic.h index 80da4f523165..6adfb86d1e5d 100644 --- a/sys/dev/pci/pci_host_generic.h +++ b/sys/dev/pci/pci_host_generic.h @@ -99,5 +99,7 @@ struct resource *pci_host_generic_core_alloc_resource(device_t, device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); int pci_host_generic_core_release_resource(device_t, device_t, int, int, struct resource *); +int pci_host_generic_translate_resource(device_t, int, rman_res_t, rman_res_t, + rman_res_t *, rman_res_t *); #endif /* __PCI_HOST_GENERIC_H_ */