git: cb894f746c07 - main - Map arm64 pci config memory as non-posted

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Sun, 05 Mar 2023 20:28:03 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=cb894f746c07001dd5aebfafca596374ec335964

commit cb894f746c07001dd5aebfafca596374ec335964
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2023-03-05 12:34:35 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2023-03-05 20:17:21 +0000

    Map arm64 pci config memory as non-posted
    
    On arm64 PCI config memory is expected to be mapped with a non-posted
    device type. To handle this use the new bus_map_resource support in
    arm64 to map memory with the new VM_MEMATTR_DEVICE_NP attribute. This
    memory has already been allocated and activated, it just needs to be
    mapped.
    
    Reviewed by:    kevans, mmel
    Differential Revision:  https://reviews.freebsd.org/D30079
---
 sys/arm/nvidia/tegra_pcie.c         |  9 +++++++--
 sys/arm64/cavium/thunder_pcie_pem.c | 13 ++++++++++++-
 sys/arm64/qoriq/qoriq_dw_pci.c      | 14 +++++++++++++-
 sys/arm64/rockchip/rk_pcie.c        | 18 ++++++++++++++++--
 sys/dev/pci/pci_dw_mv.c             | 14 +++++++++++++-
 sys/dev/pci/pci_host_generic.c      | 26 +++++++++++++++++++++++++-
 6 files changed, 86 insertions(+), 8 deletions(-)

diff --git a/sys/arm/nvidia/tegra_pcie.c b/sys/arm/nvidia/tegra_pcie.c
index ecc58a93066f..a12d874e409b 100644
--- a/sys/arm/nvidia/tegra_pcie.c
+++ b/sys/arm/nvidia/tegra_pcie.c
@@ -392,7 +392,7 @@ tegra_pcbib_map_cfg(struct tegra_pcib_softc *sc, u_int bus, u_int slot,
     u_int func, u_int reg)
 {
 	bus_size_t offs;
-	int rv;
+	int flags, rv;
 
 	offs = sc->cfg_base_addr;
 	offs |= PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | PCI_CFG_FUN(func) |
@@ -402,7 +402,12 @@ tegra_pcbib_map_cfg(struct tegra_pcib_softc *sc, u_int bus, u_int slot,
 	if (sc->cfg_handle != 0)
 		bus_space_unmap(sc->bus_tag, sc->cfg_handle, 0x800);
 
-	rv = bus_space_map(sc->bus_tag, offs, 0x800, 0, &sc->cfg_handle);
+#if defined(BUS_SPACE_MAP_NONPOSTED)
+	flags = BUS_SPACE_MAP_NONPOSTED;
+#else
+	flags = 0;
+#endif
+	rv = bus_space_map(sc->bus_tag, offs, 0x800, flags, &sc->cfg_handle);
 	if (rv != 0)
 		device_printf(sc->dev, "Cannot map config space\n");
 	else
diff --git a/sys/arm64/cavium/thunder_pcie_pem.c b/sys/arm64/cavium/thunder_pcie_pem.c
index cbc70d7862de..3f4df8a621a3 100644
--- a/sys/arm64/cavium/thunder_pcie_pem.c
+++ b/sys/arm64/cavium/thunder_pcie_pem.c
@@ -745,6 +745,8 @@ thunder_pem_probe(device_t dev)
 static int
 thunder_pem_attach(device_t dev)
 {
+	struct resource_map_request req;
+	struct resource_map map;
 	devclass_t pci_class;
 	device_t parent;
 	struct thunder_pem_softc *sc;
@@ -766,11 +768,20 @@ thunder_pem_attach(device_t dev)
 		rid = RID_PEM_SPACE;
 
 	sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
-	    &rid, RF_ACTIVE);
+	    &rid, RF_ACTIVE | RF_UNMAPPED);
 	if (sc->reg == NULL) {
 		device_printf(dev, "Failed to allocate resource\n");
 		return (ENXIO);
 	}
+	resource_init_map_request(&req);
+	req.memattr = VM_MEMATTR_DEVICE_NP;
+	error = bus_map_resource(dev, SYS_RES_MEMORY, sc->reg, &req, &map);
+	if (error != 0) {
+		device_printf(dev, "could not map memory.\n");
+		return (error);
+	}
+	rman_set_mapping(sc->reg, &map);
+
 	sc->reg_bst = rman_get_bustag(sc->reg);
 	sc->reg_bsh = rman_get_bushandle(sc->reg);
 
diff --git a/sys/arm64/qoriq/qoriq_dw_pci.c b/sys/arm64/qoriq/qoriq_dw_pci.c
index f06b06a3aa01..2a11c9cf6cd4 100644
--- a/sys/arm64/qoriq/qoriq_dw_pci.c
+++ b/sys/arm64/qoriq/qoriq_dw_pci.c
@@ -188,6 +188,8 @@ qorif_dw_pci_probe(device_t dev)
 static int
 qorif_dw_pci_attach(device_t dev)
 {
+	struct resource_map_request req;
+	struct resource_map map;
 	struct qorif_dw_pci_softc *sc;
 	phandle_t node;
 	int rv;
@@ -202,13 +204,23 @@ qorif_dw_pci_attach(device_t dev)
 
 	rid = 0;
 	sc->dw_sc.dbi_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
-	    RF_ACTIVE);
+	    RF_ACTIVE | RF_UNMAPPED);
 	if (sc->dw_sc.dbi_res == NULL) {
 		device_printf(dev, "Cannot allocate DBI memory\n");
 		rv = ENXIO;
 		goto out;
 	}
 
