mirror of https://gitee.com/openkylin/qemu.git
atomic_template: add inline trace/plugin helpers
In preparation for plugin support. Signed-off-by: Emilio G. Cota <cota@braap.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
38b47b19ec
commit
cfec388518
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Common Atomic Helper Functions
|
||||||
|
*
|
||||||
|
* This file should be included before the various instantiations of
|
||||||
|
* the atomic_template.h helpers.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Linaro
|
||||||
|
* Written by Alex Bennée <alex.bennee@linaro.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||||
|
* See the COPYING file in the top-level directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void atomic_trace_rmw_pre(CPUArchState *env, target_ulong addr, uint16_t info)
|
||||||
|
{
|
||||||
|
CPUState *cpu = env_cpu(env);
|
||||||
|
|
||||||
|
trace_guest_mem_before_exec(cpu, addr, info);
|
||||||
|
trace_guest_mem_before_exec(cpu, addr, info | TRACE_MEM_ST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
atomic_trace_rmw_post(CPUArchState *env, target_ulong addr, uint16_t info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void atomic_trace_ld_pre(CPUArchState *env, target_ulong addr, uint16_t info)
|
||||||
|
{
|
||||||
|
trace_guest_mem_before_exec(env_cpu(env), addr, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void atomic_trace_ld_post(CPUArchState *env, target_ulong addr, uint16_t info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void atomic_trace_st_pre(CPUArchState *env, target_ulong addr, uint16_t info)
|
||||||
|
{
|
||||||
|
trace_guest_mem_before_exec(env_cpu(env), addr, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void atomic_trace_st_post(CPUArchState *env, target_ulong addr, uint16_t info)
|
||||||
|
{
|
||||||
|
}
|
|
@ -59,29 +59,6 @@
|
||||||
# define ABI_TYPE uint32_t
|
# define ABI_TYPE uint32_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ATOMIC_TRACE_RMW do { \
|
|
||||||
uint16_t info = glue(trace_mem_build_info_no_se, MEND) \
|
|
||||||
(SHIFT, false, ATOMIC_MMU_IDX); \
|
|
||||||
\
|
|
||||||
trace_guest_mem_before_exec(env_cpu(env), addr, info); \
|
|
||||||
trace_guest_mem_before_exec(env_cpu(env), addr, \
|
|
||||||
info | TRACE_MEM_ST); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ATOMIC_TRACE_LD do { \
|
|
||||||
uint16_t info = glue(trace_mem_build_info_no_se, MEND) \
|
|
||||||
(SHIFT, false, ATOMIC_MMU_IDX); \
|
|
||||||
\
|
|
||||||
trace_guest_mem_before_exec(env_cpu(env), addr, info); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ATOMIC_TRACE_ST do { \
|
|
||||||
uint16_t info = glue(trace_mem_build_info_no_se, MEND) \
|
|
||||||
(SHIFT, true, ATOMIC_MMU_IDX); \
|
|
||||||
\
|
|
||||||
trace_guest_mem_before_exec(env_cpu(env), addr, info); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Define host-endian atomic operations. Note that END is used within
|
/* Define host-endian atomic operations. Note that END is used within
|
||||||
the ATOMIC_NAME macro, and redefined below. */
|
the ATOMIC_NAME macro, and redefined below. */
|
||||||
#if DATA_SIZE == 1
|
#if DATA_SIZE == 1
|
||||||
|
@ -101,14 +78,17 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
DATA_TYPE ret;
|
DATA_TYPE ret;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_RMW;
|
atomic_trace_rmw_pre(env, addr, info);
|
||||||
#if DATA_SIZE == 16
|
#if DATA_SIZE == 16
|
||||||
ret = atomic16_cmpxchg(haddr, cmpv, newv);
|
ret = atomic16_cmpxchg(haddr, cmpv, newv);
|
||||||
#else
|
#else
|
||||||
ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
|
ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
|
||||||
#endif
|
#endif
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_rmw_post(env, addr, info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,10 +98,13 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
|
||||||
{
|
{
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_LD;
|
atomic_trace_ld_pre(env, addr, info);
|
||||||
val = atomic16_read(haddr);
|
val = atomic16_read(haddr);
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_ld_post(env, addr, info);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +113,13 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
|
||||||
{
|
{
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, true,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_ST;
|
atomic_trace_st_pre(env, addr, info);
|
||||||
atomic16_set(haddr, val);
|
atomic16_set(haddr, val);
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_st_post(env, addr, info);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
@ -143,10 +129,13 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
DATA_TYPE ret;
|
DATA_TYPE ret;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_RMW;
|
atomic_trace_rmw_pre(env, addr, info);
|
||||||
ret = atomic_xchg__nocheck(haddr, val);
|
ret = atomic_xchg__nocheck(haddr, val);
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_rmw_post(env, addr, info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,10 +146,14 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ATOMIC_MMU_DECLS; \
|
ATOMIC_MMU_DECLS; \
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
||||||
DATA_TYPE ret; \
|
DATA_TYPE ret; \
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, \
|
||||||
|
false, \
|
||||||
|
ATOMIC_MMU_IDX); \
|
||||||
\
|
\
|
||||||
ATOMIC_TRACE_RMW; \
|
atomic_trace_rmw_pre(env, addr, info); \
|
||||||
ret = atomic_##X(haddr, val); \
|
ret = atomic_##X(haddr, val); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
|
atomic_trace_rmw_post(env, addr, info); \
|
||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +182,11 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ATOMIC_MMU_DECLS; \
|
ATOMIC_MMU_DECLS; \
|
||||||
XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
||||||
XDATA_TYPE cmp, old, new, val = xval; \
|
XDATA_TYPE cmp, old, new, val = xval; \
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, \
|
||||||
|
false, \
|
||||||
|
ATOMIC_MMU_IDX); \
|
||||||
\
|
\
|
||||||
ATOMIC_TRACE_RMW; \
|
atomic_trace_rmw_pre(env, addr, info); \
|
||||||
smp_mb(); \
|
smp_mb(); \
|
||||||
cmp = atomic_read__nocheck(haddr); \
|
cmp = atomic_read__nocheck(haddr); \
|
||||||
do { \
|
do { \
|
||||||
|
@ -198,6 +194,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
cmp = atomic_cmpxchg__nocheck(haddr, old, new); \
|
cmp = atomic_cmpxchg__nocheck(haddr, old, new); \
|
||||||
} while (cmp != old); \
|
} while (cmp != old); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
|
atomic_trace_rmw_post(env, addr, info); \
|
||||||
return RET; \
|
return RET; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,14 +232,18 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
DATA_TYPE ret;
|
DATA_TYPE ret;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT,
|
||||||
|
false,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_RMW;
|
atomic_trace_rmw_pre(env, addr, info);
|
||||||
#if DATA_SIZE == 16
|
#if DATA_SIZE == 16
|
||||||
ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
|
ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
|
||||||
#else
|
#else
|
||||||
ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
|
ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
|
||||||
#endif
|
#endif
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_rmw_post(env, addr, info);
|
||||||
return BSWAP(ret);
|
return BSWAP(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,10 +253,14 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
|
||||||
{
|
{
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT,
|
||||||
|
false,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_LD;
|
atomic_trace_ld_pre(env, addr, info);
|
||||||
val = atomic16_read(haddr);
|
val = atomic16_read(haddr);
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_ld_post(env, addr, info);
|
||||||
return BSWAP(val);
|
return BSWAP(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,11 +269,16 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
|
||||||
{
|
{
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT,
|
||||||
|
true,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_ST;
|
val = BSWAP(val);
|
||||||
|
atomic_trace_st_pre(env, addr, info);
|
||||||
val = BSWAP(val);
|
val = BSWAP(val);
|
||||||
atomic16_set(haddr, val);
|
atomic16_set(haddr, val);
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_st_post(env, addr, info);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
@ -278,10 +288,14 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
|
||||||
ATOMIC_MMU_DECLS;
|
ATOMIC_MMU_DECLS;
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
|
||||||
ABI_TYPE ret;
|
ABI_TYPE ret;
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT,
|
||||||
|
false,
|
||||||
|
ATOMIC_MMU_IDX);
|
||||||
|
|
||||||
ATOMIC_TRACE_RMW;
|
atomic_trace_rmw_pre(env, addr, info);
|
||||||
ret = atomic_xchg__nocheck(haddr, BSWAP(val));
|
ret = atomic_xchg__nocheck(haddr, BSWAP(val));
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
|
atomic_trace_rmw_post(env, addr, info);
|
||||||
return BSWAP(ret);
|
return BSWAP(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,10 +306,14 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ATOMIC_MMU_DECLS; \
|
ATOMIC_MMU_DECLS; \
|
||||||
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
||||||
DATA_TYPE ret; \
|
DATA_TYPE ret; \
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, \
|
||||||
|
false, \
|
||||||
|
ATOMIC_MMU_IDX); \
|
||||||
\
|
\
|
||||||
ATOMIC_TRACE_RMW; \
|
atomic_trace_rmw_pre(env, addr, info); \
|
||||||
ret = atomic_##X(haddr, BSWAP(val)); \
|
ret = atomic_##X(haddr, BSWAP(val)); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
|
atomic_trace_rmw_post(env, addr, info); \
|
||||||
return BSWAP(ret); \
|
return BSWAP(ret); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,8 +340,11 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ATOMIC_MMU_DECLS; \
|
ATOMIC_MMU_DECLS; \
|
||||||
XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
|
||||||
XDATA_TYPE ldo, ldn, old, new, val = xval; \
|
XDATA_TYPE ldo, ldn, old, new, val = xval; \
|
||||||
|
uint16_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, \
|
||||||
|
false, \
|
||||||
|
ATOMIC_MMU_IDX); \
|
||||||
\
|
\
|
||||||
ATOMIC_TRACE_RMW; \
|
atomic_trace_rmw_pre(env, addr, info); \
|
||||||
smp_mb(); \
|
smp_mb(); \
|
||||||
ldn = atomic_read__nocheck(haddr); \
|
ldn = atomic_read__nocheck(haddr); \
|
||||||
do { \
|
do { \
|
||||||
|
@ -331,6 +352,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||||
ldn = atomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
|
ldn = atomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
|
||||||
} while (ldo != ldn); \
|
} while (ldo != ldn); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
|
atomic_trace_rmw_post(env, addr, info); \
|
||||||
return RET; \
|
return RET; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,10 +380,6 @@ GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
|
||||||
#undef MEND
|
#undef MEND
|
||||||
#endif /* DATA_SIZE > 1 */
|
#endif /* DATA_SIZE > 1 */
|
||||||
|
|
||||||
#undef ATOMIC_TRACE_ST
|
|
||||||
#undef ATOMIC_TRACE_LD
|
|
||||||
#undef ATOMIC_TRACE_RMW
|
|
||||||
|
|
||||||
#undef BSWAP
|
#undef BSWAP
|
||||||
#undef ABI_TYPE
|
#undef ABI_TYPE
|
||||||
#undef DATA_TYPE
|
#undef DATA_TYPE
|
||||||
|
|
|
@ -1825,6 +1825,8 @@ void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||||
#define ATOMIC_MMU_CLEANUP
|
#define ATOMIC_MMU_CLEANUP
|
||||||
#define ATOMIC_MMU_IDX get_mmuidx(oi)
|
#define ATOMIC_MMU_IDX get_mmuidx(oi)
|
||||||
|
|
||||||
|
#include "atomic_common.inc.c"
|
||||||
|
|
||||||
#define DATA_SIZE 1
|
#define DATA_SIZE 1
|
||||||
#include "atomic_template.h"
|
#include "atomic_template.h"
|
||||||
|
|
||||||
|
|
|
@ -756,6 +756,8 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
||||||
#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
|
#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
|
||||||
#define EXTRA_ARGS
|
#define EXTRA_ARGS
|
||||||
|
|
||||||
|
#include "atomic_common.inc.c"
|
||||||
|
|
||||||
#define DATA_SIZE 1
|
#define DATA_SIZE 1
|
||||||
#include "atomic_template.h"
|
#include "atomic_template.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue