aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2021-04-08 11:54:20 +0000
committerAndrew Turner <andrew@FreeBSD.org>2021-05-01 06:01:20 +0000
commit2abd4f858146a266d48e3c55c2e29376e8b00967 (patch)
tree6024d5766578ecd074224068d4a9463c398de628
parenta6ca7519f89c52e9fab205cded0f2bf32d914cd6 (diff)
downloadsrc-2abd4f858146a266d48e3c55c2e29376e8b00967.tar.gz
src-2abd4f858146a266d48e3c55c2e29376e8b00967.zip
Add a way to map arm64 non-posted device memory
On arm64 we currently use a non-posted write for device memory, however we should move to use posted writes. This is expected to work on most hardware, however we will need to support a non-posted option for some broken hardware. Reviewed by: imp, manu, bcr (manpage) Differential Revision: https://reviews.freebsd.org/D29722
-rw-r--r--share/man/man9/bus_space.97
-rw-r--r--sys/arm64/arm64/bus_machdep.c6
-rw-r--r--sys/arm64/include/bus.h1
-rw-r--r--sys/arm64/include/vm.h5
-rw-r--r--usr.bin/vmstat/vmstat.c3
5 files changed, 20 insertions, 2 deletions
diff --git a/share/man/man9/bus_space.9 b/share/man/man9/bus_space.9
index 80e041dea4eb..9d5ca602acfe 100644
--- a/share/man/man9/bus_space.9
+++ b/share/man/man9/bus_space.9
@@ -52,7 +52,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 7, 2020
+.Dd May 1, 2021
.Dt BUS_SPACE 9
.Os
.Sh NAME
@@ -876,6 +876,11 @@ call should fail.
If this
flag is not specified, the system may map the space in whatever way is
most convenient.
+.It Dv BUS_SPACE_MAP_NONPOSTED
+Try to map the space using non-posted device memory.
+This is to support buses and devices where mapping with posted device
+memory is unsupported or broken.
+This flag is currently only available on arm64.
.El
.Pp
Not all combinations of flags make sense or are supported with all
diff --git a/sys/arm64/arm64/bus_machdep.c b/sys/arm64/arm64/bus_machdep.c
index 69d7c5b591b2..b2136af38cad 100644
--- a/sys/arm64/arm64/bus_machdep.c
+++ b/sys/arm64/arm64/bus_machdep.c
@@ -99,9 +99,13 @@ static int
generic_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
+ vm_memattr_t ma;
void *va;
- va = pmap_mapdev(bpa, size);
+ ma = VM_MEMATTR_DEVICE;
+ if (flags == BUS_SPACE_MAP_NONPOSTED)
+ ma = VM_MEMATTR_DEVICE_NP;
+ va = pmap_mapdev_attr(bpa, size, ma);
if (va == NULL)
return (ENOMEM);
*bshp = (bus_space_handle_t)va;
diff --git a/sys/arm64/include/bus.h b/sys/arm64/include/bus.h
index a2bd432a5de5..61573b27728d 100644
--- a/sys/arm64/include/bus.h
+++ b/sys/arm64/include/bus.h
@@ -85,6 +85,7 @@
#define BUS_SPACE_MAP_CACHEABLE 0x01
#define BUS_SPACE_MAP_LINEAR 0x02
#define BUS_SPACE_MAP_PREFETCHABLE 0x04
+#define BUS_SPACE_MAP_NONPOSTED 0x08
#define BUS_SPACE_UNRESTRICTED (~0)
diff --git a/sys/arm64/include/vm.h b/sys/arm64/include/vm.h
index 3df3af24c010..e479aab52e26 100644
--- a/sys/arm64/include/vm.h
+++ b/sys/arm64/include/vm.h
@@ -36,7 +36,12 @@
#define VM_MEMATTR_WRITE_THROUGH 3
#define VM_MEMATTR_DEVICE_nGnRE 4
+/*
+ * VM_MEMATTR_DEVICE can be changed to VM_MEMATTR_DEVICE_nGnRE when
+ * the PCI drivers use VM_MEMATTR_DEVICE_NP for their config space.
+ */
#define VM_MEMATTR_DEVICE VM_MEMATTR_DEVICE_nGnRnE
+#define VM_MEMATTR_DEVICE_NP VM_MEMATTR_DEVICE_nGnRnE
#ifdef _KERNEL
/* If defined vmstat will try to use both of these in a switch statement */
diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c
index 403dc6e2a054..ba1dc9eef883 100644
--- a/usr.bin/vmstat/vmstat.c
+++ b/usr.bin/vmstat/vmstat.c
@@ -1570,6 +1570,9 @@ display_object(struct kinfo_vmobject *kvo)
#ifdef VM_MEMATTR_DEVICE
MEMATTR_STR(VM_MEMATTR_DEVICE, "DEV")
#endif
+#ifdef VM_MEMATTR_DEVICE_NP
+ MEMATTR_STR(VM_MEMATTR_DEVICE, "NP")
+#endif
#ifdef VM_MEMATTR_CACHEABLE
MEMATTR_STR(VM_MEMATTR_CACHEABLE, "C")
#endif