+	resource_init_map_request(&req);
+	req.memattr = VM_MEMATTR_DEVICE_NP;
+	rv = bus_map_resource(dev, SYS_RES_MEMORY, sc->dw_sc.dbi_res, &req,
+	    &map);
+	if (rv != 0) {
+		device_printf(dev, "could not map memory.\n");
+		return (rv);
+	}
+	rman_set_mapping(sc->dw_sc.dbi_res, &map);
+
 	/* PCI interrupt */
 	rid = 0;
 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
diff --git a/sys/arm64/rockchip/rk_pcie.c b/sys/arm64/rockchip/rk_pcie.c
index 32f70a9c9b44..b59784275198 100644
--- a/sys/arm64/rockchip/rk_pcie.c
+++ b/sys/arm64/rockchip/rk_pcie.c
@@ -1143,7 +1143,10 @@ rk_pcie_probe(device_t dev)
 
 static int
 rk_pcie_attach(device_t dev)
-{	struct rk_pcie_softc *sc;
+{
+	struct resource_map_request req;
+	struct resource_map map;
+	struct rk_pcie_softc *sc;
 	uint32_t val;
 	int rv, rid, max_speed;
 
@@ -1192,13 +1195,24 @@ rk_pcie_attach(device_t dev)
 		goto out;
 	}
 	sc->axi_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
-	    RF_ACTIVE);
+	    RF_ACTIVE | RF_UNMAPPED);
 	if (sc->axi_mem_res == NULL) {
 		device_printf(dev, "Cannot allocate 'axi-base' (rid: %d)\n",
 		    rid);
 		rv = ENXIO;
 		goto out;
 	}
+	resource_init_map_request(&req);
+	req.memattr = VM_MEMATTR_DEVICE_NP;
+	rv = bus_map_resource(dev, SYS_RES_MEMORY, sc->axi_mem_res, &req,
+	    &map);
+	if (rv != 0) {
+		device_printf(dev, "Cannot map 'axi-base' (rid: %d)\n",
+		    rid);
+		goto out;
+	}
+	rman_set_mapping(sc->axi_mem_res, &map);
+
 	rv = ofw_bus_find_string_index(sc->node, "reg-names", "apb-base", &rid);
 	if (rv != 0) {
 		device_printf(dev, "Cannot get 'apb-base' memory\n");
diff --git a/sys/dev/pci/pci_dw_mv.c b/sys/dev/pci/pci_dw_mv.c
index 663d14e77d45..71b1087680d7 100644
--- a/sys/dev/pci/pci_dw_mv.c
+++ b/sys/dev/pci/pci_dw_mv.c
@@ -221,6 +221,8 @@ pci_mv_probe(device_t dev)
 static int
 pci_mv_attach(device_t dev)
 {
+	struct resource_map_request req;
+	struct resource_map map;
 	struct pci_mv_softc *sc;
 	phandle_t node;
 	int rv;
@@ -233,13 +235,23 @@ pci_mv_attach(device_t dev)
 
 	rid = 0;
 	sc->dw_sc.dbi_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
-	    RF_ACTIVE);
+	    RF_ACTIVE | RF_UNMAPPED);
 	if (sc->dw_sc.dbi_res == NULL) {
 		device_printf(dev, "Cannot allocate DBI memory\n");
 		rv = ENXIO;
 		goto out;
 	}
 
+	resource_init_map_request(&req);
+	req.memattr = VM_MEMATTR_DEVICE_NP;
+	rv = bus_map_resource(dev, SYS_RES_MEMORY, sc->dw_sc.dbi_res, &req,
+	    &map);
+	if (rv != 0) {
+		device_printf(dev, "could not map memory.\n");
+		return (rv);
+	}
+	rman_set_mapping(sc->dw_sc.dbi_res, &map);
+
 	/* PCI interrupt */
 	rid = 0;
 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c
index fbc9c2e1d3c2..3d12266a3ddd 100644
--- a/sys/dev/pci/pci_host_generic.c
+++ b/sys/dev/pci/pci_host_generic.c
@@ -54,6 +54,15 @@ __FBSDID("$FreeBSD$");
 
 #include "pcib_if.h"
 
+#if defined(VM_MEMATTR_DEVICE_NP)
+#define	PCI_UNMAPPED
+#define	PCI_RF_FLAGS	RF_UNMAPPED
+#else
+#error
+#define	PCI_RF_FLAGS	0
+#endif
+
+
 /* Forward prototypes */
 
 static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
@@ -69,6 +78,10 @@ static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
 int
 pci_host_generic_core_attach(device_t dev)
 {
+#ifdef PCI_UNMAPPED
+	struct resource_map_request req;
+	struct resource_map map;
+#endif
 	struct generic_pcie_core_softc *sc;
 	uint64_t phys_base;
 	uint64_t pci_base;
@@ -95,12 +108,23 @@ pci_host_generic_core_attach(device_t dev)
 		return (error);
 
 	rid = 0;
-	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    PCI_RF_FLAGS | RF_ACTIVE);
 	if (sc->res == NULL) {
 		device_printf(dev, "could not allocate memory.\n");
 		error = ENXIO;
 		goto err_resource;
 	}
+#ifdef PCI_UNMAPPED
+	resource_init_map_request(&req);
+	req.memattr = VM_MEMATTR_DEVICE_NP;
+	error = bus_map_resource(dev, SYS_RES_MEMORY, sc->res, &req, &map);
+	if (error != 0) {
+		device_printf(dev, "could not map memory.\n");
+		return (error);
+	}
+	rman_set_mapping(sc->res, &map);
+#endif
 
 	sc->bst = rman_get_bustag(sc->res);
 	sc->bsh = rman_get_bushandle(sc->res);