git: cb894f746c07 - main - Map arm64 pci config memory as non-posted
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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);