xref: /qemu/util/cacheflush.c (revision 1da8de39)
1084cfca1SRichard Henderson /*
2084cfca1SRichard Henderson  * Flush the host cpu caches.
3084cfca1SRichard Henderson  *
4084cfca1SRichard Henderson  * This work is licensed under the terms of the GNU GPL, version 2 or later.
5084cfca1SRichard Henderson  * See the COPYING file in the top-level directory.
6084cfca1SRichard Henderson  */
7084cfca1SRichard Henderson 
8084cfca1SRichard Henderson #include "qemu/osdep.h"
9084cfca1SRichard Henderson #include "qemu/cacheflush.h"
10084cfca1SRichard Henderson 
11084cfca1SRichard Henderson 
12084cfca1SRichard Henderson #if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
13084cfca1SRichard Henderson 
14084cfca1SRichard Henderson /* Caches are coherent and do not require flushing; symbol inline. */
15084cfca1SRichard Henderson 
16084cfca1SRichard Henderson #elif defined(__mips__)
17084cfca1SRichard Henderson 
18084cfca1SRichard Henderson #ifdef __OpenBSD__
19084cfca1SRichard Henderson #include <machine/sysarch.h>
20084cfca1SRichard Henderson #else
21084cfca1SRichard Henderson #include <sys/cachectl.h>
22084cfca1SRichard Henderson #endif
23084cfca1SRichard Henderson 
24*1da8de39SRichard Henderson void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
25084cfca1SRichard Henderson {
26*1da8de39SRichard Henderson     if (rx != rw) {
27*1da8de39SRichard Henderson         cacheflush((void *)rw, len, DCACHE);
28*1da8de39SRichard Henderson     }
29*1da8de39SRichard Henderson     cacheflush((void *)rx, len, ICACHE);
30084cfca1SRichard Henderson }
31084cfca1SRichard Henderson 
32084cfca1SRichard Henderson #elif defined(__powerpc__)
33084cfca1SRichard Henderson 
34*1da8de39SRichard Henderson void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
35084cfca1SRichard Henderson {
36*1da8de39SRichard Henderson     uintptr_t p, b, e;
37084cfca1SRichard Henderson     size_t dsize = qemu_dcache_linesize;
38084cfca1SRichard Henderson     size_t isize = qemu_icache_linesize;
39084cfca1SRichard Henderson 
40*1da8de39SRichard Henderson     b = rw & ~(dsize - 1);
41*1da8de39SRichard Henderson     e = (rw + len + dsize - 1) & ~(dsize - 1);
42*1da8de39SRichard Henderson     for (p = b; p < e; p += dsize) {
43084cfca1SRichard Henderson         asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
44084cfca1SRichard Henderson     }
45084cfca1SRichard Henderson     asm volatile ("sync" : : : "memory");
46084cfca1SRichard Henderson 
47*1da8de39SRichard Henderson     b = rx & ~(isize - 1);
48*1da8de39SRichard Henderson     e = (rx + len + isize - 1) & ~(isize - 1);
49*1da8de39SRichard Henderson     for (p = b; p < e; p += isize) {
50084cfca1SRichard Henderson         asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
51084cfca1SRichard Henderson     }
52084cfca1SRichard Henderson     asm volatile ("sync" : : : "memory");
53084cfca1SRichard Henderson     asm volatile ("isync" : : : "memory");
54084cfca1SRichard Henderson }
55084cfca1SRichard Henderson 
56084cfca1SRichard Henderson #elif defined(__sparc__)
57084cfca1SRichard Henderson 
58*1da8de39SRichard Henderson void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
59084cfca1SRichard Henderson {
60*1da8de39SRichard Henderson     /* No additional data flush to the RW virtual address required. */
61*1da8de39SRichard Henderson     uintptr_t p, end = (rx + len + 7) & -8;
62*1da8de39SRichard Henderson     for (p = rx & -8; p < end; p += 8) {
63084cfca1SRichard Henderson         __asm__ __volatile__("flush\t%0" : : "r" (p));
64084cfca1SRichard Henderson     }
65084cfca1SRichard Henderson }
66084cfca1SRichard Henderson 
67084cfca1SRichard Henderson #else
68084cfca1SRichard Henderson 
69*1da8de39SRichard Henderson void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
70084cfca1SRichard Henderson {
71*1da8de39SRichard Henderson     if (rw != rx) {
72*1da8de39SRichard Henderson         __builtin___clear_cache((char *)rw, (char *)rw + len);
73*1da8de39SRichard Henderson     }
74*1da8de39SRichard Henderson     __builtin___clear_cache((char *)rx, (char *)rx + len);
75084cfca1SRichard Henderson }
76084cfca1SRichard Henderson 
77084cfca1SRichard Henderson #endif
78