| /* |
| * Internal execution defines for qemu (target specific) |
| * |
| * Copyright (c) 2003 Fabrice Bellard |
| * |
| * SPDX-License-Identifier: LGPL-2.1-or-later |
| */ |
| |
| #ifndef ACCEL_TCG_INTERNAL_TARGET_H |
| #define ACCEL_TCG_INTERNAL_TARGET_H |
| |
| #include "exec/exec-all.h" |
| #include "exec/translate-all.h" |
| |
| /* |
| * Access to the various translations structures need to be serialised |
| * via locks for consistency. In user-mode emulation access to the |
| * memory related structures are protected with mmap_lock. |
| * In !user-mode we use per-page locks. |
| */ |
| #ifdef CONFIG_USER_ONLY |
| #define assert_memory_lock() tcg_debug_assert(have_mmap_lock()) |
| #else |
| #define assert_memory_lock() |
| #endif |
| |
| #if defined(CONFIG_SOFTMMU) && defined(CONFIG_DEBUG_TCG) |
| void assert_no_pages_locked(void); |
| #else |
| static inline void assert_no_pages_locked(void) { } |
| #endif |
| |
| #ifdef CONFIG_USER_ONLY |
| static inline void page_table_config_init(void) { } |
| #else |
| void page_table_config_init(void); |
| #endif |
| |
| #ifdef CONFIG_USER_ONLY |
| /* |
| * For user-only, page_protect sets the page read-only. |
| * Since most execution is already on read-only pages, and we'd need to |
| * account for other TBs on the same page, defer undoing any page protection |
| * until we receive the write fault. |
| */ |
| static inline void tb_lock_page0(tb_page_addr_t p0) |
| { |
| page_protect(p0); |
| } |
| |
| static inline void tb_lock_page1(tb_page_addr_t p0, tb_page_addr_t p1) |
| { |
| page_protect(p1); |
| } |
| |
| static inline void tb_unlock_page1(tb_page_addr_t p0, tb_page_addr_t p1) { } |
| static inline void tb_unlock_pages(TranslationBlock *tb) { } |
| #else |
| void tb_lock_page0(tb_page_addr_t); |
| void tb_lock_page1(tb_page_addr_t, tb_page_addr_t); |
| void tb_unlock_page1(tb_page_addr_t, tb_page_addr_t); |
| void tb_unlock_pages(TranslationBlock *); |
| #endif |
| |
| #ifdef CONFIG_SOFTMMU |
| void tb_invalidate_phys_range_fast(ram_addr_t ram_addr, |
| unsigned size, |
| uintptr_t retaddr); |
| G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); |
| #endif /* CONFIG_SOFTMMU */ |
| |
| TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc, |
| uint64_t cs_base, uint32_t flags, |
| int cflags); |
| void page_init(void); |
| void tb_htable_init(void); |
| void tb_reset_jump(TranslationBlock *tb, int n); |
| TranslationBlock *tb_link_page(TranslationBlock *tb); |
| bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); |
| void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, |
| uintptr_t host_pc); |
| |
| bool tcg_exec_realizefn(CPUState *cpu, Error **errp); |
| void tcg_exec_unrealizefn(CPUState *cpu); |
| |
| /* Return the current PC from CPU, which may be cached in TB. */ |
| static inline vaddr log_pc(CPUState *cpu, const TranslationBlock *tb) |
| { |
| if (tb_cflags(tb) & CF_PCREL) { |
| return cpu->cc->get_pc(cpu); |
| } else { |
| return tb->pc; |
| } |
| } |
| |
| extern bool one_insn_per_tb; |
| |
| /** |
| * tcg_req_mo: |
| * @type: TCGBar |
| * |
| * Filter @type to the barrier that is required for the guest |
| * memory ordering vs the host memory ordering. A non-zero |
| * result indicates that some barrier is required. |
| * |
| * If TCG_GUEST_DEFAULT_MO is not defined, assume that the |
| * guest requires strict ordering. |
| * |
| * This is a macro so that it's constant even without optimization. |
| */ |
| #ifdef TCG_GUEST_DEFAULT_MO |
| # define tcg_req_mo(type) \ |
| ((type) & TCG_GUEST_DEFAULT_MO & ~TCG_TARGET_DEFAULT_MO) |
| #else |
| # define tcg_req_mo(type) ((type) & ~TCG_TARGET_DEFAULT_MO) |
| #endif |
| |
| /** |
| * cpu_req_mo: |
| * @type: TCGBar |
| * |
| * If tcg_req_mo indicates a barrier for @type is required |
| * for the guest memory model, issue a host memory barrier. |
| */ |
| #define cpu_req_mo(type) \ |
| do { \ |
| if (tcg_req_mo(type)) { \ |
| smp_mb(); \ |
| } \ |
| } while (0) |
| |
| #endif /* ACCEL_TCG_INTERNAL_H */ |