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();
}