aboutsummaryrefslogtreecommitdiff
path: root/sys/mips
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2019-05-16 19:10:48 +0000
committerConrad Meyer <cem@FreeBSD.org>2019-05-16 19:10:48 +0000
commitfa3ac573a2f712393cebd195bf7331cff3d1b8fe (patch)
treef35de6adc89e0c983e4438a25151b56ffbe8495c /sys/mips
parent7460ef5d7a710a92e75ca78d22b49cbf667865c6 (diff)
downloadsrc-fa3ac573a2f712393cebd195bf7331cff3d1b8fe.tar.gz
src-fa3ac573a2f712393cebd195bf7331cff3d1b8fe.zip
mips: Implement basic pmap_kenter_device, pmap_kremove_device
Unbreak mips.BERI_DE4_SDROOT build, which uses device xdma. Device xdma depends on the pmap_kenter_device APIs. Reported by: tinderbox (local) Sponsored by: Dell EMC Isilon
Notes
Notes: svn path=/head/; revision=347888
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/include/pmap.h2
-rw-r--r--sys/mips/mips/pmap.c38
2 files changed, 40 insertions, 0 deletions
diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h
index ba31de835d23..edc9089a6fbc 100644
--- a/sys/mips/include/pmap.h
+++ b/sys/mips/include/pmap.h
@@ -177,7 +177,9 @@ void pmap_unmapdev(vm_offset_t, vm_size_t);
vm_offset_t pmap_steal_memory(vm_size_t size);
void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, vm_memattr_t attr);
+void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
void pmap_kremove(vm_offset_t va);
+void pmap_kremove_device(vm_offset_t, vm_size_t);
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
void pmap_kenter_temporary_free(vm_paddr_t pa);
void pmap_flush_pvcache(vm_page_t m);
diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
index a0de635ff396..d0edad94a582 100644
--- a/sys/mips/mips/pmap.c
+++ b/sys/mips/mips/pmap.c
@@ -854,6 +854,44 @@ pmap_kenter(vm_offset_t va, vm_paddr_t pa)
pmap_kenter_attr(va, pa, VM_MEMATTR_DEFAULT);
}
+void
+pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
+{
+
+ KASSERT((size & PAGE_MASK) == 0,
+ ("%s: device mapping not page-sized", __func__));
+
+ for (; size > 0; size -= PAGE_SIZE) {
+ /*
+ * XXXCEM: this is somewhat inefficient on SMP systems in that
+ * every single page is individually TLB-invalidated via
+ * rendezvous (pmap_update_page()), instead of invalidating the
+ * entire range via a single rendezvous.
+ */
+ pmap_kenter_attr(va, pa, VM_MEMATTR_UNCACHEABLE);
+ va += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ }
+}
+
+void
+pmap_kremove_device(vm_offset_t va, vm_size_t size)
+{
+
+ KASSERT((size & PAGE_MASK) == 0,
+ ("%s: device mapping not page-sized", __func__));
+
+ /*
+ * XXXCEM: Similar to pmap_kenter_device, this is inefficient on SMP,
+ * in that pages are invalidated individually instead of a single range
+ * rendezvous.
+ */
+ for (; size > 0; size -= PAGE_SIZE) {
+ pmap_kremove(va);
+ va += PAGE_SIZE;
+ }
+}
+
/*
* remove a page from the kernel pagetables
*/