xref: /openbmc/qemu/accel/tcg/atomic_common.c.inc (revision efee71c8)
1/*
2 * Common Atomic Helper Functions
3 *
4 * This file should be included before the various instantiations of
5 * the atomic_template.h helpers.
6 *
7 * Copyright (c) 2019 Linaro
8 * Written by Alex Bennée <alex.bennee@linaro.org>
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
12 * This work is licensed under the terms of the GNU GPL, version 2 or later.
13 * See the COPYING file in the top-level directory.
14 */
15
16static uint16_t atomic_trace_rmw_pre(CPUArchState *env, target_ulong addr,
17                                     TCGMemOpIdx oi)
18{
19    CPUState *cpu = env_cpu(env);
20    uint16_t info = trace_mem_get_info(get_memop(oi), get_mmuidx(oi), false);
21
22    trace_guest_mem_before_exec(cpu, addr, info);
23    trace_guest_mem_before_exec(cpu, addr, info | TRACE_MEM_ST);
24
25    return info;
26}
27
28static void atomic_trace_rmw_post(CPUArchState *env, target_ulong addr,
29                                  uint16_t info)
30{
31    qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info);
32    qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info | TRACE_MEM_ST);
33}
34
35#if HAVE_ATOMIC128
36static uint16_t atomic_trace_ld_pre(CPUArchState *env, target_ulong addr,
37                                    TCGMemOpIdx oi)
38{
39    uint16_t info = trace_mem_get_info(get_memop(oi), get_mmuidx(oi), false);
40
41    trace_guest_mem_before_exec(env_cpu(env), addr, info);
42
43    return info;
44}
45
46static void atomic_trace_ld_post(CPUArchState *env, target_ulong addr,
47                                 uint16_t info)
48{
49    qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info);
50}
51
52static uint16_t atomic_trace_st_pre(CPUArchState *env, target_ulong addr,
53                                    TCGMemOpIdx oi)
54{
55    uint16_t info = trace_mem_get_info(get_memop(oi), get_mmuidx(oi), true);
56
57    trace_guest_mem_before_exec(env_cpu(env), addr, info);
58
59    return info;
60}
61
62static void atomic_trace_st_post(CPUArchState *env, target_ulong addr,
63                                 uint16_t info)
64{
65    qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info);
66}
67#endif
68
69/*
70 * Atomic helpers callable from TCG.
71 * These have a common interface and all defer to cpu_atomic_*
72 * using the host return address from GETPC().
73 */
74
75#define CMPXCHG_HELPER(OP, TYPE) \
76    TYPE HELPER(atomic_##OP)(CPUArchState *env, target_ulong addr,  \
77                             TYPE oldv, TYPE newv, uint32_t oi)     \
78    { return cpu_atomic_##OP##_mmu(env, addr, oldv, newv, oi, GETPC()); }
79
80CMPXCHG_HELPER(cmpxchgb, uint32_t)
81CMPXCHG_HELPER(cmpxchgw_be, uint32_t)
82CMPXCHG_HELPER(cmpxchgw_le, uint32_t)
83CMPXCHG_HELPER(cmpxchgl_be, uint32_t)
84CMPXCHG_HELPER(cmpxchgl_le, uint32_t)
85
86#ifdef CONFIG_ATOMIC64
87CMPXCHG_HELPER(cmpxchgq_be, uint64_t)
88CMPXCHG_HELPER(cmpxchgq_le, uint64_t)
89#endif
90
91#undef CMPXCHG_HELPER
92
93#define ATOMIC_HELPER(OP, TYPE) \
94    TYPE HELPER(glue(atomic_,OP))(CPUArchState *env, target_ulong addr,  \
95                                  TYPE val, uint32_t oi)                 \
96    { return glue(glue(cpu_atomic_,OP),_mmu)(env, addr, val, oi, GETPC()); }
97
98#ifdef CONFIG_ATOMIC64
99#define GEN_ATOMIC_HELPERS(OP)              \
100    ATOMIC_HELPER(glue(OP,b), uint32_t)     \
101    ATOMIC_HELPER(glue(OP,w_be), uint32_t)  \
102    ATOMIC_HELPER(glue(OP,w_le), uint32_t)  \
103    ATOMIC_HELPER(glue(OP,l_be), uint32_t)  \
104    ATOMIC_HELPER(glue(OP,l_le), uint32_t)  \
105    ATOMIC_HELPER(glue(OP,q_be), uint64_t)  \
106    ATOMIC_HELPER(glue(OP,q_le), uint64_t)
107#else
108#define GEN_ATOMIC_HELPERS(OP)              \
109    ATOMIC_HELPER(glue(OP,b), uint32_t)     \
110    ATOMIC_HELPER(glue(OP,w_be), uint32_t)  \
111    ATOMIC_HELPER(glue(OP,w_le), uint32_t)  \
112    ATOMIC_HELPER(glue(OP,l_be), uint32_t)  \
113    ATOMIC_HELPER(glue(OP,l_le), uint32_t)
114#endif
115
116GEN_ATOMIC_HELPERS(fetch_add)
117GEN_ATOMIC_HELPERS(fetch_and)
118GEN_ATOMIC_HELPERS(fetch_or)
119GEN_ATOMIC_HELPERS(fetch_xor)
120GEN_ATOMIC_HELPERS(fetch_smin)
121GEN_ATOMIC_HELPERS(fetch_umin)
122GEN_ATOMIC_HELPERS(fetch_smax)
123GEN_ATOMIC_HELPERS(fetch_umax)
124
125GEN_ATOMIC_HELPERS(add_fetch)
126GEN_ATOMIC_HELPERS(and_fetch)
127GEN_ATOMIC_HELPERS(or_fetch)
128GEN_ATOMIC_HELPERS(xor_fetch)
129GEN_ATOMIC_HELPERS(smin_fetch)
130GEN_ATOMIC_HELPERS(umin_fetch)
131GEN_ATOMIC_HELPERS(smax_fetch)
132GEN_ATOMIC_HELPERS(umax_fetch)
133
134GEN_ATOMIC_HELPERS(xchg)
135
136#undef ATOMIC_HELPER
137#undef GEN_ATOMIC_HELPERS
138