Date: Fri, 10 Apr 2015 13:26:35 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281369 - in head/sys/arm: arm include Message-ID: <201504101326.t3ADQZhg098252@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Fri Apr 10 13:26:35 2015 New Revision: 281369 URL: https://svnweb.freebsd.org/changeset/base/281369 Log: Add a pmap_kremove_device() to undo mappings made with pmap_kenter_device(). Previously we used pmap_kremove(), but with ARM_NEW_PMAP it does the remove in a way that isn't SMP-coherent (which is appropriate in some circumstances such as mapping/unmapping sf buffers). With matching enter/remove routines for device mappings, each low-level implementation can do the right thing. Reviewed by: Svatopluk Kraus <onwahe@gmail.com> Modified: head/sys/arm/arm/devmap.c head/sys/arm/arm/pmap-v6-new.c head/sys/arm/arm/pmap-v6.c head/sys/arm/arm/pmap.c head/sys/arm/include/pmap-v6.h head/sys/arm/include/pmap.h Modified: head/sys/arm/arm/devmap.c ============================================================================== --- head/sys/arm/arm/devmap.c Fri Apr 10 13:26:05 2015 (r281368) +++ head/sys/arm/arm/devmap.c Fri Apr 10 13:26:35 2015 (r281369) @@ -246,7 +246,7 @@ arm_devmap_vtop(void * vpva, vm_size_t s void * pmap_mapdev(vm_offset_t pa, vm_size_t size) { - vm_offset_t va, tmpva, offset; + vm_offset_t va, offset; void * rva; /* First look in the static mapping table. */ @@ -261,12 +261,7 @@ pmap_mapdev(vm_offset_t pa, vm_size_t si if (!va) panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); - for (tmpva = va; size > 0;) { - pmap_kenter_device(tmpva, pa); - size -= PAGE_SIZE; - tmpva += PAGE_SIZE; - pa += PAGE_SIZE; - } + pmap_kenter_device(va, size, pa); return ((void *)(va + offset)); } @@ -277,25 +272,18 @@ pmap_mapdev(vm_offset_t pa, vm_size_t si void pmap_unmapdev(vm_offset_t va, vm_size_t size) { - vm_offset_t tmpva, offset; - vm_size_t origsize; + vm_offset_t offset; /* Nothing to do if we find the mapping in the static table. */ if (arm_devmap_vtop((void*)va, size) != DEVMAP_PADDR_NOTFOUND) return; - origsize = size; offset = va & PAGE_MASK; va = trunc_page(va); size = round_page(size + offset); - for (tmpva = va; size > 0;) { - pmap_kremove(tmpva); - size -= PAGE_SIZE; - tmpva += PAGE_SIZE; - } - - kva_free(va, origsize); + pmap_kremove_device(va, size); + kva_free(va, size); } #ifdef DDB Modified: head/sys/arm/arm/pmap-v6-new.c ============================================================================== --- head/sys/arm/arm/pmap-v6-new.c Fri Apr 10 13:26:05 2015 (r281368) +++ head/sys/arm/arm/pmap-v6-new.c Fri Apr 10 13:26:35 2015 (r281369) @@ -6051,11 +6051,38 @@ retry: } void -pmap_kenter_device(vm_offset_t va, vm_paddr_t pa) +pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa) { + vm_offset_t sva; - pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEVICE); - tlb_flush(va); + KASSERT((size & PAGE_MASK) == 0, + ("%s: device mapping not page-sized", __func__)); + + sva = va; + while (size != 0) { + pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEVICE); + va += PAGE_SIZE; + pa += PAGE_SIZE; + size -= PAGE_SIZE; + } + tlb_flush_range(sva, va - sva); +} + +void +pmap_kremove_device(vm_offset_t va, vm_size_t size) +{ + vm_offset_t sva; + + KASSERT((size & PAGE_MASK) == 0, + ("%s: device mapping not page-sized", __func__)); + + sva = va; + while (size != 0) { + pmap_kremove(va); + va += PAGE_SIZE; + size -= PAGE_SIZE; + } + tlb_flush_range(sva, va - sva); } void Modified: head/sys/arm/arm/pmap-v6.c ============================================================================== --- head/sys/arm/arm/pmap-v6.c Fri Apr 10 13:26:05 2015 (r281368) +++ head/sys/arm/arm/pmap-v6.c Fri Apr 10 13:26:35 2015 (r281369) @@ -2451,10 +2451,36 @@ pmap_kenter_nocache(vm_offset_t va, vm_p } void -pmap_kenter_device(vm_offset_t va, vm_paddr_t pa) +pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa) { + vm_offset_t sva; - pmap_kenter_internal(va, pa, KENTER_DEVICE); + KASSERT((size & PAGE_MASK) == 0, + ("%s: device mapping not page-sized", __func__)); + + sva = va; + while (size != 0) { + pmap_kenter_internal(va, pa, KENTER_DEVICE); + va += PAGE_SIZE; + pa += PAGE_SIZE; + size -= PAGE_SIZE; + } +} + +void +pmap_kremove_device(vm_offset_t va, vm_size_t size) +{ + vm_offset_t sva; + + KASSERT((size & PAGE_MASK) == 0, + ("%s: device mapping not page-sized", __func__)); + + sva = va; + while (size != 0) { + pmap_kremove(va); + va += PAGE_SIZE; + size -= PAGE_SIZE; + } } void Modified: head/sys/arm/arm/pmap.c ============================================================================== --- head/sys/arm/arm/pmap.c Fri Apr 10 13:26:05 2015 (r281368) +++ head/sys/arm/arm/pmap.c Fri Apr 10 13:26:35 2015 (r281369) @@ -2712,14 +2712,36 @@ pmap_kenter_nocache(vm_offset_t va, vm_p } void -pmap_kenter_device(vm_offset_t va, vm_paddr_t pa) +pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa) { + vm_offset_t sva; - /* - * XXX - Need a way for kenter_internal to handle PTE_DEVICE mapping as - * a potentially different thing than PTE_NOCACHE. - */ - pmap_kenter_internal(va, pa, 0); + KASSERT((size & PAGE_MASK) == 0, + ("%s: device mapping not page-sized", __func__)); + + sva = va; + while (size != 0) { + pmap_kenter_internal(va, pa, 0); + va += PAGE_SIZE; + pa += PAGE_SIZE; + size -= PAGE_SIZE; + } +} + +void +pmap_kremove_device(vm_offset_t va, vm_size_t size) +{ + vm_offset_t sva; + + KASSERT((size & PAGE_MASK) == 0, + ("%s: device mapping not page-sized", __func__)); + + sva = va; + while (size != 0) { + pmap_kremove(va); + va += PAGE_SIZE; + size -= PAGE_SIZE; + } } void Modified: head/sys/arm/include/pmap-v6.h ============================================================================== --- head/sys/arm/include/pmap-v6.h Fri Apr 10 13:26:05 2015 (r281368) +++ head/sys/arm/include/pmap-v6.h Fri Apr 10 13:26:35 2015 (r281369) @@ -190,7 +190,8 @@ void *pmap_mapdev_attr(vm_paddr_t, vm_si boolean_t pmap_page_is_mapped(vm_page_t ); void pmap_page_set_memattr(vm_page_t , vm_memattr_t ); void pmap_unmapdev(vm_offset_t, vm_size_t); -void pmap_kenter_device(vm_offset_t , vm_paddr_t ); +void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t); +void pmap_kremove_device(vm_offset_t, vm_size_t); void pmap_set_pcb_pagedir(pmap_t , struct pcb *); void pmap_lazyfix_action(void); Modified: head/sys/arm/include/pmap.h ============================================================================== --- head/sys/arm/include/pmap.h Fri Apr 10 13:26:05 2015 (r281368) +++ head/sys/arm/include/pmap.h Fri Apr 10 13:26:35 2015 (r281369) @@ -258,7 +258,8 @@ void pmap_bootstrap(vm_offset_t firstadd int pmap_change_attr(vm_offset_t, vm_size_t, int); void pmap_kenter(vm_offset_t va, vm_paddr_t pa); void pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa); -void pmap_kenter_device(vm_offset_t va, vm_paddr_t pa); +void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t); +void pmap_kremove_device(vm_offset_t, vm_size_t); void *pmap_kenter_temporary(vm_paddr_t pa, int i); void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa); vm_paddr_t pmap_kextract(vm_offset_t va);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504101326.t3ADQZhg098252>