util: Extract flush_icache_range to cacheflush.c

This has been a tcg-specific function, but is also in use
by hardware accelerators via physmem.c.  This can cause
link errors when tcg is disabled.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20201214140314.18544-3-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Richard Henderson 2020-12-14 08:02:33 -06:00 committed by Paolo Bonzini
parent 3b9bd3f46b
commit 084cfca143
16 changed files with 100 additions and 70 deletions

View File

@ -119,6 +119,8 @@ F: softmmu/cpus.c
F: cpus-common.c F: cpus-common.c
F: accel/tcg/ F: accel/tcg/
F: accel/stubs/tcg-stub.c F: accel/stubs/tcg-stub.c
F: util/cacheinfo.c
F: util/cacheflush.c
F: scripts/decodetree.py F: scripts/decodetree.py
F: docs/devel/decodetree.rst F: docs/devel/decodetree.rst
F: include/exec/cpu*.h F: include/exec/cpu*.h

24
include/qemu/cacheflush.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Flush the host cpu caches.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef QEMU_CACHEFLUSH_H
#define QEMU_CACHEFLUSH_H
#if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
/* icache is coherent and does not require flushing. */
}
#else
void flush_icache_range(uintptr_t start, uintptr_t stop);
#endif
#endif /* QEMU_CACHEFLUSH_H */

View File

@ -22,6 +22,7 @@
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qemu/cacheflush.h"
#include "cpu.h" #include "cpu.h"
#include "exec/exec-all.h" #include "exec/exec-all.h"
#include "exec/target_page.h" #include "exec/target_page.h"

View File

@ -148,11 +148,6 @@ typedef enum {
#define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_HAS_MEMORY_BSWAP 1 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
__builtin___clear_cache((char *)start, (char *)stop);
}
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
#ifdef CONFIG_SOFTMMU #ifdef CONFIG_SOFTMMU

View File

@ -134,11 +134,6 @@ enum {
#define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_HAS_MEMORY_BSWAP 1 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
__builtin___clear_cache((char *) start, (char *) stop);
}
/* not defined -- call should be eliminated at compile time */ /* not defined -- call should be eliminated at compile time */
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);

View File

@ -206,10 +206,6 @@ extern bool have_avx2;
#define TCG_TARGET_extract_i64_valid(ofs, len) \ #define TCG_TARGET_extract_i64_valid(ofs, len) \
(((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32) (((ofs) == 8 && (len) == 8) || ((ofs) + (len)) == 32)
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
}
static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
uintptr_t jmp_addr, uintptr_t addr) uintptr_t jmp_addr, uintptr_t addr)
{ {

View File

@ -198,20 +198,9 @@ extern bool use_mips32r2_instructions;
#define TCG_TARGET_HAS_ext16u_i64 0 /* andi rt, rs, 0xffff */ #define TCG_TARGET_HAS_ext16u_i64 0 /* andi rt, rs, 0xffff */
#endif #endif
#ifdef __OpenBSD__
#include <machine/sysarch.h>
#else
#include <sys/cachectl.h>
#endif
#define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_HAS_MEMORY_BSWAP 1 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
cacheflush ((void *)start, stop-start, ICACHE);
}
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
#ifdef CONFIG_SOFTMMU #ifdef CONFIG_SOFTMMU

View File

@ -3863,25 +3863,3 @@ void tcg_register_jit(void *buf, size_t buf_size)
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
} }
#endif /* __ELF__ */ #endif /* __ELF__ */
void flush_icache_range(uintptr_t start, uintptr_t stop)
{
uintptr_t p, start1, stop1;
size_t dsize = qemu_dcache_linesize;
size_t isize = qemu_icache_linesize;
start1 = start & ~(dsize - 1);
stop1 = (stop + dsize - 1) & ~(dsize - 1);
for (p = start1; p < stop1; p += dsize) {
asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
start &= start & ~(isize - 1);
stop1 = (stop + isize - 1) & ~(isize - 1);
for (p = start1; p < stop1; p += isize) {
asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
asm volatile ("isync" : : : "memory");
}

View File

@ -175,7 +175,6 @@ extern bool have_vsx;
#define TCG_TARGET_HAS_bitsel_vec have_vsx #define TCG_TARGET_HAS_bitsel_vec have_vsx
#define TCG_TARGET_HAS_cmpsel_vec 0 #define TCG_TARGET_HAS_cmpsel_vec 0
void flush_icache_range(uintptr_t start, uintptr_t stop);
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
#define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_DEFAULT_MO (0)

View File

@ -159,11 +159,6 @@ typedef enum {
#define TCG_TARGET_HAS_mulsh_i64 1 #define TCG_TARGET_HAS_mulsh_i64 1
#endif #endif
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
__builtin___clear_cache((char *)start, (char *)stop);
}
/* not defined -- call should be eliminated at compile time */ /* not defined -- call should be eliminated at compile time */
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);

View File

@ -145,10 +145,6 @@ enum {
TCG_AREG0 = TCG_REG_R10, TCG_AREG0 = TCG_REG_R10,
}; };
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
}
static inline void tb_target_set_jmp_target(uintptr_t tc_ptr, static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,
uintptr_t jmp_addr, uintptr_t addr) uintptr_t jmp_addr, uintptr_t addr)
{ {

View File

@ -168,14 +168,6 @@ extern bool use_vis3_instructions;
#define TCG_TARGET_DEFAULT_MO (0) #define TCG_TARGET_DEFAULT_MO (0)
#define TCG_TARGET_HAS_MEMORY_BSWAP 1 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
uintptr_t p;
for (p = start & -8; p < ((stop + 7) & -8); p += 8) {
__asm__ __volatile__("flush\t%0" : : "r" (p));
}
}
void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t); void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);
#define TCG_TARGET_NEED_POOL_LABELS #define TCG_TARGET_NEED_POOL_LABELS

