diff options
author | raj <raj@FreeBSD.org> | 2009-07-20 07:53:07 +0000 |
---|---|---|
committer | raj <raj@FreeBSD.org> | 2009-07-20 07:53:07 +0000 |
commit | d1ac98198b3b8168b7cd32bf3434b7dfdacb6f44 (patch) | |
tree | e653c8dc4b6d286936a3ab2893f8b9c0add4f68e | |
parent | fb3be5ae642345d1d3dcdb03ecfb7a223ac3ce6a (diff) | |
download | FreeBSD-src-d1ac98198b3b8168b7cd32bf3434b7dfdacb6f44.zip FreeBSD-src-d1ac98198b3b8168b7cd32bf3434b7dfdacb6f44.tar.gz |
ARM pmap fixes.
a) nocache-remap problem
When a page is remapped into a non-cacheable virtual memory region there
was no associated write-back invalidate operation performed. We remove
writeback of the original buffer size from bus_dmamem_alloc() and add
appropriate L1/L2 flush operation.
b) missing write-back invalidate operation
In pmap_kremove a page is removed so we must do a write-back
invalidate operation aligned to the page virtual address.
Submitted by: Michal Hajduk
Reviewed by: Mark Tinguely, rpaulo, stas
Approved by: re (kib)
Obtained from: Semihalf
-rw-r--r-- | sys/arm/arm/busdma_machdep.c | 4 | ||||
-rw-r--r-- | sys/arm/arm/pmap.c | 1 | ||||
-rw-r--r-- | sys/arm/arm/vm_machdep.c | 7 |
3 files changed, 7 insertions, 5 deletions
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index f35840e..cf4873f 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -630,10 +630,6 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, ((vm_offset_t)*vaddr & PAGE_MASK)); newmap->origbuffer = *vaddr; newmap->allocbuffer = tmpaddr; - cpu_idcache_wbinv_range((vm_offset_t)*vaddr, - dmat->maxsize); - cpu_l2cache_wbinv_range((vm_offset_t)*vaddr, - dmat->maxsize); *vaddr = tmpaddr; } else newmap->origbuffer = newmap->allocbuffer = NULL; diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index daa35f6..303b81e 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -2984,6 +2984,7 @@ pmap_kremove(vm_offset_t va) pmap_free_pv_entry(pve); PMAP_UNLOCK(pmap_kernel()); vm_page_unlock_queues(); + va = va & ~PAGE_MASK; cpu_dcache_wbinv_range(va, PAGE_SIZE); cpu_l2cache_wbinv_range(va, PAGE_SIZE); cpu_tlb_flushD_SE(va); diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 27104d4..1a907cc 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -426,10 +426,15 @@ arm_remap_nocache(void *addr, vm_size_t size) vm_offset_t tomap = arm_nocache_startaddr + i * PAGE_SIZE; void *ret = (void *)tomap; vm_paddr_t physaddr = vtophys((vm_offset_t)addr); + vm_offset_t vaddr = (vm_offset_t) addr; + vaddr = vaddr & ~PAGE_MASK; for (; tomap < (vm_offset_t)ret + size; tomap += PAGE_SIZE, - physaddr += PAGE_SIZE, i++) { + vaddr += PAGE_SIZE, physaddr += PAGE_SIZE, i++) { + cpu_idcache_wbinv_range(vaddr, PAGE_SIZE); + cpu_l2cache_wbinv_range(vaddr, PAGE_SIZE); pmap_kenter_nocache(tomap, physaddr); + cpu_tlb_flushID_SE(vaddr); arm_nocache_allocated[i / BITS_PER_INT] |= 1 << (i % BITS_PER_INT); } |