summaryrefslogtreecommitdiff
path: root/emu/Linux/segflush-power.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-23 00:30:12 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-23 00:30:12 +0000
commit6e425a9de8c003b5a733621a6b6730ec3cc902b8 (patch)
tree314123bcab78ff295f38f85f31dc141e5fe22d15 /emu/Linux/segflush-power.c
parent74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (diff)
20061220
Diffstat (limited to 'emu/Linux/segflush-power.c')
-rw-r--r--emu/Linux/segflush-power.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/emu/Linux/segflush-power.c b/emu/Linux/segflush-power.c
new file mode 100644
index 00000000..07f9a3cb
--- /dev/null
+++ b/emu/Linux/segflush-power.c
@@ -0,0 +1,27 @@
+/*
+ * from geoff collyer's port
+ * invalidate instruction cache and write back data cache from a to a+n-1,
+ * at least.
+ */
+void
+segflush(void *a, ulong n)
+{
+ ulong *p;
+
+ // cache blocks are often eight words (32 bytes) long, sometimes 16 bytes.
+ // need to determine it dynamically?
+ for (p = (ulong *)((ulong)a & ~3UL); (char *)p < (char *)a + n; p++)
+ __asm__("dcbst 0,%0\n\t" // not dcbf, which writes back, then invalidates
+ "icbi 0,%0\n\t"
+ : // no output
+ : "ar" (p)
+ );
+ __asm__("sync\n\t"
+ : // no output
+ :
+ );
+ __asm__("isync\n\t"
+ : // no output
+ :
+ );
+}