Module Name: src Committed By: matt Date: Wed Jun 15 22:46:40 UTC 2011
Modified Files: src/sys/arch/powerpc/booke: booke_cache.c Log Message: Rework to get the inlining working right. Also make slightly more portable among powerpc variants. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/arch/powerpc/booke/booke_cache.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/powerpc/booke/booke_cache.c diff -u src/sys/arch/powerpc/booke/booke_cache.c:1.2 src/sys/arch/powerpc/booke/booke_cache.c:1.3 --- src/sys/arch/powerpc/booke/booke_cache.c:1.2 Tue Jan 18 01:02:52 2011 +++ src/sys/arch/powerpc/booke/booke_cache.c Wed Jun 15 22:46:39 2011 @@ -37,12 +37,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: booke_cache.c,v 1.2 2011/01/18 01:02:52 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: booke_cache.c,v 1.3 2011/06/15 22:46:39 matt Exp $"); #include <sys/param.h> #include <sys/cpu.h> +#include <sys/atomic.h> -#include <uvm/uvm_extern.h> +enum cache_op { OP_DCBF, OP_DCBST, OP_DCBI, OP_DCBZ, OP_DCBA, OP_ICBI }; static void inline dcbf(vaddr_t va, vsize_t off) @@ -81,8 +82,7 @@ } static inline void -cache_op(vaddr_t va, vsize_t len, vsize_t line_size, - void (*op)(vaddr_t, vsize_t)) +cache_op(vaddr_t va, vsize_t len, vsize_t line_size, enum cache_op op) { KASSERT(line_size > 0); @@ -93,66 +93,75 @@ len += va & (line_size - 1); va &= -line_size; - for (vsize_t i = 0; i < len; i += line_size) - (*op)(va, i); - __asm volatile("mbar 0"); + for (vsize_t i = 0; i < len; i += line_size) { + switch (op) { + case OP_DCBF: dcbf(va, i); break; + case OP_DCBST: dcbst(va, i); break; + case OP_DCBI: dcbi(va, i); break; + case OP_DCBZ: dcbz(va, i); break; + case OP_DCBA: dcba(va, i); break; + case OP_ICBI: icbi(va, i); break; + } + } + if (op != OP_ICBI) + membar_producer(); } void dcache_wb_page(vaddr_t va) { - cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, dcbst); + cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBST); } void dcache_wbinv_page(vaddr_t va) { - cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, dcbf); + cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBF); } void dcache_inv_page(vaddr_t va) { - cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, dcbi); + cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBI); } void dcache_zero_page(vaddr_t va) { - cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, dcbz); + cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBZ); } void icache_inv_page(vaddr_t va) { - __asm("msync"); - cache_op(va, PAGE_SIZE, curcpu()->ci_ci.icache_line_size, icbi); - __asm("msync"); + membar_sync(); + cache_op(va, PAGE_SIZE, curcpu()->ci_ci.icache_line_size, OP_ICBI); + membar_sync(); /* synchronizing instruction will be the rfi to user mode */ } void dcache_wb(vaddr_t va, vsize_t len) { - cache_op(va, len, curcpu()->ci_ci.dcache_line_size, dcbst); + cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBST); } void dcache_wbinv(vaddr_t va, vsize_t len) { - cache_op(va, len, curcpu()->ci_ci.dcache_line_size, dcbf); + cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBF); } void dcache_inv(vaddr_t va, vsize_t len) { - cache_op(va, len, curcpu()->ci_ci.dcache_line_size, dcbi); + cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBI); } void icache_inv(vaddr_t va, vsize_t len) { - __asm volatile("msync"); - cache_op(va, len, curcpu()->ci_ci.icache_line_size, icbi); - __asm volatile("msync"); + membar_sync(); + cache_op(va, len, curcpu()->ci_ci.icache_line_size, OP_ICBI); + membar_sync(); }