]> git.proxmox.com Git - mirror_qemu.git/blame - accel/tcg/cputlb.c
accel/tcg: Remove {encode,decode}_pbm_to_runon
[mirror_qemu.git] / accel / tcg / cputlb.c
CommitLineData
0cac1b66
BS
1/*
2 * Common CPU TLB handling
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
fb0343d5 9 * version 2.1 of the License, or (at your option) any later version.
0cac1b66
BS
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
7b31bbc2 20#include "qemu/osdep.h"
8d04fb55 21#include "qemu/main-loop.h"
78271684 22#include "hw/core/tcg-cpu-ops.h"
022c62cb
PB
23#include "exec/exec-all.h"
24#include "exec/memory.h"
f08b6170 25#include "exec/cpu_ldst.h"
022c62cb 26#include "exec/cputlb.h"
0f4abea8 27#include "exec/tb-hash.h"
022c62cb 28#include "exec/memory-internal.h"
220c3ebd 29#include "exec/ram_addr.h"
0f590e74 30#include "tcg/tcg.h"
d7f30403
PM
31#include "qemu/error-report.h"
32#include "exec/log.h"
c482cb11
RH
33#include "exec/helper-proto.h"
34#include "qemu/atomic.h"
e6cd4bb5 35#include "qemu/atomic128.h"
3b9bd3f4 36#include "exec/translate-all.h"
243af022 37#include "trace/trace-root.h"
d03f1408 38#include "trace/mem.h"
65269192 39#include "internal.h"
235537fa
AB
40#ifdef CONFIG_PLUGIN
41#include "qemu/plugin-memory.h"
42#endif
0cac1b66 43
8526e1f4
AB
44/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
45/* #define DEBUG_TLB */
46/* #define DEBUG_TLB_LOG */
47
48#ifdef DEBUG_TLB
49# define DEBUG_TLB_GATE 1
50# ifdef DEBUG_TLB_LOG
51# define DEBUG_TLB_LOG_GATE 1
52# else
53# define DEBUG_TLB_LOG_GATE 0
54# endif
55#else
56# define DEBUG_TLB_GATE 0
57# define DEBUG_TLB_LOG_GATE 0
58#endif
59
60#define tlb_debug(fmt, ...) do { \
61 if (DEBUG_TLB_LOG_GATE) { \
62 qemu_log_mask(CPU_LOG_MMU, "%s: " fmt, __func__, \
63 ## __VA_ARGS__); \
64 } else if (DEBUG_TLB_GATE) { \
65 fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); \
66 } \
67} while (0)
0cac1b66 68
ea9025cb 69#define assert_cpu_is_self(cpu) do { \
f0aff0f1 70 if (DEBUG_TLB_GATE) { \
ea9025cb 71 g_assert(!(cpu)->created || qemu_cpu_is_self(cpu)); \
f0aff0f1
AB
72 } \
73 } while (0)
74
e3b9ca81
FK
75/* run_on_cpu_data.target_ptr should always be big enough for a
76 * target_ulong even on 32 bit builds */
77QEMU_BUILD_BUG_ON(sizeof(target_ulong) > sizeof(run_on_cpu_data));
78
e7218445
AB
79/* We currently can't handle more than 16 bits in the MMUIDX bitmask.
80 */
81QEMU_BUILD_BUG_ON(NB_MMU_MODES > 16);
82#define ALL_MMUIDX_BITS ((1 << NB_MMU_MODES) - 1)
83
722a1c1e 84static inline size_t tlb_n_entries(CPUTLBDescFast *fast)
7a1efe1b 85{
722a1c1e 86 return (fast->mask >> CPU_TLB_ENTRY_BITS) + 1;
7a1efe1b
RH
87}
88
722a1c1e 89static inline size_t sizeof_tlb(CPUTLBDescFast *fast)
86e1eff8 90{
722a1c1e 91 return fast->mask + (1 << CPU_TLB_ENTRY_BITS);
86e1eff8
EC
92}
93
79e42085 94static void tlb_window_reset(CPUTLBDesc *desc, int64_t ns,
86e1eff8
EC
95 size_t max_entries)
96{
79e42085
RH
97 desc->window_begin_ns = ns;
98 desc->window_max_entries = max_entries;
86e1eff8
EC
99}
100
0f4abea8
RH
101static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
102{
103 unsigned int i, i0 = tb_jmp_cache_hash_page(page_addr);
104
105 for (i = 0; i < TB_JMP_PAGE_SIZE; i++) {
106 qatomic_set(&cpu->tb_jmp_cache[i0 + i], NULL);
107 }
108}
109
110static void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
111{
112 /* Discard jump cache entries for any tb which might potentially
113 overlap the flushed page. */
114 tb_jmp_cache_clear_page(cpu, addr - TARGET_PAGE_SIZE);
115 tb_jmp_cache_clear_page(cpu, addr);
116}
117
86e1eff8
EC
118/**
119 * tlb_mmu_resize_locked() - perform TLB resize bookkeeping; resize if necessary
71ccd47b
RH
120 * @desc: The CPUTLBDesc portion of the TLB
121 * @fast: The CPUTLBDescFast portion of the same TLB
86e1eff8
EC
122 *
123 * Called with tlb_lock_held.
124 *
125 * We have two main constraints when resizing a TLB: (1) we only resize it
126 * on a TLB flush (otherwise we'd have to take a perf hit by either rehashing
127 * the array or unnecessarily flushing it), which means we do not control how
128 * frequently the resizing can occur; (2) we don't have access to the guest's
129 * future scheduling decisions, and therefore have to decide the magnitude of
130 * the resize based on past observations.
131 *
132 * In general, a memory-hungry process can benefit greatly from an appropriately
133 * sized TLB, since a guest TLB miss is very expensive. This doesn't mean that
134 * we just have to make the TLB as large as possible; while an oversized TLB
135 * results in minimal TLB miss rates, it also takes longer to be flushed
136 * (flushes can be _very_ frequent), and the reduced locality can also hurt
137 * performance.
138 *
139 * To achieve near-optimal performance for all kinds of workloads, we:
140 *
141 * 1. Aggressively increase the size of the TLB when the use rate of the
142 * TLB being flushed is high, since it is likely that in the near future this
143 * memory-hungry process will execute again, and its memory hungriness will
144 * probably be similar.
145 *
146 * 2. Slowly reduce the size of the TLB as the use rate declines over a
147 * reasonably large time window. The rationale is that if in such a time window
148 * we have not observed a high TLB use rate, it is likely that we won't observe
149 * it in the near future. In that case, once a time window expires we downsize
150 * the TLB to match the maximum use rate observed in the window.
151 *
152 * 3. Try to keep the maximum use rate in a time window in the 30-70% range,
153 * since in that range performance is likely near-optimal. Recall that the TLB
154 * is direct mapped, so we want the use rate to be low (or at least not too
155 * high), since otherwise we are likely to have a significant amount of
156 * conflict misses.
157 */
3c3959f2
RH
158static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
159 int64_t now)
86e1eff8 160{
71ccd47b 161 size_t old_size = tlb_n_entries(fast);
86e1eff8
EC
162 size_t rate;
163 size_t new_size = old_size;
86e1eff8
EC
164 int64_t window_len_ms = 100;
165 int64_t window_len_ns = window_len_ms * 1000 * 1000;
79e42085 166 bool window_expired = now > desc->window_begin_ns + window_len_ns;
86e1eff8 167
79e42085
RH
168 if (desc->n_used_entries > desc->window_max_entries) {
169 desc->window_max_entries = desc->n_used_entries;
86e1eff8 170 }
79e42085 171 rate = desc->window_max_entries * 100 / old_size;
86e1eff8
EC
172
173 if (rate > 70) {
174 new_size = MIN(old_size << 1, 1 << CPU_TLB_DYN_MAX_BITS);
175 } else if (rate < 30 && window_expired) {
79e42085
RH
176 size_t ceil = pow2ceil(desc->window_max_entries);
177 size_t expected_rate = desc->window_max_entries * 100 / ceil;
86e1eff8
EC
178
179 /*
180 * Avoid undersizing when the max number of entries seen is just below
181 * a pow2. For instance, if max_entries == 1025, the expected use rate
182 * would be 1025/2048==50%. However, if max_entries == 1023, we'd get
183 * 1023/1024==99.9% use rate, so we'd likely end up doubling the size
184 * later. Thus, make sure that the expected use rate remains below 70%.
185 * (and since we double the size, that means the lowest rate we'd
186 * expect to get is 35%, which is still in the 30-70% range where
187 * we consider that the size is appropriate.)
188 */
189 if (expected_rate > 70) {
190 ceil *= 2;
191 }
192 new_size = MAX(ceil, 1 << CPU_TLB_DYN_MIN_BITS);
193 }
194
195 if (new_size == old_size) {
196 if (window_expired) {
79e42085 197 tlb_window_reset(desc, now, desc->n_used_entries);
86e1eff8
EC
198 }
199 return;
200 }
201
71ccd47b
RH
202 g_free(fast->table);
203 g_free(desc->iotlb);
86e1eff8 204
79e42085 205 tlb_window_reset(desc, now, 0);
86e1eff8 206 /* desc->n_used_entries is cleared by the caller */
71ccd47b
RH
207 fast->mask = (new_size - 1) << CPU_TLB_ENTRY_BITS;
208 fast->table = g_try_new(CPUTLBEntry, new_size);
209 desc->iotlb = g_try_new(CPUIOTLBEntry, new_size);
210
86e1eff8
EC
211 /*
212 * If the allocations fail, try smaller sizes. We just freed some
213 * memory, so going back to half of new_size has a good chance of working.
214 * Increased memory pressure elsewhere in the system might cause the
215 * allocations to fail though, so we progressively reduce the allocation
216 * size, aborting if we cannot even allocate the smallest TLB we support.
217 */
71ccd47b 218 while (fast->table == NULL || desc->iotlb == NULL) {
86e1eff8
EC
219 if (new_size == (1 << CPU_TLB_DYN_MIN_BITS)) {
220 error_report("%s: %s", __func__, strerror(errno));
221 abort();
222 }
223 new_size = MAX(new_size >> 1, 1 << CPU_TLB_DYN_MIN_BITS);
71ccd47b 224 fast->mask = (new_size - 1) << CPU_TLB_ENTRY_BITS;
86e1eff8 225
71ccd47b
RH
226 g_free(fast->table);
227 g_free(desc->iotlb);
228 fast->table = g_try_new(CPUTLBEntry, new_size);
229 desc->iotlb = g_try_new(CPUIOTLBEntry, new_size);
86e1eff8
EC
230 }
231}
232
bbf021b0 233static void tlb_mmu_flush_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast)
86e1eff8 234{
5c948e31
RH
235 desc->n_used_entries = 0;
236 desc->large_page_addr = -1;
237 desc->large_page_mask = -1;
238 desc->vindex = 0;
239 memset(fast->table, -1, sizeof_tlb(fast));
240 memset(desc->vtable, -1, sizeof(desc->vtable));
86e1eff8
EC
241}
242
3c3959f2
RH
243static void tlb_flush_one_mmuidx_locked(CPUArchState *env, int mmu_idx,
244 int64_t now)
bbf021b0
RH
245{
246 CPUTLBDesc *desc = &env_tlb(env)->d[mmu_idx];
247 CPUTLBDescFast *fast = &env_tlb(env)->f[mmu_idx];
248
3c3959f2 249 tlb_mmu_resize_locked(desc, fast, now);
bbf021b0
RH
250 tlb_mmu_flush_locked(desc, fast);
251}
252
56e89f76
RH
253static void tlb_mmu_init(CPUTLBDesc *desc, CPUTLBDescFast *fast, int64_t now)
254{
255 size_t n_entries = 1 << CPU_TLB_DYN_DEFAULT_BITS;
256
257 tlb_window_reset(desc, now, 0);
258 desc->n_used_entries = 0;
259 fast->mask = (n_entries - 1) << CPU_TLB_ENTRY_BITS;
260 fast->table = g_new(CPUTLBEntry, n_entries);
261 desc->iotlb = g_new(CPUIOTLBEntry, n_entries);
3c16304a 262 tlb_mmu_flush_locked(desc, fast);
56e89f76
RH
263}
264
86e1eff8
EC
265static inline void tlb_n_used_entries_inc(CPUArchState *env, uintptr_t mmu_idx)
266{
a40ec84e 267 env_tlb(env)->d[mmu_idx].n_used_entries++;
86e1eff8
EC
268}
269
270static inline void tlb_n_used_entries_dec(CPUArchState *env, uintptr_t mmu_idx)
271{
a40ec84e 272 env_tlb(env)->d[mmu_idx].n_used_entries--;
86e1eff8
EC
273}
274
5005e253
EC
275void tlb_init(CPUState *cpu)
276{
71aec354 277 CPUArchState *env = cpu->env_ptr;
56e89f76
RH
278 int64_t now = get_clock_realtime();
279 int i;
71aec354 280
a40ec84e 281 qemu_spin_init(&env_tlb(env)->c.lock);
3d1523ce 282
3c16304a
RH
283 /* All tlbs are initialized flushed. */
284 env_tlb(env)->c.dirty = 0;
86e1eff8 285
56e89f76
RH
286 for (i = 0; i < NB_MMU_MODES; i++) {
287 tlb_mmu_init(&env_tlb(env)->d[i], &env_tlb(env)->f[i], now);
288 }
5005e253
EC
289}
290
816d9be5
EC
291void tlb_destroy(CPUState *cpu)
292{
293 CPUArchState *env = cpu->env_ptr;
294 int i;
295
296 qemu_spin_destroy(&env_tlb(env)->c.lock);
297 for (i = 0; i < NB_MMU_MODES; i++) {
298 CPUTLBDesc *desc = &env_tlb(env)->d[i];
299 CPUTLBDescFast *fast = &env_tlb(env)->f[i];
300
301 g_free(fast->table);
302 g_free(desc->iotlb);
303 }
304}
305
c3b9a07a
AB
306/* flush_all_helper: run fn across all cpus
307 *
308 * If the wait flag is set then the src cpu's helper will be queued as
309 * "safe" work and the loop exited creating a synchronisation point
310 * where all queued work will be finished before execution starts
311 * again.
312 */
313static void flush_all_helper(CPUState *src, run_on_cpu_func fn,
314 run_on_cpu_data d)
315{
316 CPUState *cpu;
317
318 CPU_FOREACH(cpu) {
319 if (cpu != src) {
320 async_run_on_cpu(cpu, fn, d);
321 }
322 }
323}
324
e09de0a2 325void tlb_flush_counts(size_t *pfull, size_t *ppart, size_t *pelide)
83974cf4
EC
326{
327 CPUState *cpu;
e09de0a2 328 size_t full = 0, part = 0, elide = 0;
83974cf4
EC
329
330 CPU_FOREACH(cpu) {
331 CPUArchState *env = cpu->env_ptr;
332
d73415a3
SH
333 full += qatomic_read(&env_tlb(env)->c.full_flush_count);
334 part += qatomic_read(&env_tlb(env)->c.part_flush_count);
335 elide += qatomic_read(&env_tlb(env)->c.elide_flush_count);
83974cf4 336 }
e09de0a2
RH
337 *pfull = full;
338 *ppart = part;
339 *pelide = elide;
83974cf4 340}
0cac1b66 341
e7218445 342static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
d7a74a9d
PM
343{
344 CPUArchState *env = cpu->env_ptr;
3d1523ce
RH
345 uint16_t asked = data.host_int;
346 uint16_t all_dirty, work, to_clean;
3c3959f2 347 int64_t now = get_clock_realtime();
d7a74a9d 348
f0aff0f1 349 assert_cpu_is_self(cpu);
d7a74a9d 350
3d1523ce 351 tlb_debug("mmu_idx:0x%04" PRIx16 "\n", asked);
e7218445 352
a40ec84e 353 qemu_spin_lock(&env_tlb(env)->c.lock);
60a2ad7d 354
a40ec84e 355 all_dirty = env_tlb(env)->c.dirty;
3d1523ce
RH
356 to_clean = asked & all_dirty;
357 all_dirty &= ~to_clean;
a40ec84e 358 env_tlb(env)->c.dirty = all_dirty;
3d1523ce
RH
359
360 for (work = to_clean; work != 0; work &= work - 1) {
361 int mmu_idx = ctz32(work);
3c3959f2 362 tlb_flush_one_mmuidx_locked(env, mmu_idx, now);
d7a74a9d 363 }
3d1523ce 364
a40ec84e 365 qemu_spin_unlock(&env_tlb(env)->c.lock);
d7a74a9d 366
f3ced3c5 367 cpu_tb_jmp_cache_clear(cpu);
64f2674b 368
3d1523ce 369 if (to_clean == ALL_MMUIDX_BITS) {
d73415a3 370 qatomic_set(&env_tlb(env)->c.full_flush_count,
a40ec84e 371 env_tlb(env)->c.full_flush_count + 1);
e09de0a2 372 } else {
d73415a3 373 qatomic_set(&env_tlb(env)->c.part_flush_count,
a40ec84e 374 env_tlb(env)->c.part_flush_count + ctpop16(to_clean));
3d1523ce 375 if (to_clean != asked) {
d73415a3 376 qatomic_set(&env_tlb(env)->c.elide_flush_count,
a40ec84e 377 env_tlb(env)->c.elide_flush_count +
3d1523ce
RH
378 ctpop16(asked & ~to_clean));
379 }
64f2674b 380 }
d7a74a9d
PM
381}
382
0336cbf8 383void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap)
d7a74a9d 384{
e7218445
AB
385 tlb_debug("mmu_idx: 0x%" PRIx16 "\n", idxmap);
386
64f2674b 387 if (cpu->created && !qemu_cpu_is_self(cpu)) {
ab651105
RH
388 async_run_on_cpu(cpu, tlb_flush_by_mmuidx_async_work,
389 RUN_ON_CPU_HOST_INT(idxmap));
e7218445 390 } else {
60a2ad7d 391 tlb_flush_by_mmuidx_async_work(cpu, RUN_ON_CPU_HOST_INT(idxmap));
e7218445 392 }
d7a74a9d
PM
393}
394
64f2674b
RH
395void tlb_flush(CPUState *cpu)
396{
397 tlb_flush_by_mmuidx(cpu, ALL_MMUIDX_BITS);
398}
399
c3b9a07a
AB
400void tlb_flush_by_mmuidx_all_cpus(CPUState *src_cpu, uint16_t idxmap)
401{
402 const run_on_cpu_func fn = tlb_flush_by_mmuidx_async_work;
403
404 tlb_debug("mmu_idx: 0x%"PRIx16"\n", idxmap);
405
406 flush_all_helper(src_cpu, fn, RUN_ON_CPU_HOST_INT(idxmap));
407 fn(src_cpu, RUN_ON_CPU_HOST_INT(idxmap));
408}
409
64f2674b
RH
410void tlb_flush_all_cpus(CPUState *src_cpu)
411{
412 tlb_flush_by_mmuidx_all_cpus(src_cpu, ALL_MMUIDX_BITS);
413}
414
415void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *src_cpu, uint16_t idxmap)
c3b9a07a
AB
416{
417 const run_on_cpu_func fn = tlb_flush_by_mmuidx_async_work;
418
419 tlb_debug("mmu_idx: 0x%"PRIx16"\n", idxmap);
420
421 flush_all_helper(src_cpu, fn, RUN_ON_CPU_HOST_INT(idxmap));
422 async_safe_run_on_cpu(src_cpu, fn, RUN_ON_CPU_HOST_INT(idxmap));
423}
424
64f2674b
RH
425void tlb_flush_all_cpus_synced(CPUState *src_cpu)
426{
427 tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, ALL_MMUIDX_BITS);
428}
429
3ab6e68c
RH
430static bool tlb_hit_page_mask_anyprot(CPUTLBEntry *tlb_entry,
431 target_ulong page, target_ulong mask)
432{
433 page &= mask;
434 mask &= TARGET_PAGE_MASK | TLB_INVALID_MASK;
435
436 return (page == (tlb_entry->addr_read & mask) ||
437 page == (tlb_addr_write(tlb_entry) & mask) ||
438 page == (tlb_entry->addr_code & mask));
439}
440
68fea038
RH
441static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
442 target_ulong page)
443{
3ab6e68c 444 return tlb_hit_page_mask_anyprot(tlb_entry, page, -1);
68fea038 445}
c3b9a07a 446
3cea94bb
EC
447/**
448 * tlb_entry_is_empty - return true if the entry is not in use
449 * @te: pointer to CPUTLBEntry
450 */
451static inline bool tlb_entry_is_empty(const CPUTLBEntry *te)
452{
453 return te->addr_read == -1 && te->addr_write == -1 && te->addr_code == -1;
454}
455
53d28455 456/* Called with tlb_c.lock held */
3ab6e68c
RH
457static bool tlb_flush_entry_mask_locked(CPUTLBEntry *tlb_entry,
458 target_ulong page,
459 target_ulong mask)
0cac1b66 460{
3ab6e68c 461 if (tlb_hit_page_mask_anyprot(tlb_entry, page, mask)) {
4fadb3bb 462 memset(tlb_entry, -1, sizeof(*tlb_entry));
86e1eff8 463 return true;
0cac1b66 464 }
86e1eff8 465 return false;
0cac1b66
BS
466}
467
3ab6e68c
RH
468static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
469 target_ulong page)
470{
471 return tlb_flush_entry_mask_locked(tlb_entry, page, -1);
472}
473
53d28455 474/* Called with tlb_c.lock held */
3ab6e68c
RH
475static void tlb_flush_vtlb_page_mask_locked(CPUArchState *env, int mmu_idx,
476 target_ulong page,
477 target_ulong mask)
68fea038 478{
a40ec84e 479 CPUTLBDesc *d = &env_tlb(env)->d[mmu_idx];
68fea038 480 int k;
71aec354 481
29a0af61 482 assert_cpu_is_self(env_cpu(env));
68fea038 483 for (k = 0; k < CPU_VTLB_SIZE; k++) {
3ab6e68c 484 if (tlb_flush_entry_mask_locked(&d->vtable[k], page, mask)) {
86e1eff8
EC
485 tlb_n_used_entries_dec(env, mmu_idx);
486 }
68fea038
RH
487 }
488}
489
3ab6e68c
RH
490static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
491 target_ulong page)
492{
493 tlb_flush_vtlb_page_mask_locked(env, mmu_idx, page, -1);
494}
495
1308e026
RH
496static void tlb_flush_page_locked(CPUArchState *env, int midx,
497 target_ulong page)
498{
a40ec84e
RH
499 target_ulong lp_addr = env_tlb(env)->d[midx].large_page_addr;
500 target_ulong lp_mask = env_tlb(env)->d[midx].large_page_mask;
1308e026
RH
501
502 /* Check if we need to flush due to large pages. */
503 if ((page & lp_mask) == lp_addr) {
504 tlb_debug("forcing full flush midx %d ("
505 TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
506 midx, lp_addr, lp_mask);
3c3959f2 507 tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
1308e026 508 } else {
86e1eff8
EC
509 if (tlb_flush_entry_locked(tlb_entry(env, midx, page), page)) {
510 tlb_n_used_entries_dec(env, midx);
511 }
1308e026
RH
512 tlb_flush_vtlb_page_locked(env, midx, page);
513 }
514}
515
7b7d00e0
RH
516/**
517 * tlb_flush_page_by_mmuidx_async_0:
518 * @cpu: cpu on which to flush
519 * @addr: page of virtual address to flush
520 * @idxmap: set of mmu_idx to flush
521 *
522 * Helper for tlb_flush_page_by_mmuidx and friends, flush one page
523 * at @addr from the tlbs indicated by @idxmap from @cpu.
e7218445 524 */
7b7d00e0
RH
525static void tlb_flush_page_by_mmuidx_async_0(CPUState *cpu,
526 target_ulong addr,
527 uint16_t idxmap)
d7a74a9d
PM
528{
529 CPUArchState *env = cpu->env_ptr;
e7218445 530 int mmu_idx;
d7a74a9d 531
f0aff0f1 532 assert_cpu_is_self(cpu);
d7a74a9d 533
7b7d00e0 534 tlb_debug("page addr:" TARGET_FMT_lx " mmu_map:0x%x\n", addr, idxmap);
d7a74a9d 535
a40ec84e 536 qemu_spin_lock(&env_tlb(env)->c.lock);
0336cbf8 537 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
7b7d00e0 538 if ((idxmap >> mmu_idx) & 1) {
1308e026 539 tlb_flush_page_locked(env, mmu_idx, addr);
d7a74a9d
PM
540 }
541 }
a40ec84e 542 qemu_spin_unlock(&env_tlb(env)->c.lock);
d7a74a9d 543
d7a74a9d
PM
544 tb_flush_jmp_cache(cpu, addr);
545}
546
7b7d00e0
RH
547/**
548 * tlb_flush_page_by_mmuidx_async_1:
549 * @cpu: cpu on which to flush
550 * @data: encoded addr + idxmap
551 *
552 * Helper for tlb_flush_page_by_mmuidx and friends, called through
553 * async_run_on_cpu. The idxmap parameter is encoded in the page
554 * offset of the target_ptr field. This limits the set of mmu_idx
555 * that can be passed via this method.
556 */
557static void tlb_flush_page_by_mmuidx_async_1(CPUState *cpu,
558 run_on_cpu_data data)
559{
560 target_ulong addr_and_idxmap = (target_ulong) data.target_ptr;
561 target_ulong addr = addr_and_idxmap & TARGET_PAGE_MASK;
562 uint16_t idxmap = addr_and_idxmap & ~TARGET_PAGE_MASK;
563
564 tlb_flush_page_by_mmuidx_async_0(cpu, addr, idxmap);
565}
566
567typedef struct {
568 target_ulong addr;
569 uint16_t idxmap;
570} TLBFlushPageByMMUIdxData;
571
572/**
573 * tlb_flush_page_by_mmuidx_async_2:
574 * @cpu: cpu on which to flush
575 * @data: allocated addr + idxmap
576 *
577 * Helper for tlb_flush_page_by_mmuidx and friends, called through
578 * async_run_on_cpu. The addr+idxmap parameters are stored in a
579 * TLBFlushPageByMMUIdxData structure that has been allocated
580 * specifically for this helper. Free the structure when done.
581 */
582static void tlb_flush_page_by_mmuidx_async_2(CPUState *cpu,
583 run_on_cpu_data data)
e7218445 584{
7b7d00e0
RH
585 TLBFlushPageByMMUIdxData *d = data.host_ptr;
586
587 tlb_flush_page_by_mmuidx_async_0(cpu, d->addr, d->idxmap);
588 g_free(d);
589}
e7218445 590
7b7d00e0
RH
591void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, uint16_t idxmap)
592{
e7218445
AB
593 tlb_debug("addr: "TARGET_FMT_lx" mmu_idx:%" PRIx16 "\n", addr, idxmap);
594
595 /* This should already be page aligned */
7b7d00e0 596 addr &= TARGET_PAGE_MASK;
e7218445 597
7b7d00e0
RH
598 if (qemu_cpu_is_self(cpu)) {
599 tlb_flush_page_by_mmuidx_async_0(cpu, addr, idxmap);
600 } else if (idxmap < TARGET_PAGE_SIZE) {
601 /*
602 * Most targets have only a few mmu_idx. In the case where
603 * we can stuff idxmap into the low TARGET_PAGE_BITS, avoid
604 * allocating memory for this operation.
605 */
606 async_run_on_cpu(cpu, tlb_flush_page_by_mmuidx_async_1,
607 RUN_ON_CPU_TARGET_PTR(addr | idxmap));
e7218445 608 } else {
7b7d00e0
RH
609 TLBFlushPageByMMUIdxData *d = g_new(TLBFlushPageByMMUIdxData, 1);
610
611 /* Otherwise allocate a structure, freed by the worker. */
612 d->addr = addr;
613 d->idxmap = idxmap;
614 async_run_on_cpu(cpu, tlb_flush_page_by_mmuidx_async_2,
615 RUN_ON_CPU_HOST_PTR(d));
e7218445
AB
616 }
617}
618
f8144c6c
RH
619void tlb_flush_page(CPUState *cpu, target_ulong addr)
620{
621 tlb_flush_page_by_mmuidx(cpu, addr, ALL_MMUIDX_BITS);
622}
623
c3b9a07a
AB
624void tlb_flush_page_by_mmuidx_all_cpus(CPUState *src_cpu, target_ulong addr,
625 uint16_t idxmap)
e3b9ca81 626{
c3b9a07a
AB
627 tlb_debug("addr: "TARGET_FMT_lx" mmu_idx:%"PRIx16"\n", addr, idxmap);
628
629 /* This should already be page aligned */
7b7d00e0
RH
630 addr &= TARGET_PAGE_MASK;
631
632 /*
633 * Allocate memory to hold addr+idxmap only when needed.
634 * See tlb_flush_page_by_mmuidx for details.
635 */
636 if (idxmap < TARGET_PAGE_SIZE) {
637 flush_all_helper(src_cpu, tlb_flush_page_by_mmuidx_async_1,
638 RUN_ON_CPU_TARGET_PTR(addr | idxmap));
639 } else {
640 CPUState *dst_cpu;
641
642 /* Allocate a separate data block for each destination cpu. */
643 CPU_FOREACH(dst_cpu) {
644 if (dst_cpu != src_cpu) {
645 TLBFlushPageByMMUIdxData *d
646 = g_new(TLBFlushPageByMMUIdxData, 1);
647
648 d->addr = addr;
649 d->idxmap = idxmap;
650 async_run_on_cpu(dst_cpu, tlb_flush_page_by_mmuidx_async_2,
651 RUN_ON_CPU_HOST_PTR(d));
652 }
653 }
654 }
c3b9a07a 655
7b7d00e0 656 tlb_flush_page_by_mmuidx_async_0(src_cpu, addr, idxmap);
c3b9a07a
AB
657}
658
f8144c6c
RH
659void tlb_flush_page_all_cpus(CPUState *src, target_ulong addr)
660{
661 tlb_flush_page_by_mmuidx_all_cpus(src, addr, ALL_MMUIDX_BITS);
662}
663
c3b9a07a 664void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
1308e026
RH
665 target_ulong addr,
666 uint16_t idxmap)
c3b9a07a 667{
c3b9a07a
AB
668 tlb_debug("addr: "TARGET_FMT_lx" mmu_idx:%"PRIx16"\n", addr, idxmap);
669
670 /* This should already be page aligned */
7b7d00e0 671 addr &= TARGET_PAGE_MASK;
c3b9a07a 672
7b7d00e0
RH
673 /*
674 * Allocate memory to hold addr+idxmap only when needed.
675 * See tlb_flush_page_by_mmuidx for details.
676 */
677 if (idxmap < TARGET_PAGE_SIZE) {
678 flush_all_helper(src_cpu, tlb_flush_page_by_mmuidx_async_1,
679 RUN_ON_CPU_TARGET_PTR(addr | idxmap));
680 async_safe_run_on_cpu(src_cpu, tlb_flush_page_by_mmuidx_async_1,
681 RUN_ON_CPU_TARGET_PTR(addr | idxmap));
682 } else {
683 CPUState *dst_cpu;
684 TLBFlushPageByMMUIdxData *d;
685
686 /* Allocate a separate data block for each destination cpu. */
687 CPU_FOREACH(dst_cpu) {
688 if (dst_cpu != src_cpu) {
689 d = g_new(TLBFlushPageByMMUIdxData, 1);
690 d->addr = addr;
691 d->idxmap = idxmap;
692 async_run_on_cpu(dst_cpu, tlb_flush_page_by_mmuidx_async_2,
693 RUN_ON_CPU_HOST_PTR(d));
694 }
695 }
696
697 d = g_new(TLBFlushPageByMMUIdxData, 1);
698 d->addr = addr;
699 d->idxmap = idxmap;
700 async_safe_run_on_cpu(src_cpu, tlb_flush_page_by_mmuidx_async_2,
701 RUN_ON_CPU_HOST_PTR(d));
702 }
c3b9a07a
AB
703}
704
f8144c6c 705void tlb_flush_page_all_cpus_synced(CPUState *src, target_ulong addr)
c3b9a07a 706{
f8144c6c 707 tlb_flush_page_by_mmuidx_all_cpus_synced(src, addr, ALL_MMUIDX_BITS);
e3b9ca81
FK
708}
709
3c4ddec1
RH
710static void tlb_flush_range_locked(CPUArchState *env, int midx,
711 target_ulong addr, target_ulong len,
712 unsigned bits)
3ab6e68c
RH
713{
714 CPUTLBDesc *d = &env_tlb(env)->d[midx];
715 CPUTLBDescFast *f = &env_tlb(env)->f[midx];
716 target_ulong mask = MAKE_64BIT_MASK(0, bits);
717
718 /*
719 * If @bits is smaller than the tlb size, there may be multiple entries
720 * within the TLB; otherwise all addresses that match under @mask hit
721 * the same TLB entry.
3ab6e68c
RH
722 * TODO: Perhaps allow bits to be a few bits less than the size.
723 * For now, just flush the entire TLB.
3c4ddec1
RH
724 *
725 * If @len is larger than the tlb size, then it will take longer to
726 * test all of the entries in the TLB than it will to flush it all.
3ab6e68c 727 */
3c4ddec1 728 if (mask < f->mask || len > f->mask) {
3ab6e68c 729 tlb_debug("forcing full flush midx %d ("
3c4ddec1
RH
730 TARGET_FMT_lx "/" TARGET_FMT_lx "+" TARGET_FMT_lx ")\n",
731 midx, addr, mask, len);
3ab6e68c
RH
732 tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
733 return;
734 }
735
3c4ddec1
RH
736 /*
737 * Check if we need to flush due to large pages.
738 * Because large_page_mask contains all 1's from the msb,
739 * we only need to test the end of the range.
740 */
741 if (((addr + len - 1) & d->large_page_mask) == d->large_page_addr) {
3ab6e68c
RH
742 tlb_debug("forcing full flush midx %d ("
743 TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
744 midx, d->large_page_addr, d->large_page_mask);
745 tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
746 return;
747 }
748
3c4ddec1
RH
749 for (target_ulong i = 0; i < len; i += TARGET_PAGE_SIZE) {
750 target_ulong page = addr + i;
751 CPUTLBEntry *entry = tlb_entry(env, midx, page);
752
753 if (tlb_flush_entry_mask_locked(entry, page, mask)) {
754 tlb_n_used_entries_dec(env, midx);
755 }
756 tlb_flush_vtlb_page_mask_locked(env, midx, page, mask);
3ab6e68c 757 }
3ab6e68c
RH
758}
759
760typedef struct {
761 target_ulong addr;
3c4ddec1 762 target_ulong len;
3ab6e68c
RH
763 uint16_t idxmap;
764 uint16_t bits;
3960a59f 765} TLBFlushRangeData;
3ab6e68c
RH
766
767static void
768tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
3960a59f 769 TLBFlushRangeData d)
3ab6e68c
RH
770{
771 CPUArchState *env = cpu->env_ptr;
772 int mmu_idx;
773
774 assert_cpu_is_self(cpu);
775
3c4ddec1
RH
776 tlb_debug("range:" TARGET_FMT_lx "/%u+" TARGET_FMT_lx " mmu_map:0x%x\n",
777 d.addr, d.bits, d.len, d.idxmap);
3ab6e68c
RH
778
779 qemu_spin_lock(&env_tlb(env)->c.lock);
780 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
781 if ((d.idxmap >> mmu_idx) & 1) {
3c4ddec1 782 tlb_flush_range_locked(env, mmu_idx, d.addr, d.len, d.bits);
3ab6e68c
RH
783 }
784 }
785 qemu_spin_unlock(&env_tlb(env)->c.lock);
786
3c4ddec1
RH
787 for (target_ulong i = 0; i < d.len; i += TARGET_PAGE_SIZE) {
788 tb_flush_jmp_cache(cpu, d.addr + i);
789 }
3ab6e68c
RH
790}
791
3ab6e68c
RH
792static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
793 run_on_cpu_data data)
794{
3960a59f 795 TLBFlushRangeData *d = data.host_ptr;
3ab6e68c
RH
796 tlb_flush_page_bits_by_mmuidx_async_0(cpu, *d);
797 g_free(d);
798}
799
800void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
801 uint16_t idxmap, unsigned bits)
802{
3960a59f 803 TLBFlushRangeData d;
3ab6e68c
RH
804
805 /* If all bits are significant, this devolves to tlb_flush_page. */
806 if (bits >= TARGET_LONG_BITS) {
807 tlb_flush_page_by_mmuidx(cpu, addr, idxmap);
808 return;
809 }
810 /* If no page bits are significant, this devolves to tlb_flush. */
811 if (bits < TARGET_PAGE_BITS) {
812 tlb_flush_by_mmuidx(cpu, idxmap);
813 return;
814 }
815
816 /* This should already be page aligned */
817 d.addr = addr & TARGET_PAGE_MASK;
3c4ddec1 818 d.len = TARGET_PAGE_SIZE;
3ab6e68c
RH
819 d.idxmap = idxmap;
820 d.bits = bits;
821
822 if (qemu_cpu_is_self(cpu)) {
823 tlb_flush_page_bits_by_mmuidx_async_0(cpu, d);
3ab6e68c 824 } else {
3ab6e68c 825 /* Otherwise allocate a structure, freed by the worker. */
3960a59f 826 TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
3ab6e68c
RH
827 async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
828 RUN_ON_CPU_HOST_PTR(p));
829 }
830}
831
832void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
833 target_ulong addr,
834 uint16_t idxmap,
835 unsigned bits)
836{
3960a59f 837 TLBFlushRangeData d;
d34e4d1a 838 CPUState *dst_cpu;
3ab6e68c
RH
839
840 /* If all bits are significant, this devolves to tlb_flush_page. */
841 if (bits >= TARGET_LONG_BITS) {
842 tlb_flush_page_by_mmuidx_all_cpus(src_cpu, addr, idxmap);
843 return;
844 }
845 /* If no page bits are significant, this devolves to tlb_flush. */
846 if (bits < TARGET_PAGE_BITS) {
847 tlb_flush_by_mmuidx_all_cpus(src_cpu, idxmap);
848 return;
849 }
850
851 /* This should already be page aligned */
852 d.addr = addr & TARGET_PAGE_MASK;
3c4ddec1 853 d.len = TARGET_PAGE_SIZE;
3ab6e68c
RH
854 d.idxmap = idxmap;
855 d.bits = bits;
856
d34e4d1a
RH
857 /* Allocate a separate data block for each destination cpu. */
858 CPU_FOREACH(dst_cpu) {
859 if (dst_cpu != src_cpu) {
860 TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
861 async_run_on_cpu(dst_cpu,
862 tlb_flush_page_bits_by_mmuidx_async_2,
863 RUN_ON_CPU_HOST_PTR(p));
3ab6e68c
RH
864 }
865 }
866
867 tlb_flush_page_bits_by_mmuidx_async_0(src_cpu, d);
868}
869
870void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
871 target_ulong addr,
872 uint16_t idxmap,
873 unsigned bits)
874{
d34e4d1a
RH
875 TLBFlushRangeData d, *p;
876 CPUState *dst_cpu;
3ab6e68c
RH
877
878 /* If all bits are significant, this devolves to tlb_flush_page. */
879 if (bits >= TARGET_LONG_BITS) {
880 tlb_flush_page_by_mmuidx_all_cpus_synced(src_cpu, addr, idxmap);
881 return;
882 }
883 /* If no page bits are significant, this devolves to tlb_flush. */
884 if (bits < TARGET_PAGE_BITS) {
885 tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, idxmap);
886 return;
887 }
888
889 /* This should already be page aligned */
890 d.addr = addr & TARGET_PAGE_MASK;
3c4ddec1 891 d.len = TARGET_PAGE_SIZE;
3ab6e68c
RH
892 d.idxmap = idxmap;
893 d.bits = bits;
894
d34e4d1a
RH
895 /* Allocate a separate data block for each destination cpu. */
896 CPU_FOREACH(dst_cpu) {
897 if (dst_cpu != src_cpu) {
898 p = g_memdup(&d, sizeof(d));
899 async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
900 RUN_ON_CPU_HOST_PTR(p));
3ab6e68c 901 }
3ab6e68c 902 }
d34e4d1a
RH
903
904 p = g_memdup(&d, sizeof(d));
905 async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
906 RUN_ON_CPU_HOST_PTR(p));
3ab6e68c
RH
907}
908
0cac1b66
BS
909/* update the TLBs so that writes to code in the virtual page 'addr'
910 can be detected */
911void tlb_protect_code(ram_addr_t ram_addr)
912{
03eebc9e
SH
913 cpu_physical_memory_test_and_clear_dirty(ram_addr, TARGET_PAGE_SIZE,
914 DIRTY_MEMORY_CODE);
0cac1b66
BS
915}
916
917/* update the TLB so that writes in physical page 'phys_addr' are no longer
918 tested for self modifying code */
9564f52d 919void tlb_unprotect_code(ram_addr_t ram_addr)
0cac1b66 920{
52159192 921 cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_CODE);
0cac1b66
BS
922}
923
0cac1b66 924
b0706b71
AB
925/*
926 * Dirty write flag handling
927 *
928 * When the TCG code writes to a location it looks up the address in
929 * the TLB and uses that data to compute the final address. If any of
930 * the lower bits of the address are set then the slow path is forced.
931 * There are a number of reasons to do this but for normal RAM the
932 * most usual is detecting writes to code regions which may invalidate
933 * generated code.
934 *
71aec354 935 * Other vCPUs might be reading their TLBs during guest execution, so we update
d73415a3 936 * te->addr_write with qatomic_set. We don't need to worry about this for
71aec354 937 * oversized guests as MTTCG is disabled for them.
b0706b71 938 *
53d28455 939 * Called with tlb_c.lock held.
b0706b71 940 */
71aec354
EC
941static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
942 uintptr_t start, uintptr_t length)
0cac1b66 943{
b0706b71 944 uintptr_t addr = tlb_entry->addr_write;
0cac1b66 945
7b0d792c
RH
946 if ((addr & (TLB_INVALID_MASK | TLB_MMIO |
947 TLB_DISCARD_WRITE | TLB_NOTDIRTY)) == 0) {
b0706b71
AB
948 addr &= TARGET_PAGE_MASK;
949 addr += tlb_entry->addend;
0cac1b66 950 if ((addr - start) < length) {
71aec354 951#if TCG_OVERSIZED_GUEST
0cac1b66 952 tlb_entry->addr_write |= TLB_NOTDIRTY;
b0706b71 953#else
d73415a3 954 qatomic_set(&tlb_entry->addr_write,
71aec354
EC
955 tlb_entry->addr_write | TLB_NOTDIRTY);
956#endif
b0706b71
AB
957 }
958 }
b0706b71
AB
959}
960
71aec354 961/*
53d28455 962 * Called with tlb_c.lock held.
71aec354
EC
963 * Called only from the vCPU context, i.e. the TLB's owner thread.
964 */
965static inline void copy_tlb_helper_locked(CPUTLBEntry *d, const CPUTLBEntry *s)
b0706b71 966{
b0706b71 967 *d = *s;
0cac1b66
BS
968}
969
b0706b71 970/* This is a cross vCPU call (i.e. another vCPU resetting the flags of
71aec354 971 * the target vCPU).
53d28455 972 * We must take tlb_c.lock to avoid racing with another vCPU update. The only
71aec354 973 * thing actually updated is the target TLB entry ->addr_write flags.
b0706b71 974 */
9a13565d 975void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
0cac1b66
BS
976{
977 CPUArchState *env;
978
9a13565d 979 int mmu_idx;
0cac1b66 980
9a13565d 981 env = cpu->env_ptr;
a40ec84e 982 qemu_spin_lock(&env_tlb(env)->c.lock);
9a13565d
PC
983 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
984 unsigned int i;
722a1c1e 985 unsigned int n = tlb_n_entries(&env_tlb(env)->f[mmu_idx]);
0cac1b66 986
86e1eff8 987 for (i = 0; i < n; i++) {
a40ec84e
RH
988 tlb_reset_dirty_range_locked(&env_tlb(env)->f[mmu_idx].table[i],
989 start1, length);
9a13565d 990 }
88e89a57 991
9a13565d 992 for (i = 0; i < CPU_VTLB_SIZE; i++) {
a40ec84e
RH
993 tlb_reset_dirty_range_locked(&env_tlb(env)->d[mmu_idx].vtable[i],
994 start1, length);
0cac1b66
BS
995 }
996 }
a40ec84e 997 qemu_spin_unlock(&env_tlb(env)->c.lock);
0cac1b66
BS
998}
999
53d28455 1000/* Called with tlb_c.lock held */
71aec354
EC
1001static inline void tlb_set_dirty1_locked(CPUTLBEntry *tlb_entry,
1002 target_ulong vaddr)
0cac1b66
BS
1003{
1004 if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY)) {
1005 tlb_entry->addr_write = vaddr;
1006 }
1007}
1008
1009/* update the TLB corresponding to virtual page vaddr
1010 so that it is no longer dirty */
bcae01e4 1011void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
0cac1b66 1012{
bcae01e4 1013 CPUArchState *env = cpu->env_ptr;
0cac1b66
BS
1014 int mmu_idx;
1015
f0aff0f1
AB
1016 assert_cpu_is_self(cpu);
1017
0cac1b66 1018 vaddr &= TARGET_PAGE_MASK;
a40ec84e 1019 qemu_spin_lock(&env_tlb(env)->c.lock);
0cac1b66 1020 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
383beda9 1021 tlb_set_dirty1_locked(tlb_entry(env, mmu_idx, vaddr), vaddr);
0cac1b66 1022 }
88e89a57
XT
1023
1024 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
1025 int k;
1026 for (k = 0; k < CPU_VTLB_SIZE; k++) {
a40ec84e 1027 tlb_set_dirty1_locked(&env_tlb(env)->d[mmu_idx].vtable[k], vaddr);
88e89a57
XT
1028 }
1029 }
a40ec84e 1030 qemu_spin_unlock(&env_tlb(env)->c.lock);
0cac1b66
BS
1031}
1032
1033/* Our TLB does not support large pages, so remember the area covered by
1034 large pages and trigger a full TLB flush if these are invalidated. */
1308e026
RH
1035static void tlb_add_large_page(CPUArchState *env, int mmu_idx,
1036 target_ulong vaddr, target_ulong size)
0cac1b66 1037{
a40ec84e 1038 target_ulong lp_addr = env_tlb(env)->d[mmu_idx].large_page_addr;
1308e026 1039 target_ulong lp_mask = ~(size - 1);
0cac1b66 1040
1308e026
RH
1041 if (lp_addr == (target_ulong)-1) {
1042 /* No previous large page. */
1043 lp_addr = vaddr;
1044 } else {
1045 /* Extend the existing region to include the new page.
1046 This is a compromise between unnecessary flushes and
1047 the cost of maintaining a full variable size TLB. */
a40ec84e 1048 lp_mask &= env_tlb(env)->d[mmu_idx].large_page_mask;
1308e026
RH
1049 while (((lp_addr ^ vaddr) & lp_mask) != 0) {
1050 lp_mask <<= 1;
1051 }
0cac1b66 1052 }
a40ec84e
RH
1053 env_tlb(env)->d[mmu_idx].large_page_addr = lp_addr & lp_mask;
1054 env_tlb(env)->d[mmu_idx].large_page_mask = lp_mask;
0cac1b66
BS
1055}
1056
1057/* Add a new TLB entry. At most one entry for a given virtual address
79e2b9ae
PB
1058 * is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the
1059 * supplied size is only used by tlb_flush_page.
1060 *
1061 * Called from TCG-generated code, which is under an RCU read-side
1062 * critical section.
1063 */
fadc1cbe
PM
1064void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
1065 hwaddr paddr, MemTxAttrs attrs, int prot,
1066 int mmu_idx, target_ulong size)
0cac1b66 1067{
0c591eb0 1068 CPUArchState *env = cpu->env_ptr;
a40ec84e
RH
1069 CPUTLB *tlb = env_tlb(env);
1070 CPUTLBDesc *desc = &tlb->d[mmu_idx];
0cac1b66
BS
1071 MemoryRegionSection *section;
1072 unsigned int index;
1073 target_ulong address;
8f5db641 1074 target_ulong write_address;
0cac1b66 1075 uintptr_t addend;
68fea038 1076 CPUTLBEntry *te, tn;
55df6fcf
PM
1077 hwaddr iotlb, xlat, sz, paddr_page;
1078 target_ulong vaddr_page;
d7898cda 1079 int asidx = cpu_asidx_from_attrs(cpu, attrs);
50b107c5 1080 int wp_flags;
8f5db641 1081 bool is_ram, is_romd;
0cac1b66 1082
f0aff0f1 1083 assert_cpu_is_self(cpu);
55df6fcf 1084
1308e026 1085 if (size <= TARGET_PAGE_SIZE) {
55df6fcf
PM
1086 sz = TARGET_PAGE_SIZE;
1087 } else {
1308e026 1088 tlb_add_large_page(env, mmu_idx, vaddr, size);
55df6fcf 1089 sz = size;
0cac1b66 1090 }
55df6fcf
PM
1091 vaddr_page = vaddr & TARGET_PAGE_MASK;
1092 paddr_page = paddr & TARGET_PAGE_MASK;
149f54b5 1093
55df6fcf
PM
1094 section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
1095 &xlat, &sz, attrs, &prot);
149f54b5
PB
1096 assert(sz >= TARGET_PAGE_SIZE);
1097
8526e1f4
AB
1098 tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
1099 " prot=%x idx=%d\n",
1100 vaddr, paddr, prot, mmu_idx);
0cac1b66 1101
55df6fcf
PM
1102 address = vaddr_page;
1103 if (size < TARGET_PAGE_SIZE) {
30d7e098
RH
1104 /* Repeat the MMU check and TLB fill on every access. */
1105 address |= TLB_INVALID_MASK;
55df6fcf 1106 }
a26fc6f5 1107 if (attrs.byte_swap) {
5b87b3e6 1108 address |= TLB_BSWAP;
a26fc6f5 1109 }
8f5db641
RH
1110
1111 is_ram = memory_region_is_ram(section->mr);
1112 is_romd = memory_region_is_romd(section->mr);
1113
1114 if (is_ram || is_romd) {
1115 /* RAM and ROMD both have associated host memory. */
1116 addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
1117 } else {
1118 /* I/O does not; force the host address to NULL. */
8f3e03cb 1119 addend = 0;
8f5db641
RH
1120 }
1121
1122 write_address = address;
1123 if (is_ram) {
1124 iotlb = memory_region_get_ram_addr(section->mr) + xlat;
1125 /*
1126 * Computing is_clean is expensive; avoid all that unless
1127 * the page is actually writable.
1128 */
1129 if (prot & PAGE_WRITE) {
1130 if (section->readonly) {
1131 write_address |= TLB_DISCARD_WRITE;
1132 } else if (cpu_physical_memory_is_clean(iotlb)) {
1133 write_address |= TLB_NOTDIRTY;
1134 }
1135 }
8f3e03cb 1136 } else {
8f5db641
RH
1137 /* I/O or ROMD */
1138 iotlb = memory_region_section_get_iotlb(cpu, section) + xlat;
1139 /*
1140 * Writes to romd devices must go through MMIO to enable write.
1141 * Reads to romd devices go through the ram_ptr found above,
1142 * but of course reads to I/O must go through MMIO.
1143 */
1144 write_address |= TLB_MMIO;
1145 if (!is_romd) {
1146 address = write_address;
1147 }
0cac1b66 1148 }
0cac1b66 1149
50b107c5
RH
1150 wp_flags = cpu_watchpoint_address_matches(cpu, vaddr_page,
1151 TARGET_PAGE_SIZE);
0cac1b66 1152
383beda9
RH
1153 index = tlb_index(env, mmu_idx, vaddr_page);
1154 te = tlb_entry(env, mmu_idx, vaddr_page);
b0706b71 1155
71aec354
EC
1156 /*
1157 * Hold the TLB lock for the rest of the function. We could acquire/release
1158 * the lock several times in the function, but it is faster to amortize the
1159 * acquisition cost by acquiring it just once. Note that this leads to
1160 * a longer critical section, but this is not a concern since the TLB lock
1161 * is unlikely to be contended.
1162 */
a40ec84e 1163 qemu_spin_lock(&tlb->c.lock);
71aec354 1164
3d1523ce 1165 /* Note that the tlb is no longer clean. */
a40ec84e 1166 tlb->c.dirty |= 1 << mmu_idx;
3d1523ce 1167
71aec354
EC
1168 /* Make sure there's no cached translation for the new page. */
1169 tlb_flush_vtlb_page_locked(env, mmu_idx, vaddr_page);
1170
68fea038
RH
1171 /*
1172 * Only evict the old entry to the victim tlb if it's for a
1173 * different page; otherwise just overwrite the stale data.
1174 */
3cea94bb 1175 if (!tlb_hit_page_anyprot(te, vaddr_page) && !tlb_entry_is_empty(te)) {
a40ec84e
RH
1176 unsigned vidx = desc->vindex++ % CPU_VTLB_SIZE;
1177 CPUTLBEntry *tv = &desc->vtable[vidx];
b0706b71 1178
68fea038 1179 /* Evict the old entry into the victim tlb. */
71aec354 1180 copy_tlb_helper_locked(tv, te);
a40ec84e 1181 desc->viotlb[vidx] = desc->iotlb[index];
86e1eff8 1182 tlb_n_used_entries_dec(env, mmu_idx);
68fea038 1183 }
88e89a57
XT
1184
1185 /* refill the tlb */
ace41090
PM
1186 /*
1187 * At this point iotlb contains a physical section number in the lower
1188 * TARGET_PAGE_BITS, and either
8f5db641
RH
1189 * + the ram_addr_t of the page base of the target RAM (RAM)
1190 * + the offset within section->mr of the page base (I/O, ROMD)
55df6fcf 1191 * We subtract the vaddr_page (which is page aligned and thus won't
ace41090
PM
1192 * disturb the low bits) to give an offset which can be added to the
1193 * (non-page-aligned) vaddr of the eventual memory access to get
1194 * the MemoryRegion offset for the access. Note that the vaddr we
1195 * subtract here is that of the page base, and not the same as the
1196 * vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
1197 */
a40ec84e
RH
1198 desc->iotlb[index].addr = iotlb - vaddr_page;
1199 desc->iotlb[index].attrs = attrs;
b0706b71
AB
1200
1201 /* Now calculate the new entry */
55df6fcf 1202 tn.addend = addend - vaddr_page;
0cac1b66 1203 if (prot & PAGE_READ) {
b0706b71 1204 tn.addr_read = address;
50b107c5
RH
1205 if (wp_flags & BP_MEM_READ) {
1206 tn.addr_read |= TLB_WATCHPOINT;
1207 }
0cac1b66 1208 } else {
b0706b71 1209 tn.addr_read = -1;
0cac1b66
BS
1210 }
1211
1212 if (prot & PAGE_EXEC) {
8f5db641 1213 tn.addr_code = address;
0cac1b66 1214 } else {
b0706b71 1215 tn.addr_code = -1;
0cac1b66 1216 }
b0706b71
AB
1217
1218 tn.addr_write = -1;
0cac1b66 1219 if (prot & PAGE_WRITE) {
8f5db641 1220 tn.addr_write = write_address;
f52bfb12
DH
1221 if (prot & PAGE_WRITE_INV) {
1222 tn.addr_write |= TLB_INVALID_MASK;
1223 }
50b107c5
RH
1224 if (wp_flags & BP_MEM_WRITE) {
1225 tn.addr_write |= TLB_WATCHPOINT;
1226 }
0cac1b66 1227 }
b0706b71 1228
71aec354 1229 copy_tlb_helper_locked(te, &tn);
86e1eff8 1230 tlb_n_used_entries_inc(env, mmu_idx);
a40ec84e 1231 qemu_spin_unlock(&tlb->c.lock);
0cac1b66
BS
1232}
1233
fadc1cbe
PM
1234/* Add a new TLB entry, but without specifying the memory
1235 * transaction attributes to be used.
1236 */
1237void tlb_set_page(CPUState *cpu, target_ulong vaddr,
1238 hwaddr paddr, int prot,
1239 int mmu_idx, target_ulong size)
1240{
1241 tlb_set_page_with_attrs(cpu, vaddr, paddr, MEMTXATTRS_UNSPECIFIED,
1242 prot, mmu_idx, size);
1243}
1244
857baec1
AB
1245static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
1246{
1247 ram_addr_t ram_addr;
1248
1249 ram_addr = qemu_ram_addr_from_host(ptr);
1250 if (ram_addr == RAM_ADDR_INVALID) {
1251 error_report("Bad ram pointer %p", ptr);
1252 abort();
1253 }
1254 return ram_addr;
1255}
1256
c319dc13
RH
1257/*
1258 * Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
1259 * caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
1260 * be discarded and looked up again (e.g. via tlb_entry()).
1261 */
1262static void tlb_fill(CPUState *cpu, target_ulong addr, int size,
1263 MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
1264{
1265 CPUClass *cc = CPU_GET_CLASS(cpu);
1266 bool ok;
1267
1268 /*
1269 * This is not a probe, so only valid return is success; failure
1270 * should result in exception + longjmp to the cpu loop.
1271 */
78271684
CF
1272 ok = cc->tcg_ops->tlb_fill(cpu, addr, size,
1273 access_type, mmu_idx, false, retaddr);
c319dc13
RH
1274 assert(ok);
1275}
1276
78271684
CF
1277static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
1278 MMUAccessType access_type,
1279 int mmu_idx, uintptr_t retaddr)
1280{
1281 CPUClass *cc = CPU_GET_CLASS(cpu);
1282
1283 cc->tcg_ops->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
1284}
1285
1286static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
1287 vaddr addr, unsigned size,
1288 MMUAccessType access_type,
1289 int mmu_idx, MemTxAttrs attrs,
1290 MemTxResult response,
1291 uintptr_t retaddr)
1292{
1293 CPUClass *cc = CPU_GET_CLASS(cpu);
1294
1295 if (!cpu->ignore_memory_transaction_failures &&
1296 cc->tcg_ops->do_transaction_failed) {
1297 cc->tcg_ops->do_transaction_failed(cpu, physaddr, addr, size,
1298 access_type, mmu_idx, attrs,
1299 response, retaddr);
1300 }
1301}
1302
82a45b96 1303static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
f1be3696 1304 int mmu_idx, target_ulong addr, uintptr_t retaddr,
be5c4787 1305 MMUAccessType access_type, MemOp op)
82a45b96 1306{
29a0af61 1307 CPUState *cpu = env_cpu(env);
2d54f194
PM
1308 hwaddr mr_offset;
1309 MemoryRegionSection *section;
1310 MemoryRegion *mr;
82a45b96 1311 uint64_t val;
8d04fb55 1312 bool locked = false;
04e3aabd 1313 MemTxResult r;
82a45b96 1314
2d54f194
PM
1315 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
1316 mr = section->mr;
1317 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
82a45b96 1318 cpu->mem_io_pc = retaddr;
08565552 1319 if (!cpu->can_do_io) {
82a45b96
RH
1320 cpu_io_recompile(cpu, retaddr);
1321 }
1322
41744954 1323 if (!qemu_mutex_iothread_locked()) {
8d04fb55
JK
1324 qemu_mutex_lock_iothread();
1325 locked = true;
1326 }
be5c4787 1327 r = memory_region_dispatch_read(mr, mr_offset, &val, op, iotlbentry->attrs);
04e3aabd 1328 if (r != MEMTX_OK) {
2d54f194
PM
1329 hwaddr physaddr = mr_offset +
1330 section->offset_within_address_space -
1331 section->offset_within_region;
1332
be5c4787 1333 cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), access_type,
04e3aabd
PM
1334 mmu_idx, iotlbentry->attrs, r, retaddr);
1335 }
8d04fb55
JK
1336 if (locked) {
1337 qemu_mutex_unlock_iothread();
1338 }
1339
82a45b96
RH
1340 return val;
1341}
1342
2f3a57ee
AB
1343/*
1344 * Save a potentially trashed IOTLB entry for later lookup by plugin.
570ef309
AB
1345 * This is read by tlb_plugin_lookup if the iotlb entry doesn't match
1346 * because of the side effect of io_writex changing memory layout.
2f3a57ee
AB
1347 */
1348static void save_iotlb_data(CPUState *cs, hwaddr addr,
1349 MemoryRegionSection *section, hwaddr mr_offset)
1350{
1351#ifdef CONFIG_PLUGIN
1352 SavedIOTLB *saved = &cs->saved_iotlb;
1353 saved->addr = addr;
1354 saved->section = section;
1355 saved->mr_offset = mr_offset;
1356#endif
1357}
1358
82a45b96 1359static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
f1be3696 1360 int mmu_idx, uint64_t val, target_ulong addr,
be5c4787 1361 uintptr_t retaddr, MemOp op)
82a45b96 1362{
29a0af61 1363 CPUState *cpu = env_cpu(env);
2d54f194
PM
1364 hwaddr mr_offset;
1365 MemoryRegionSection *section;
1366 MemoryRegion *mr;
8d04fb55 1367 bool locked = false;
04e3aabd 1368 MemTxResult r;
82a45b96 1369
2d54f194
PM
1370 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
1371 mr = section->mr;
1372 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
08565552 1373 if (!cpu->can_do_io) {
82a45b96
RH
1374 cpu_io_recompile(cpu, retaddr);
1375 }
82a45b96 1376 cpu->mem_io_pc = retaddr;
8d04fb55 1377
2f3a57ee
AB
1378 /*
1379 * The memory_region_dispatch may trigger a flush/resize
1380 * so for plugins we save the iotlb_data just in case.
1381 */
1382 save_iotlb_data(cpu, iotlbentry->addr, section, mr_offset);
1383
41744954 1384 if (!qemu_mutex_iothread_locked()) {
8d04fb55
JK
1385 qemu_mutex_lock_iothread();
1386 locked = true;
1387 }
be5c4787 1388 r = memory_region_dispatch_write(mr, mr_offset, val, op, iotlbentry->attrs);
04e3aabd 1389 if (r != MEMTX_OK) {
2d54f194
PM
1390 hwaddr physaddr = mr_offset +
1391 section->offset_within_address_space -
1392 section->offset_within_region;
1393
be5c4787
TN
1394 cpu_transaction_failed(cpu, physaddr, addr, memop_size(op),
1395 MMU_DATA_STORE, mmu_idx, iotlbentry->attrs, r,
1396 retaddr);
04e3aabd 1397 }
8d04fb55
JK
1398 if (locked) {
1399 qemu_mutex_unlock_iothread();
1400 }
82a45b96
RH
1401}
1402
4811e909
RH
1403static inline target_ulong tlb_read_ofs(CPUTLBEntry *entry, size_t ofs)
1404{
1405#if TCG_OVERSIZED_GUEST
1406 return *(target_ulong *)((uintptr_t)entry + ofs);
1407#else
d73415a3
SH
1408 /* ofs might correspond to .addr_write, so use qatomic_read */
1409 return qatomic_read((target_ulong *)((uintptr_t)entry + ofs));
4811e909
RH
1410#endif
1411}
1412
7e9a7c50
RH
1413/* Return true if ADDR is present in the victim tlb, and has been copied
1414 back to the main tlb. */
1415static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
1416 size_t elt_ofs, target_ulong page)
1417{
1418 size_t vidx;
71aec354 1419
29a0af61 1420 assert_cpu_is_self(env_cpu(env));
7e9a7c50 1421 for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
a40ec84e
RH
1422 CPUTLBEntry *vtlb = &env_tlb(env)->d[mmu_idx].vtable[vidx];
1423 target_ulong cmp;
1424
d73415a3 1425 /* elt_ofs might correspond to .addr_write, so use qatomic_read */
a40ec84e
RH
1426#if TCG_OVERSIZED_GUEST
1427 cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
1428#else
d73415a3 1429 cmp = qatomic_read((target_ulong *)((uintptr_t)vtlb + elt_ofs));
a40ec84e 1430#endif
7e9a7c50
RH
1431
1432 if (cmp == page) {
1433 /* Found entry in victim tlb, swap tlb and iotlb. */
a40ec84e 1434 CPUTLBEntry tmptlb, *tlb = &env_tlb(env)->f[mmu_idx].table[index];
b0706b71 1435
a40ec84e 1436 qemu_spin_lock(&env_tlb(env)->c.lock);
71aec354
EC
1437 copy_tlb_helper_locked(&tmptlb, tlb);
1438 copy_tlb_helper_locked(tlb, vtlb);
1439 copy_tlb_helper_locked(vtlb, &tmptlb);
a40ec84e 1440 qemu_spin_unlock(&env_tlb(env)->c.lock);
b0706b71 1441
a40ec84e
RH
1442 CPUIOTLBEntry tmpio, *io = &env_tlb(env)->d[mmu_idx].iotlb[index];
1443 CPUIOTLBEntry *vio = &env_tlb(env)->d[mmu_idx].viotlb[vidx];
7e9a7c50
RH
1444 tmpio = *io; *io = *vio; *vio = tmpio;
1445 return true;
1446 }
1447 }
1448 return false;
1449}
1450
1451/* Macro to call the above, with local variables from the use context. */
a390284b 1452#define VICTIM_TLB_HIT(TY, ADDR) \
7e9a7c50 1453 victim_tlb_hit(env, mmu_idx, index, offsetof(CPUTLBEntry, TY), \
a390284b 1454 (ADDR) & TARGET_PAGE_MASK)
7e9a7c50 1455
30d7e098
RH
1456/*
1457 * Return a ram_addr_t for the virtual address for execution.
1458 *
1459 * Return -1 if we can't translate and execute from an entire page
1460 * of RAM. This will force us to execute by loading and translating
1461 * one insn at a time, without caching.
1462 *
1463 * NOTE: This function will trigger an exception if the page is
1464 * not executable.
f2553f04 1465 */
4b2190da
EC
1466tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
1467 void **hostp)
f2553f04 1468{
383beda9
RH
1469 uintptr_t mmu_idx = cpu_mmu_index(env, true);
1470 uintptr_t index = tlb_index(env, mmu_idx, addr);
1471 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
f2553f04 1472 void *p;
f2553f04 1473
383beda9 1474 if (unlikely(!tlb_hit(entry->addr_code, addr))) {
b493ccf1 1475 if (!VICTIM_TLB_HIT(addr_code, addr)) {
29a0af61 1476 tlb_fill(env_cpu(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
6d967cb8
EC
1477 index = tlb_index(env, mmu_idx, addr);
1478 entry = tlb_entry(env, mmu_idx, addr);
30d7e098
RH
1479
1480 if (unlikely(entry->addr_code & TLB_INVALID_MASK)) {
1481 /*
1482 * The MMU protection covers a smaller range than a target
1483 * page, so we must redo the MMU check for every insn.
1484 */
1485 return -1;
1486 }
71b9a453 1487 }
383beda9 1488 assert(tlb_hit(entry->addr_code, addr));
f2553f04 1489 }
55df6fcf 1490
30d7e098
RH
1491 if (unlikely(entry->addr_code & TLB_MMIO)) {
1492 /* The region is not backed by RAM. */
4b2190da
EC
1493 if (hostp) {
1494 *hostp = NULL;
1495 }
20cb6ae4 1496 return -1;
55df6fcf
PM
1497 }
1498
383beda9 1499 p = (void *)((uintptr_t)addr + entry->addend);
4b2190da
EC
1500 if (hostp) {
1501 *hostp = p;
1502 }
f2553f04
FK
1503 return qemu_ram_addr_from_host_nofail(p);
1504}
1505
4b2190da
EC
1506tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
1507{
1508 return get_page_addr_code_hostp(env, addr, NULL);
1509}
1510
707526ad
RH
1511static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
1512 CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
1513{
1514 ram_addr_t ram_addr = mem_vaddr + iotlbentry->addr;
1515
1516 trace_memory_notdirty_write_access(mem_vaddr, ram_addr, size);
1517
1518 if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) {
1519 struct page_collection *pages
1520 = page_collection_lock(ram_addr, ram_addr + size);
5a7c27bb 1521 tb_invalidate_phys_page_fast(pages, ram_addr, size, retaddr);
707526ad
RH
1522 page_collection_unlock(pages);
1523 }
1524
1525 /*
1526 * Set both VGA and migration bits for simplicity and to remove
1527 * the notdirty callback faster.
1528 */
1529 cpu_physical_memory_set_dirty_range(ram_addr, size, DIRTY_CLIENTS_NOCODE);
1530
1531 /* We remove the notdirty callback only if the code has been flushed. */
1532 if (!cpu_physical_memory_is_clean(ram_addr)) {
1533 trace_memory_notdirty_set_dirty(mem_vaddr);
1534 tlb_set_dirty(cpu, mem_vaddr);
1535 }
1536}
1537
069cfe77
RH
1538static int probe_access_internal(CPUArchState *env, target_ulong addr,
1539 int fault_size, MMUAccessType access_type,
1540 int mmu_idx, bool nonfault,
1541 void **phost, uintptr_t retaddr)
3b08f0a9 1542{
383beda9
RH
1543 uintptr_t index = tlb_index(env, mmu_idx, addr);
1544 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
069cfe77 1545 target_ulong tlb_addr, page_addr;
c25c283d 1546 size_t elt_ofs;
069cfe77 1547 int flags;
ca86cf32 1548
c25c283d
DH
1549 switch (access_type) {
1550 case MMU_DATA_LOAD:
1551 elt_ofs = offsetof(CPUTLBEntry, addr_read);
c25c283d
DH
1552 break;
1553 case MMU_DATA_STORE:
1554 elt_ofs = offsetof(CPUTLBEntry, addr_write);
c25c283d
DH
1555 break;
1556 case MMU_INST_FETCH:
1557 elt_ofs = offsetof(CPUTLBEntry, addr_code);
c25c283d
DH
1558 break;
1559 default:
1560 g_assert_not_reached();
1561 }
1562 tlb_addr = tlb_read_ofs(entry, elt_ofs);
1563
069cfe77
RH
1564 page_addr = addr & TARGET_PAGE_MASK;
1565 if (!tlb_hit_page(tlb_addr, page_addr)) {
1566 if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page_addr)) {
1567 CPUState *cs = env_cpu(env);
1568 CPUClass *cc = CPU_GET_CLASS(cs);
1569
78271684
CF
1570 if (!cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type,
1571 mmu_idx, nonfault, retaddr)) {
069cfe77
RH
1572 /* Non-faulting page table read failed. */
1573 *phost = NULL;
1574 return TLB_INVALID_MASK;
1575 }
1576
1577 /* TLB resize via tlb_fill may have moved the entry. */
03a98189 1578 entry = tlb_entry(env, mmu_idx, addr);
3b08f0a9 1579 }
c25c283d 1580 tlb_addr = tlb_read_ofs(entry, elt_ofs);
03a98189 1581 }
069cfe77 1582 flags = tlb_addr & TLB_FLAGS_MASK;
03a98189 1583
069cfe77
RH
1584 /* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */
1585 if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) {
1586 *phost = NULL;
1587 return TLB_MMIO;
fef39ccd
DH
1588 }
1589
069cfe77
RH
1590 /* Everything else is RAM. */
1591 *phost = (void *)((uintptr_t)addr + entry->addend);
1592 return flags;
1593}
1594
1595int probe_access_flags(CPUArchState *env, target_ulong addr,
1596 MMUAccessType access_type, int mmu_idx,
1597 bool nonfault, void **phost, uintptr_t retaddr)
1598{
1599 int flags;
1600
1601 flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
1602 nonfault, phost, retaddr);
1603
1604 /* Handle clean RAM pages. */
1605 if (unlikely(flags & TLB_NOTDIRTY)) {
1606 uintptr_t index = tlb_index(env, mmu_idx, addr);
73bc0bd4 1607 CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
fef39ccd 1608
069cfe77
RH
1609 notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
1610 flags &= ~TLB_NOTDIRTY;
1611 }
1612
1613 return flags;
1614}
1615
1616void *probe_access(CPUArchState *env, target_ulong addr, int size,
1617 MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
1618{
1619 void *host;
1620 int flags;
1621
1622 g_assert(-(addr | TARGET_PAGE_MASK) >= size);
1623
1624 flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
1625 false, &host, retaddr);
1626
1627 /* Per the interface, size == 0 merely faults the access. */
1628 if (size == 0) {
1629 return NULL;
1630 }
1631
1632 if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) {
1633 uintptr_t index = tlb_index(env, mmu_idx, addr);
1634 CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
73bc0bd4
RH
1635
1636 /* Handle watchpoints. */
069cfe77
RH
1637 if (flags & TLB_WATCHPOINT) {
1638 int wp_access = (access_type == MMU_DATA_STORE
1639 ? BP_MEM_WRITE : BP_MEM_READ);
73bc0bd4
RH
1640 cpu_check_watchpoint(env_cpu(env), addr, size,
1641 iotlbentry->attrs, wp_access, retaddr);
1642 }
1643
1644 /* Handle clean RAM pages. */
069cfe77
RH
1645 if (flags & TLB_NOTDIRTY) {
1646 notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
73bc0bd4 1647 }
fef39ccd
DH
1648 }
1649
069cfe77 1650 return host;
3b08f0a9
RH
1651}
1652
4811e909
RH
1653void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
1654 MMUAccessType access_type, int mmu_idx)
1655{
069cfe77
RH
1656 void *host;
1657 int flags;
4811e909 1658
069cfe77
RH
1659 flags = probe_access_internal(env, addr, 0, access_type,
1660 mmu_idx, true, &host, 0);
4811e909 1661
069cfe77
RH
1662 /* No combination of flags are expected by the caller. */
1663 return flags ? NULL : host;
4811e909
RH
1664}
1665
235537fa
AB
1666#ifdef CONFIG_PLUGIN
1667/*
1668 * Perform a TLB lookup and populate the qemu_plugin_hwaddr structure.
1669 * This should be a hot path as we will have just looked this path up
1670 * in the softmmu lookup code (or helper). We don't handle re-fills or
1671 * checking the victim table. This is purely informational.
1672 *
2f3a57ee
AB
1673 * This almost never fails as the memory access being instrumented
1674 * should have just filled the TLB. The one corner case is io_writex
1675 * which can cause TLB flushes and potential resizing of the TLBs
570ef309
AB
1676 * losing the information we need. In those cases we need to recover
1677 * data from a copy of the iotlbentry. As long as this always occurs
1678 * from the same thread (which a mem callback will be) this is safe.
235537fa
AB
1679 */
1680
1681bool tlb_plugin_lookup(CPUState *cpu, target_ulong addr, int mmu_idx,
1682 bool is_store, struct qemu_plugin_hwaddr *data)
1683{
1684 CPUArchState *env = cpu->env_ptr;
1685 CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
1686 uintptr_t index = tlb_index(env, mmu_idx, addr);
1687 target_ulong tlb_addr = is_store ? tlb_addr_write(tlbe) : tlbe->addr_read;
1688
1689 if (likely(tlb_hit(tlb_addr, addr))) {
1690 /* We must have an iotlb entry for MMIO */
1691 if (tlb_addr & TLB_MMIO) {
1692 CPUIOTLBEntry *iotlbentry;
1693 iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
1694 data->is_io = true;
1695 data->v.io.section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
1696 data->v.io.offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
1697 } else {
1698 data->is_io = false;
1699 data->v.ram.hostaddr = addr + tlbe->addend;
1700 }
1701 return true;
2f3a57ee
AB
1702 } else {
1703 SavedIOTLB *saved = &cpu->saved_iotlb;
1704 data->is_io = true;
1705 data->v.io.section = saved->section;
1706 data->v.io.offset = saved->mr_offset;
1707 return true;
235537fa 1708 }
235537fa
AB
1709}
1710
1711#endif
1712
c482cb11
RH
1713/* Probe for a read-modify-write atomic operation. Do not allow unaligned
1714 * operations, or io operations to proceed. Return the host address. */
1715static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
707526ad 1716 TCGMemOpIdx oi, uintptr_t retaddr)
c482cb11
RH
1717{
1718 size_t mmu_idx = get_mmuidx(oi);
383beda9
RH
1719 uintptr_t index = tlb_index(env, mmu_idx, addr);
1720 CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
403f290c 1721 target_ulong tlb_addr = tlb_addr_write(tlbe);
14776ab5 1722 MemOp mop = get_memop(oi);
c482cb11
RH
1723 int a_bits = get_alignment_bits(mop);
1724 int s_bits = mop & MO_SIZE;
34d49937 1725 void *hostaddr;
c482cb11
RH
1726
1727 /* Adjust the given return address. */
1728 retaddr -= GETPC_ADJ;
1729
1730 /* Enforce guest required alignment. */
1731 if (unlikely(a_bits > 0 && (addr & ((1 << a_bits) - 1)))) {
1732 /* ??? Maybe indicate atomic op to cpu_unaligned_access */
29a0af61 1733 cpu_unaligned_access(env_cpu(env), addr, MMU_DATA_STORE,
c482cb11
RH
1734 mmu_idx, retaddr);
1735 }
1736
1737 /* Enforce qemu required alignment. */
1738 if (unlikely(addr & ((1 << s_bits) - 1))) {
1739 /* We get here if guest alignment was not requested,
1740 or was not enforced by cpu_unaligned_access above.
1741 We might widen the access and emulate, but for now
1742 mark an exception and exit the cpu loop. */
1743 goto stop_the_world;
1744 }
1745
1746 /* Check TLB entry and enforce page permissions. */
334692bc 1747 if (!tlb_hit(tlb_addr, addr)) {
c482cb11 1748 if (!VICTIM_TLB_HIT(addr_write, addr)) {
29a0af61 1749 tlb_fill(env_cpu(env), addr, 1 << s_bits, MMU_DATA_STORE,
98670d47 1750 mmu_idx, retaddr);
6d967cb8
EC
1751 index = tlb_index(env, mmu_idx, addr);
1752 tlbe = tlb_entry(env, mmu_idx, addr);
c482cb11 1753 }
403f290c 1754 tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
c482cb11
RH
1755 }
1756
55df6fcf 1757 /* Notice an IO access or a needs-MMU-lookup access */
30d7e098 1758 if (unlikely(tlb_addr & TLB_MMIO)) {
c482cb11
RH
1759 /* There's really nothing that can be done to
1760 support this apart from stop-the-world. */
1761 goto stop_the_world;
1762 }
1763
1764 /* Let the guest notice RMW on a write-only page. */
34d49937 1765 if (unlikely(tlbe->addr_read != (tlb_addr & ~TLB_NOTDIRTY))) {
29a0af61 1766 tlb_fill(env_cpu(env), addr, 1 << s_bits, MMU_DATA_LOAD,
98670d47 1767 mmu_idx, retaddr);
c482cb11
RH
1768 /* Since we don't support reads and writes to different addresses,
1769 and we do have the proper page loaded for write, this shouldn't
1770 ever return. But just in case, handle via stop-the-world. */
1771 goto stop_the_world;
1772 }
1773
34d49937
PM
1774 hostaddr = (void *)((uintptr_t)addr + tlbe->addend);
1775
34d49937 1776 if (unlikely(tlb_addr & TLB_NOTDIRTY)) {
707526ad
RH
1777 notdirty_write(env_cpu(env), addr, 1 << s_bits,
1778 &env_tlb(env)->d[mmu_idx].iotlb[index], retaddr);
34d49937
PM
1779 }
1780
1781 return hostaddr;
c482cb11
RH
1782
1783 stop_the_world:
29a0af61 1784 cpu_loop_exit_atomic(env_cpu(env), retaddr);
c482cb11
RH
1785}
1786
eed56642
AB
1787/*
1788 * Load Helpers
1789 *
1790 * We support two different access types. SOFTMMU_CODE_ACCESS is
1791 * specifically for reading instructions from system memory. It is
1792 * called by the translation loop and in some helpers where the code
1793 * is disassembled. It shouldn't be called directly by guest code.
1794 */
0f590e74 1795
2dd92606
RH
1796typedef uint64_t FullLoadHelper(CPUArchState *env, target_ulong addr,
1797 TCGMemOpIdx oi, uintptr_t retaddr);
1798
80d9d1c6
RH
1799static inline uint64_t QEMU_ALWAYS_INLINE
1800load_memop(const void *haddr, MemOp op)
1801{
1802 switch (op) {
1803 case MO_UB:
1804 return ldub_p(haddr);
1805 case MO_BEUW:
1806 return lduw_be_p(haddr);
1807 case MO_LEUW:
1808 return lduw_le_p(haddr);
1809 case MO_BEUL:
1810 return (uint32_t)ldl_be_p(haddr);
1811 case MO_LEUL:
1812 return (uint32_t)ldl_le_p(haddr);
1813 case MO_BEQ:
1814 return ldq_be_p(haddr);
1815 case MO_LEQ:
1816 return ldq_le_p(haddr);
1817 default:
1818 qemu_build_not_reached();
1819 }
1820}
1821
c6b716cd 1822static inline uint64_t QEMU_ALWAYS_INLINE
2dd92606 1823load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
be5c4787 1824 uintptr_t retaddr, MemOp op, bool code_read,
2dd92606 1825 FullLoadHelper *full_load)
eed56642
AB
1826{
1827 uintptr_t mmu_idx = get_mmuidx(oi);
1828 uintptr_t index = tlb_index(env, mmu_idx, addr);
1829 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
1830 target_ulong tlb_addr = code_read ? entry->addr_code : entry->addr_read;
1831 const size_t tlb_off = code_read ?
1832 offsetof(CPUTLBEntry, addr_code) : offsetof(CPUTLBEntry, addr_read);
f1be3696
RH
1833 const MMUAccessType access_type =
1834 code_read ? MMU_INST_FETCH : MMU_DATA_LOAD;
eed56642
AB
1835 unsigned a_bits = get_alignment_bits(get_memop(oi));
1836 void *haddr;
1837 uint64_t res;
be5c4787 1838 size_t size = memop_size(op);
eed56642
AB
1839
1840 /* Handle CPU specific unaligned behaviour */
1841 if (addr & ((1 << a_bits) - 1)) {
29a0af61 1842 cpu_unaligned_access(env_cpu(env), addr, access_type,
eed56642
AB
1843 mmu_idx, retaddr);
1844 }
0f590e74 1845
eed56642
AB
1846 /* If the TLB entry is for a different page, reload and try again. */
1847 if (!tlb_hit(tlb_addr, addr)) {
1848 if (!victim_tlb_hit(env, mmu_idx, index, tlb_off,
1849 addr & TARGET_PAGE_MASK)) {
29a0af61 1850 tlb_fill(env_cpu(env), addr, size,
f1be3696 1851 access_type, mmu_idx, retaddr);
eed56642
AB
1852 index = tlb_index(env, mmu_idx, addr);
1853 entry = tlb_entry(env, mmu_idx, addr);
1854 }
1855 tlb_addr = code_read ? entry->addr_code : entry->addr_read;
30d7e098 1856 tlb_addr &= ~TLB_INVALID_MASK;
eed56642
AB
1857 }
1858
50b107c5 1859 /* Handle anything that isn't just a straight memory access. */
eed56642 1860 if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
50b107c5 1861 CPUIOTLBEntry *iotlbentry;
5b87b3e6 1862 bool need_swap;
50b107c5
RH
1863
1864 /* For anything that is unaligned, recurse through full_load. */
eed56642
AB
1865 if ((addr & (size - 1)) != 0) {
1866 goto do_unaligned_access;
1867 }
50b107c5
RH
1868
1869 iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
1870
1871 /* Handle watchpoints. */
1872 if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
1873 /* On watchpoint hit, this will longjmp out. */
1874 cpu_check_watchpoint(env_cpu(env), addr, size,
1875 iotlbentry->attrs, BP_MEM_READ, retaddr);
50b107c5
RH
1876 }
1877
5b87b3e6
RH
1878 need_swap = size > 1 && (tlb_addr & TLB_BSWAP);
1879
50b107c5 1880 /* Handle I/O access. */
5b87b3e6
RH
1881 if (likely(tlb_addr & TLB_MMIO)) {
1882 return io_readx(env, iotlbentry, mmu_idx, addr, retaddr,
1883 access_type, op ^ (need_swap * MO_BSWAP));
1884 }
1885
1886 haddr = (void *)((uintptr_t)addr + entry->addend);
1887
1888 /*
1889 * Keep these two load_memop separate to ensure that the compiler
1890 * is able to fold the entire function to a single instruction.
1891 * There is a build-time assert inside to remind you of this. ;-)
1892 */
1893 if (unlikely(need_swap)) {
1894 return load_memop(haddr, op ^ MO_BSWAP);
1895 }
1896 return load_memop(haddr, op);
eed56642
AB
1897 }
1898
1899 /* Handle slow unaligned access (it spans two pages or IO). */
1900 if (size > 1
1901 && unlikely((addr & ~TARGET_PAGE_MASK) + size - 1
1902 >= TARGET_PAGE_SIZE)) {
1903 target_ulong addr1, addr2;
8c79b288 1904 uint64_t r1, r2;
eed56642
AB
1905 unsigned shift;
1906 do_unaligned_access:
ab7a2009 1907 addr1 = addr & ~((target_ulong)size - 1);
eed56642 1908 addr2 = addr1 + size;
2dd92606
RH
1909 r1 = full_load(env, addr1, oi, retaddr);
1910 r2 = full_load(env, addr2, oi, retaddr);
eed56642
AB
1911 shift = (addr & (size - 1)) * 8;
1912
be5c4787 1913 if (memop_big_endian(op)) {
eed56642
AB
1914 /* Big-endian combine. */
1915 res = (r1 << shift) | (r2 >> ((size * 8) - shift));
1916 } else {
1917 /* Little-endian combine. */
1918 res = (r1 >> shift) | (r2 << ((size * 8) - shift));
1919 }
1920 return res & MAKE_64BIT_MASK(0, size * 8);
1921 }
1922
1923 haddr = (void *)((uintptr_t)addr + entry->addend);
80d9d1c6 1924 return load_memop(haddr, op);
eed56642
AB
1925}
1926
1927/*
1928 * For the benefit of TCG generated code, we want to avoid the
1929 * complication of ABI-specific return type promotion and always
1930 * return a value extended to the register size of the host. This is
1931 * tcg_target_long, except in the case of a 32-bit host and 64-bit
1932 * data, and for that we always have uint64_t.
1933 *
1934 * We don't bother with this widened value for SOFTMMU_CODE_ACCESS.
1935 */
1936
2dd92606
RH
1937static uint64_t full_ldub_mmu(CPUArchState *env, target_ulong addr,
1938 TCGMemOpIdx oi, uintptr_t retaddr)
1939{
be5c4787 1940 return load_helper(env, addr, oi, retaddr, MO_UB, false, full_ldub_mmu);
2dd92606
RH
1941}
1942
fc1bc777
RH
1943tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
1944 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 1945{
2dd92606
RH
1946 return full_ldub_mmu(env, addr, oi, retaddr);
1947}
1948
1949static uint64_t full_le_lduw_mmu(CPUArchState *env, target_ulong addr,
1950 TCGMemOpIdx oi, uintptr_t retaddr)
1951{
be5c4787 1952 return load_helper(env, addr, oi, retaddr, MO_LEUW, false,
2dd92606 1953 full_le_lduw_mmu);
eed56642
AB
1954}
1955
fc1bc777
RH
1956tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
1957 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 1958{
2dd92606
RH
1959 return full_le_lduw_mmu(env, addr, oi, retaddr);
1960}
1961
1962static uint64_t full_be_lduw_mmu(CPUArchState *env, target_ulong addr,
1963 TCGMemOpIdx oi, uintptr_t retaddr)
1964{
be5c4787 1965 return load_helper(env, addr, oi, retaddr, MO_BEUW, false,
2dd92606 1966 full_be_lduw_mmu);
eed56642
AB
1967}
1968
fc1bc777
RH
1969tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
1970 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 1971{
2dd92606
RH
1972 return full_be_lduw_mmu(env, addr, oi, retaddr);
1973}
1974
1975static uint64_t full_le_ldul_mmu(CPUArchState *env, target_ulong addr,
1976 TCGMemOpIdx oi, uintptr_t retaddr)
1977{
be5c4787 1978 return load_helper(env, addr, oi, retaddr, MO_LEUL, false,
2dd92606 1979 full_le_ldul_mmu);
eed56642
AB
1980}
1981
fc1bc777
RH
1982tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
1983 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 1984{
2dd92606
RH
1985 return full_le_ldul_mmu(env, addr, oi, retaddr);
1986}
1987
1988static uint64_t full_be_ldul_mmu(CPUArchState *env, target_ulong addr,
1989 TCGMemOpIdx oi, uintptr_t retaddr)
1990{
be5c4787 1991 return load_helper(env, addr, oi, retaddr, MO_BEUL, false,
2dd92606 1992 full_be_ldul_mmu);
eed56642
AB
1993}
1994
fc1bc777
RH
1995tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
1996 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 1997{
2dd92606 1998 return full_be_ldul_mmu(env, addr, oi, retaddr);
eed56642
AB
1999}
2000
fc1bc777
RH
2001uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
2002 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2003{
be5c4787 2004 return load_helper(env, addr, oi, retaddr, MO_LEQ, false,
2dd92606 2005 helper_le_ldq_mmu);
eed56642
AB
2006}
2007
fc1bc777
RH
2008uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
2009 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2010{
be5c4787 2011 return load_helper(env, addr, oi, retaddr, MO_BEQ, false,
2dd92606 2012 helper_be_ldq_mmu);
eed56642
AB
2013}
2014
2015/*
2016 * Provide signed versions of the load routines as well. We can of course
2017 * avoid this for 64-bit data, or for 32-bit data on 32-bit host.
2018 */
2019
2020
2021tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
2022 TCGMemOpIdx oi, uintptr_t retaddr)
2023{
2024 return (int8_t)helper_ret_ldub_mmu(env, addr, oi, retaddr);
2025}
2026
2027tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
2028 TCGMemOpIdx oi, uintptr_t retaddr)
2029{
2030 return (int16_t)helper_le_lduw_mmu(env, addr, oi, retaddr);
2031}
2032
2033tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
2034 TCGMemOpIdx oi, uintptr_t retaddr)
2035{
2036 return (int16_t)helper_be_lduw_mmu(env, addr, oi, retaddr);
2037}
2038
2039tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
2040 TCGMemOpIdx oi, uintptr_t retaddr)
2041{
2042 return (int32_t)helper_le_ldul_mmu(env, addr, oi, retaddr);
2043}
2044
2045tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
2046 TCGMemOpIdx oi, uintptr_t retaddr)
2047{
2048 return (int32_t)helper_be_ldul_mmu(env, addr, oi, retaddr);
2049}
2050
d03f1408
RH
2051/*
2052 * Load helpers for cpu_ldst.h.
2053 */
2054
2055static inline uint64_t cpu_load_helper(CPUArchState *env, abi_ptr addr,
2056 int mmu_idx, uintptr_t retaddr,
2057 MemOp op, FullLoadHelper *full_load)
2058{
2059 uint16_t meminfo;
2060 TCGMemOpIdx oi;
2061 uint64_t ret;
2062
2063 meminfo = trace_mem_get_info(op, mmu_idx, false);
2064 trace_guest_mem_before_exec(env_cpu(env), addr, meminfo);
2065
2066 op &= ~MO_SIGN;
2067 oi = make_memop_idx(op, mmu_idx);
2068 ret = full_load(env, addr, oi, retaddr);
2069
2070 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, meminfo);
2071
2072 return ret;
2073}
2074
2075uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2076 int mmu_idx, uintptr_t ra)
2077{
2078 return cpu_load_helper(env, addr, mmu_idx, ra, MO_UB, full_ldub_mmu);
2079}
2080
2081int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2082 int mmu_idx, uintptr_t ra)
2083{
2084 return (int8_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_SB,
2085 full_ldub_mmu);
2086}
2087
b9e60257
RH
2088uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2089 int mmu_idx, uintptr_t ra)
d03f1408 2090{
b9e60257 2091 return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUW, full_be_lduw_mmu);
d03f1408
RH
2092}
2093
b9e60257
RH
2094int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2095 int mmu_idx, uintptr_t ra)
2096{
2097 return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_BESW,
2098 full_be_lduw_mmu);
2099}
2100
2101uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2102 int mmu_idx, uintptr_t ra)
2103{
2104 return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUL, full_be_ldul_mmu);
2105}
2106
2107uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2108 int mmu_idx, uintptr_t ra)
2109{
2110 return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEQ, helper_be_ldq_mmu);
2111}
2112
2113uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2114 int mmu_idx, uintptr_t ra)
2115{
2116 return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUW, full_le_lduw_mmu);
2117}
2118
2119int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2120 int mmu_idx, uintptr_t ra)
d03f1408 2121{
b9e60257
RH
2122 return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_LESW,
2123 full_le_lduw_mmu);
d03f1408
RH
2124}
2125
b9e60257
RH
2126uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2127 int mmu_idx, uintptr_t ra)
d03f1408 2128{
b9e60257 2129 return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUL, full_le_ldul_mmu);
d03f1408
RH
2130}
2131
b9e60257
RH
2132uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
2133 int mmu_idx, uintptr_t ra)
d03f1408 2134{
b9e60257 2135 return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEQ, helper_le_ldq_mmu);
d03f1408
RH
2136}
2137
cfe04a4b
RH
2138uint32_t cpu_ldub_data_ra(CPUArchState *env, target_ulong ptr,
2139 uintptr_t retaddr)
2140{
2141 return cpu_ldub_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
2142}
2143
2144int cpu_ldsb_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
2145{
2146 return cpu_ldsb_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
2147}
2148
b9e60257
RH
2149uint32_t cpu_lduw_be_data_ra(CPUArchState *env, target_ulong ptr,
2150 uintptr_t retaddr)
2151{
2152 return cpu_lduw_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
2153}
2154
2155int cpu_ldsw_be_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
cfe04a4b 2156{
b9e60257 2157 return cpu_ldsw_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2158}
2159
b9e60257
RH
2160uint32_t cpu_ldl_be_data_ra(CPUArchState *env, target_ulong ptr,
2161 uintptr_t retaddr)
cfe04a4b 2162{
b9e60257 2163 return cpu_ldl_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2164}
2165
b9e60257
RH
2166uint64_t cpu_ldq_be_data_ra(CPUArchState *env, target_ulong ptr,
2167 uintptr_t retaddr)
cfe04a4b 2168{
b9e60257 2169 return cpu_ldq_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2170}
2171
b9e60257
RH
2172uint32_t cpu_lduw_le_data_ra(CPUArchState *env, target_ulong ptr,
2173 uintptr_t retaddr)
cfe04a4b 2174{
b9e60257
RH
2175 return cpu_lduw_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
2176}
2177
2178int cpu_ldsw_le_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
2179{
2180 return cpu_ldsw_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
2181}
2182
2183uint32_t cpu_ldl_le_data_ra(CPUArchState *env, target_ulong ptr,
2184 uintptr_t retaddr)
2185{
2186 return cpu_ldl_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
2187}
2188
2189uint64_t cpu_ldq_le_data_ra(CPUArchState *env, target_ulong ptr,
2190 uintptr_t retaddr)
2191{
2192 return cpu_ldq_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2193}
2194
2195uint32_t cpu_ldub_data(CPUArchState *env, target_ulong ptr)
2196{
2197 return cpu_ldub_data_ra(env, ptr, 0);
2198}
2199
2200int cpu_ldsb_data(CPUArchState *env, target_ulong ptr)
2201{
2202 return cpu_ldsb_data_ra(env, ptr, 0);
2203}
2204
b9e60257
RH
2205uint32_t cpu_lduw_be_data(CPUArchState *env, target_ulong ptr)
2206{
2207 return cpu_lduw_be_data_ra(env, ptr, 0);
2208}
2209
2210int cpu_ldsw_be_data(CPUArchState *env, target_ulong ptr)
2211{
2212 return cpu_ldsw_be_data_ra(env, ptr, 0);
2213}
2214
2215uint32_t cpu_ldl_be_data(CPUArchState *env, target_ulong ptr)
2216{
2217 return cpu_ldl_be_data_ra(env, ptr, 0);
2218}
2219
2220uint64_t cpu_ldq_be_data(CPUArchState *env, target_ulong ptr)
cfe04a4b 2221{
b9e60257 2222 return cpu_ldq_be_data_ra(env, ptr, 0);
cfe04a4b
RH
2223}
2224
b9e60257 2225uint32_t cpu_lduw_le_data(CPUArchState *env, target_ulong ptr)
cfe04a4b 2226{
b9e60257 2227 return cpu_lduw_le_data_ra(env, ptr, 0);
cfe04a4b
RH
2228}
2229
b9e60257 2230int cpu_ldsw_le_data(CPUArchState *env, target_ulong ptr)
cfe04a4b 2231{
b9e60257 2232 return cpu_ldsw_le_data_ra(env, ptr, 0);
cfe04a4b
RH
2233}
2234
b9e60257 2235uint32_t cpu_ldl_le_data(CPUArchState *env, target_ulong ptr)
cfe04a4b 2236{
b9e60257
RH
2237 return cpu_ldl_le_data_ra(env, ptr, 0);
2238}
2239
2240uint64_t cpu_ldq_le_data(CPUArchState *env, target_ulong ptr)
2241{
2242 return cpu_ldq_le_data_ra(env, ptr, 0);
cfe04a4b
RH
2243}
2244
eed56642
AB
2245/*
2246 * Store Helpers
2247 */
2248
80d9d1c6
RH
2249static inline void QEMU_ALWAYS_INLINE
2250store_memop(void *haddr, uint64_t val, MemOp op)
2251{
2252 switch (op) {
2253 case MO_UB:
2254 stb_p(haddr, val);
2255 break;
2256 case MO_BEUW:
2257 stw_be_p(haddr, val);
2258 break;
2259 case MO_LEUW:
2260 stw_le_p(haddr, val);
2261 break;
2262 case MO_BEUL:
2263 stl_be_p(haddr, val);
2264 break;
2265 case MO_LEUL:
2266 stl_le_p(haddr, val);
2267 break;
2268 case MO_BEQ:
2269 stq_be_p(haddr, val);
2270 break;
2271 case MO_LEQ:
2272 stq_le_p(haddr, val);
2273 break;
2274 default:
2275 qemu_build_not_reached();
2276 }
2277}
2278
6b8b622e
RH
2279static void __attribute__((noinline))
2280store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
2281 uintptr_t retaddr, size_t size, uintptr_t mmu_idx,
2282 bool big_endian)
2283{
2284 const size_t tlb_off = offsetof(CPUTLBEntry, addr_write);
2285 uintptr_t index, index2;
2286 CPUTLBEntry *entry, *entry2;
2287 target_ulong page2, tlb_addr, tlb_addr2;
2288 TCGMemOpIdx oi;
2289 size_t size2;
2290 int i;
2291
2292 /*
2293 * Ensure the second page is in the TLB. Note that the first page
2294 * is already guaranteed to be filled, and that the second page
2295 * cannot evict the first.
2296 */
2297 page2 = (addr + size) & TARGET_PAGE_MASK;
2298 size2 = (addr + size) & ~TARGET_PAGE_MASK;
2299 index2 = tlb_index(env, mmu_idx, page2);
2300 entry2 = tlb_entry(env, mmu_idx, page2);
2301
2302 tlb_addr2 = tlb_addr_write(entry2);
2303 if (!tlb_hit_page(tlb_addr2, page2)) {
2304 if (!victim_tlb_hit(env, mmu_idx, index2, tlb_off, page2)) {
2305 tlb_fill(env_cpu(env), page2, size2, MMU_DATA_STORE,
2306 mmu_idx, retaddr);
2307 index2 = tlb_index(env, mmu_idx, page2);
2308 entry2 = tlb_entry(env, mmu_idx, page2);
2309 }
2310 tlb_addr2 = tlb_addr_write(entry2);
2311 }
2312
2313 index = tlb_index(env, mmu_idx, addr);
2314 entry = tlb_entry(env, mmu_idx, addr);
2315 tlb_addr = tlb_addr_write(entry);
2316
2317 /*
2318 * Handle watchpoints. Since this may trap, all checks
2319 * must happen before any store.
2320 */
2321 if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
2322 cpu_check_watchpoint(env_cpu(env), addr, size - size2,
2323 env_tlb(env)->d[mmu_idx].iotlb[index].attrs,
2324 BP_MEM_WRITE, retaddr);
2325 }
2326 if (unlikely(tlb_addr2 & TLB_WATCHPOINT)) {
2327 cpu_check_watchpoint(env_cpu(env), page2, size2,
2328 env_tlb(env)->d[mmu_idx].iotlb[index2].attrs,
2329 BP_MEM_WRITE, retaddr);
2330 }
2331
2332 /*
2333 * XXX: not efficient, but simple.
2334 * This loop must go in the forward direction to avoid issues
2335 * with self-modifying code in Windows 64-bit.
2336 */
2337 oi = make_memop_idx(MO_UB, mmu_idx);
2338 if (big_endian) {
2339 for (i = 0; i < size; ++i) {
2340 /* Big-endian extract. */
2341 uint8_t val8 = val >> (((size - 1) * 8) - (i * 8));
2342 helper_ret_stb_mmu(env, addr + i, val8, oi, retaddr);
2343 }
2344 } else {
2345 for (i = 0; i < size; ++i) {
2346 /* Little-endian extract. */
2347 uint8_t val8 = val >> (i * 8);
2348 helper_ret_stb_mmu(env, addr + i, val8, oi, retaddr);
2349 }
2350 }
2351}
2352
c6b716cd 2353static inline void QEMU_ALWAYS_INLINE
4601f8d1 2354store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
be5c4787 2355 TCGMemOpIdx oi, uintptr_t retaddr, MemOp op)
eed56642
AB
2356{
2357 uintptr_t mmu_idx = get_mmuidx(oi);
2358 uintptr_t index = tlb_index(env, mmu_idx, addr);
2359 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
2360 target_ulong tlb_addr = tlb_addr_write(entry);
2361 const size_t tlb_off = offsetof(CPUTLBEntry, addr_write);
2362 unsigned a_bits = get_alignment_bits(get_memop(oi));
2363 void *haddr;
be5c4787 2364 size_t size = memop_size(op);
eed56642
AB
2365
2366 /* Handle CPU specific unaligned behaviour */
2367 if (addr & ((1 << a_bits) - 1)) {
29a0af61 2368 cpu_unaligned_access(env_cpu(env), addr, MMU_DATA_STORE,
eed56642
AB
2369 mmu_idx, retaddr);
2370 }
2371
2372 /* If the TLB entry is for a different page, reload and try again. */
2373 if (!tlb_hit(tlb_addr, addr)) {
2374 if (!victim_tlb_hit(env, mmu_idx, index, tlb_off,
2375 addr & TARGET_PAGE_MASK)) {
29a0af61 2376 tlb_fill(env_cpu(env), addr, size, MMU_DATA_STORE,
eed56642
AB
2377 mmu_idx, retaddr);
2378 index = tlb_index(env, mmu_idx, addr);
2379 entry = tlb_entry(env, mmu_idx, addr);
2380 }
2381 tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
2382 }
2383
50b107c5 2384 /* Handle anything that isn't just a straight memory access. */
eed56642 2385 if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
50b107c5 2386 CPUIOTLBEntry *iotlbentry;
5b87b3e6 2387 bool need_swap;
50b107c5
RH
2388
2389 /* For anything that is unaligned, recurse through byte stores. */
eed56642
AB
2390 if ((addr & (size - 1)) != 0) {
2391 goto do_unaligned_access;
2392 }
50b107c5
RH
2393
2394 iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
2395
2396 /* Handle watchpoints. */
2397 if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
2398 /* On watchpoint hit, this will longjmp out. */
2399 cpu_check_watchpoint(env_cpu(env), addr, size,
2400 iotlbentry->attrs, BP_MEM_WRITE, retaddr);
50b107c5
RH
2401 }
2402
5b87b3e6
RH
2403 need_swap = size > 1 && (tlb_addr & TLB_BSWAP);
2404
50b107c5 2405 /* Handle I/O access. */
08565552 2406 if (tlb_addr & TLB_MMIO) {
5b87b3e6
RH
2407 io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
2408 op ^ (need_swap * MO_BSWAP));
2409 return;
2410 }
2411
7b0d792c
RH
2412 /* Ignore writes to ROM. */
2413 if (unlikely(tlb_addr & TLB_DISCARD_WRITE)) {
2414 return;
2415 }
2416
08565552
RH
2417 /* Handle clean RAM pages. */
2418 if (tlb_addr & TLB_NOTDIRTY) {
707526ad 2419 notdirty_write(env_cpu(env), addr, size, iotlbentry, retaddr);
08565552
RH
2420 }
2421
707526ad
RH
2422 haddr = (void *)((uintptr_t)addr + entry->addend);
2423
5b87b3e6
RH
2424 /*
2425 * Keep these two store_memop separate to ensure that the compiler
2426 * is able to fold the entire function to a single instruction.
2427 * There is a build-time assert inside to remind you of this. ;-)
2428 */
2429 if (unlikely(need_swap)) {
2430 store_memop(haddr, val, op ^ MO_BSWAP);
2431 } else {
2432 store_memop(haddr, val, op);
2433 }
eed56642
AB
2434 return;
2435 }
2436
2437 /* Handle slow unaligned access (it spans two pages or IO). */
2438 if (size > 1
2439 && unlikely((addr & ~TARGET_PAGE_MASK) + size - 1
2440 >= TARGET_PAGE_SIZE)) {
eed56642 2441 do_unaligned_access:
6b8b622e
RH
2442 store_helper_unaligned(env, addr, val, retaddr, size,
2443 mmu_idx, memop_big_endian(op));
eed56642
AB
2444 return;
2445 }
2446
2447 haddr = (void *)((uintptr_t)addr + entry->addend);
80d9d1c6 2448 store_memop(haddr, val, op);
eed56642
AB
2449}
2450
6b8b622e
RH
2451void __attribute__((noinline))
2452helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
2453 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2454{
be5c4787 2455 store_helper(env, addr, val, oi, retaddr, MO_UB);
eed56642
AB
2456}
2457
fc1bc777
RH
2458void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
2459 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2460{
be5c4787 2461 store_helper(env, addr, val, oi, retaddr, MO_LEUW);
eed56642
AB
2462}
2463
fc1bc777
RH
2464void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
2465 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2466{
be5c4787 2467 store_helper(env, addr, val, oi, retaddr, MO_BEUW);
eed56642
AB
2468}
2469
fc1bc777
RH
2470void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
2471 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2472{
be5c4787 2473 store_helper(env, addr, val, oi, retaddr, MO_LEUL);
eed56642
AB
2474}
2475
fc1bc777
RH
2476void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
2477 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2478{
be5c4787 2479 store_helper(env, addr, val, oi, retaddr, MO_BEUL);
eed56642
AB
2480}
2481
fc1bc777
RH
2482void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
2483 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2484{
be5c4787 2485 store_helper(env, addr, val, oi, retaddr, MO_LEQ);
eed56642
AB
2486}
2487
fc1bc777
RH
2488void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
2489 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2490{
be5c4787 2491 store_helper(env, addr, val, oi, retaddr, MO_BEQ);
eed56642 2492}
0f590e74 2493
d03f1408
RH
2494/*
2495 * Store Helpers for cpu_ldst.h
2496 */
2497
2498static inline void QEMU_ALWAYS_INLINE
2499cpu_store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
2500 int mmu_idx, uintptr_t retaddr, MemOp op)
2501{
2502 TCGMemOpIdx oi;
2503 uint16_t meminfo;
2504
2505 meminfo = trace_mem_get_info(op, mmu_idx, true);
2506 trace_guest_mem_before_exec(env_cpu(env), addr, meminfo);
2507
2508 oi = make_memop_idx(op, mmu_idx);
2509 store_helper(env, addr, val, oi, retaddr, op);
2510
2511 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, meminfo);
2512}
2513
2514void cpu_stb_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
2515 int mmu_idx, uintptr_t retaddr)
2516{
2517 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_UB);
2518}
2519
b9e60257
RH
2520void cpu_stw_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
2521 int mmu_idx, uintptr_t retaddr)
d03f1408 2522{
b9e60257 2523 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEUW);
d03f1408
RH
2524}
2525
b9e60257
RH
2526void cpu_stl_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
2527 int mmu_idx, uintptr_t retaddr)
d03f1408 2528{
b9e60257 2529 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEUL);
d03f1408
RH
2530}
2531
b9e60257
RH
2532void cpu_stq_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
2533 int mmu_idx, uintptr_t retaddr)
2534{
2535 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEQ);
2536}
2537
2538void cpu_stw_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
2539 int mmu_idx, uintptr_t retaddr)
d03f1408 2540{
b9e60257
RH
2541 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEUW);
2542}
2543
2544void cpu_stl_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
2545 int mmu_idx, uintptr_t retaddr)
2546{
2547 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEUL);
2548}
2549
2550void cpu_stq_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
2551 int mmu_idx, uintptr_t retaddr)
2552{
2553 cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEQ);
d03f1408
RH
2554}
2555
cfe04a4b
RH
2556void cpu_stb_data_ra(CPUArchState *env, target_ulong ptr,
2557 uint32_t val, uintptr_t retaddr)
2558{
2559 cpu_stb_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
2560}
2561
b9e60257
RH
2562void cpu_stw_be_data_ra(CPUArchState *env, target_ulong ptr,
2563 uint32_t val, uintptr_t retaddr)
cfe04a4b 2564{
b9e60257 2565 cpu_stw_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2566}
2567
b9e60257
RH
2568void cpu_stl_be_data_ra(CPUArchState *env, target_ulong ptr,
2569 uint32_t val, uintptr_t retaddr)
cfe04a4b 2570{
b9e60257 2571 cpu_stl_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2572}
2573
b9e60257
RH
2574void cpu_stq_be_data_ra(CPUArchState *env, target_ulong ptr,
2575 uint64_t val, uintptr_t retaddr)
cfe04a4b 2576{
b9e60257
RH
2577 cpu_stq_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
2578}
2579
2580void cpu_stw_le_data_ra(CPUArchState *env, target_ulong ptr,
2581 uint32_t val, uintptr_t retaddr)
2582{
2583 cpu_stw_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
2584}
2585
2586void cpu_stl_le_data_ra(CPUArchState *env, target_ulong ptr,
2587 uint32_t val, uintptr_t retaddr)
2588{
2589 cpu_stl_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
2590}
2591
2592void cpu_stq_le_data_ra(CPUArchState *env, target_ulong ptr,
2593 uint64_t val, uintptr_t retaddr)
2594{
2595 cpu_stq_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
cfe04a4b
RH
2596}
2597
2598void cpu_stb_data(CPUArchState *env, target_ulong ptr, uint32_t val)
2599{
2600 cpu_stb_data_ra(env, ptr, val, 0);
2601}
2602
b9e60257
RH
2603void cpu_stw_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
2604{
2605 cpu_stw_be_data_ra(env, ptr, val, 0);
2606}
2607
2608void cpu_stl_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
2609{
2610 cpu_stl_be_data_ra(env, ptr, val, 0);
2611}
2612
2613void cpu_stq_be_data(CPUArchState *env, target_ulong ptr, uint64_t val)
2614{
2615 cpu_stq_be_data_ra(env, ptr, val, 0);
2616}
2617
2618void cpu_stw_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
cfe04a4b 2619{
b9e60257 2620 cpu_stw_le_data_ra(env, ptr, val, 0);
cfe04a4b
RH
2621}
2622
b9e60257 2623void cpu_stl_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
cfe04a4b 2624{
b9e60257 2625 cpu_stl_le_data_ra(env, ptr, val, 0);
cfe04a4b
RH
2626}
2627
b9e60257 2628void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
cfe04a4b 2629{
b9e60257 2630 cpu_stq_le_data_ra(env, ptr, val, 0);
cfe04a4b
RH
2631}
2632
c482cb11
RH
2633/* First set of helpers allows passing in of OI and RETADDR. This makes
2634 them callable from other helpers. */
2635
2636#define EXTRA_ARGS , TCGMemOpIdx oi, uintptr_t retaddr
2637#define ATOMIC_NAME(X) \
2638 HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu))
707526ad
RH
2639#define ATOMIC_MMU_DECLS
2640#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, oi, retaddr)
2641#define ATOMIC_MMU_CLEANUP
504f73f7 2642#define ATOMIC_MMU_IDX get_mmuidx(oi)
c482cb11 2643
139c1837 2644#include "atomic_common.c.inc"
c482cb11
RH
2645
2646#define DATA_SIZE 1
2647#include "atomic_template.h"
2648
2649#define DATA_SIZE 2
2650#include "atomic_template.h"
2651
2652#define DATA_SIZE 4
2653#include "atomic_template.h"
2654
df79b996 2655#ifdef CONFIG_ATOMIC64
c482cb11
RH
2656#define DATA_SIZE 8
2657#include "atomic_template.h"
df79b996 2658#endif
c482cb11 2659
e6cd4bb5 2660#if HAVE_CMPXCHG128 || HAVE_ATOMIC128
7ebee43e
RH
2661#define DATA_SIZE 16
2662#include "atomic_template.h"
2663#endif
2664
c482cb11
RH
2665/* Second set of helpers are directly callable from TCG as helpers. */
2666
2667#undef EXTRA_ARGS
2668#undef ATOMIC_NAME
2669#undef ATOMIC_MMU_LOOKUP
2670#define EXTRA_ARGS , TCGMemOpIdx oi
2671#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
707526ad 2672#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, oi, GETPC())
c482cb11
RH
2673
2674#define DATA_SIZE 1
2675#include "atomic_template.h"
2676
2677#define DATA_SIZE 2
2678#include "atomic_template.h"
2679
2680#define DATA_SIZE 4
2681#include "atomic_template.h"
2682
df79b996 2683#ifdef CONFIG_ATOMIC64
c482cb11
RH
2684#define DATA_SIZE 8
2685#include "atomic_template.h"
df79b996 2686#endif
504f73f7 2687#undef ATOMIC_MMU_IDX
c482cb11
RH
2688
2689/* Code access functions. */
2690
fc4120a3 2691static uint64_t full_ldub_code(CPUArchState *env, target_ulong addr,
2dd92606
RH
2692 TCGMemOpIdx oi, uintptr_t retaddr)
2693{
fc4120a3 2694 return load_helper(env, addr, oi, retaddr, MO_8, true, full_ldub_code);
2dd92606
RH
2695}
2696
fc4120a3 2697uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr)
eed56642 2698{
fc4120a3
RH
2699 TCGMemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(env, true));
2700 return full_ldub_code(env, addr, oi, 0);
2dd92606
RH
2701}
2702
fc4120a3
RH
2703static uint64_t full_lduw_code(CPUArchState *env, target_ulong addr,
2704 TCGMemOpIdx oi, uintptr_t retaddr)
2dd92606 2705{
fc4120a3 2706 return load_helper(env, addr, oi, retaddr, MO_TEUW, true, full_lduw_code);
eed56642 2707}
0cac1b66 2708
fc4120a3 2709uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr)
eed56642 2710{
fc4120a3
RH
2711 TCGMemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(env, true));
2712 return full_lduw_code(env, addr, oi, 0);
2dd92606
RH
2713}
2714
fc4120a3
RH
2715static uint64_t full_ldl_code(CPUArchState *env, target_ulong addr,
2716 TCGMemOpIdx oi, uintptr_t retaddr)
2dd92606 2717{
fc4120a3 2718 return load_helper(env, addr, oi, retaddr, MO_TEUL, true, full_ldl_code);
eed56642 2719}
0cac1b66 2720
fc4120a3 2721uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
eed56642 2722{
fc4120a3
RH
2723 TCGMemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(env, true));
2724 return full_ldl_code(env, addr, oi, 0);
eed56642
AB
2725}
2726
fc4120a3
RH
2727static uint64_t full_ldq_code(CPUArchState *env, target_ulong addr,
2728 TCGMemOpIdx oi, uintptr_t retaddr)
eed56642 2729{
fc4120a3 2730 return load_helper(env, addr, oi, retaddr, MO_TEQ, true, full_ldq_code);
eed56642
AB
2731}
2732
fc4120a3 2733uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
eed56642 2734{
fc4120a3
RH
2735 TCGMemOpIdx oi = make_memop_idx(MO_TEQ, cpu_mmu_index(env, true));
2736 return full_ldq_code(env, addr, oi, 0);
eed56642 2737}