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>
This commit is contained in:
parent
5b36d2f7ec
commit
8e7c521fdb
@ -246,7 +246,7 @@ arm_devmap_vtop(void * vpva, vm_size_t size)
|
|||||||
void *
|
void *
|
||||||
pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
||||||
{
|
{
|
||||||
vm_offset_t va, tmpva, offset;
|
vm_offset_t va, offset;
|
||||||
void * rva;
|
void * rva;
|
||||||
|
|
||||||
/* First look in the static mapping table. */
|
/* First look in the static mapping table. */
|
||||||
@ -261,12 +261,7 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
|||||||
if (!va)
|
if (!va)
|
||||||
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
|
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
|
||||||
|
|
||||||
for (tmpva = va; size > 0;) {
|
pmap_kenter_device(va, size, pa);
|
||||||
pmap_kenter_device(tmpva, pa);
|
|
||||||
size -= PAGE_SIZE;
|
|
||||||
tmpva += PAGE_SIZE;
|
|
||||||
pa += PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((void *)(va + offset));
|
return ((void *)(va + offset));
|
||||||
}
|
}
|
||||||
@ -277,25 +272,18 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
|||||||
void
|
void
|
||||||
pmap_unmapdev(vm_offset_t va, vm_size_t size)
|
pmap_unmapdev(vm_offset_t va, vm_size_t size)
|
||||||
{
|
{
|
||||||
vm_offset_t tmpva, offset;
|
vm_offset_t offset;
|
||||||
vm_size_t origsize;
|
|
||||||
|
|
||||||
/* Nothing to do if we find the mapping in the static table. */
|
/* Nothing to do if we find the mapping in the static table. */
|
||||||
if (arm_devmap_vtop((void*)va, size) != DEVMAP_PADDR_NOTFOUND)
|
if (arm_devmap_vtop((void*)va, size) != DEVMAP_PADDR_NOTFOUND)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
origsize = size;
|
|
||||||
offset = va & PAGE_MASK;
|
offset = va & PAGE_MASK;
|
||||||
va = trunc_page(va);
|
va = trunc_page(va);
|
||||||
size = round_page(size + offset);
|
size = round_page(size + offset);
|
||||||
|
|
||||||
for (tmpva = va; size > 0;) {
|
pmap_kremove_device(va, size);
|
||||||
pmap_kremove(tmpva);
|
kva_free(va, size);
|
||||||
size -= PAGE_SIZE;
|
|
||||||
tmpva += PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
kva_free(va, origsize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DDB
|
#ifdef DDB
|
||||||
|
@ -6051,11 +6051,38 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
KASSERT((size & PAGE_MASK) == 0,
|
||||||
tlb_flush(va);
|
("%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
|
void
|
||||||
|
@ -2451,10 +2451,36 @@ pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
void
|
||||||
|
@ -2712,14 +2712,36 @@ pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
||||||
|
|
||||||
/*
|
KASSERT((size & PAGE_MASK) == 0,
|
||||||
* XXX - Need a way for kenter_internal to handle PTE_DEVICE mapping as
|
("%s: device mapping not page-sized", __func__));
|
||||||
* a potentially different thing than PTE_NOCACHE.
|
|
||||||
*/
|
sva = va;
|
||||||
pmap_kenter_internal(va, pa, 0);
|
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
|
void
|
||||||
|
@ -190,7 +190,8 @@ void *pmap_mapdev_attr(vm_paddr_t, vm_size_t, int);
|
|||||||
boolean_t pmap_page_is_mapped(vm_page_t );
|
boolean_t pmap_page_is_mapped(vm_page_t );
|
||||||
void pmap_page_set_memattr(vm_page_t , vm_memattr_t );
|
void pmap_page_set_memattr(vm_page_t , vm_memattr_t );
|
||||||
void pmap_unmapdev(vm_offset_t, vm_size_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_set_pcb_pagedir(pmap_t , struct pcb *);
|
||||||
void pmap_lazyfix_action(void);
|
void pmap_lazyfix_action(void);
|
||||||
|
|
||||||
|
@ -258,7 +258,8 @@ void pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt);
|
|||||||
int pmap_change_attr(vm_offset_t, vm_size_t, int);
|
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(vm_offset_t va, vm_paddr_t pa);
|
||||||
void pmap_kenter_nocache(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_temporary(vm_paddr_t pa, int i);
|
||||||
void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa);
|
void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa);
|
||||||
vm_paddr_t pmap_kextract(vm_offset_t va);
|
vm_paddr_t pmap_kextract(vm_offset_t va);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user