View File

@ -35,6 +35,7 @@
#include "qemu/host-utils.h" #include "qemu/host-utils.h"
#include "qemu/qemu-print.h" #include "qemu/qemu-print.h"
#include "qemu/timer.h" #include "qemu/timer.h"
#include "qemu/cacheflush.h"
/* Note: the long term plan is to reduce the dependencies on the QEMU /* Note: the long term plan is to reduce the dependencies on the QEMU
CPU definitions. Currently they are used for qemu_ld/st CPU definitions. Currently they are used for qemu_ld/st

View File

@ -191,10 +191,6 @@ void tci_disas(uint8_t opc);
#define HAVE_TCG_QEMU_TB_EXEC #define HAVE_TCG_QEMU_TB_EXEC
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
}
/* We could notice __i386__ or __s390x__ and reduce the barriers depending /* We could notice __i386__ or __s390x__ and reduce the barriers depending
on the host. But if you want performance, you use the normal backend. on the host. But if you want performance, you use the normal backend.
We prefer consistency across hosts on this. */ We prefer consistency across hosts on this. */

71
util/cacheflush.c Normal file
View File

@ -0,0 +1,71 @@
/*
* Flush the host cpu caches.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qemu/cacheflush.h"
#if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
/* Caches are coherent and do not require flushing; symbol inline. */
#elif defined(__mips__)
#ifdef __OpenBSD__
#include <machine/sysarch.h>
#else
#include <sys/cachectl.h>
#endif
void flush_icache_range(uintptr_t start, uintptr_t stop)
{
cacheflush((void *)start, stop - start, ICACHE);
}
#elif defined(__powerpc__)
void flush_icache_range(uintptr_t start, uintptr_t stop)
{
uintptr_t p, start1, stop1;
size_t dsize = qemu_dcache_linesize;
size_t isize = qemu_icache_linesize;
start1 = start & ~(dsize - 1);
stop1 = (stop + dsize - 1) & ~(dsize - 1);
for (p = start1; p < stop1; p += dsize) {
asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
start &= start & ~(isize - 1);
stop1 = (stop + isize - 1) & ~(isize - 1);
for (p = start1; p < stop1; p += isize) {
asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
asm volatile ("isync" : : : "memory");
}
#elif defined(__sparc__)
void flush_icache_range(uintptr_t start, uintptr_t stop)
{
uintptr_t p;
for (p = start & -8; p < ((stop + 7) & -8); p += 8) {
__asm__ __volatile__("flush\t%0" : : "r" (p));
}
}
#else
void flush_icache_range(uintptr_t start, uintptr_t stop)
{
__builtin___clear_cache((char *)start, (char *)stop);
}
#endif

View File

@ -21,7 +21,7 @@ util_ss.add(files('envlist.c', 'path.c', 'module.c'))
util_ss.add(files('host-utils.c')) util_ss.add(files('host-utils.c'))
util_ss.add(files('bitmap.c', 'bitops.c')) util_ss.add(files('bitmap.c', 'bitops.c'))
util_ss.add(files('fifo8.c')) util_ss.add(files('fifo8.c'))
util_ss.add(files('cacheinfo.c')) util_ss.add(files('cacheinfo.c', 'cacheflush.c'))
util_ss.add(files('error.c', 'qemu-error.c')) util_ss.add(files('error.c', 'qemu-error.c'))
util_ss.add(files('qemu-print.c')) util_ss.add(files('qemu-print.c'))
util_ss.add(files('id.c')) util_ss.add(files('id.c'))