diff options
Diffstat (limited to '')
258 files changed, 1598 insertions, 1640 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 9b5e41f616..23174b4ca7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -168,7 +168,7 @@ F: include/exec/helper*.h.inc F: include/exec/helper-info.c.inc F: include/exec/page-protection.h F: include/system/tcg.h -F: include/accel/tcg/cpu-ops.h +F: include/accel/tcg/ F: host/include/*/host/cpuinfo.h F: util/cpuinfo-*.c F: include/tcg/ @@ -493,7 +493,6 @@ M: Richard Henderson <richard.henderson@linaro.org> R: Paolo Bonzini <pbonzini@redhat.com> S: Maintained F: include/exec/cpu*.h -F: include/exec/exec-all.h F: include/exec/target_long.h F: include/qemu/accel.h F: include/system/accel-*.h @@ -852,6 +851,7 @@ F: include/hw/arm/fsl-imx8mp.h F: include/hw/misc/imx8mp_*.h F: include/hw/pci-host/fsl_imx8m_phy.h F: docs/system/arm/imx8mp-evk.rst +F: tests/functional/test_aarch64_imx8mp_evk.py F: tests/qtest/rs5c372-test.c MPS2 / MPS3 diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c index 5375de7bcf..b8b6116bc8 100644 --- a/accel/hvf/hvf-accel-ops.c +++ b/accel/hvf/hvf-accel-ops.c @@ -51,7 +51,6 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "system/address-spaces.h" -#include "exec/exec-all.h" #include "gdbstub/enums.h" #include "hw/boards.h" #include "system/accel-ops.h" diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c index d404e01ade..3fc65d6b23 100644 --- a/accel/hvf/hvf-all.c +++ b/accel/hvf/hvf-all.c @@ -58,8 +58,13 @@ int hvf_sw_breakpoints_active(CPUState *cpu) return !QTAILQ_EMPTY(&hvf_state->hvf_sw_breakpoints); } -int hvf_update_guest_debug(CPUState *cpu) +static void do_hvf_update_guest_debug(CPUState *cpu, run_on_cpu_data arg) { hvf_arch_update_guest_debug(cpu); +} + +int hvf_update_guest_debug(CPUState *cpu) +{ + run_on_cpu(cpu, do_hvf_update_guest_debug, RUN_ON_CPU_NULL); return 0; } diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 87eba83d7d..cc5f362305 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -22,8 +22,8 @@ #include "qapi/error.h" #include "qapi/type-helpers.h" #include "hw/core/cpu.h" -#include "accel/tcg/cpu-ldst.h" #include "accel/tcg/cpu-ops.h" +#include "accel/tcg/helper-retaddr.h" #include "trace.h" #include "disas/disas.h" #include "exec/cpu-common.h" @@ -36,7 +36,6 @@ #include "qemu/rcu.h" #include "exec/log.h" #include "qemu/main-loop.h" -#include "cpu.h" #include "exec/icount.h" #include "exec/replay-core.h" #include "system/tcg.h" @@ -46,7 +45,6 @@ #include "tb-context.h" #include "tb-internal.h" #include "internal-common.h" -#include "internal-target.h" /* -icount align implementation. */ @@ -151,12 +149,9 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) #endif /* CONFIG USER ONLY */ struct tb_desc { - vaddr pc; - uint64_t cs_base; + TCGTBCPUState s; CPUArchState *env; tb_page_addr_t page_addr0; - uint32_t flags; - uint32_t cflags; }; static bool tb_lookup_cmp(const void *p, const void *d) @@ -164,11 +159,11 @@ static bool tb_lookup_cmp(const void *p, const void *d) const TranslationBlock *tb = p; const struct tb_desc *desc = d; - if ((tb_cflags(tb) & CF_PCREL || tb->pc == desc->pc) && + if ((tb_cflags(tb) & CF_PCREL || tb->pc == desc->s.pc) && tb_page_addr0(tb) == desc->page_addr0 && - tb->cs_base == desc->cs_base && - tb->flags == desc->flags && - tb_cflags(tb) == desc->cflags) { + tb->cs_base == desc->s.cs_base && + tb->flags == desc->s.flags && + tb_cflags(tb) == desc->s.cflags) { /* check next page if needed */ tb_page_addr_t tb_phys_page1 = tb_page_addr1(tb); if (tb_phys_page1 == -1) { @@ -186,7 +181,7 @@ static bool tb_lookup_cmp(const void *p, const void *d) * is different for the new TB. Therefore any exception raised * here by the faulting lookup is not premature. */ - virt_page1 = TARGET_PAGE_ALIGN(desc->pc); + virt_page1 = TARGET_PAGE_ALIGN(desc->s.pc); phys_page1 = get_page_addr_code(desc->env, virt_page1); if (tb_phys_page1 == phys_page1) { return true; @@ -196,26 +191,21 @@ static bool tb_lookup_cmp(const void *p, const void *d) return false; } -static TranslationBlock *tb_htable_lookup(CPUState *cpu, vaddr pc, - uint64_t cs_base, uint32_t flags, - uint32_t cflags) +static TranslationBlock *tb_htable_lookup(CPUState *cpu, TCGTBCPUState s) { tb_page_addr_t phys_pc; struct tb_desc desc; uint32_t h; + desc.s = s; desc.env = cpu_env(cpu); - desc.cs_base = cs_base; - desc.flags = flags; - desc.cflags = cflags; - desc.pc = pc; - phys_pc = get_page_addr_code(desc.env, pc); + phys_pc = get_page_addr_code(desc.env, s.pc); if (phys_pc == -1) { return NULL; } desc.page_addr0 = phys_pc; - h = tb_hash_func(phys_pc, (cflags & CF_PCREL ? 0 : pc), - flags, cs_base, cflags); + h = tb_hash_func(phys_pc, (s.cflags & CF_PCREL ? 0 : s.pc), + s.flags, s.cs_base, s.cflags); return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp); } @@ -233,35 +223,33 @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, vaddr pc, * * Returns: an existing translation block or NULL. */ -static inline TranslationBlock *tb_lookup(CPUState *cpu, vaddr pc, - uint64_t cs_base, uint32_t flags, - uint32_t cflags) +static inline TranslationBlock *tb_lookup(CPUState *cpu, TCGTBCPUState s) { TranslationBlock *tb; CPUJumpCache *jc; uint32_t hash; /* we should never be trying to look up an INVALID tb */ - tcg_debug_assert(!(cflags & CF_INVALID)); + tcg_debug_assert(!(s.cflags & CF_INVALID)); - hash = tb_jmp_cache_hash_func(pc); + hash = tb_jmp_cache_hash_func(s.pc); jc = cpu->tb_jmp_cache; tb = qatomic_read(&jc->array[hash].tb); if (likely(tb && - jc->array[hash].pc == pc && - tb->cs_base == cs_base && - tb->flags == flags && - tb_cflags(tb) == cflags)) { + jc->array[hash].pc == s.pc && + tb->cs_base == s.cs_base && + tb->flags == s.flags && + tb_cflags(tb) == s.cflags)) { goto hit; } - tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags); + tb = tb_htable_lookup(cpu, s); if (tb == NULL) { return NULL; } - jc->array[hash].pc = pc; + jc->array[hash].pc = s.pc; qatomic_set(&jc->array[hash].tb, tb); hit: @@ -269,7 +257,7 @@ hit: * As long as tb is not NULL, the contents are consistent. Therefore, * the virtual PC has to match for non-CF_PCREL translations. */ - assert((tb_cflags(tb) & CF_PCREL) || tb->pc == pc); + assert((tb_cflags(tb) & CF_PCREL) || tb->pc == s.pc); return tb; } @@ -286,14 +274,11 @@ static void log_cpu_exec(vaddr pc, CPUState *cpu, if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { FILE *logfile = qemu_log_trylock(); if (logfile) { - int flags = 0; + int flags = CPU_DUMP_CCOP; if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) { flags |= CPU_DUMP_FPU; } -#if defined(TARGET_I386) - flags |= CPU_DUMP_CCOP; -#endif if (qemu_loglevel_mask(CPU_LOG_TB_VPU)) { flags |= CPU_DUMP_VPU; } @@ -389,9 +374,6 @@ const void *HELPER(lookup_tb_ptr)(CPUArchState *env) { CPUState *cpu = env_cpu(env); TranslationBlock *tb; - vaddr pc; - uint64_t cs_base; - uint32_t flags, cflags; /* * By definition we've just finished a TB, so I/O is OK. @@ -401,20 +383,21 @@ const void *HELPER(lookup_tb_ptr)(CPUArchState *env) * The next TB, if we chain to it, will clear the flag again. */ cpu->neg.can_do_io = true; - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); - cflags = curr_cflags(cpu); - if (check_for_breakpoints(cpu, pc, &cflags)) { + TCGTBCPUState s = cpu->cc->tcg_ops->get_tb_cpu_state(cpu); + s.cflags = curr_cflags(cpu); + + if (check_for_breakpoints(cpu, s.pc, &s.cflags)) { cpu_loop_exit(cpu); } - tb = tb_lookup(cpu, pc, cs_base, flags, cflags); + tb = tb_lookup(cpu, s); if (tb == NULL) { return tcg_code_gen_epilogue; } if (qemu_loglevel_mask(CPU_LOG_TB_CPU | CPU_LOG_EXEC)) { - log_cpu_exec(pc, cpu, tb); + log_cpu_exec(s.pc, cpu, tb); } return tb->tc.ptr; @@ -564,11 +547,7 @@ static void cpu_exec_longjmp_cleanup(CPUState *cpu) void cpu_exec_step_atomic(CPUState *cpu) { - CPUArchState *env = cpu_env(cpu); TranslationBlock *tb; - vaddr pc; - uint64_t cs_base; - uint32_t flags, cflags; int tb_exit; if (sigsetjmp(cpu->jmp_env, 0) == 0) { @@ -577,13 +556,13 @@ void cpu_exec_step_atomic(CPUState *cpu) g_assert(!cpu->running); cpu->running = true; - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); + TCGTBCPUState s = cpu->cc->tcg_ops->get_tb_cpu_state(cpu); + s.cflags = curr_cflags(cpu); - cflags = curr_cflags(cpu); /* Execute in a serial context. */ - cflags &= ~CF_PARALLEL; + s.cflags &= ~CF_PARALLEL; /* After 1 insn, return and release the exclusive lock. */ - cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | 1; + s.cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | 1; /* * No need to check_for_breakpoints here. * We only arrive in cpu_exec_step_atomic after beginning execution @@ -591,16 +570,16 @@ void cpu_exec_step_atomic(CPUState *cpu) * Any breakpoint for this insn will have been recognized earlier. */ - tb = tb_lookup(cpu, pc, cs_base, flags, cflags); + tb = tb_lookup(cpu, s); if (tb == NULL) { mmap_lock(); - tb = tb_gen_code(cpu, pc, cs_base, flags, cflags); + tb = tb_gen_code(cpu, s); mmap_unlock(); } cpu_exec_enter(cpu); /* execute the generated code */ - trace_exec_tb(tb, pc); + trace_exec_tb(tb, s.pc); cpu_tb_exec(cpu, tb, &tb_exit); cpu_exec_exit(cpu); } else { @@ -733,10 +712,10 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret) * If user mode only, we simulate a fake exception which will be * handled outside the cpu execution loop. */ -#if defined(TARGET_I386) const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; - tcg_ops->fake_user_interrupt(cpu); -#endif /* TARGET_I386 */ + if (tcg_ops->fake_user_interrupt) { + tcg_ops->fake_user_interrupt(cpu); + } *ret = cpu->exception_index; cpu->exception_index = -1; return true; @@ -823,33 +802,22 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, cpu->exception_index = EXCP_HLT; bql_unlock(); return true; - } -#if defined(TARGET_I386) - else if (interrupt_request & CPU_INTERRUPT_INIT) { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUArchState *env = &x86_cpu->env; - replay_interrupt(); - cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0, 0); - do_cpu_init(x86_cpu); - cpu->exception_index = EXCP_HALTED; - bql_unlock(); - return true; - } -#else - else if (interrupt_request & CPU_INTERRUPT_RESET) { - replay_interrupt(); - cpu_reset(cpu); - bql_unlock(); - return true; - } -#endif /* !TARGET_I386 */ - /* The target hook has 3 exit conditions: - False when the interrupt isn't processed, - True when it is, and we should restart on a new TB, - and via longjmp via cpu_loop_exit. */ - else { + } else { const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; + if (interrupt_request & CPU_INTERRUPT_RESET) { + replay_interrupt(); + tcg_ops->cpu_exec_reset(cpu); + bql_unlock(); + return true; + } + + /* + * The target hook has 3 exit conditions: + * False when the interrupt isn't processed, + * True when it is, and we should restart on a new TB, + * and via longjmp via cpu_loop_exit. + */ if (tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) { if (!tcg_ops->need_replay_interrupt || tcg_ops->need_replay_interrupt(interrupt_request)) { @@ -956,11 +924,8 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc) while (!cpu_handle_interrupt(cpu, &last_tb)) { TranslationBlock *tb; - vaddr pc; - uint64_t cs_base; - uint32_t flags, cflags; - - cpu_get_tb_cpu_state(cpu_env(cpu), &pc, &cs_base, &flags); + TCGTBCPUState s = cpu->cc->tcg_ops->get_tb_cpu_state(cpu); + s.cflags = cpu->cflags_next_tb; /* * When requested, use an exact setting for cflags for the next @@ -969,33 +934,32 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc) * have CF_INVALID set, -1 is a convenient invalid value that * does not require tcg headers for cpu_common_reset. */ - cflags = cpu->cflags_next_tb; - if (cflags == -1) { - cflags = curr_cflags(cpu); + if (s.cflags == -1) { + s.cflags = curr_cflags(cpu); } else { cpu->cflags_next_tb = -1; } - if (check_for_breakpoints(cpu, pc, &cflags)) { + if (check_for_breakpoints(cpu, s.pc, &s.cflags)) { break; } - tb = tb_lookup(cpu, pc, cs_base, flags, cflags); + tb = tb_lookup(cpu, s); if (tb == NULL) { CPUJumpCache *jc; uint32_t h; mmap_lock(); - tb = tb_gen_code(cpu, pc, cs_base, flags, cflags); + tb = tb_gen_code(cpu, s); mmap_unlock(); /* * We add the TB in the virtual pc hash table * for the fast lookup */ - h = tb_jmp_cache_hash_func(pc); + h = tb_jmp_cache_hash_func(s.pc); jc = cpu->tb_jmp_cache; - jc->array[h].pc = pc; + jc->array[h].pc = s.pc; qatomic_set(&jc->array[h].tb, tb); } @@ -1015,7 +979,7 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc) tb_add_jump(last_tb, tb_exit, tb); } - cpu_loop_exec_tb(cpu, tb, pc, &last_tb, &tb_exit); + cpu_loop_exec_tb(cpu, tb, s.pc, &last_tb, &tb_exit); /* Try to align the host and virtual clocks if the guest is in advance */ @@ -1074,8 +1038,10 @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp) #ifndef CONFIG_USER_ONLY assert(tcg_ops->cpu_exec_halt); assert(tcg_ops->cpu_exec_interrupt); + assert(tcg_ops->cpu_exec_reset); #endif /* !CONFIG_USER_ONLY */ assert(tcg_ops->translate_code); + assert(tcg_ops->get_tb_cpu_state); assert(tcg_ops->mmu_index); tcg_ops->initialize(); tcg_target_initialized = true; diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index d9fb68d719..5f6d7c601c 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -19,11 +19,14 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" +#include "qemu/target-info.h" #include "accel/tcg/cpu-ops.h" -#include "exec/exec-all.h" +#include "accel/tcg/iommu.h" +#include "accel/tcg/probe.h" #include "exec/page-protection.h" #include "system/memory.h" -#include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/cpu-ldst-common.h" +#include "accel/tcg/cpu-mmu-index.h" #include "exec/cputlb.h" #include "exec/tb-flush.h" #include "system/ram_addr.h" @@ -43,7 +46,6 @@ #include "tb-internal.h" #include "tlb-bounds.h" #include "internal-common.h" -#include "internal-target.h" #ifdef CONFIG_PLUGIN #include "qemu/plugin-memory.h" #endif @@ -771,19 +773,19 @@ void tlb_flush_range_by_mmuidx(CPUState *cpu, vaddr addr, assert_cpu_is_self(cpu); + /* If no page bits are significant, this devolves to tlb_flush. */ + if (bits < TARGET_PAGE_BITS) { + tlb_flush_by_mmuidx(cpu, idxmap); + return; + } /* * If all bits are significant, and len is small, * this devolves to tlb_flush_page. */ - if (bits >= TARGET_LONG_BITS && len <= TARGET_PAGE_SIZE) { + if (len <= TARGET_PAGE_SIZE && bits >= target_long_bits()) { tlb_flush_page_by_mmuidx(cpu, addr, idxmap); return; } - /* If no page bits are significant, this devolves to tlb_flush. */ - if (bits < TARGET_PAGE_BITS) { - tlb_flush_by_mmuidx(cpu, idxmap); - return; - } /* This should already be page aligned */ d.addr = addr & TARGET_PAGE_MASK; @@ -809,19 +811,19 @@ void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *src_cpu, TLBFlushRangeData d, *p; CPUState *dst_cpu; + /* If no page bits are significant, this devolves to tlb_flush. */ + if (bits < TARGET_PAGE_BITS) { + tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, idxmap); + return; + } /* * If all bits are significant, and len is small, * this devolves to tlb_flush_page. */ - if (bits >= TARGET_LONG_BITS && len <= TARGET_PAGE_SIZE) { + if (len <= TARGET_PAGE_SIZE && bits >= target_long_bits()) { tlb_flush_page_by_mmuidx_all_cpus_synced(src_cpu, addr, idxmap); return; } - /* If no page bits are significant, this devolves to tlb_flush. */ - if (bits < TARGET_PAGE_BITS) { - tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, idxmap); - return; - } /* This should already be page aligned */ d.addr = addr & TARGET_PAGE_MASK; @@ -1340,7 +1342,7 @@ static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size, trace_memory_notdirty_write_access(mem_vaddr, ram_addr, size); if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) { - tb_invalidate_phys_range_fast(ram_addr, size, retaddr); + tb_invalidate_phys_range_fast(cpu, ram_addr, size, retaddr); } /* diff --git a/accel/tcg/internal-common.h b/accel/tcg/internal-common.h index 2f00560d10..1dbc45dd95 100644 --- a/accel/tcg/internal-common.h +++ b/accel/tcg/internal-common.h @@ -11,6 +11,8 @@ #include "exec/cpu-common.h" #include "exec/translation-block.h" +#include "exec/mmap-lock.h" +#include "accel/tcg/tb-cpu-state.h" extern int64_t max_delay; extern int64_t max_advance; @@ -45,9 +47,7 @@ static inline bool cpu_plugin_mem_cbs_enabled(const CPUState *cpu) #endif } -TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc, - uint64_t cs_base, uint32_t flags, - int cflags); +TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s); void page_init(void); void tb_htable_init(void); void tb_reset_jump(TranslationBlock *tb, int n); @@ -108,4 +108,35 @@ static inline tb_page_addr_t get_page_addr_code(CPUArchState *env, return get_page_addr_code_hostp(env, addr, NULL); } +/* + * 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 + +#ifndef CONFIG_USER_ONLY +G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); +#endif /* CONFIG_USER_ONLY */ + +void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); +void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr); + #endif diff --git a/accel/tcg/internal-target.h b/accel/tcg/internal-target.h deleted file mode 100644 index 9a9cef3140..0000000000 --- a/accel/tcg/internal-target.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 "cpu-param.h" -#include "exec/exec-all.h" -#include "exec/translation-block.h" -#include "tb-internal.h" -#include "exec/mmap-lock.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 - -#ifndef CONFIG_USER_ONLY -G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); -#endif /* CONFIG_USER_ONLY */ - -#endif /* ACCEL_TCG_INTERNAL_H */ diff --git a/accel/tcg/ldst_common.c.inc b/accel/tcg/ldst_common.c.inc index 9791a4e9ef..57f3e06192 100644 --- a/accel/tcg/ldst_common.c.inc +++ b/accel/tcg/ldst_common.c.inc @@ -123,7 +123,7 @@ void helper_st_i128(CPUArchState *env, uint64_t addr, Int128 val, MemOpIdx oi) * Load helpers for cpu_ldst.h */ -static void plugin_load_cb(CPUArchState *env, abi_ptr addr, +static void plugin_load_cb(CPUArchState *env, vaddr addr, uint64_t value_low, uint64_t value_high, MemOpIdx oi) @@ -193,7 +193,7 @@ Int128 cpu_ld16_mmu(CPUArchState *env, vaddr addr, * Store helpers for cpu_ldst.h */ -static void plugin_store_cb(CPUArchState *env, abi_ptr addr, +static void plugin_store_cb(CPUArchState *env, vaddr addr, uint64_t value_low, uint64_t value_high, MemOpIdx oi) diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index 047afa49a2..d6f533f9a1 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -5,9 +5,13 @@ endif tcg_ss = ss.source_set() tcg_ss.add(files( + 'cpu-exec.c', 'cpu-exec-common.c', 'tcg-runtime.c', 'tcg-runtime-gvec.c', + 'tb-maint.c', + 'tcg-all.c', + 'translate-all.c', 'translator.c', )) if get_option('plugins') @@ -17,25 +21,13 @@ endif libuser_ss.add_all(tcg_ss) libsystem_ss.add_all(tcg_ss) -tcg_specific_ss = ss.source_set() -tcg_specific_ss.add(files( - 'tcg-all.c', - 'cpu-exec.c', - 'tb-maint.c', - 'translate-all.c', -)) -tcg_specific_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c')) -specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_specific_ss) - -specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files( - 'cputlb.c', -)) - libuser_ss.add(files( + 'user-exec.c', 'user-exec-stub.c', )) libsystem_ss.add(files( + 'cputlb.c', 'icount-common.c', 'monitor.c', 'tcg-accel-ops.c', diff --git a/accel/tcg/tb-hash.h b/accel/tcg/tb-hash.h index 3bc5042d9d..f7b159f04c 100644 --- a/accel/tcg/tb-hash.h +++ b/accel/tcg/tb-hash.h @@ -20,8 +20,7 @@ #ifndef EXEC_TB_HASH_H #define EXEC_TB_HASH_H -#include "exec/cpu-defs.h" -#include "exec/exec-all.h" +#include "exec/vaddr.h" #include "exec/target_page.h" #include "exec/translation-block.h" #include "qemu/xxhash.h" diff --git a/accel/tcg/tb-internal.h b/accel/tcg/tb-internal.h index 08538e2896..40439f03c3 100644 --- a/accel/tcg/tb-internal.h +++ b/accel/tcg/tb-internal.h @@ -45,11 +45,11 @@ 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); +void tb_invalidate_phys_range_fast(CPUState *cpu, ram_addr_t ram_addr, + unsigned size, uintptr_t retaddr); #endif /* CONFIG_SOFTMMU */ -bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); +bool tb_invalidate_phys_page_unwind(CPUState *cpu, tb_page_addr_t addr, + uintptr_t pc); #endif diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index d479f53ae0..0048316f99 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -20,14 +20,13 @@ #include "qemu/osdep.h" #include "qemu/interval-tree.h" #include "qemu/qtree.h" -#include "cpu.h" #include "exec/cputlb.h" #include "exec/log.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/mmap-lock.h" #include "exec/tb-flush.h" #include "exec/target_page.h" +#include "accel/tcg/cpu-ops.h" #include "tb-internal.h" #include "system/tcg.h" #include "tcg/tcg.h" @@ -35,7 +34,6 @@ #include "tb-context.h" #include "tb-internal.h" #include "internal-common.h" -#include "internal-target.h" #ifdef CONFIG_USER_ONLY #include "user/page-protection.h" #endif @@ -159,11 +157,7 @@ static PageForEachNext foreach_tb_next(PageForEachNext tb, /* * In system mode we want L1_MAP to be based on ram offsets. */ -#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS -# define L1_MAP_ADDR_SPACE_BITS HOST_LONG_BITS -#else -# define L1_MAP_ADDR_SPACE_BITS TARGET_PHYS_ADDR_SPACE_BITS -#endif +#define L1_MAP_ADDR_SPACE_BITS HOST_LONG_BITS /* Size of the L2 (and L3, etc) page tables. */ #define V_L2_BITS 10 @@ -1012,7 +1006,8 @@ TranslationBlock *tb_link_page(TranslationBlock *tb) * Called with mmap_lock held for user-mode emulation. * NOTE: this function must not be called while a TB is running. */ -void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last) +void tb_invalidate_phys_range(CPUState *cpu, tb_page_addr_t start, + tb_page_addr_t last) { TranslationBlock *tb; PageForEachNext n; @@ -1035,17 +1030,16 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr) start = addr & TARGET_PAGE_MASK; last = addr | ~TARGET_PAGE_MASK; - tb_invalidate_phys_range(start, last); + tb_invalidate_phys_range(NULL, start, last); } /* * Called with mmap_lock held. If pc is not 0 then it indicates the * host PC of the faulting store instruction that caused this invalidate. - * Returns true if the caller needs to abort execution of the current - * TB (because it was modified by this store and the guest CPU has - * precise-SMC semantics). + * Returns true if the caller needs to abort execution of the current TB. */ -bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) +bool tb_invalidate_phys_page_unwind(CPUState *cpu, tb_page_addr_t addr, + uintptr_t pc) { TranslationBlock *current_tb; bool current_tb_modified; @@ -1057,10 +1051,7 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) * Without precise smc semantics, or when outside of a TB, * we can skip to invalidate. */ -#ifndef TARGET_HAS_PRECISE_SMC - pc = 0; -#endif - if (!pc) { + if (!pc || !cpu || !cpu->cc->tcg_ops->precise_smc) { tb_invalidate_phys_page(addr); return false; } @@ -1083,15 +1074,14 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) * the CPU state. */ current_tb_modified = true; - cpu_restore_state_from_tb(current_cpu, current_tb, pc); + cpu_restore_state_from_tb(cpu, current_tb, pc); } tb_phys_invalidate__locked(tb); } if (current_tb_modified) { /* Force execution of one insn next time. */ - CPUState *cpu = current_cpu; - cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu); + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); return true; } return false; @@ -1100,23 +1090,28 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) /* * @p must be non-NULL. * Call with all @pages locked. + * (@cpu, @retaddr) may be (NULL, 0) outside of a cpu context, + * in which case precise_smc need not be detected. */ static void -tb_invalidate_phys_page_range__locked(struct page_collection *pages, +tb_invalidate_phys_page_range__locked(CPUState *cpu, + struct page_collection *pages, PageDesc *p, tb_page_addr_t start, tb_page_addr_t last, uintptr_t retaddr) { TranslationBlock *tb; PageForEachNext n; -#ifdef TARGET_HAS_PRECISE_SMC bool current_tb_modified = false; - TranslationBlock *current_tb = retaddr ? tcg_tb_lookup(retaddr) : NULL; -#endif /* TARGET_HAS_PRECISE_SMC */ + TranslationBlock *current_tb = NULL; /* Range may not cross a page. */ tcg_debug_assert(((start ^ last) & TARGET_PAGE_MASK) == 0); + if (retaddr && cpu && cpu->cc->tcg_ops->precise_smc) { + current_tb = tcg_tb_lookup(retaddr); + } + /* * We remove all the TBs in the range [start, last]. * XXX: see if in some cases it could be faster to invalidate all the code @@ -1134,8 +1129,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, tb_last = tb_start + (tb_last & ~TARGET_PAGE_MASK); } if (!(tb_last < start || tb_start > last)) { -#ifdef TARGET_HAS_PRECISE_SMC - if (current_tb == tb && + if (unlikely(current_tb == tb) && (tb_cflags(current_tb) & CF_COUNT_MASK) != 1) { /* * If we are modifying the current TB, we must stop @@ -1145,9 +1139,8 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, * restore the CPU state. */ current_tb_modified = true; - cpu_restore_state_from_tb(current_cpu, current_tb, retaddr); + cpu_restore_state_from_tb(cpu, current_tb, retaddr); } -#endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate__locked(tb); } } @@ -1157,15 +1150,13 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, tlb_unprotect_code(start); } -#ifdef TARGET_HAS_PRECISE_SMC - if (current_tb_modified) { + if (unlikely(current_tb_modified)) { page_collection_unlock(pages); /* Force execution of one insn next time. */ - current_cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu); + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); mmap_unlock(); - cpu_loop_exit_noexc(current_cpu); + cpu_loop_exit_noexc(cpu); } -#endif } /* @@ -1175,7 +1166,8 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, * access: the virtual CPU will exit the current TB if code is modified inside * this TB. */ -void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last) +void tb_invalidate_phys_range(CPUState *cpu, tb_page_addr_t start, + tb_page_addr_t last) { struct page_collection *pages; tb_page_addr_t index, index_last; @@ -1194,44 +1186,30 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last) page_start = index << TARGET_PAGE_BITS; page_last = page_start | ~TARGET_PAGE_MASK; page_last = MIN(page_last, last); - tb_invalidate_phys_page_range__locked(pages, pd, + tb_invalidate_phys_page_range__locked(cpu, pages, pd, page_start, page_last, 0); } page_collection_unlock(pages); } /* - * Call with all @pages in the range [@start, @start + len[ locked. - */ -static void tb_invalidate_phys_page_fast__locked(struct page_collection *pages, - tb_page_addr_t start, - unsigned len, uintptr_t ra) -{ - PageDesc *p; - - p = page_find(start >> TARGET_PAGE_BITS); - if (!p) { - return; - } - - assert_page_locked(p); - tb_invalidate_phys_page_range__locked(pages, p, start, start + len - 1, ra); -} - -/* * len must be <= 8 and start must be a multiple of len. * Called via softmmu_template.h when code areas are written to with * iothread mutex not held. */ -void tb_invalidate_phys_range_fast(ram_addr_t ram_addr, - unsigned size, - uintptr_t retaddr) +void tb_invalidate_phys_range_fast(CPUState *cpu, ram_addr_t start, + unsigned len, uintptr_t ra) { - struct page_collection *pages; + PageDesc *p = page_find(start >> TARGET_PAGE_BITS); - pages = page_collection_lock(ram_addr, ram_addr + size - 1); - tb_invalidate_phys_page_fast__locked(pages, ram_addr, size, retaddr); - page_collection_unlock(pages); + if (p) { + ram_addr_t last = start + len - 1; + struct page_collection *pages = page_collection_lock(start, last); + + tb_invalidate_phys_page_range__locked(cpu, pages, p, + start, last, ra); + page_collection_unlock(pages); + } } #endif /* CONFIG_USER_ONLY */ diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c index 0ce34ac912..6e5dc333d5 100644 --- a/accel/tcg/tcg-all.c +++ b/accel/tcg/tcg-all.c @@ -36,15 +36,11 @@ #include "qapi/qapi-builtin-visit.h" #include "qemu/units.h" #include "qemu/target-info.h" -#if defined(CONFIG_USER_ONLY) -#include "hw/qdev-core.h" -#else +#ifndef CONFIG_USER_ONLY #include "hw/boards.h" -#include "system/tcg.h" #endif #include "accel/tcg/cpu-ops.h" #include "internal-common.h" -#include "cpu-param.h" struct TCGState { diff --git a/accel/tcg/tlb-bounds.h b/accel/tcg/tlb-bounds.h index efd34d4793..f83d9ac9ee 100644 --- a/accel/tcg/tlb-bounds.h +++ b/accel/tcg/tlb-bounds.h @@ -7,26 +7,7 @@ #define ACCEL_TCG_TLB_BOUNDS_H #define CPU_TLB_DYN_MIN_BITS 6 +#define CPU_TLB_DYN_MAX_BITS (32 - TARGET_PAGE_BITS) #define CPU_TLB_DYN_DEFAULT_BITS 8 -# if HOST_LONG_BITS == 32 -/* Make sure we do not require a double-word shift for the TLB load */ -# define CPU_TLB_DYN_MAX_BITS (32 - TARGET_PAGE_BITS) -# else /* HOST_LONG_BITS == 64 */ -/* - * Assuming TARGET_PAGE_BITS==12, with 2**22 entries we can cover 2**(22+12) == - * 2**34 == 16G of address space. This is roughly what one would expect a - * TLB to cover in a modern (as of 2018) x86_64 CPU. For instance, Intel - * Skylake's Level-2 STLB has 16 1G entries. - * Also, make sure we do not size the TLB past the guest's address space. - */ -# ifdef TARGET_PAGE_BITS_VARY -# define CPU_TLB_DYN_MAX_BITS \ - MIN(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS) -# else -# define CPU_TLB_DYN_MAX_BITS \ - MIN_CONST(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS) -# endif -# endif - #endif /* ACCEL_TCG_TLB_BOUNDS_H */ diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index c007b9a190..451b383aa8 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -21,55 +21,23 @@ #include "trace.h" #include "disas/disas.h" -#include "exec/exec-all.h" #include "tcg/tcg.h" -#if defined(CONFIG_USER_ONLY) -#include "qemu.h" -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include <sys/param.h> -#if __FreeBSD_version >= 700104 -#define HAVE_KINFO_GETVMMAP -#define sigqueue sigqueue_freebsd /* avoid redefinition */ -#include <sys/proc.h> -#include <machine/profile.h> -#define _KERNEL -#include <sys/user.h> -#undef _KERNEL -#undef sigqueue -#include <libutil.h> -#endif -#endif -#else -#include "system/ram_addr.h" -#endif - -#include "cpu-param.h" -#include "exec/cputlb.h" -#include "exec/page-protection.h" #include "exec/mmap-lock.h" #include "tb-internal.h" #include "tlb-bounds.h" -#include "exec/translator.h" #include "exec/tb-flush.h" -#include "qemu/bitmap.h" -#include "qemu/qemu-print.h" -#include "qemu/main-loop.h" #include "qemu/cacheinfo.h" -#include "qemu/timer.h" +#include "qemu/target-info.h" #include "exec/log.h" #include "exec/icount.h" -#include "system/tcg.h" -#include "qapi/error.h" #include "accel/tcg/cpu-ops.h" #include "tb-jmp-cache.h" #include "tb-hash.h" #include "tb-context.h" #include "tb-internal.h" #include "internal-common.h" -#include "internal-target.h" #include "tcg/perf.h" #include "tcg/insn-start-words.h" -#include "cpu.h" TBContext tb_ctx; @@ -110,7 +78,7 @@ static int64_t decode_sleb128(const uint8_t **pp) val |= (int64_t)(byte & 0x7f) << shift; shift += 7; } while (byte & 0x80); - if (shift < TARGET_LONG_BITS && (byte & 0x40)) { + if (shift < 64 && (byte & 0x40)) { val |= -(int64_t)1 << shift; } @@ -121,7 +89,7 @@ static int64_t decode_sleb128(const uint8_t **pp) /* Encode the data collected about the instructions while compiling TB. Place the data at BLOCK, and return the number of bytes consumed. - The logical table consists of TARGET_INSN_START_WORDS target_ulong's, + The logical table consists of INSN_START_WORDS uint64_t's, which come from the target's insn_start data, followed by a uintptr_t which comes from the host pc of the end of the code implementing the insn. @@ -141,13 +109,13 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) for (i = 0, n = tb->icount; i < n; ++i) { uint64_t prev, curr; - for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { + for (j = 0; j < INSN_START_WORDS; ++j) { if (i == 0) { prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb->pc : 0); } else { - prev = insn_data[(i - 1) * TARGET_INSN_START_WORDS + j]; + prev = insn_data[(i - 1) * INSN_START_WORDS + j]; } - curr = insn_data[i * TARGET_INSN_START_WORDS + j]; + curr = insn_data[i * INSN_START_WORDS + j]; p = encode_sleb128(p, curr - prev); } prev = (i == 0 ? 0 : insn_end_off[i - 1]); @@ -179,7 +147,7 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, return -1; } - memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS); + memset(data, 0, sizeof(uint64_t) * INSN_START_WORDS); if (!(tb_cflags(tb) & CF_PCREL)) { data[0] = tb->pc; } @@ -189,7 +157,7 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, * at which the end of the insn exceeds host_pc. */ for (i = 0; i < num_insns; ++i) { - for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { + for (j = 0; j < INSN_START_WORDS; ++j) { data[j] += decode_sleb128(&p); } iter_pc += decode_sleb128(&p); @@ -207,7 +175,7 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, uintptr_t host_pc) { - uint64_t data[TARGET_INSN_START_WORDS]; + uint64_t data[INSN_START_WORDS]; int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); if (insns_left < 0) { @@ -291,9 +259,7 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb, } /* Called with mmap_lock held for user mode emulation. */ -TranslationBlock *tb_gen_code(CPUState *cpu, - vaddr pc, uint64_t cs_base, - uint32_t flags, int cflags) +TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s) { CPUArchState *env = cpu_env(cpu); TranslationBlock *tb, *existing_tb; @@ -306,14 +272,14 @@ TranslationBlock *tb_gen_code(CPUState *cpu, assert_memory_lock(); qemu_thread_jit_write(); - phys_pc = get_page_addr_code_hostp(env, pc, &host_pc); + phys_pc = get_page_addr_code_hostp(env, s.pc, &host_pc); if (phys_pc == -1) { /* Generate a one-shot TB with 1 insn in it */ - cflags = (cflags & ~CF_COUNT_MASK) | 1; + s.cflags = (s.cflags & ~CF_COUNT_MASK) | 1; } - max_insns = cflags & CF_COUNT_MASK; + max_insns = s.cflags & CF_COUNT_MASK; if (max_insns == 0) { max_insns = TCG_MAX_INSNS; } @@ -333,12 +299,12 @@ TranslationBlock *tb_gen_code(CPUState *cpu, gen_code_buf = tcg_ctx->code_gen_ptr; tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf); - if (!(cflags & CF_PCREL)) { - tb->pc = pc; + if (!(s.cflags & CF_PCREL)) { + tb->pc = s.pc; } - tb->cs_base = cs_base; - tb->flags = flags; - tb->cflags = cflags; + tb->cs_base = s.cs_base; + tb->flags = s.flags; + tb->cflags = s.cflags; tb_set_page_addr0(tb, phys_pc); tb_set_page_addr1(tb, -1); if (phys_pc != -1) { @@ -346,19 +312,18 @@ TranslationBlock *tb_gen_code(CPUState *cpu, } tcg_ctx->gen_tb = tb; - tcg_ctx->addr_type = TARGET_LONG_BITS == 32 ? TCG_TYPE_I32 : TCG_TYPE_I64; + tcg_ctx->addr_type = target_long_bits() == 32 ? TCG_TYPE_I32 : TCG_TYPE_I64; #ifdef CONFIG_SOFTMMU tcg_ctx->page_bits = TARGET_PAGE_BITS; tcg_ctx->page_mask = TARGET_PAGE_MASK; tcg_ctx->tlb_dyn_max_bits = CPU_TLB_DYN_MAX_BITS; #endif - tcg_ctx->insn_start_words = TARGET_INSN_START_WORDS; tcg_ctx->guest_mo = cpu->cc->tcg_ops->guest_default_memory_order; restart_translate: - trace_translate_block(tb, pc, tb->tc.ptr); + trace_translate_block(tb, s.pc, tb->tc.ptr); - gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti); + gen_code_size = setjmp_gen_code(env, tb, s.pc, host_pc, &max_insns, &ti); if (unlikely(gen_code_size < 0)) { switch (gen_code_size) { case -1: @@ -435,10 +400,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu, * For CF_PCREL, attribute all executions of the generated code * to its first mapping. */ - perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf)); + perf_report_code(s.pc, tb, tcg_splitwx_to_rx(gen_code_buf)); if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && - qemu_log_in_addr_range(pc)) { + qemu_log_in_addr_range(s.pc)) { FILE *logfile = qemu_log_trylock(); if (logfile) { int code_size, data_size; @@ -460,7 +425,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, fprintf(logfile, "OUT: [size=%d]\n", gen_code_size); fprintf(logfile, " -- guest addr 0x%016" PRIx64 " + tb prologue\n", - tcg_ctx->gen_insn_data[insn * TARGET_INSN_START_WORDS]); + tcg_ctx->gen_insn_data[insn * INSN_START_WORDS]); chunk_start = tcg_ctx->gen_insn_end_off[insn]; disas(logfile, tb->tc.ptr, chunk_start); @@ -473,7 +438,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, size_t chunk_end = tcg_ctx->gen_insn_end_off[insn]; if (chunk_end > chunk_start) { fprintf(logfile, " -- guest addr 0x%016" PRIx64 "\n", - tcg_ctx->gen_insn_data[insn * TARGET_INSN_START_WORDS]); + tcg_ctx->gen_insn_data[insn * INSN_START_WORDS]); disas(logfile, tb->tc.ptr + chunk_start, chunk_end - chunk_start); chunk_start = chunk_end; @@ -591,15 +556,11 @@ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr) /* The exception probably happened in a helper. The CPU state should have been saved before calling it. Fetch the PC from there. */ CPUArchState *env = cpu_env(cpu); - vaddr pc; - uint64_t cs_base; - tb_page_addr_t addr; - uint32_t flags; + TCGTBCPUState s = cpu->cc->tcg_ops->get_tb_cpu_state(cpu); + tb_page_addr_t addr = get_page_addr_code(env, s.pc); - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); - addr = get_page_addr_code(env, pc); if (addr != -1) { - tb_invalidate_phys_range(addr, addr); + tb_invalidate_phys_range(cpu, addr, addr); } } } diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 5eef8e7f18..f25d80e2dc 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -19,19 +19,20 @@ #include "qemu/osdep.h" #include "accel/tcg/cpu-ops.h" #include "disas/disas.h" -#include "cpu.h" #include "exec/vaddr.h" -#include "exec/exec-all.h" #include "exec/tlb-flags.h" #include "tcg/tcg.h" #include "qemu/bitops.h" #include "qemu/rcu.h" -#include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/cpu-ldst-common.h" +#include "accel/tcg/helper-retaddr.h" +#include "accel/tcg/probe.h" #include "user/cpu_loop.h" +#include "user/guest-host.h" #include "qemu/main-loop.h" #include "user/page-protection.h" #include "exec/page-protection.h" -#include "exec/helper-proto.h" +#include "exec/helper-proto-common.h" #include "qemu/atomic128.h" #include "qemu/bswap.h" #include "qemu/int128.h" @@ -39,7 +40,6 @@ #include "tcg/tcg-ldst.h" #include "backend-ldst.h" #include "internal-common.h" -#include "internal-target.h" #include "tb-internal.h" __thread uintptr_t helper_retaddr; @@ -126,9 +126,9 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write) * guest, we'd end up in an infinite loop of retrying the faulting access. */ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, - uintptr_t host_pc, abi_ptr guest_addr) + uintptr_t host_pc, vaddr guest_addr) { - switch (page_unprotect(guest_addr, host_pc)) { + switch (page_unprotect(cpu, guest_addr, host_pc)) { case 0: /* * Fault not caused by a page marked unwritable to protect @@ -162,7 +162,7 @@ typedef struct PageFlagsNode { static IntervalTreeRoot pageflags_root; -static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last) +static PageFlagsNode *pageflags_find(vaddr start, vaddr last) { IntervalTreeNode *n; @@ -170,8 +170,7 @@ static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last) return n ? container_of(n, PageFlagsNode, itree) : NULL; } -static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start, - target_ulong last) +static PageFlagsNode *pageflags_next(PageFlagsNode *p, vaddr start, vaddr last) { IntervalTreeNode *n; @@ -200,13 +199,22 @@ int walk_memory_regions(void *priv, walk_memory_regions_fn fn) return rc; } -static int dump_region(void *priv, target_ulong start, - target_ulong end, unsigned long prot) +static int dump_region(void *opaque, vaddr start, vaddr end, int prot) { - FILE *f = (FILE *)priv; + FILE *f = opaque; + uint64_t mask; + int width; - fprintf(f, TARGET_FMT_lx"-"TARGET_FMT_lx" "TARGET_FMT_lx" %c%c%c\n", - start, end, end - start, + if (guest_addr_max <= UINT32_MAX) { + mask = UINT32_MAX, width = 8; + } else { + mask = UINT64_MAX, width = 16; + } + + fprintf(f, "%0*" PRIx64 "-%0*" PRIx64 " %0*" PRIx64 " %c%c%c\n", + width, start & mask, + width, end & mask, + width, (end - start) & mask, ((prot & PAGE_READ) ? 'r' : '-'), ((prot & PAGE_WRITE) ? 'w' : '-'), ((prot & PAGE_EXEC) ? 'x' : '-')); @@ -216,14 +224,14 @@ static int dump_region(void *priv, target_ulong start, /* dump memory mappings */ void page_dump(FILE *f) { - const int length = sizeof(target_ulong) * 2; + int width = guest_addr_max <= UINT32_MAX ? 8 : 16; fprintf(f, "%-*s %-*s %-*s %s\n", - length, "start", length, "end", length, "size", "prot"); + width, "start", width, "end", width, "size", "prot"); walk_memory_regions(f, dump_region); } -int page_get_flags(target_ulong address) +int page_get_flags(vaddr address) { PageFlagsNode *p = pageflags_find(address, address); @@ -246,7 +254,7 @@ int page_get_flags(target_ulong address) } /* A subroutine of page_set_flags: insert a new node for [start,last]. */ -static void pageflags_create(target_ulong start, target_ulong last, int flags) +static void pageflags_create(vaddr start, vaddr last, int flags) { PageFlagsNode *p = g_new(PageFlagsNode, 1); @@ -257,13 +265,13 @@ static void pageflags_create(target_ulong start, target_ulong last, int flags) } /* A subroutine of page_set_flags: remove everything in [start,last]. */ -static bool pageflags_unset(target_ulong start, target_ulong last) +static bool pageflags_unset(vaddr start, vaddr last) { bool inval_tb = false; while (true) { PageFlagsNode *p = pageflags_find(start, last); - target_ulong p_last; + vaddr p_last; if (!p) { break; @@ -302,8 +310,7 @@ static bool pageflags_unset(target_ulong start, target_ulong last) * A subroutine of page_set_flags: nothing overlaps [start,last], * but check adjacent mappings and maybe merge into a single range. */ -static void pageflags_create_merge(target_ulong start, target_ulong last, - int flags) +static void pageflags_create_merge(vaddr start, vaddr last, int flags) { PageFlagsNode *next = NULL, *prev = NULL; @@ -354,11 +361,11 @@ static void pageflags_create_merge(target_ulong start, target_ulong last, #define PAGE_STICKY (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY) /* A subroutine of page_set_flags: add flags to [start,last]. */ -static bool pageflags_set_clear(target_ulong start, target_ulong last, +static bool pageflags_set_clear(vaddr start, vaddr last, int set_flags, int clear_flags) { PageFlagsNode *p; - target_ulong p_start, p_last; + vaddr p_start, p_last; int p_flags, merge_flags; bool inval_tb = false; @@ -493,7 +500,7 @@ static bool pageflags_set_clear(target_ulong start, target_ulong last, return inval_tb; } -void page_set_flags(target_ulong start, target_ulong last, int flags) +void page_set_flags(vaddr start, vaddr last, int flags) { bool reset = false; bool inval_tb = false; @@ -502,7 +509,7 @@ void page_set_flags(target_ulong start, target_ulong last, int flags) guest address space. If this assert fires, it probably indicates a missing call to h2g_valid. */ assert(start <= last); - assert(last <= GUEST_ADDR_MAX); + assert(last <= guest_addr_max); /* Only set PAGE_ANON with new mappings. */ assert(!(flags & PAGE_ANON) || (flags & PAGE_RESET)); assert_memory_lock(); @@ -529,13 +536,13 @@ void page_set_flags(target_ulong start, target_ulong last, int flags) ~(reset ? 0 : PAGE_STICKY)); } if (inval_tb) { - tb_invalidate_phys_range(start, last); + tb_invalidate_phys_range(NULL, start, last); } } -bool page_check_range(target_ulong start, target_ulong len, int flags) +bool page_check_range(vaddr start, vaddr len, int flags) { - target_ulong last; + vaddr last; int locked; /* tri-state: =0: unlocked, +1: global, -1: local */ bool ret; @@ -584,7 +591,7 @@ bool page_check_range(target_ulong start, target_ulong len, int flags) break; } /* Asking about writable, but has been protected: undo. */ - if (!page_unprotect(start, 0)) { + if (!page_unprotect(NULL, start, 0)) { ret = false; break; } @@ -611,20 +618,19 @@ bool page_check_range(target_ulong start, target_ulong len, int flags) return ret; } -bool page_check_range_empty(target_ulong start, target_ulong last) +bool page_check_range_empty(vaddr start, vaddr last) { assert(last >= start); assert_memory_lock(); return pageflags_find(start, last) == NULL; } -target_ulong page_find_range_empty(target_ulong min, target_ulong max, - target_ulong len, target_ulong align) +vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align) { - target_ulong len_m1, align_m1; + vaddr len_m1, align_m1; assert(min <= max); - assert(max <= GUEST_ADDR_MAX); + assert(max <= guest_addr_max); assert(len != 0); assert(is_power_of_2(align)); assert_memory_lock(); @@ -662,7 +668,7 @@ target_ulong page_find_range_empty(target_ulong min, target_ulong max, void tb_lock_page0(tb_page_addr_t address) { PageFlagsNode *p; - target_ulong start, last; + vaddr start, last; int host_page_size = qemu_real_host_page_size(); int prot; @@ -704,11 +710,13 @@ void tb_lock_page0(tb_page_addr_t address) * immediately exited. (We can only return 2 if the 'pc' argument is * non-zero.) */ -int page_unprotect(tb_page_addr_t address, uintptr_t pc) +int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc) { PageFlagsNode *p; bool current_tb_invalidated; + assert((cpu == NULL) == (pc == 0)); + /* * Technically this isn't safe inside a signal handler. However we * know this only ever happens in a synchronous SEGV handler, so in @@ -731,15 +739,15 @@ int page_unprotect(tb_page_addr_t address, uintptr_t pc) * this thread raced with another one which got here first and * set the page to PAGE_WRITE and did the TB invalidate for us. */ -#ifdef TARGET_HAS_PRECISE_SMC - TranslationBlock *current_tb = tcg_tb_lookup(pc); - if (current_tb) { - current_tb_invalidated = tb_cflags(current_tb) & CF_INVALID; + if (pc && cpu->cc->tcg_ops->precise_smc) { + TranslationBlock *current_tb = tcg_tb_lookup(pc); + if (current_tb) { + current_tb_invalidated = tb_cflags(current_tb) & CF_INVALID; + } } -#endif } else { int host_page_size = qemu_real_host_page_size(); - target_ulong start, len, i; + vaddr start, len, i; int prot; if (host_page_size <= TARGET_PAGE_SIZE) { @@ -747,14 +755,15 @@ int page_unprotect(tb_page_addr_t address, uintptr_t pc) len = TARGET_PAGE_SIZE; prot = p->flags | PAGE_WRITE; pageflags_set_clear(start, start + len - 1, PAGE_WRITE, 0); - current_tb_invalidated = tb_invalidate_phys_page_unwind(start, pc); + current_tb_invalidated = + tb_invalidate_phys_page_unwind(cpu, start, pc); } else { start = address & -host_page_size; len = host_page_size; prot = 0; for (i = 0; i < len; i += TARGET_PAGE_SIZE) { - target_ulong addr = start + i; + vaddr addr = start + i; p = pageflags_find(addr, addr); if (p) { @@ -770,7 +779,7 @@ int page_unprotect(tb_page_addr_t address, uintptr_t pc) * the corresponding translated code. */ current_tb_invalidated |= - tb_invalidate_phys_page_unwind(addr, pc); + tb_invalidate_phys_page_unwind(cpu, addr, pc); } } if (prot & PAGE_EXEC) { @@ -850,6 +859,12 @@ void *probe_access(CPUArchState *env, vaddr addr, int size, return size ? g2h(env_cpu(env), addr) : NULL; } +void *tlb_vaddr_to_host(CPUArchState *env, vaddr addr, + MMUAccessType access_type, int mmu_idx) +{ + return g2h(env_cpu(env), addr); +} + tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr, void **hostp) { @@ -864,7 +879,6 @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr, return addr; } -#ifdef TARGET_PAGE_DATA_SIZE /* * Allocate chunks of target data together. For the only current user, * if we allocate one hunk per page, we have overhead of 40/128 or 40%. @@ -880,10 +894,16 @@ typedef struct TargetPageDataNode { } TargetPageDataNode; static IntervalTreeRoot targetdata_root; +static size_t target_page_data_size; -void page_reset_target_data(target_ulong start, target_ulong last) +void page_reset_target_data(vaddr start, vaddr last) { IntervalTreeNode *n, *next; + size_t size = target_page_data_size; + + if (likely(size == 0)) { + return; + } assert_memory_lock(); @@ -895,7 +915,7 @@ void page_reset_target_data(target_ulong start, target_ulong last) n != NULL; n = next, next = next ? interval_tree_iter_next(n, start, last) : NULL) { - target_ulong n_start, n_last, p_ofs, p_len; + vaddr n_start, n_last, p_ofs, p_len; TargetPageDataNode *t = container_of(n, TargetPageDataNode, itree); if (n->start >= start && n->last <= last) { @@ -914,16 +934,21 @@ void page_reset_target_data(target_ulong start, target_ulong last) n_last = MIN(last, n->last); p_len = (n_last + 1 - n_start) >> TARGET_PAGE_BITS; - memset(t->data + p_ofs * TARGET_PAGE_DATA_SIZE, 0, - p_len * TARGET_PAGE_DATA_SIZE); + memset(t->data + p_ofs * size, 0, p_len * size); } } -void *page_get_target_data(target_ulong address) +void *page_get_target_data(vaddr address, size_t size) { IntervalTreeNode *n; TargetPageDataNode *t; - target_ulong page, region, p_ofs; + vaddr page, region, p_ofs; + + /* Remember the size from the first call, and it should be constant. */ + if (unlikely(target_page_data_size != size)) { + assert(target_page_data_size == 0); + target_page_data_size = size; + } page = address & TARGET_PAGE_MASK; region = address & TBD_MASK; @@ -939,8 +964,7 @@ void *page_get_target_data(target_ulong address) mmap_lock(); n = interval_tree_iter_first(&targetdata_root, page, page); if (!n) { - t = g_malloc0(sizeof(TargetPageDataNode) - + TPD_PAGES * TARGET_PAGE_DATA_SIZE); + t = g_malloc0(sizeof(TargetPageDataNode) + TPD_PAGES * size); n = &t->itree; n->start = region; n->last = region | ~TBD_MASK; @@ -951,11 +975,8 @@ void *page_get_target_data(target_ulong address) t = container_of(n, TargetPageDataNode, itree); p_ofs = (page - region) >> TARGET_PAGE_BITS; - return t->data + p_ofs * TARGET_PAGE_DATA_SIZE; + return t->data + p_ofs * size; } -#else -void page_reset_target_data(target_ulong start, target_ulong last) { } -#endif /* TARGET_PAGE_DATA_SIZE */ /* The system-mode versions of these helpers are in cputlb.c. */ @@ -1017,7 +1038,7 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr, * be under mmap_lock() in order to prevent the creation of * another TranslationBlock in between. */ - tb_invalidate_phys_range(addr, addr + l - 1); + tb_invalidate_phys_range(NULL, addr, addr + l - 1); written = pwrite(fd, buf, l, (off_t)(uintptr_t)g2h_untagged(addr)); if (written != l) { @@ -1123,7 +1144,7 @@ static uint64_t do_ld8_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi, return ret; } -static Int128 do_ld16_mmu(CPUState *cpu, abi_ptr addr, +static Int128 do_ld16_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi, uintptr_t ra) { void *haddr; diff --git a/bsd-user/main.c b/bsd-user/main.c index fdb160bed0..603fc80ba7 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -36,7 +36,6 @@ #include "qemu/help_option.h" #include "qemu/module.h" #include "qemu/plugin.h" -#include "exec/exec-all.h" #include "user/guest-base.h" #include "user/page-protection.h" #include "tcg/startup.h" @@ -90,6 +89,7 @@ bool have_guest_base; #endif unsigned long reserved_va; +unsigned long guest_addr_max; const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; const char *qemu_uname_release; @@ -501,6 +501,13 @@ int main(int argc, char **argv) /* MAX_RESERVED_VA + 1 is a large power of 2, so is aligned. */ reserved_va = max_reserved_va; } + if (reserved_va != 0) { + guest_addr_max = reserved_va; + } else if (MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) { + guest_addr_max = UINT32_MAX; + } else { + guest_addr_max = ~0ul; + } if (getenv("QEMU_STRACE")) { do_strace = 1; diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 244670dd24..93388e7c34 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -23,7 +23,6 @@ #include "cpu.h" #include "qemu/units.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" #include "user/abitypes.h" #include "user/cpu_loop.h" diff --git a/bsd-user/signal.c b/bsd-user/signal.c index 1aa0fd79d6..dadcc037dc 100644 --- a/bsd-user/signal.c +++ b/bsd-user/signal.c @@ -1030,7 +1030,7 @@ void process_pending_signals(CPUArchState *env) ts->in_sigsuspend = false; } -void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, +void cpu_loop_exit_sigsegv(CPUState *cpu, vaddr addr, MMUAccessType access_type, bool maperr, uintptr_t ra) { const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; @@ -1046,7 +1046,7 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, cpu_loop_exit_restore(cpu, ra); } -void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, +void cpu_loop_exit_sigbus(CPUState *cpu, vaddr addr, MMUAccessType access_type, uintptr_t ra) { const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; diff --git a/docs/devel/codebase.rst b/docs/devel/codebase.rst index 40273e7d31..2a3143787a 100644 --- a/docs/devel/codebase.rst +++ b/docs/devel/codebase.rst @@ -116,7 +116,7 @@ yet, so sometimes the source code is all you have. * `monitor <https://gitlab.com/qemu-project/qemu/-/tree/master/monitor>`_: `Monitor <QEMU monitor>` implementation (HMP & QMP). * `nbd <https://gitlab.com/qemu-project/qemu/-/tree/master/nbd>`_: - QEMU `NBD (Network Block Device) <nbd>` server. + QEMU NBD (Network Block Device) server. * `net <https://gitlab.com/qemu-project/qemu/-/tree/master/net>`_: Network (host) support. * `pc-bios <https://gitlab.com/qemu-project/qemu/-/tree/master/pc-bios>`_: diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc index cfe1acb78a..384e95ba76 100644 --- a/docs/system/qemu-block-drivers.rst.inc +++ b/docs/system/qemu-block-drivers.rst.inc @@ -500,8 +500,6 @@ What you should *never* do: - expect it to work when loadvm'ing - write to the FAT directory on the host system while accessing it with the guest system -.. _nbd: - NBD access ~~~~~~~~~~ diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c index 5cc67b132f..d7ee306de7 100644 --- a/hw/arm/npcm8xx.c +++ b/hw/arm/npcm8xx.c @@ -67,6 +67,9 @@ /* SDHCI Modules */ #define NPCM8XX_MMC_BA 0xf0842000 +/* PSPI Modules */ +#define NPCM8XX_PSPI_BA 0xf0201000 + /* Run PLL1 at 1600 MHz */ #define NPCM8XX_PLLCON1_FIXUP_VAL 0x00402101 /* Run the CPU from PLL1 and UART from PLL2 */ @@ -83,6 +86,7 @@ enum NPCM8xxInterrupt { NPCM8XX_PECI_IRQ = 6, NPCM8XX_KCS_HIB_IRQ = 9, NPCM8XX_MMC_IRQ = 26, + NPCM8XX_PSPI_IRQ = 28, NPCM8XX_TIMER0_IRQ = 32, /* Timer Module 0 */ NPCM8XX_TIMER1_IRQ, NPCM8XX_TIMER2_IRQ, @@ -441,6 +445,7 @@ static void npcm8xx_init(Object *obj) } object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI); + object_initialize_child(obj, "pspi", &s->pspi, TYPE_NPCM_PSPI); } static void npcm8xx_realize(DeviceState *dev, Error **errp) @@ -705,6 +710,11 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0, npcm8xx_irq(s, NPCM8XX_MMC_IRQ)); + /* PSPI */ + sysbus_realize(SYS_BUS_DEVICE(&s->pspi), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->pspi), 0, NPCM8XX_PSPI_BA); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pspi), 0, + npcm8xx_irq(s, NPCM8XX_PSPI_IRQ)); create_unimplemented_device("npcm8xx.shm", 0xc0001000, 4 * KiB); create_unimplemented_device("npcm8xx.gicextra", 0xdfffa000, 24 * KiB); @@ -720,7 +730,6 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp) create_unimplemented_device("npcm8xx.siox[1]", 0xf0101000, 4 * KiB); create_unimplemented_device("npcm8xx.siox[2]", 0xf0102000, 4 * KiB); create_unimplemented_device("npcm8xx.tmps", 0xf0188000, 4 * KiB); - create_unimplemented_device("npcm8xx.pspi", 0xf0201000, 4 * KiB); create_unimplemented_device("npcm8xx.viru1", 0xf0204000, 4 * KiB); create_unimplemented_device("npcm8xx.viru2", 0xf0205000, 4 * KiB); create_unimplemented_device("npcm8xx.jtm1", 0xf0208000, 4 * KiB); diff --git a/hw/arm/npcm8xx_boards.c b/hw/arm/npcm8xx_boards.c index 9d9f6d0c9a..3bf3e1f8f1 100644 --- a/hw/arm/npcm8xx_boards.c +++ b/hw/arm/npcm8xx_boards.c @@ -213,7 +213,7 @@ static void npcm8xx_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char * const valid_cpu_types[] = { - ARM_CPU_TYPE_NAME("cortex-a9"), + ARM_CPU_TYPE_NAME("cortex-a35"), NULL }; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 3ac8f8e178..7e8e0f0298 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -537,15 +537,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) static void build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); /* * Table 5-117 Flag Definitions * set only "Timer interrupt Mode" and assume "Timer Interrupt * polarity" bit as '0: Interrupt is Active high' */ - uint32_t irqflags = vmc->claim_edge_triggered_timers ? - 1 : /* Interrupt is Edge triggered */ - 0; /* Interrupt is Level triggered */ + const uint32_t irqflags = 0; /* Interrupt is Level triggered */ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; @@ -670,7 +667,6 @@ static void build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { int i; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); const MemMapEntry *memmap = vms->memmap; AcpiTable table = { .sig = "APIC", .rev = 4, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; @@ -741,7 +737,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) memmap[VIRT_HIGH_GIC_REDIST2].size); } - if (its_class_name() && !vmc->no_its) { + if (its_class_name()) { /* * ACPI spec, Revision 6.0 Errata A * (original 6.0 definition has invalid Length) @@ -973,7 +969,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) vms->oem_table_id); } - if (its_class_name() && !vmc->no_its) { + if (its_class_name()) { acpi_add_table(table_offsets, tables_blob); build_iort(tables_blob, tables->linker, vms); } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 177f3dd22c..9a6cd085a3 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -370,14 +370,9 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) * the correct information. */ ARMCPU *armcpu; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; MachineState *ms = MACHINE(vms); - if (vmc->claim_edge_triggered_timers) { - irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI; - } - if (vms->gic_version == VIRT_GIC_VERSION_2) { irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, GIC_FDT_IRQ_PPI_CPU_WIDTH, @@ -1704,7 +1699,6 @@ static void virt_build_smbios(VirtMachineState *vms) { MachineClass *mc = MACHINE_GET_CLASS(vms); MachineState *ms = MACHINE(vms); - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); uint8_t *smbios_tables, *smbios_anchor; size_t smbios_tables_len, smbios_anchor_len; struct smbios_phys_mem_area mem_array; @@ -1714,8 +1708,7 @@ static void virt_build_smbios(VirtMachineState *vms) product = "KVM Virtual Machine"; } - smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name); + smbios_set_defaults("QEMU", product, mc->name); /* build the array of physical mem area from base_memmap */ mem_array.address = vms->memmap[VIRT_MEM].base; @@ -1770,24 +1763,18 @@ void virt_machine_done(Notifier *notifier, void *data) static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) { - uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); + uint8_t clustersz; - if (!vmc->disallow_affinity_adjustment) { - /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the - * GIC's target-list limitations. 32-bit KVM hosts currently - * always create clusters of 4 CPUs, but that is expected to - * change when they gain support for gicv3. When KVM is enabled - * it will override the changes we make here, therefore our - * purposes are to make TCG consistent (with 64-bit KVM hosts) - * and to improve SGI efficiency. - */ - if (vms->gic_version == VIRT_GIC_VERSION_2) { - clustersz = GIC_TARGETLIST_BITS; - } else { - clustersz = GICV3_TARGETLIST_BITS; - } + /* + * Adjust MPIDR to make TCG consistent (with 64-bit KVM hosts) + * and to improve SGI efficiency. + */ + if (vms->gic_version == VIRT_GIC_VERSION_2) { + clustersz = GIC_TARGETLIST_BITS; + } else { + clustersz = GICV3_TARGETLIST_BITS; } + return arm_build_mp_affinity(idx, clustersz); } @@ -2273,10 +2260,6 @@ static void machvirt_init(MachineState *machine) object_property_set_bool(cpuobj, "kvm-steal-time", false, NULL); } - if (vmc->no_pmu && object_property_find(cpuobj, "pmu")) { - object_property_set_bool(cpuobj, "pmu", false, NULL); - } - if (vmc->no_tcg_lpa2 && object_property_find(cpuobj, "lpa2")) { object_property_set_bool(cpuobj, "lpa2", false, NULL); } @@ -3348,21 +3331,17 @@ static void virt_instance_init(Object *obj) vms->highmem_compact = !vmc->no_highmem_compact; vms->gic_version = VIRT_GIC_VERSION_NOSEL; - vms->highmem_ecam = !vmc->no_highmem_ecam; + vms->highmem_ecam = true; vms->highmem_mmio = true; vms->highmem_redists = true; - if (vmc->no_its) { - vms->its = false; - } else { - /* Default allows ITS instantiation */ - vms->its = true; + /* Default allows ITS instantiation */ + vms->its = true; - if (vmc->no_tcg_its) { - vms->tcg_its = false; - } else { - vms->tcg_its = true; - } + if (vmc->no_tcg_its) { + vms->tcg_its = false; + } else { + vms->tcg_its = true; } /* Default disallows iommu instantiation */ @@ -3583,99 +3562,3 @@ static void virt_machine_4_1_options(MachineClass *mc) mc->auto_enable_numa_with_memhp = false; } DEFINE_VIRT_MACHINE(4, 1) - -static void virt_machine_4_0_options(MachineClass *mc) -{ - virt_machine_4_1_options(mc); - compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len); -} -DEFINE_VIRT_MACHINE(4, 0) - -static void virt_machine_3_1_options(MachineClass *mc) -{ - virt_machine_4_0_options(mc); - compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len); -} -DEFINE_VIRT_MACHINE(3, 1) - -static void virt_machine_3_0_options(MachineClass *mc) -{ - virt_machine_3_1_options(mc); - compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len); -} -DEFINE_VIRT_MACHINE(3, 0) - -static void virt_machine_2_12_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_3_0_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len); - vmc->no_highmem_ecam = true; - mc->max_cpus = 255; -} -DEFINE_VIRT_MACHINE(2, 12) - -static void virt_machine_2_11_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_12_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len); - vmc->smbios_old_sys_ver = true; -} -DEFINE_VIRT_MACHINE(2, 11) - -static void virt_machine_2_10_options(MachineClass *mc) -{ - virt_machine_2_11_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len); - /* before 2.11 we never faulted accesses to bad addresses */ - mc->ignore_memory_transaction_failures = true; -} -DEFINE_VIRT_MACHINE(2, 10) - -static void virt_machine_2_9_options(MachineClass *mc) -{ - virt_machine_2_10_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len); -} -DEFINE_VIRT_MACHINE(2, 9) - -static void virt_machine_2_8_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_9_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len); - /* For 2.8 and earlier we falsely claimed in the DT that - * our timers were edge-triggered, not level-triggered. - */ - vmc->claim_edge_triggered_timers = true; -} -DEFINE_VIRT_MACHINE(2, 8) - -static void virt_machine_2_7_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_8_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len); - /* ITS was introduced with 2.8 */ - vmc->no_its = true; - /* Stick with 1K pages for migration compatibility */ - mc->minimum_page_bits = 0; -} -DEFINE_VIRT_MACHINE(2, 7) - -static void virt_machine_2_6_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_7_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len); - vmc->disallow_affinity_adjustment = true; - /* Disable PMU for 2.6 as PMU support was first introduced in 2.7 */ - vmc->no_pmu = true; -} -DEFINE_VIRT_MACHINE(2, 6) diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c index f23c52af26..450ece4548 100644 --- a/hw/gpio/imx_gpio.c +++ b/hw/gpio/imx_gpio.c @@ -72,7 +72,7 @@ static void imx_gpio_update_int(IMXGPIOState *s) static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level) { /* if this signal isn't configured as an input signal, nothing to do */ - if (!extract32(s->gdir, line, 1)) { + if (extract32(s->gdir, line, 1)) { return; } diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index f4fe961a98..7c38c4c9b7 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -377,11 +377,13 @@ static void loongarch_extioi_unrealize(DeviceState *dev) g_free(s->cpu); } -static void loongarch_extioi_reset(DeviceState *d) +static void loongarch_extioi_reset_hold(Object *obj, ResetType type) { - LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(d); + LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_GET_CLASS(obj); - s->status = 0; + if (lec->parent_phases.hold) { + lec->parent_phases.hold(obj, type); + } } static int vmstate_extioi_post_load(void *opaque, int version_id) @@ -406,12 +408,14 @@ static void loongarch_extioi_class_init(ObjectClass *klass, const void *data) DeviceClass *dc = DEVICE_CLASS(klass); LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_CLASS(klass); LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_extioi_realize, &lec->parent_realize); device_class_set_parent_unrealize(dc, loongarch_extioi_unrealize, &lec->parent_unrealize); - device_class_set_legacy_reset(dc, loongarch_extioi_reset); + resettable_class_set_parent_phases(rc, NULL, loongarch_extioi_reset_hold, + NULL, &lec->parent_phases); lecc->post_load = vmstate_extioi_post_load; } diff --git a/hw/intc/loongarch_extioi_common.c b/hw/intc/loongarch_extioi_common.c index 9e1589060c..4a904b3bc1 100644 --- a/hw/intc/loongarch_extioi_common.c +++ b/hw/intc/loongarch_extioi_common.c @@ -108,6 +108,43 @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp) } } +static void loongarch_extioi_common_reset_hold(Object *obj, ResetType type) +{ + LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(obj); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(obj); + ExtIOICore *core; + int i; + + if (lecc->parent_phases.hold) { + lecc->parent_phases.hold(obj, type); + } + + /* Clear HW registers for the board */ + memset(s->nodetype, 0, sizeof(s->nodetype)); + memset(s->bounce, 0, sizeof(s->bounce)); + memset(s->isr, 0, sizeof(s->isr)); + memset(s->enable, 0, sizeof(s->enable)); + memset(s->ipmap, 0, sizeof(s->ipmap)); + memset(s->coremap, 0, sizeof(s->coremap)); + memset(s->sw_pending, 0, sizeof(s->sw_pending)); + memset(s->sw_ipmap, 0, sizeof(s->sw_ipmap)); + memset(s->sw_coremap, 0, sizeof(s->sw_coremap)); + + for (i = 0; i < s->num_cpu; i++) { + core = s->cpu + i; + /* EXTIOI with targeted CPU available however not present */ + if (!core->cpu) { + continue; + } + + /* Clear HW registers for CPUs */ + memset(core->coreisr, 0, sizeof(core->coreisr)); + memset(core->sw_isr, 0, sizeof(core->sw_isr)); + } + + s->status = 0; +} + static int loongarch_extioi_common_pre_save(void *opaque) { LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque; @@ -180,9 +217,13 @@ static void loongarch_extioi_common_class_init(ObjectClass *klass, DeviceClass *dc = DEVICE_CLASS(klass); LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_extioi_common_realize, &lecc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, + loongarch_extioi_common_reset_hold, + NULL, &lecc->parent_phases); device_class_set_props(dc, extioi_properties); dc->vmsd = &vmstate_loongarch_extioi; hc->plug = loongarch_extioi_cpu_plug; diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 2f8bb57828..74372a2039 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -93,6 +93,32 @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp) } } +static void loongarch_ipi_reset_hold(Object *obj, ResetType type) +{ + int i; + LoongarchIPIClass *lic = LOONGARCH_IPI_GET_CLASS(obj); + LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(obj); + IPICore *core; + + if (lic->parent_phases.hold) { + lic->parent_phases.hold(obj, type); + } + + for (i = 0; i < lics->num_cpu; i++) { + core = lics->cpu + i; + /* IPI with targeted CPU available however not present */ + if (!core->cpu) { + continue; + } + + core->status = 0; + core->en = 0; + core->set = 0; + core->clear = 0; + memset(core->buf, 0, sizeof(core->buf)); + } +} + static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -145,10 +171,13 @@ static void loongarch_ipi_class_init(ObjectClass *klass, const void *data) LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_ipi_realize, &lic->parent_realize); + resettable_class_set_parent_phases(rc, NULL, loongarch_ipi_reset_hold, + NULL, &lic->parent_phases); licc->get_iocsr_as = get_iocsr_as; licc->cpu_by_arch_id = loongarch_cpu_by_arch_id; hc->plug = loongarch_ipi_cpu_plug; diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c index 6c2b6de3f0..834096265a 100644 --- a/hw/intc/loongarch_pch_pic.c +++ b/hw/intc/loongarch_pch_pic.c @@ -354,25 +354,13 @@ static const MemoryRegionOps loongarch_pch_pic_reg8_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static void loongarch_pch_pic_reset(DeviceState *d) +static void loongarch_pic_reset_hold(Object *obj, ResetType type) { - LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(d); - int i; - - s->int_mask = -1; - s->htmsi_en = 0x0; - s->intedge = 0x0; - s->intclr = 0x0; - s->auto_crtl0 = 0x0; - s->auto_crtl1 = 0x0; - for (i = 0; i < 64; i++) { - s->route_entry[i] = 0x1; - s->htmsi_vector[i] = 0x0; + LoongarchPICClass *lpc = LOONGARCH_PIC_GET_CLASS(obj); + + if (lpc->parent_phases.hold) { + lpc->parent_phases.hold(obj, type); } - s->intirr = 0x0; - s->intisr = 0x0; - s->last_intirr = 0x0; - s->int_polarity = 0x0; } static void loongarch_pic_realize(DeviceState *dev, Error **errp) @@ -408,8 +396,10 @@ static void loongarch_pic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongarchPICClass *lpc = LOONGARCH_PIC_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); - device_class_set_legacy_reset(dc, loongarch_pch_pic_reset); + resettable_class_set_parent_phases(rc, NULL, loongarch_pic_reset_hold, + NULL, &lpc->parent_phases); device_class_set_parent_realize(dc, loongarch_pic_realize, &lpc->parent_realize); } diff --git a/hw/intc/loongarch_pic_common.c b/hw/intc/loongarch_pic_common.c index fdb250c418..6dccacc741 100644 --- a/hw/intc/loongarch_pic_common.c +++ b/hw/intc/loongarch_pic_common.c @@ -44,6 +44,27 @@ static void loongarch_pic_common_realize(DeviceState *dev, Error **errp) } } +static void loongarch_pic_common_reset_hold(Object *obj, ResetType type) +{ + LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(obj); + int i; + + s->int_mask = UINT64_MAX; + s->htmsi_en = 0x0; + s->intedge = 0x0; + s->intclr = 0x0; + s->auto_crtl0 = 0x0; + s->auto_crtl1 = 0x0; + for (i = 0; i < 64; i++) { + s->route_entry[i] = 0x1; + s->htmsi_vector[i] = 0x0; + } + s->intirr = 0x0; + s->intisr = 0x0; + s->last_intirr = 0x0; + s->int_polarity = 0x0; +} + static const Property loongarch_pic_common_properties[] = { DEFINE_PROP_UINT32("pch_pic_irq_num", LoongArchPICCommonState, irq_num, 0), }; @@ -76,9 +97,13 @@ static void loongarch_pic_common_class_init(ObjectClass *klass, { DeviceClass *dc = DEVICE_CLASS(klass); LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_pic_common_realize, &lpcc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, + loongarch_pic_common_reset_hold, + NULL, &lpcc->parent_phases); device_class_set_props(dc, loongarch_pic_common_properties); dc->vmsd = &vmstate_loongarch_pic_common; } diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 354cf458c8..0324d6adcb 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -245,6 +245,7 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) &kernel_entry, &kernel_low, &kernel_high, NULL, ELFDATA2LSB, EM_LOONGARCH, 1, 0); + kernel_entry = cpu_loongarch_virt_to_phys(NULL, kernel_entry); if (kernel_size < 0) { kernel_size = load_loongarch_linux_image(info->kernel_filename, &kernel_entry, &kernel_low, diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c index fced6c445a..073b6de75c 100644 --- a/hw/loongarch/virt-acpi-build.c +++ b/hw/loongarch/virt-acpi-build.c @@ -514,7 +514,7 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); GArray *table_offsets; AcpiFadtData fadt_data; - unsigned facs, rsdt, dsdt; + unsigned facs, xsdt, dsdt; uint8_t *u; GArray *tables_blob = tables->table_data; @@ -600,17 +600,17 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) } /* RSDT is pointed to by RSDP */ - rsdt = tables_blob->len; - build_rsdt(tables_blob, tables->linker, table_offsets, + xsdt = tables_blob->len; + build_xsdt(tables_blob, tables->linker, table_offsets, lvms->oem_id, lvms->oem_table_id); /* RSDP is in FSEG memory, so allocate it separately */ { AcpiRsdpData rsdp_data = { - .revision = 0, + .revision = 2, .oem_id = lvms->oem_id, - .xsdt_tbl_offset = NULL, - .rsdt_tbl_offset = &rsdt, + .xsdt_tbl_offset = &xsdt, + .rsdt_tbl_offset = NULL, }; build_rsdp(tables->rsdp, tables->linker, &rsdp_data); } diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 779544fada..7ad7fb68ff 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -773,6 +773,48 @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name, visit_type_OnOffAuto(v, name, &lvms->acpi, errp); } +static char *virt_get_oem_id(Object *obj, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + + return g_strdup(lvms->oem_id); +} + +static void virt_set_oem_id(Object *obj, const char *value, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + size_t len = strlen(value); + + if (len > 6) { + error_setg(errp, + "User specified oem-id value is bigger than 6 bytes in size"); + return; + } + + strncpy(lvms->oem_id, value, 6); +} + +static char *virt_get_oem_table_id(Object *obj, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + + return g_strdup(lvms->oem_table_id); +} + +static void virt_set_oem_table_id(Object *obj, const char *value, + Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + size_t len = strlen(value); + + if (len > 8) { + error_setg(errp, + "User specified oem-table-id value is bigger than 8 bytes in size"); + return; + } + strncpy(lvms->oem_table_id, value, 8); +} + static void virt_initfn(Object *obj) { LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); @@ -1177,6 +1219,22 @@ static void virt_class_init(ObjectClass *oc, const void *data) #ifdef CONFIG_TPM machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); #endif + object_class_property_add_str(oc, "x-oem-id", + virt_get_oem_id, + virt_set_oem_id); + object_class_property_set_description(oc, "x-oem-id", + "Override the default value of field OEMID " + "in ACPI table header." + "The string may be up to 6 bytes in size"); + + + object_class_property_add_str(oc, "x-oem-table-id", + virt_get_oem_table_id, + virt_set_oem_table_id); + object_class_property_set_description(oc, "x-oem-table-id", + "Override the default value of field OEM Table ID " + "in ACPI table header." + "The string may be up to 8 bytes in size"); } static const TypeInfo virt_machine_types[] = { diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c index 183f838392..f6e49ce9b8 100644 --- a/hw/pci-host/designware.c +++ b/hw/pci-host/designware.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qemu/module.h" #include "qemu/log.h" #include "qemu/bitops.h" #include "hw/pci/msi.h" @@ -349,14 +348,14 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address, case DESIGNWARE_PCIE_ATU_LOWER_BASE: case DESIGNWARE_PCIE_ATU_UPPER_BASE: - viewport->base = deposit64(root->msi.base, + viewport->base = deposit64(viewport->base, address == DESIGNWARE_PCIE_ATU_LOWER_BASE ? 0 : 32, 32, val); break; case DESIGNWARE_PCIE_ATU_LOWER_TARGET: case DESIGNWARE_PCIE_ATU_UPPER_TARGET: - viewport->target = deposit64(root->msi.base, + viewport->target = deposit64(viewport->target, address == DESIGNWARE_PCIE_ATU_LOWER_TARGET ? 0 : 32, 32, val); break; diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c index 820f752b9e..10cf634da1 100644 --- a/hw/ppc/spapr_nested.c +++ b/hw/ppc/spapr_nested.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include "qemu/cutils.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/target_long.h" #include "helper_regs.h" diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c index be2e3944dc..74e76b94a5 100644 --- a/hw/riscv/riscv-iommu-sys.c +++ b/hw/riscv/riscv-iommu-sys.c @@ -26,7 +26,6 @@ #include "qemu/host-utils.h" #include "qemu/module.h" #include "qom/object.h" -#include "exec/exec-all.h" #include "trace.h" #include "riscv-iommu.h" diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c index 41306fb600..300eabc595 100644 --- a/hw/sh4/sh7750.c +++ b/hw/sh4/sh7750.c @@ -36,7 +36,6 @@ #include "sh7750_regnames.h" #include "hw/sh4/sh_intc.h" #include "hw/timer/tmu012.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "trace.h" diff --git a/include/accel/tcg/cpu-ldst.h b/include/accel/tcg/cpu-ldst.h index f97a730703..0de7f5eaa6 100644 --- a/include/accel/tcg/cpu-ldst.h +++ b/include/accel/tcg/cpu-ldst.h @@ -502,62 +502,4 @@ static inline uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr) return cpu_ldq_code_mmu(env, addr, oi, 0); } -/** - * tlb_vaddr_to_host: - * @env: CPUArchState - * @addr: guest virtual address to look up - * @access_type: 0 for read, 1 for write, 2 for execute - * @mmu_idx: MMU index to use for lookup - * - * Look up the specified guest virtual index in the TCG softmmu TLB. - * If we can translate a host virtual address suitable for direct RAM - * access, without causing a guest exception, then return it. - * Otherwise (TLB entry is for an I/O access, guest software - * TLB fill required, etc) return NULL. - */ -#ifdef CONFIG_USER_ONLY -static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, - MMUAccessType access_type, int mmu_idx) -{ - return g2h(env_cpu(env), addr); -} -#else -void *tlb_vaddr_to_host(CPUArchState *env, vaddr addr, - MMUAccessType access_type, int mmu_idx); -#endif - -/* - * For user-only, helpers that use guest to host address translation - * must protect the actual host memory access by recording 'retaddr' - * for the signal handler. This is required for a race condition in - * which another thread unmaps the page between a probe and the - * actual access. - */ -#ifdef CONFIG_USER_ONLY -extern __thread uintptr_t helper_retaddr; - -static inline void set_helper_retaddr(uintptr_t ra) -{ - helper_retaddr = ra; - /* - * Ensure that this write is visible to the SIGSEGV handler that - * may be invoked due to a subsequent invalid memory operation. - */ - signal_barrier(); -} - -static inline void clear_helper_retaddr(void) -{ - /* - * Ensure that previous memory operations have succeeded before - * removing the data visible to the signal handler. - */ - signal_barrier(); - helper_retaddr = 0; -} -#else -#define set_helper_retaddr(ra) do { } while (0) -#define clear_helper_retaddr() do { } while (0) -#endif - #endif /* ACCEL_TCG_CPU_LDST_H */ diff --git a/include/accel/tcg/cpu-ops.h b/include/accel/tcg/cpu-ops.h index 0e4352513d..cd22e5d5b9 100644 --- a/include/accel/tcg/cpu-ops.h +++ b/include/accel/tcg/cpu-ops.h @@ -16,6 +16,7 @@ #include "exec/memop.h" #include "exec/mmu-access-type.h" #include "exec/vaddr.h" +#include "accel/tcg/tb-cpu-state.h" #include "tcg/tcg-mo.h" struct TCGCPUOps { @@ -29,6 +30,13 @@ struct TCGCPUOps { bool mttcg_supported; /** + * @precise_smc: Stores which modify code within the current TB force + * the TB to exit; the next executed instruction will see + * the result of the store. + */ + bool precise_smc; + + /** * @guest_default_memory_order: default barrier that is required * for the guest memory ordering. */ @@ -54,6 +62,12 @@ struct TCGCPUOps { void (*translate_code)(CPUState *cpu, TranslationBlock *tb, int *max_insns, vaddr pc, void *host_pc); /** + * @get_tb_cpu_state: Extract CPU state for a TCG #TranslationBlock + * + * Fill in all data required to select or compile a TranslationBlock. + */ + TCGTBCPUState (*get_tb_cpu_state)(CPUState *cs); + /** * @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock * * This is called when we abandon execution of a TB before starting it, @@ -143,11 +157,20 @@ struct TCGCPUOps { */ void (*record_sigbus)(CPUState *cpu, vaddr addr, MMUAccessType access_type, uintptr_t ra); + + /** + * untagged_addr: Remove an ignored tag from an address + * @cpu: cpu context + * @addr: tagged guest address + */ + vaddr (*untagged_addr)(CPUState *cs, vaddr addr); #else /** @do_interrupt: Callback for interrupt handling. */ void (*do_interrupt)(CPUState *cpu); /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */ bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); + /** @cpu_exec_reset: Callback for reset in cpu_exec. */ + void (*cpu_exec_reset)(CPUState *cpu); /** * @cpu_exec_halt: Callback for handling halt in cpu_exec. * diff --git a/include/accel/tcg/getpc.h b/include/accel/tcg/getpc.h index 8a97ce34e7..0fc08addcf 100644 --- a/include/accel/tcg/getpc.h +++ b/include/accel/tcg/getpc.h @@ -8,10 +8,6 @@ #ifndef ACCEL_TCG_GETPC_H #define ACCEL_TCG_GETPC_H -#ifndef CONFIG_TCG -#error Can only include this header with TCG -#endif - /* GETPC is the true target of the return instruction that we'll execute. */ #ifdef CONFIG_TCG_INTERPRETER extern __thread uintptr_t tci_tb_ptr; diff --git a/include/accel/tcg/helper-retaddr.h b/include/accel/tcg/helper-retaddr.h new file mode 100644 index 0000000000..037fda2b83 --- /dev/null +++ b/include/accel/tcg/helper-retaddr.h @@ -0,0 +1,43 @@ +/* + * Get user helper pc for memory unwinding. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifndef ACCEL_TCG_HELPER_RETADDR_H +#define ACCEL_TCG_HELPER_RETADDR_H + +/* + * For user-only, helpers that use guest to host address translation + * must protect the actual host memory access by recording 'retaddr' + * for the signal handler. This is required for a race condition in + * which another thread unmaps the page between a probe and the + * actual access. + */ +#ifdef CONFIG_USER_ONLY +extern __thread uintptr_t helper_retaddr; + +static inline void set_helper_retaddr(uintptr_t ra) +{ + helper_retaddr = ra; + /* + * Ensure that this write is visible to the SIGSEGV handler that + * may be invoked due to a subsequent invalid memory operation. + */ + signal_barrier(); +} + +static inline void clear_helper_retaddr(void) +{ + /* + * Ensure that previous memory operations have succeeded before + * removing the data visible to the signal handler. + */ + signal_barrier(); + helper_retaddr = 0; +} +#else +#define set_helper_retaddr(ra) do { } while (0) +#define clear_helper_retaddr() do { } while (0) +#endif + +#endif /* ACCEL_TCG_HELPER_RETADDR_H */ diff --git a/include/accel/tcg/iommu.h b/include/accel/tcg/iommu.h new file mode 100644 index 0000000000..90cfd6c0ed --- /dev/null +++ b/include/accel/tcg/iommu.h @@ -0,0 +1,41 @@ +/* + * TCG IOMMU translations. + * + * Copyright (c) 2003 Fabrice Bellard + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +#ifndef ACCEL_TCG_IOMMU_H +#define ACCEL_TCG_IOMMU_H + +#ifdef CONFIG_USER_ONLY +#error Cannot include accel/tcg/iommu.h from user emulation +#endif + +#include "exec/hwaddr.h" +#include "exec/memattrs.h" + +/** + * iotlb_to_section: + * @cpu: CPU performing the access + * @index: TCG CPU IOTLB entry + * + * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that + * it refers to. @index will have been initially created and returned + * by memory_region_section_get_iotlb(). + */ +MemoryRegionSection *iotlb_to_section(CPUState *cpu, + hwaddr index, MemTxAttrs attrs); + +MemoryRegionSection *address_space_translate_for_iotlb(CPUState *cpu, + int asidx, + hwaddr addr, + hwaddr *xlat, + hwaddr *plen, + MemTxAttrs attrs, + int *prot); + +hwaddr memory_region_section_get_iotlb(CPUState *cpu, + MemoryRegionSection *section); + +#endif + diff --git a/include/exec/exec-all.h b/include/accel/tcg/probe.h index 944b579d91..dd9ecbbdf1 100644 --- a/include/exec/exec-all.h +++ b/include/accel/tcg/probe.h @@ -1,30 +1,14 @@ /* - * internal execution defines for qemu + * Probe guest virtual addresses for access permissions. * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * Copyright (c) 2003 Fabrice Bellard + * SPDX-License-Identifier: LGPL-2.1-or-later */ - -#ifndef EXEC_ALL_H -#define EXEC_ALL_H +#ifndef ACCEL_TCG_PROBE_H +#define ACCEL_TCG_PROBE_H #include "exec/mmu-access-type.h" -#include "exec/translation-block.h" - -#if defined(CONFIG_TCG) -#include "accel/tcg/getpc.h" +#include "exec/vaddr.h" /** * probe_access: @@ -118,36 +102,21 @@ int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size, void **phost, CPUTLBEntryFull **pfull); #endif /* !CONFIG_USER_ONLY */ -#endif /* CONFIG_TCG */ - -/* TranslationBlock invalidate API */ -void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); -void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last); -void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr); - -#if !defined(CONFIG_USER_ONLY) /** - * iotlb_to_section: - * @cpu: CPU performing the access - * @index: TCG CPU IOTLB entry + * tlb_vaddr_to_host: + * @env: CPUArchState + * @addr: guest virtual address to look up + * @access_type: 0 for read, 1 for write, 2 for execute + * @mmu_idx: MMU index to use for lookup * - * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that - * it refers to. @index will have been initially created and returned - * by memory_region_section_get_iotlb(). + * Look up the specified guest virtual index in the TCG softmmu TLB. + * If we can translate a host virtual address suitable for direct RAM + * access, without causing a guest exception, then return it. + * Otherwise (TLB entry is for an I/O access, guest software + * TLB fill required, etc) return NULL. */ -struct MemoryRegionSection *iotlb_to_section(CPUState *cpu, - hwaddr index, MemTxAttrs attrs); -#endif - -#if !defined(CONFIG_USER_ONLY) - -MemoryRegionSection * -address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, - hwaddr *xlat, hwaddr *plen, - MemTxAttrs attrs, int *prot); -hwaddr memory_region_section_get_iotlb(CPUState *cpu, - MemoryRegionSection *section); -#endif +void *tlb_vaddr_to_host(CPUArchState *env, vaddr addr, + MMUAccessType access_type, int mmu_idx); #endif diff --git a/include/accel/tcg/tb-cpu-state.h b/include/accel/tcg/tb-cpu-state.h new file mode 100644 index 0000000000..8f912900ca --- /dev/null +++ b/include/accel/tcg/tb-cpu-state.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Definition of TCGTBCPUState. + */ + +#ifndef EXEC_TB_CPU_STATE_H +#define EXEC_TB_CPU_STATE_H + +#include "exec/vaddr.h" + +typedef struct TCGTBCPUState { + vaddr pc; + uint32_t flags; + uint32_t cflags; + uint64_t cs_base; +} TCGTBCPUState; + +#endif diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h index 16782ef46c..76e6c25bec 100644 --- a/include/exec/helper-proto-common.h +++ b/include/exec/helper-proto-common.h @@ -13,4 +13,6 @@ #include "exec/helper-proto.h.inc" #undef HELPER_H +#include "accel/tcg/getpc.h" + #endif /* HELPER_PROTO_COMMON_H */ diff --git a/include/exec/poison.h b/include/exec/poison.h index bc422719d8..a779adbb7a 100644 --- a/include/exec/poison.h +++ b/include/exec/poison.h @@ -37,7 +37,6 @@ #pragma GCC poison TARGET_NAME #pragma GCC poison TARGET_BIG_ENDIAN #pragma GCC poison TCG_GUEST_DEFAULT_MO -#pragma GCC poison TARGET_HAS_PRECISE_SMC #pragma GCC poison TARGET_LONG_BITS #pragma GCC poison TARGET_FMT_lx diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h index 8b8e730561..cdce399eba 100644 --- a/include/exec/translation-block.h +++ b/include/exec/translation-block.h @@ -207,4 +207,8 @@ static inline void tb_set_page_addr1(TranslationBlock *tb, #endif } +/* TranslationBlock invalidate API */ +void tb_invalidate_phys_range(CPUState *cpu, tb_page_addr_t start, + tb_page_addr_t last); + #endif /* EXEC_TRANSLATION_BLOCK_H */ diff --git a/include/hw/arm/npcm8xx.h b/include/hw/arm/npcm8xx.h index 9812e6fa7e..3436abff99 100644 --- a/include/hw/arm/npcm8xx.h +++ b/include/hw/arm/npcm8xx.h @@ -36,6 +36,7 @@ #include "hw/usb/hcd-ehci.h" #include "hw/usb/hcd-ohci.h" #include "target/arm/cpu.h" +#include "hw/ssi/npcm_pspi.h" #define NPCM8XX_MAX_NUM_CPUS (4) @@ -99,6 +100,7 @@ struct NPCM8xxState { OHCISysBusState ohci[2]; NPCM7xxFIUState fiu[3]; NPCM7xxSDHCIState mmc; + NPCMPSPIState pspi; }; struct NPCM8xxClass { diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index c8e94e6aed..9a1b0f53d2 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -117,14 +117,8 @@ typedef enum VirtGICType { struct VirtMachineClass { MachineClass parent; - bool disallow_affinity_adjustment; - bool no_its; bool no_tcg_its; - bool no_pmu; - bool claim_edge_triggered_timers; - bool smbios_old_sys_ver; bool no_highmem_compact; - bool no_highmem_ecam; bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */ bool kvm_no_adjvtime; bool no_kvm_steal_time; diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index 351f18afcf..4a6ae903e9 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -22,6 +22,7 @@ struct LoongArchExtIOIClass { DeviceRealize parent_realize; DeviceUnrealize parent_unrealize; + ResettablePhases parent_phases; }; #endif /* LOONGARCH_EXTIOI_H */ diff --git a/include/hw/intc/loongarch_extioi_common.h b/include/hw/intc/loongarch_extioi_common.h index 22d7880977..735bfee80a 100644 --- a/include/hw/intc/loongarch_extioi_common.h +++ b/include/hw/intc/loongarch_extioi_common.h @@ -94,6 +94,7 @@ struct LoongArchExtIOICommonClass { SysBusDeviceClass parent_class; DeviceRealize parent_realize; + ResettablePhases parent_phases; int (*pre_save)(void *s); int (*post_load)(void *s, int version_id); }; diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h index 923bf21ecb..a7c6bf85d3 100644 --- a/include/hw/intc/loongarch_ipi.h +++ b/include/hw/intc/loongarch_ipi.h @@ -21,6 +21,7 @@ struct LoongarchIPIState { struct LoongarchIPIClass { LoongsonIPICommonClass parent_class; DeviceRealize parent_realize; + ResettablePhases parent_phases; }; #endif diff --git a/include/hw/intc/loongarch_pch_pic.h b/include/hw/intc/loongarch_pch_pic.h index 481cc58aed..839a59a43b 100644 --- a/include/hw/intc/loongarch_pch_pic.h +++ b/include/hw/intc/loongarch_pch_pic.h @@ -22,6 +22,7 @@ struct LoongarchPICClass { LoongArchPICCommonClass parent_class; DeviceRealize parent_realize; + ResettablePhases parent_phases; }; #endif /* HW_LOONGARCH_PCH_PIC_H */ diff --git a/include/hw/intc/loongarch_pic_common.h b/include/hw/intc/loongarch_pic_common.h index 43cce48978..d301377cd7 100644 --- a/include/hw/intc/loongarch_pic_common.h +++ b/include/hw/intc/loongarch_pic_common.h @@ -76,6 +76,7 @@ struct LoongArchPICCommonClass { SysBusDeviceClass parent_class; DeviceRealize parent_realize; + ResettablePhases parent_phases; int (*pre_save)(LoongArchPICCommonState *s); int (*post_load)(LoongArchPICCommonState *s, int version_id); }; diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h index d30805f7f2..1b51cbcfe1 100644 --- a/include/qemu/target-info-impl.h +++ b/include/qemu/target-info-impl.h @@ -14,6 +14,12 @@ typedef struct TargetInfo { /* runtime equivalent of TARGET_NAME definition */ const char *target_name; + /* runtime equivalent of TARGET_LONG_BITS definition */ + unsigned long_bits; + /* runtime equivalent of CPU_RESOLVING_TYPE definition */ + const char *cpu_type; + /* QOM typename machines for this binary must implement */ + const char *machine_typename; } TargetInfo; /** diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h index 58d4136897..850a2958b9 100644 --- a/include/qemu/target-info.h +++ b/include/qemu/target-info.h @@ -17,6 +17,21 @@ const char *target_name(void); /** + * target_long_bits: + * + * Returns: number of bits in a long type for this target (i.e. 64). + */ +unsigned target_long_bits(void); + +/** + * target_machine_typename: + * + * Returns: Name of the QOM interface implemented by machines + * usable on this target binary. + */ +const char *target_machine_typename(void); + +/** * target_cpu_type: * * Returns: target CPU base QOM type name (i.e. TYPE_X86_CPU). diff --git a/include/system/ram_addr.h b/include/system/ram_addr.h index b4e4425acb..15a1b1a4fa 100644 --- a/include/system/ram_addr.h +++ b/include/system/ram_addr.h @@ -24,7 +24,6 @@ #include "exec/cputlb.h" #include "exec/ramlist.h" #include "system/ramblock.h" -#include "exec/exec-all.h" #include "system/memory.h" #include "exec/target_page.h" #include "qemu/rcu.h" diff --git a/include/tcg/insn-start-words.h b/include/tcg/insn-start-words.h index d416d19bcf..c52aec50a7 100644 --- a/include/tcg/insn-start-words.h +++ b/include/tcg/insn-start-words.h @@ -1,13 +1,12 @@ /* SPDX-License-Identifier: MIT */ /* - * Define TARGET_INSN_START_WORDS + * Define INSN_START_WORDS * Copyright (c) 2008 Fabrice Bellard */ -#ifndef TARGET_INSN_START_WORDS +#ifndef TCG_INSN_START_WORDS +#define TCG_INSN_START_WORDS -#include "cpu-param.h" +#define INSN_START_WORDS 3 -# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS) - -#endif /* TARGET_INSN_START_WORDS */ +#endif /* TCG_INSN_START_WORDS */ diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h index 59d19755e6..c912578fdd 100644 --- a/include/tcg/tcg-op.h +++ b/include/tcg/tcg-op.h @@ -9,6 +9,7 @@ #define TCG_TCG_OP_H #include "tcg/tcg-op-common.h" +#include "tcg/insn-start-words.h" #include "exec/target_long.h" #ifndef TARGET_LONG_BITS @@ -23,24 +24,34 @@ # error #endif +#if INSN_START_WORDS != 3 +# error Mismatch with insn-start-words.h +#endif + #if TARGET_INSN_START_EXTRA_WORDS == 0 static inline void tcg_gen_insn_start(target_ulong pc) { - TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 64 / TCG_TARGET_REG_BITS); + TCGOp *op = tcg_emit_op(INDEX_op_insn_start, + INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS); tcg_set_insn_start_param(op, 0, pc); + tcg_set_insn_start_param(op, 1, 0); + tcg_set_insn_start_param(op, 2, 0); } #elif TARGET_INSN_START_EXTRA_WORDS == 1 static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1) { - TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 2 * 64 / TCG_TARGET_REG_BITS); + TCGOp *op = tcg_emit_op(INDEX_op_insn_start, + INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS); tcg_set_insn_start_param(op, 0, pc); tcg_set_insn_start_param(op, 1, a1); + tcg_set_insn_start_param(op, 2, 0); } #elif TARGET_INSN_START_EXTRA_WORDS == 2 static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1, target_ulong a2) { - TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 3 * 64 / TCG_TARGET_REG_BITS); + TCGOp *op = tcg_emit_op(INDEX_op_insn_start, + INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS); tcg_set_insn_start_param(op, 0, pc); tcg_set_insn_start_param(op, 1, a1); tcg_set_insn_start_param(op, 2, a2); diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h index 995b79383e..e988edd93a 100644 --- a/include/tcg/tcg-opc.h +++ b/include/tcg/tcg-opc.h @@ -114,8 +114,7 @@ DEF(extrh_i64_i32, 1, 1, 0, 0) #define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2) -/* There are tcg_ctx->insn_start_words here, not just one. */ -DEF(insn_start, 0, 0, DATA64_ARGS, TCG_OPF_NOT_PRESENT) +DEF(insn_start, 0, 0, DATA64_ARGS * INSN_START_WORDS, TCG_OPF_NOT_PRESENT) DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index aa300a2f8b..a8c00c72cc 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -34,6 +34,7 @@ #include "tcg-target-reg-bits.h" #include "tcg-target.h" #include "tcg/tcg-cond.h" +#include "tcg/insn-start-words.h" #include "tcg/debug-assert.h" /* XXX: make safe guess about sizes */ @@ -359,7 +360,6 @@ struct TCGContext { int page_mask; uint8_t page_bits; uint8_t tlb_dyn_max_bits; - uint8_t insn_start_words; TCGBar guest_mo; TCGRegSet reserved_regs; @@ -582,18 +582,19 @@ static inline TCGv_vec temp_tcgv_vec(TCGTemp *t) return (TCGv_vec)temp_tcgv_i32(t); } -static inline TCGArg tcg_get_insn_param(TCGOp *op, int arg) +static inline TCGArg tcg_get_insn_param(TCGOp *op, unsigned arg) { return op->args[arg]; } -static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v) +static inline void tcg_set_insn_param(TCGOp *op, unsigned arg, TCGArg v) { op->args[arg] = v; } -static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg) +static inline uint64_t tcg_get_insn_start_param(TCGOp *op, unsigned arg) { + tcg_debug_assert(arg < INSN_START_WORDS); if (TCG_TARGET_REG_BITS == 64) { return tcg_get_insn_param(op, arg); } else { @@ -602,8 +603,9 @@ static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg) } } -static inline void tcg_set_insn_start_param(TCGOp *op, int arg, uint64_t v) +static inline void tcg_set_insn_start_param(TCGOp *op, unsigned arg, uint64_t v) { + tcg_debug_assert(arg < INSN_START_WORDS); if (TCG_TARGET_REG_BITS == 64) { tcg_set_insn_param(op, arg, v); } else { diff --git a/include/user/cpu_loop.h b/include/user/cpu_loop.h index 589c66543f..ad8a1d711f 100644 --- a/include/user/cpu_loop.h +++ b/include/user/cpu_loop.h @@ -20,11 +20,9 @@ #ifndef USER_CPU_LOOP_H #define USER_CPU_LOOP_H -#include "exec/abi_ptr.h" +#include "exec/vaddr.h" #include "exec/mmu-access-type.h" -#include "exec/log.h" -#include "exec/target_long.h" -#include "special-errno.h" + /** * adjust_signal_pc: @@ -46,7 +44,7 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write); * Return true if the write fault has been handled, and should be re-tried. */ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, - uintptr_t host_pc, abi_ptr guest_addr); + uintptr_t host_pc, vaddr guest_addr); /** * cpu_loop_exit_sigsegv: @@ -59,7 +57,7 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, * Use the TCGCPUOps hook to record cpu state, do guest operating system * specific things to raise SIGSEGV, and jump to the main cpu loop. */ -G_NORETURN void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, +G_NORETURN void cpu_loop_exit_sigsegv(CPUState *cpu, vaddr addr, MMUAccessType access_type, bool maperr, uintptr_t ra); @@ -73,7 +71,7 @@ G_NORETURN void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, * Use the TCGCPUOps hook to record cpu state, do guest operating system * specific things to raise SIGBUS, and jump to the main cpu loop. */ -G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, +G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, vaddr addr, MMUAccessType access_type, uintptr_t ra); diff --git a/include/user/guest-host.h b/include/user/guest-host.h index 8d2079bbbb..8f7ef75896 100644 --- a/include/user/guest-host.h +++ b/include/user/guest-host.h @@ -8,9 +8,9 @@ #ifndef USER_GUEST_HOST_H #define USER_GUEST_HOST_H -#include "user/abitypes.h" +#include "exec/vaddr.h" #include "user/guest-base.h" -#include "cpu.h" +#include "accel/tcg/cpu-ops.h" /* * If non-zero, the guest virtual address space is a contiguous subset @@ -23,59 +23,48 @@ extern unsigned long reserved_va; /* - * Limit the guest addresses as best we can. - * - * When not using -R reserved_va, we cannot really limit the guest - * to less address space than the host. For 32-bit guests, this - * acts as a sanity check that we're not giving the guest an address - * that it cannot even represent. For 64-bit guests... the address - * might not be what the real kernel would give, but it is at least - * representable in the guest. - * - * TODO: Improve address allocation to avoid this problem, and to - * avoid setting bits at the top of guest addresses that might need - * to be used for tags. + * The last byte of the guest address space. + * If reserved_va is non-zero, guest_addr_max matches. + * If reserved_va is zero, guest_addr_max equals the full guest space. */ -#define GUEST_ADDR_MAX_ \ - ((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \ - UINT32_MAX : ~0ul) -#define GUEST_ADDR_MAX (reserved_va ? : GUEST_ADDR_MAX_) +extern unsigned long guest_addr_max; -#ifndef TARGET_TAGGED_ADDRESSES -static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x) +static inline vaddr cpu_untagged_addr(CPUState *cs, vaddr x) { + const TCGCPUOps *tcg_ops = cs->cc->tcg_ops; + if (tcg_ops->untagged_addr) { + return tcg_ops->untagged_addr(cs, x); + } return x; } -#endif /* All direct uses of g2h and h2g need to go away for usermode softmmu. */ -static inline void *g2h_untagged(abi_ptr x) +static inline void *g2h_untagged(vaddr x) { return (void *)((uintptr_t)(x) + guest_base); } -static inline void *g2h(CPUState *cs, abi_ptr x) +static inline void *g2h(CPUState *cs, vaddr x) { return g2h_untagged(cpu_untagged_addr(cs, x)); } -static inline bool guest_addr_valid_untagged(abi_ulong x) +static inline bool guest_addr_valid_untagged(vaddr x) { - return x <= GUEST_ADDR_MAX; + return x <= guest_addr_max; } -static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len) +static inline bool guest_range_valid_untagged(vaddr start, vaddr len) { - return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1; + return len - 1 <= guest_addr_max && start <= guest_addr_max - len + 1; } #define h2g_valid(x) \ - (HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \ - (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX) + ((uintptr_t)(x) - guest_base <= guest_addr_max) #define h2g_nocheck(x) ({ \ uintptr_t __ret = (uintptr_t)(x) - guest_base; \ - (abi_ptr)__ret; \ + (vaddr)__ret; \ }) #define h2g(x) ({ \ diff --git a/include/user/page-protection.h b/include/user/page-protection.h index d5c8748d49..4bde664e4a 100644 --- a/include/user/page-protection.h +++ b/include/user/page-protection.h @@ -12,13 +12,12 @@ #error Cannot include this header from system emulation #endif -#include "cpu-param.h" -#include "exec/target_long.h" +#include "exec/vaddr.h" #include "exec/translation-block.h" -int page_unprotect(tb_page_addr_t address, uintptr_t pc); +int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc); -int page_get_flags(target_ulong address); +int page_get_flags(vaddr address); /** * page_set_flags: @@ -31,9 +30,9 @@ int page_get_flags(target_ulong address); * The flag PAGE_WRITE_ORG is positioned automatically depending * on PAGE_WRITE. The mmap_lock should already be held. */ -void page_set_flags(target_ulong start, target_ulong last, int flags); +void page_set_flags(vaddr start, vaddr last, int flags); -void page_reset_target_data(target_ulong start, target_ulong last); +void page_reset_target_data(vaddr start, vaddr last); /** * page_check_range @@ -45,7 +44,7 @@ void page_reset_target_data(target_ulong start, target_ulong last); * Return false if any page is unmapped. Thus testing flags == 0 is * equivalent to testing for flags == PAGE_VALID. */ -bool page_check_range(target_ulong start, target_ulong last, int flags); +bool page_check_range(vaddr start, vaddr last, int flags); /** * page_check_range_empty: @@ -57,7 +56,7 @@ bool page_check_range(target_ulong start, target_ulong last, int flags); * The memory lock must be held so that the caller will can ensure * the result stays true until a new mapping can be installed. */ -bool page_check_range_empty(target_ulong start, target_ulong last); +bool page_check_range_empty(vaddr start, vaddr last); /** * page_find_range_empty @@ -71,26 +70,25 @@ bool page_check_range_empty(target_ulong start, target_ulong last); * The memory lock must be held, as the caller will want to ensure * the returned range stays empty until a new mapping can be installed. */ -target_ulong page_find_range_empty(target_ulong min, target_ulong max, - target_ulong len, target_ulong align); +vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align); /** - * page_get_target_data(address) + * page_get_target_data * @address: guest virtual address + * @size: per-page size * - * Return TARGET_PAGE_DATA_SIZE bytes of out-of-band data to associate + * Return @size bytes of out-of-band data to associate * with the guest page at @address, allocating it if necessary. The * caller should already have verified that the address is valid. + * The value of @size must be the same for every call. * * The memory will be freed when the guest page is deallocated, * e.g. with the munmap system call. */ __attribute__((returns_nonnull)) -void *page_get_target_data(target_ulong address); - -typedef int (*walk_memory_regions_fn)(void *, target_ulong, - target_ulong, unsigned long); +void *page_get_target_data(vaddr address, size_t size); +typedef int (*walk_memory_regions_fn)(void *, vaddr, vaddr, int); int walk_memory_regions(void *, walk_memory_regions_fn); void page_dump(FILE *f); diff --git a/linux-user/elfload.c b/linux-user/elfload.c index fbfdec2f17..82ebf6a212 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -4059,8 +4059,7 @@ static void bswap_note(struct elf_note *en) /* * Calculate file (dump) size of given memory region. */ -static size_t vma_dump_size(target_ulong start, target_ulong end, - unsigned long flags) +static size_t vma_dump_size(vaddr start, vaddr end, int flags) { /* The area must be readable. */ if (!(flags & PAGE_READ)) { @@ -4253,14 +4252,14 @@ static int dump_write(int fd, const void *ptr, size_t size) return (0); } -static int wmr_page_unprotect_regions(void *opaque, target_ulong start, - target_ulong end, unsigned long flags) +static int wmr_page_unprotect_regions(void *opaque, vaddr start, + vaddr end, int flags) { if ((flags & (PAGE_WRITE | PAGE_WRITE_ORG)) == PAGE_WRITE_ORG) { size_t step = MAX(TARGET_PAGE_SIZE, qemu_real_host_page_size()); while (1) { - page_unprotect(start, 0); + page_unprotect(NULL, start, 0); if (end - start <= step) { break; } @@ -4275,8 +4274,8 @@ typedef struct { size_t size; } CountAndSizeRegions; -static int wmr_count_and_size_regions(void *opaque, target_ulong start, - target_ulong end, unsigned long flags) +static int wmr_count_and_size_regions(void *opaque, vaddr start, + vaddr end, int flags) { CountAndSizeRegions *css = opaque; @@ -4290,8 +4289,8 @@ typedef struct { off_t offset; } FillRegionPhdr; -static int wmr_fill_region_phdr(void *opaque, target_ulong start, - target_ulong end, unsigned long flags) +static int wmr_fill_region_phdr(void *opaque, vaddr start, + vaddr end, int flags) { FillRegionPhdr *d = opaque; struct elf_phdr *phdr = d->phdr; @@ -4313,8 +4312,8 @@ static int wmr_fill_region_phdr(void *opaque, target_ulong start, return 0; } -static int wmr_write_region(void *opaque, target_ulong start, - target_ulong end, unsigned long flags) +static int wmr_write_region(void *opaque, vaddr start, + vaddr end, int flags) { int fd = *(int *)opaque; size_t size = vma_dump_size(start, end, flags); diff --git a/linux-user/main.c b/linux-user/main.c index e2ec5970be..5ac5b55dc6 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -40,7 +40,6 @@ #include "qemu/plugin.h" #include "user/guest-base.h" #include "user/page-protection.h" -#include "exec/exec-all.h" #include "exec/gdbstub.h" #include "gdbstub/user.h" #include "tcg/startup.h" @@ -123,6 +122,7 @@ static const char *last_log_filename; #endif unsigned long reserved_va; +unsigned long guest_addr_max; static void usage(int exitcode); @@ -859,6 +859,13 @@ int main(int argc, char **argv, char **envp) /* MAX_RESERVED_VA + 1 is a large power of 2, so is aligned. */ reserved_va = max_reserved_va; } + if (reserved_va != 0) { + guest_addr_max = reserved_va; + } else if (MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) { + guest_addr_max = UINT32_MAX; + } else { + guest_addr_max = ~0ul; + } /* * Temporarily disable diff --git a/linux-user/signal.c b/linux-user/signal.c index 4dafc2c3a2..cd0e7398aa 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -750,7 +750,7 @@ void force_sigsegv(int oldsig) } #endif -void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, +void cpu_loop_exit_sigsegv(CPUState *cpu, vaddr addr, MMUAccessType access_type, bool maperr, uintptr_t ra) { const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; @@ -766,7 +766,7 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, cpu_loop_exit_restore(cpu, ra); } -void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, +void cpu_loop_exit_sigbus(CPUState *cpu, vaddr addr, MMUAccessType access_type, uintptr_t ra) { const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5826ac3adb..23b901b713 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8135,8 +8135,8 @@ static void open_self_maps_4(const struct open_self_maps_data *d, * Callback for walk_memory_regions, when read_self_maps() fails. * Proceed without the benefit of host /proc/self/maps cross-check. */ -static int open_self_maps_3(void *opaque, target_ulong guest_start, - target_ulong guest_end, unsigned long flags) +static int open_self_maps_3(void *opaque, vaddr guest_start, + vaddr guest_end, int flags) { static const MapInfo mi = { .is_priv = true }; @@ -8147,8 +8147,8 @@ static int open_self_maps_3(void *opaque, target_ulong guest_start, /* * Callback for walk_memory_regions, when read_self_maps() succeeds. */ -static int open_self_maps_2(void *opaque, target_ulong guest_start, - target_ulong guest_end, unsigned long flags) +static int open_self_maps_2(void *opaque, vaddr guest_start, + vaddr guest_end, int flags) { const struct open_self_maps_data *d = opaque; uintptr_t host_start = (uintptr_t)g2h_untagged(guest_start); diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h index 4aa253b566..691b9a1775 100644 --- a/linux-user/user-internals.h +++ b/linux-user/user-internals.h @@ -19,7 +19,6 @@ #define LINUX_USER_USER_INTERNALS_H #include "user/thunk.h" -#include "exec/exec-all.h" #include "qemu/log.h" extern char *exec_path; diff --git a/semihosting/uaccess.c b/semihosting/uaccess.c index 81ffecaaba..4554844e15 100644 --- a/semihosting/uaccess.c +++ b/semihosting/uaccess.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "accel/tcg/cpu-mmu-index.h" -#include "exec/exec-all.h" +#include "accel/tcg/probe.h" #include "exec/target_page.h" #include "exec/tlb-flags.h" #include "semihosting/uaccess.h" diff --git a/system/physmem.c b/system/physmem.c index 4a7a2e5e12..a8a9ca309e 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -29,9 +29,9 @@ #ifdef CONFIG_TCG #include "accel/tcg/cpu-ops.h" +#include "accel/tcg/iommu.h" #endif /* CONFIG_TCG */ -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/page-protection.h" #include "exec/target_page.h" @@ -587,6 +587,8 @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat, return mr; } +#ifdef CONFIG_TCG + typedef struct TCGIOMMUNotifier { IOMMUNotifier n; MemoryRegion *mr; @@ -746,6 +748,33 @@ translate_fail: return &d->map.sections[PHYS_SECTION_UNASSIGNED]; } +MemoryRegionSection *iotlb_to_section(CPUState *cpu, + hwaddr index, MemTxAttrs attrs) +{ + int asidx = cpu_asidx_from_attrs(cpu, attrs); + CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx]; + AddressSpaceDispatch *d = cpuas->memory_dispatch; + int section_index = index & ~TARGET_PAGE_MASK; + MemoryRegionSection *ret; + + assert(section_index < d->map.sections_nb); + ret = d->map.sections + section_index; + assert(ret->mr); + assert(ret->mr->ops); + + return ret; +} + +/* Called from RCU critical section */ +hwaddr memory_region_section_get_iotlb(CPUState *cpu, + MemoryRegionSection *section) +{ + AddressSpaceDispatch *d = flatview_to_dispatch(section->fv); + return section - d->map.sections; +} + +#endif /* CONFIG_TCG */ + void cpu_address_space_init(CPUState *cpu, int asidx, const char *prefix, MemoryRegion *mr) { @@ -1002,14 +1031,6 @@ bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap, return false; } -/* Called from RCU critical section */ -hwaddr memory_region_section_get_iotlb(CPUState *cpu, - MemoryRegionSection *section) -{ - AddressSpaceDispatch *d = flatview_to_dispatch(section->fv); - return section - d->map.sections; -} - static int subpage_register(subpage_t *mmio, uint32_t start, uint32_t end, uint16_t section); static subpage_t *subpage_init(FlatView *fv, hwaddr base); @@ -2670,23 +2691,6 @@ static uint16_t dummy_section(PhysPageMap *map, FlatView *fv, MemoryRegion *mr) return phys_section_add(map, §ion); } -MemoryRegionSection *iotlb_to_section(CPUState *cpu, - hwaddr index, MemTxAttrs attrs) -{ - int asidx = cpu_asidx_from_attrs(cpu, attrs); - CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx]; - AddressSpaceDispatch *d = cpuas->memory_dispatch; - int section_index = index & ~TARGET_PAGE_MASK; - MemoryRegionSection *ret; - - assert(section_index < d->map.sections_nb); - ret = d->map.sections + section_index; - assert(ret->mr); - assert(ret->mr->ops); - - return ret; -} - static void io_mem_init(void) { memory_region_init_io(&io_mem_unassigned, NULL, &unassigned_mem_ops, NULL, @@ -2831,7 +2835,7 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr, } if (dirty_log_mask & (1 << DIRTY_MEMORY_CODE)) { assert(tcg_enabled()); - tb_invalidate_phys_range(addr, addr + length - 1); + tb_invalidate_phys_range(NULL, addr, addr + length - 1); dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); } cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask); diff --git a/system/vl.c b/system/vl.c index b69d5bb81e..fd402b8ff8 100644 --- a/system/vl.c +++ b/system/vl.c @@ -27,6 +27,7 @@ #include "qemu/datadir.h" #include "qemu/units.h" #include "qemu/module.h" +#include "qemu/target-info.h" #include "exec/cpu-common.h" #include "exec/page-vary.h" #include "hw/qdev-properties.h" @@ -1564,7 +1565,7 @@ static void machine_help_func(const QDict *qdict) GSList *el; const char *type = qdict_get_try_str(qdict, "type"); - machines = object_class_get_list(TYPE_MACHINE, false); + machines = object_class_get_list(target_machine_typename(), false); if (type) { ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines)); if (machine_class) { diff --git a/target-info-stub.c b/target-info-stub.c index 773a10188c..fecc0e7128 100644 --- a/target-info-stub.c +++ b/target-info-stub.c @@ -9,18 +9,17 @@ #include "qemu/osdep.h" #include "qemu/target-info.h" #include "qemu/target-info-impl.h" +#include "hw/boards.h" #include "cpu.h" static const TargetInfo target_info_stub = { .target_name = TARGET_NAME, + .long_bits = TARGET_LONG_BITS, + .cpu_type = CPU_RESOLVING_TYPE, + .machine_typename = TYPE_MACHINE, }; const TargetInfo *target_info(void) { return &target_info_stub; } - -const char *target_cpu_type(void) -{ - return CPU_RESOLVING_TYPE; -} diff --git a/target-info.c b/target-info.c index 84b18931e7..16fdca7aaa 100644 --- a/target-info.c +++ b/target-info.c @@ -14,3 +14,18 @@ const char *target_name(void) { return target_info()->target_name; } + +unsigned target_long_bits(void) +{ + return target_info()->long_bits; +} + +const char *target_cpu_type(void) +{ + return target_info()->cpu_type; +} + +const char *target_machine_typename(void) +{ + return target_info()->machine_typename; +} diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 27e2008a4e..890b84c032 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -23,9 +23,9 @@ #include "qapi/error.h" #include "qemu/qemu-print.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "exec/target_page.h" +#include "accel/tcg/cpu-ops.h" #include "fpu/softfloat.h" @@ -41,6 +41,18 @@ static vaddr alpha_cpu_get_pc(CPUState *cs) return env->pc; } +static TCGTBCPUState alpha_get_tb_cpu_state(CPUState *cs) +{ + CPUAlphaState *env = cpu_env(cs); + uint32_t flags = env->flags & ENV_FLAG_TB_MASK; + +#ifdef CONFIG_USER_ONLY + flags |= TB_FLAG_UNALIGN * !cs->prctl_unalign_sigbus; +#endif + + return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; +} + static void alpha_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -232,8 +244,6 @@ static const struct SysemuCPUOps alpha_sysemu_ops = { }; #endif -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps alpha_tcg_ops = { /* Alpha processors have a weak memory model */ .guest_default_memory_order = 0, @@ -241,6 +251,7 @@ static const TCGCPUOps alpha_tcg_ops = { .initialize = alpha_translate_init, .translate_code = alpha_translate_code, + .get_tb_cpu_state = alpha_get_tb_cpu_state, .synchronize_from_tb = alpha_cpu_synchronize_from_tb, .restore_state_to_opc = alpha_restore_state_to_opc, .mmu_index = alpha_cpu_mmu_index, @@ -252,6 +263,7 @@ static const TCGCPUOps alpha_tcg_ops = { .tlb_fill = alpha_cpu_tlb_fill, .cpu_exec_interrupt = alpha_cpu_exec_interrupt, .cpu_exec_halt = alpha_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = alpha_cpu_do_interrupt, .do_transaction_failed = alpha_cpu_do_transaction_failed, .do_unaligned_access = alpha_cpu_do_unaligned_access, diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index 849f673489..45944e46b5 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -464,17 +464,6 @@ void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, MemTxResult response, uintptr_t retaddr); #endif -static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) -{ - *pc = env->pc; - *cs_base = 0; - *pflags = env->flags & ENV_FLAG_TB_MASK; -#ifdef CONFIG_USER_ONLY - *pflags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus; -#endif -} - #ifdef CONFIG_USER_ONLY /* Copied from linux ieee_swcr_to_fpcr. */ static inline uint64_t alpha_ieee_swcr_to_fpcr(uint64_t swcr) diff --git a/target/alpha/fpu_helper.c b/target/alpha/fpu_helper.c index 6aefb9b851..30f3c7fd18 100644 --- a/target/alpha/fpu_helper.c +++ b/target/alpha/fpu_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/alpha/int_helper.c b/target/alpha/int_helper.c index 5672696f6f..6bfe63500e 100644 --- a/target/alpha/int_helper.c +++ b/target/alpha/int_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c index a4d5adb40c..2113fe33ae 100644 --- a/target/alpha/mem_helper.c +++ b/target/alpha/mem_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" static void do_unaligned_access(CPUAlphaState *env, vaddr addr, uintptr_t retaddr) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 7f3195a5dc..cebab0318c 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -21,7 +21,6 @@ #include "cpu.h" #include "system/cpus.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" diff --git a/target/alpha/vax_helper.c b/target/alpha/vax_helper.c index f94fb519db..c1d201e7b4 100644 --- a/target/alpha/vax_helper.c +++ b/target/alpha/vax_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index 883c0a0e8c..a1a944adb4 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -46,7 +46,7 @@ static inline void gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3) #ifdef CONFIG_KVM int fdarray[3]; - if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, NULL)) { + if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL)) { return; } diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index 5c5bc8a009..8b46c7c570 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -17,14 +17,9 @@ #endif #ifdef CONFIG_USER_ONLY -# ifdef TARGET_AARCH64 -# define TARGET_TAGGED_ADDRESSES -# ifdef __FreeBSD__ -# define TARGET_PAGE_BITS 12 -# else +# if defined(TARGET_AARCH64) && defined(CONFIG_LINUX) /* Allow user-only to vary page size from 4k */ # define TARGET_PAGE_BITS_VARY -# endif # else # define TARGET_PAGE_BITS 12 # endif diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 5e951675c6..45cb6fd7ee 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -33,7 +33,6 @@ #endif /* CONFIG_TCG */ #include "internals.h" #include "cpu-features.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "hw/qdev-properties.h" #if !defined(CONFIG_USER_ONLY) @@ -2672,7 +2671,31 @@ static const char *arm_gdb_get_core_xml_file(CPUState *cs) return "arm-core.xml"; } -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY +/** + * aarch64_untagged_addr: + * + * Remove any address tag from @x. This is explicitly related to the + * linux syscall TIF_TAGGED_ADDR setting, not TBI in general. + * + * There should be a better place to put this, but we need this in + * include/exec/cpu_ldst.h, and not some place linux-user specific. + * + * Note that arm-*-user will never set tagged_addr_enable. + */ +static vaddr aarch64_untagged_addr(CPUState *cs, vaddr x) +{ + CPUARMState *env = cpu_env(cs); + if (env->tagged_addr_enable) { + /* + * TBI is enabled for userspace but not kernelspace addresses. + * Only clear the tag if bit 55 is clear. + */ + x &= sextract64(x, 0, 56); + } + return x; +} +#else #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps arm_sysemu_ops = { @@ -2694,6 +2717,7 @@ static const TCGCPUOps arm_tcg_ops = { .initialize = arm_translate_init, .translate_code = arm_translate_code, + .get_tb_cpu_state = arm_get_tb_cpu_state, .synchronize_from_tb = arm_cpu_synchronize_from_tb, .debug_excp_handler = arm_debug_excp_handler, .restore_state_to_opc = arm_restore_state_to_opc, @@ -2702,10 +2726,12 @@ static const TCGCPUOps arm_tcg_ops = { #ifdef CONFIG_USER_ONLY .record_sigsegv = arm_cpu_record_sigsegv, .record_sigbus = arm_cpu_record_sigbus, + .untagged_addr = aarch64_untagged_addr, #else .tlb_fill_align = arm_cpu_tlb_fill_align, .cpu_exec_interrupt = arm_cpu_exec_interrupt, .cpu_exec_halt = arm_cpu_exec_halt, + .cpu_exec_reset = cpu_reset, .do_interrupt = arm_cpu_do_interrupt, .do_transaction_failed = arm_cpu_do_transaction_failed, .do_unaligned_access = arm_cpu_do_unaligned_access, diff --git a/target/arm/cpu.h b/target/arm/cpu.h index fdcf8cd1ae..6ed6409cb7 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -783,12 +783,9 @@ typedef struct CPUArchState { #else /* CONFIG_USER_ONLY */ /* For usermode syscall translation. */ bool eabi; -#endif /* CONFIG_USER_ONLY */ - -#ifdef TARGET_TAGGED_ADDRESSES /* Linux syscall tagged address support */ bool tagged_addr_enable; -#endif +#endif /* CONFIG_USER_ONLY */ } CPUARMState; static inline void set_feature(CPUARMState *env, int feature) @@ -3119,9 +3116,6 @@ static inline bool bswap_code(bool sctlr_b) #endif } -void cpu_get_tb_cpu_state(CPUARMState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags); - enum { QEMU_PSCI_CONDUIT_DISABLED = 0, QEMU_PSCI_CONDUIT_SMC = 1, @@ -3219,35 +3213,4 @@ extern const uint64_t pred_esz_masks[5]; #define LOG2_TAG_GRANULE 4 #define TAG_GRANULE (1 << LOG2_TAG_GRANULE) -#ifdef CONFIG_USER_ONLY - -#define TARGET_PAGE_DATA_SIZE (TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1)) - -#ifdef TARGET_TAGGED_ADDRESSES -/** - * cpu_untagged_addr: - * @cs: CPU context - * @x: tagged address - * - * Remove any address tag from @x. This is explicitly related to the - * linux syscall TIF_TAGGED_ADDR setting, not TBI in general. - * - * There should be a better place to put this, but we need this in - * include/exec/cpu_ldst.h, and not some place linux-user specific. - */ -static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x) -{ - CPUARMState *env = cpu_env(cs); - if (env->tagged_addr_enable) { - /* - * TBI is enabled for userspace but not kernelspace addresses. - * Only clear the tag if bit 55 is clear. - */ - x &= sextract64(x, 0, 56); - } - return x; -} -#endif /* TARGET_TAGGED_ADDRESSES */ -#endif /* CONFIG_USER_ONLY */ - #endif diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index 473ee2af38..de7999f6a9 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -11,7 +11,6 @@ #include "internals.h" #include "cpu-features.h" #include "cpregs.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "exec/watchpoint.h" #include "system/tcg.h" diff --git a/target/arm/helper.c b/target/arm/helper.c index c7ff9f657c..4a2d1ecbfe 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -20,7 +20,6 @@ #include "qemu/bitops.h" #include "qemu/qemu-print.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "hw/irq.h" #include "system/cpu-timers.h" @@ -30,6 +29,7 @@ #include "qapi/error.h" #include "qemu/guest-random.h" #ifdef CONFIG_TCG +#include "accel/tcg/probe.h" #include "semihosting/common-semi.h" #endif #include "cpregs.h" @@ -4987,7 +4987,7 @@ static void ic_ivau_write(CPUARMState *env, const ARMCPRegInfo *ri, mmap_lock(); - tb_invalidate_phys_range(start_address, end_address); + tb_invalidate_phys_range(env_cpu(env), start_address, end_address); mmap_unlock(); } @@ -11423,115 +11423,6 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env) return arm_mmu_idx_el(env, arm_current_el(env)); } -static bool mve_no_pred(CPUARMState *env) -{ - /* - * Return true if there is definitely no predication of MVE - * instructions by VPR or LTPSIZE. (Returning false even if there - * isn't any predication is OK; generated code will just be - * a little worse.) - * If the CPU does not implement MVE then this TB flag is always 0. - * - * NOTE: if you change this logic, the "recalculate s->mve_no_pred" - * logic in gen_update_fp_context() needs to be updated to match. - * - * We do not include the effect of the ECI bits here -- they are - * tracked in other TB flags. This simplifies the logic for - * "when did we emit code that changes the MVE_NO_PRED TB flag - * and thus need to end the TB?". - */ - if (cpu_isar_feature(aa32_mve, env_archcpu(env))) { - return false; - } - if (env->v7m.vpr) { - return false; - } - if (env->v7m.ltpsize < 4) { - return false; - } - return true; -} - -void cpu_get_tb_cpu_state(CPUARMState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) -{ - CPUARMTBFlags flags; - - assert_hflags_rebuild_correctly(env); - flags = env->hflags; - - if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) { - *pc = env->pc; - if (cpu_isar_feature(aa64_bti, env_archcpu(env))) { - DP_TBFLAG_A64(flags, BTYPE, env->btype); - } - } else { - *pc = env->regs[15]; - - if (arm_feature(env, ARM_FEATURE_M)) { - if (arm_feature(env, ARM_FEATURE_M_SECURITY) && - FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) - != env->v7m.secure) { - DP_TBFLAG_M32(flags, FPCCR_S_WRONG, 1); - } - - if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) && - (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) || - (env->v7m.secure && - !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) { - /* - * ASPEN is set, but FPCA/SFPA indicate that there is no - * active FP context; we must create a new FP context before - * executing any FP insn. - */ - DP_TBFLAG_M32(flags, NEW_FP_CTXT_NEEDED, 1); - } - - bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK; - if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) { - DP_TBFLAG_M32(flags, LSPACT, 1); - } - - if (mve_no_pred(env)) { - DP_TBFLAG_M32(flags, MVE_NO_PRED, 1); - } - } else { - /* - * Note that XSCALE_CPAR shares bits with VECSTRIDE. - * Note that VECLEN+VECSTRIDE are RES0 for M-profile. - */ - if (arm_feature(env, ARM_FEATURE_XSCALE)) { - DP_TBFLAG_A32(flags, XSCALE_CPAR, env->cp15.c15_cpar); - } else { - DP_TBFLAG_A32(flags, VECLEN, env->vfp.vec_len); - DP_TBFLAG_A32(flags, VECSTRIDE, env->vfp.vec_stride); - } - if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) { - DP_TBFLAG_A32(flags, VFPEN, 1); - } - } - - DP_TBFLAG_AM32(flags, THUMB, env->thumb); - DP_TBFLAG_AM32(flags, CONDEXEC, env->condexec_bits); - } - - /* - * The SS_ACTIVE and PSTATE_SS bits correspond to the state machine - * states defined in the ARM ARM for software singlestep: - * SS_ACTIVE PSTATE.SS State - * 0 x Inactive (the TB flag for SS is always 0) - * 1 0 Active-pending - * 1 1 Active-not-pending - * SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB. - */ - if (EX_TBFLAG_ANY(flags, SS_ACTIVE) && (env->pstate & PSTATE_SS)) { - DP_TBFLAG_ANY(flags, PSTATE__SS, 1); - } - - *pflags = flags.flags; - *cs_base = flags.flags2; -} - #ifdef TARGET_AARCH64 /* * The manual says that when SVE is enabled and VQ is widened the diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 34ca36fab5..42258cc2d8 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -2278,28 +2278,23 @@ static inline bool hvf_arm_hw_debug_active(CPUState *cpu) return ((cur_hw_wps > 0) || (cur_hw_bps > 0)); } -static void hvf_arch_set_traps(void) +static void hvf_arch_set_traps(CPUState *cpu) { - CPUState *cpu; bool should_enable_traps = false; hv_return_t r = HV_SUCCESS; /* Check whether guest debugging is enabled for at least one vCPU; if it * is, enable exiting the guest on all vCPUs */ - CPU_FOREACH(cpu) { - should_enable_traps |= cpu->accel->guest_debug_enabled; - } - CPU_FOREACH(cpu) { - /* Set whether debug exceptions exit the guest */ - r = hv_vcpu_set_trap_debug_exceptions(cpu->accel->fd, - should_enable_traps); - assert_hvf_ok(r); + should_enable_traps |= cpu->accel->guest_debug_enabled; + /* Set whether debug exceptions exit the guest */ + r = hv_vcpu_set_trap_debug_exceptions(cpu->accel->fd, + should_enable_traps); + assert_hvf_ok(r); - /* Set whether accesses to debug registers exit the guest */ - r = hv_vcpu_set_trap_debug_reg_accesses(cpu->accel->fd, - should_enable_traps); - assert_hvf_ok(r); - } + /* Set whether accesses to debug registers exit the guest */ + r = hv_vcpu_set_trap_debug_reg_accesses(cpu->accel->fd, + should_enable_traps); + assert_hvf_ok(r); } void hvf_arch_update_guest_debug(CPUState *cpu) @@ -2340,7 +2335,7 @@ void hvf_arch_update_guest_debug(CPUState *cpu) deposit64(env->cp15.mdscr_el1, MDSCR_EL1_MDE_SHIFT, 1, 0); } - hvf_arch_set_traps(); + hvf_arch_set_traps(cpu); } bool hvf_arch_supports_guest_debug(void) diff --git a/target/arm/internals.h b/target/arm/internals.h index 4d3d84ffeb..660d3a88e0 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -28,6 +28,7 @@ #include "exec/hwaddr.h" #include "exec/vaddr.h" #include "exec/breakpoint.h" +#include "accel/tcg/tb-cpu-state.h" #include "hw/registerfields.h" #include "tcg/tcg-gvec-desc.h" #include "system/memory.h" @@ -372,6 +373,7 @@ void arm_restore_state_to_opc(CPUState *cs, const uint64_t *data); #ifdef CONFIG_TCG +TCGTBCPUState arm_get_tb_cpu_state(CPUState *cs); void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb); /* Our implementation of TCGCPUOps::cpu_exec_halt */ @@ -1906,8 +1908,6 @@ static inline bool arm_fgt_active(CPUARMState *env, int el) (!arm_feature(env, ARM_FEATURE_EL3) || (env->cp15.scr_el3 & SCR_FGTEN)); } -void assert_hflags_rebuild_correctly(CPUARMState *env); - /* * Although the ARM implementation of hardware assisted debugging * allows for different breakpoints per-core, the current GDB diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 97de8c7e93..9c62d12b23 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -100,8 +100,7 @@ static int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature) return kvm_vcpu_ioctl(CPU(cpu), KVM_ARM_VCPU_FINALIZE, &feature); } -bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, - int *fdarray, +bool kvm_arm_create_scratch_host_vcpu(int *fdarray, struct kvm_vcpu_init *init) { int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1; @@ -150,40 +149,13 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, struct kvm_vcpu_init preferred; ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred); - if (!ret) { - init->target = preferred.target; - } - } - if (ret >= 0) { - ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init); - if (ret < 0) { - goto err; - } - } else if (cpus_to_try) { - /* Old kernel which doesn't know about the - * PREFERRED_TARGET ioctl: we know it will only support - * creating one kind of guest CPU which is its preferred - * CPU type. - */ - struct kvm_vcpu_init try; - - while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) { - try.target = *cpus_to_try++; - memcpy(try.features, init->features, sizeof(init->features)); - ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, &try); - if (ret >= 0) { - break; - } - } if (ret < 0) { goto err; } - init->target = try.target; - } else { - /* Treat a NULL cpus_to_try argument the same as an empty - * list, which means we will fail the call since this must - * be an old kernel which doesn't support PREFERRED_TARGET. - */ + init->target = preferred.target; + } + ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init); + if (ret < 0) { goto err; } @@ -259,17 +231,6 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) uint64_t features = 0; int err; - /* Old kernels may not know about the PREFERRED_TARGET ioctl: however - * we know these will only support creating one kind of guest CPU, - * which is its preferred CPU type. Fortunately these old kernels - * support only a very limited number of CPUs. - */ - static const uint32_t cpus_to_try[] = { - KVM_ARM_TARGET_AEM_V8, - KVM_ARM_TARGET_FOUNDATION_V8, - KVM_ARM_TARGET_CORTEX_A57, - QEMU_KVM_ARM_TARGET_NONE - }; /* * target = -1 informs kvm_arm_create_scratch_host_vcpu() * to use the preferred target @@ -300,7 +261,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) features |= 1ULL << ARM_FEATURE_PMU; } - if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { + if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) { return false; } @@ -1835,7 +1796,7 @@ uint32_t kvm_arm_sve_get_vls(ARMCPU *cpu) probed = true; - if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, &init)) { + if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) { error_report("failed to create scratch VCPU with SVE enabled"); abort(); } diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 05c3de8cd4..5f17fc2f3d 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -97,10 +97,6 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu); #ifdef CONFIG_KVM /** * kvm_arm_create_scratch_host_vcpu: - * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with - * QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not - * know the PREFERRED_TARGET ioctl. Passing NULL is the same as passing - * an empty array. * @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order * @init: filled in with the necessary values for creating a host * vcpu. If NULL is provided, will not init the vCPU (though the cpufd @@ -113,8 +109,7 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu); * Returns: true on success (and fdarray and init are filled in), * false on failure (and fdarray and init are not valid). */ -bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, - int *fdarray, +bool kvm_arm_create_scratch_host_vcpu(int *fdarray, struct kvm_vcpu_init *init); /** diff --git a/target/arm/ptw.c b/target/arm/ptw.c index e0e82ae507..89979c07e5 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -10,10 +10,10 @@ #include "qemu/log.h" #include "qemu/range.h" #include "qemu/main-loop.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "exec/tlb-flags.h" +#include "accel/tcg/probe.h" #include "cpu.h" #include "internals.h" #include "cpu-features.h" @@ -3551,13 +3551,9 @@ bool get_phys_addr_with_space_nogpc(CPUARMState *env, vaddr address, memop, result, fi); } -bool get_phys_addr(CPUARMState *env, vaddr address, - MMUAccessType access_type, MemOp memop, ARMMMUIdx mmu_idx, - GetPhysAddrResult *result, ARMMMUFaultInfo *fi) +static ARMSecuritySpace +arm_mmu_idx_to_security_space(CPUARMState *env, ARMMMUIdx mmu_idx) { - S1Translate ptw = { - .in_mmu_idx = mmu_idx, - }; ARMSecuritySpace ss; switch (mmu_idx) { @@ -3618,28 +3614,33 @@ bool get_phys_addr(CPUARMState *env, vaddr address, g_assert_not_reached(); } - ptw.in_space = ss; + return ss; +} + +bool get_phys_addr(CPUARMState *env, vaddr address, + MMUAccessType access_type, MemOp memop, ARMMMUIdx mmu_idx, + GetPhysAddrResult *result, ARMMMUFaultInfo *fi) +{ + S1Translate ptw = { + .in_mmu_idx = mmu_idx, + .in_space = arm_mmu_idx_to_security_space(env, mmu_idx), + }; + return get_phys_addr_gpc(env, &ptw, address, access_type, memop, result, fi); } -hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, - MemTxAttrs *attrs) +static hwaddr arm_cpu_get_phys_page(CPUARMState *env, vaddr addr, + MemTxAttrs *attrs, ARMMMUIdx mmu_idx) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - ARMMMUIdx mmu_idx = arm_mmu_idx(env); - ARMSecuritySpace ss = arm_security_space(env); S1Translate ptw = { .in_mmu_idx = mmu_idx, - .in_space = ss, + .in_space = arm_mmu_idx_to_security_space(env, mmu_idx), .in_debug = true, }; GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; - bool ret; - - ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, 0, &res, &fi); + bool ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, 0, &res, &fi); *attrs = res.f.attrs; if (ret) { @@ -3647,3 +3648,33 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, } return res.f.phys_addr; } + +hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, + MemTxAttrs *attrs) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + ARMMMUIdx mmu_idx = arm_mmu_idx(env); + + hwaddr res = arm_cpu_get_phys_page(env, addr, attrs, mmu_idx); + + if (res != -1) { + return res; + } + + /* + * Memory may be accessible for an "unprivileged load/store" variant. + * In this case, get_a64_user_mem_index function generates an op using an + * unprivileged mmu idx, so we need to try with it. + */ + switch (mmu_idx) { + case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: + return arm_cpu_get_phys_page(env, addr, attrs, ARMMMUIdx_E10_0); + case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: + return arm_cpu_get_phys_page(env, addr, attrs, ARMMMUIdx_E20_0); + default: + return -1; + } +} diff --git a/target/arm/tcg-stubs.c b/target/arm/tcg-stubs.c index 93a15cad61..5e5166c049 100644 --- a/target/arm/tcg-stubs.c +++ b/target/arm/tcg-stubs.c @@ -21,10 +21,6 @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome, { g_assert_not_reached(); } -/* Temporarily while cpu_get_tb_cpu_state() is still in common code */ -void assert_hflags_rebuild_correctly(CPUARMState *env) -{ -} /* TLBI insns are only used by TCG, so we don't need to do anything for KVM */ void define_tlb_insn_regs(ARMCPU *cpu) diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c index b34b657857..95b23d9b55 100644 --- a/target/arm/tcg/cpu-v7m.c +++ b/target/arm/tcg/cpu-v7m.c @@ -238,6 +238,7 @@ static const TCGCPUOps arm_v7m_tcg_ops = { .initialize = arm_translate_init, .translate_code = arm_translate_code, + .get_tb_cpu_state = arm_get_tb_cpu_state, .synchronize_from_tb = arm_cpu_synchronize_from_tb, .debug_excp_handler = arm_debug_excp_handler, .restore_state_to_opc = arm_restore_state_to_opc, @@ -250,6 +251,7 @@ static const TCGCPUOps arm_v7m_tcg_ops = { .tlb_fill_align = arm_cpu_tlb_fill_align, .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt, .cpu_exec_halt = arm_cpu_exec_halt, + .cpu_exec_reset = cpu_reset, .do_interrupt = arm_v7m_cpu_do_interrupt, .do_transaction_failed = arm_cpu_do_transaction_failed, .do_unaligned_access = arm_cpu_do_unaligned_access, diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c index 842d9e6000..4f618ae390 100644 --- a/target/arm/tcg/helper-a64.c +++ b/target/arm/tcg/helper-a64.c @@ -29,8 +29,9 @@ #include "internals.h" #include "qemu/crc32c.h" #include "exec/cpu-common.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/helper-retaddr.h" +#include "accel/tcg/probe.h" #include "exec/target_page.h" #include "exec/tlb-flags.h" #include "qemu/int128.h" diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c index e51d9f7b15..fd407a7b28 100644 --- a/target/arm/tcg/hflags.c +++ b/target/arm/tcg/hflags.c @@ -10,6 +10,8 @@ #include "internals.h" #include "cpu-features.h" #include "exec/helper-proto.h" +#include "exec/translation-block.h" +#include "accel/tcg/cpu-ops.h" #include "cpregs.h" static inline bool fgt_svc(CPUARMState *env, int el) @@ -498,7 +500,7 @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el) env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx); } -void assert_hflags_rebuild_correctly(CPUARMState *env) +static void assert_hflags_rebuild_correctly(CPUARMState *env) { #ifdef CONFIG_DEBUG_TCG CPUARMTBFlags c = env->hflags; @@ -513,3 +515,116 @@ void assert_hflags_rebuild_correctly(CPUARMState *env) } #endif } + +static bool mve_no_pred(CPUARMState *env) +{ + /* + * Return true if there is definitely no predication of MVE + * instructions by VPR or LTPSIZE. (Returning false even if there + * isn't any predication is OK; generated code will just be + * a little worse.) + * If the CPU does not implement MVE then this TB flag is always 0. + * + * NOTE: if you change this logic, the "recalculate s->mve_no_pred" + * logic in gen_update_fp_context() needs to be updated to match. + * + * We do not include the effect of the ECI bits here -- they are + * tracked in other TB flags. This simplifies the logic for + * "when did we emit code that changes the MVE_NO_PRED TB flag + * and thus need to end the TB?". + */ + if (cpu_isar_feature(aa32_mve, env_archcpu(env))) { + return false; + } + if (env->v7m.vpr) { + return false; + } + if (env->v7m.ltpsize < 4) { + return false; + } + return true; +} + +TCGTBCPUState arm_get_tb_cpu_state(CPUState *cs) +{ + CPUARMState *env = cpu_env(cs); + CPUARMTBFlags flags; + vaddr pc; + + assert_hflags_rebuild_correctly(env); + flags = env->hflags; + + if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) { + pc = env->pc; + if (cpu_isar_feature(aa64_bti, env_archcpu(env))) { + DP_TBFLAG_A64(flags, BTYPE, env->btype); + } + } else { + pc = env->regs[15]; + + if (arm_feature(env, ARM_FEATURE_M)) { + if (arm_feature(env, ARM_FEATURE_M_SECURITY) && + FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) + != env->v7m.secure) { + DP_TBFLAG_M32(flags, FPCCR_S_WRONG, 1); + } + + if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) && + (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) || + (env->v7m.secure && + !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) { + /* + * ASPEN is set, but FPCA/SFPA indicate that there is no + * active FP context; we must create a new FP context before + * executing any FP insn. + */ + DP_TBFLAG_M32(flags, NEW_FP_CTXT_NEEDED, 1); + } + + bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK; + if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) { + DP_TBFLAG_M32(flags, LSPACT, 1); + } + + if (mve_no_pred(env)) { + DP_TBFLAG_M32(flags, MVE_NO_PRED, 1); + } + } else { + /* + * Note that XSCALE_CPAR shares bits with VECSTRIDE. + * Note that VECLEN+VECSTRIDE are RES0 for M-profile. + */ + if (arm_feature(env, ARM_FEATURE_XSCALE)) { + DP_TBFLAG_A32(flags, XSCALE_CPAR, env->cp15.c15_cpar); + } else { + DP_TBFLAG_A32(flags, VECLEN, env->vfp.vec_len); + DP_TBFLAG_A32(flags, VECSTRIDE, env->vfp.vec_stride); + } + if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) { + DP_TBFLAG_A32(flags, VFPEN, 1); + } + } + + DP_TBFLAG_AM32(flags, THUMB, env->thumb); + DP_TBFLAG_AM32(flags, CONDEXEC, env->condexec_bits); + } + + /* + * The SS_ACTIVE and PSTATE_SS bits correspond to the state machine + * states defined in the ARM ARM for software singlestep: + * SS_ACTIVE PSTATE.SS State + * 0 x Inactive (the TB flag for SS is always 0) + * 1 0 Active-pending + * 1 1 Active-not-pending + * SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB. + */ + if (EX_TBFLAG_ANY(flags, SS_ACTIVE) && (env->pstate & PSTATE_SS)) { + DP_TBFLAG_ANY(flags, PSTATE__SS, 1); + } + + return (TCGTBCPUState){ + .pc = pc, + .flags = flags.flags, + .cs_base = flags.flags2, + }; +} diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c index 37dc98dc35..6614719832 100644 --- a/target/arm/tcg/m_helper.c +++ b/target/arm/tcg/m_helper.c @@ -15,7 +15,6 @@ #include "qemu/main-loop.h" #include "qemu/bitops.h" #include "qemu/log.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #ifdef CONFIG_TCG #include "accel/tcg/cpu-ldst.h" diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c index 7dc5fb776b..0efc18a181 100644 --- a/target/arm/tcg/mte_helper.c +++ b/target/arm/tcg/mte_helper.c @@ -21,7 +21,6 @@ #include "qemu/log.h" #include "cpu.h" #include "internals.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #ifdef CONFIG_USER_ONLY #include "user/cpu_loop.h" @@ -30,6 +29,7 @@ #include "system/ram_addr.h" #endif #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/helper-proto.h" #include "exec/tlb-flags.h" #include "accel/tcg/cpu-ops.h" @@ -37,7 +37,6 @@ #include "qemu/guest-random.h" #include "mte_helper.h" - static int choose_nonexcluded_tag(int tag, int offset, uint16_t exclude) { if (exclude == 0xffff) { @@ -63,6 +62,7 @@ uint8_t *allocation_tag_mem_probe(CPUARMState *env, int ptr_mmu_idx, bool probe, uintptr_t ra) { #ifdef CONFIG_USER_ONLY + const size_t page_data_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1); uint64_t clean_ptr = useronly_clean_ptr(ptr); int flags = page_get_flags(clean_ptr); uint8_t *tags; @@ -83,7 +83,7 @@ uint8_t *allocation_tag_mem_probe(CPUARMState *env, int ptr_mmu_idx, return NULL; } - tags = page_get_target_data(clean_ptr); + tags = page_get_target_data(clean_ptr, page_data_size); index = extract32(ptr, LOG2_TAG_GRANULE + 1, TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1); diff --git a/target/arm/tcg/mve_helper.c b/target/arm/tcg/mve_helper.c index f9f67d1f88..506d1c3475 100644 --- a/target/arm/tcg/mve_helper.c +++ b/target/arm/tcg/mve_helper.c @@ -23,7 +23,6 @@ #include "vec_internal.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" #include "tcg/tcg.h" #include "fpu/softfloat.h" #include "crypto/clmul.h" diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index 38d49cbb9d..dc3f83c37d 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -23,8 +23,8 @@ #include "exec/target_page.h" #include "internals.h" #include "cpu-features.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "cpregs.h" #define SIGNBIT (uint32_t)0x80000000 diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c index 59bf27541d..c591c3052c 100644 --- a/target/arm/tcg/pauth_helper.c +++ b/target/arm/tcg/pauth_helper.c @@ -21,7 +21,6 @@ #include "cpu.h" #include "internals.h" #include "cpu-features.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "exec/helper-proto.h" #include "tcg/tcg-gvec-desc.h" diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c index 96b84c37a2..de0c6e54d4 100644 --- a/target/arm/tcg/sme_helper.c +++ b/target/arm/tcg/sme_helper.c @@ -23,7 +23,7 @@ #include "tcg/tcg-gvec-desc.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" +#include "accel/tcg/helper-retaddr.h" #include "qemu/int128.h" #include "fpu/softfloat.h" #include "vec_internal.h" diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c index 87b6b4b3e6..a2c363a4e1 100644 --- a/target/arm/tcg/sve_helper.c +++ b/target/arm/tcg/sve_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "internals.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/helper-proto.h" #include "exec/target_page.h" @@ -31,7 +30,9 @@ #include "vec_internal.h" #include "sve_ldst_internal.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/helper-retaddr.h" #include "accel/tcg/cpu-ops.h" +#include "accel/tcg/probe.h" #ifdef CONFIG_USER_ONLY #include "user/page-protection.h" #endif diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index 8841f039bc..5ea4d6590f 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -9,7 +9,6 @@ #include "cpu.h" #include "internals.h" #include "cpu-features.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index d9305f9d26..52cf47e775 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -17,7 +17,6 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "translate.h" #include "translate-a64.h" diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index 88df9c482a..e773ab7268 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -7760,7 +7760,8 @@ static bool arm_check_ss_active(DisasContext *dc) static void arm_post_translate_insn(DisasContext *dc) { - if (dc->condjmp && dc->base.is_jmp == DISAS_NEXT) { + if (dc->condjmp && + (dc->base.is_jmp == DISAS_NEXT || dc->base.is_jmp == DISAS_TOO_MANY)) { if (dc->pc_save != dc->condlabel.pc_save) { gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save); } diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index 53e485d28a..1bfdb0fb9b 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -4,7 +4,6 @@ #include "cpu.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" -#include "exec/exec-all.h" #include "exec/translator.h" #include "exec/translation-block.h" #include "exec/helper-gen.h" diff --git a/target/avr/cpu.c b/target/avr/cpu.c index 3f261c6fec..250241541b 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -21,13 +21,13 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/qemu-print.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "system/address-spaces.h" #include "cpu.h" #include "disas/dis-asm.h" #include "tcg/debug-assert.h" #include "hw/qdev-properties.h" +#include "accel/tcg/cpu-ops.h" static void avr_cpu_set_pc(CPUState *cs, vaddr value) { @@ -54,6 +54,21 @@ static int avr_cpu_mmu_index(CPUState *cs, bool ifetch) return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX; } +static TCGTBCPUState avr_get_tb_cpu_state(CPUState *cs) +{ + CPUAVRState *env = cpu_env(cs); + uint32_t flags = 0; + + if (env->fullacc) { + flags |= TB_FLAGS_FULL_ACCESS; + } + if (env->skip) { + flags |= TB_FLAGS_SKIP; + } + + return (TCGTBCPUState){ .pc = env->pc_w * 2, .flags = flags }; +} + static void avr_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -221,18 +236,18 @@ static const struct SysemuCPUOps avr_sysemu_ops = { .get_phys_page_debug = avr_cpu_get_phys_page_debug, }; -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps avr_tcg_ops = { .guest_default_memory_order = 0, .mttcg_supported = false, .initialize = avr_cpu_tcg_init, .translate_code = avr_cpu_translate_code, + .get_tb_cpu_state = avr_get_tb_cpu_state, .synchronize_from_tb = avr_cpu_synchronize_from_tb, .restore_state_to_opc = avr_restore_state_to_opc, .mmu_index = avr_cpu_mmu_index, .cpu_exec_interrupt = avr_cpu_exec_interrupt, .cpu_exec_halt = avr_cpu_has_work, + .cpu_exec_reset = cpu_reset, .tlb_fill = avr_cpu_tlb_fill, .do_interrupt = avr_cpu_do_interrupt, }; diff --git a/target/avr/cpu.h b/target/avr/cpu.h index d6666175a9..518e243d81 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -205,24 +205,6 @@ enum { TB_FLAGS_SKIP = 2, }; -static inline void cpu_get_tb_cpu_state(CPUAVRState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) -{ - uint32_t flags = 0; - - *pc = env->pc_w * 2; - *cs_base = 0; - - if (env->fullacc) { - flags |= TB_FLAGS_FULL_ACCESS; - } - if (env->skip) { - flags |= TB_FLAGS_SKIP; - } - - *pflags = flags; -} - static inline int cpu_interrupts_enabled(CPUAVRState *env) { return env->sregI != 0; diff --git a/target/avr/helper.c b/target/avr/helper.c index afa591470f..b9cd6d5ef2 100644 --- a/target/avr/helper.c +++ b/target/avr/helper.c @@ -23,7 +23,6 @@ #include "qemu/error-report.h" #include "cpu.h" #include "accel/tcg/cpu-ops.h" -#include "accel/tcg/getpc.h" #include "exec/cputlb.h" #include "exec/page-protection.h" #include "exec/target_page.h" diff --git a/target/avr/translate.c b/target/avr/translate.c index b9c592c899..804b0b21db 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -22,7 +22,6 @@ #include "qemu/qemu-print.h" #include "tcg/tcg.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "tcg/tcg-op.h" #include "exec/helper-proto.h" diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index a5d31c33bd..a5a04173ab 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -19,13 +19,13 @@ #include "qemu/qemu-print.h" #include "cpu.h" #include "internal.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "qapi/error.h" #include "hw/qdev-properties.h" #include "fpu/softfloat-helpers.h" #include "tcg/tcg.h" #include "exec/gdbstub.h" +#include "accel/tcg/cpu-ops.h" static void hexagon_v66_cpu_init(Object *obj) { } static void hexagon_v67_cpu_init(Object *obj) { } @@ -255,6 +255,22 @@ static vaddr hexagon_cpu_get_pc(CPUState *cs) return cpu_env(cs)->gpr[HEX_REG_PC]; } +static TCGTBCPUState hexagon_get_tb_cpu_state(CPUState *cs) +{ + CPUHexagonState *env = cpu_env(cs); + vaddr pc = env->gpr[HEX_REG_PC]; + uint32_t hex_flags = 0; + + if (pc == env->gpr[HEX_REG_SA0]) { + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1); + } + if (pc & PCALIGN_MASK) { + hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0); + } + + return (TCGTBCPUState){ .pc = pc, .flags = hex_flags }; +} + static void hexagon_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -322,14 +338,13 @@ static void hexagon_cpu_init(Object *obj) { } -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps hexagon_tcg_ops = { /* MTTCG not yet supported: require strict ordering */ .guest_default_memory_order = TCG_MO_ALL, .mttcg_supported = false, .initialize = hexagon_translate_init, .translate_code = hexagon_translate_code, + .get_tb_cpu_state = hexagon_get_tb_cpu_state, .synchronize_from_tb = hexagon_cpu_synchronize_from_tb, .restore_state_to_opc = hexagon_restore_state_to_opc, .mmu_index = hexagon_cpu_mmu_index, diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index c065fa8ddc..43a854f517 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -137,21 +137,6 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env, uint32_t exception, uintptr_t pc); -static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - uint32_t hex_flags = 0; - *pc = env->gpr[HEX_REG_PC]; - *cs_base = 0; - if (*pc == env->gpr[HEX_REG_SA0]) { - hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1); - } - *flags = hex_flags; - if (*pc & PCALIGN_MASK) { - hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0); - } -} - typedef HexagonCPU ArchCPU; void hexagon_translate_init(void); diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h index c1a88392c0..c7840fbf2e 100644 --- a/target/hexagon/mmvec/macros.h +++ b/target/hexagon/mmvec/macros.h @@ -22,6 +22,7 @@ #include "arch.h" #include "mmvec/system_ext_mmvec.h" #include "accel/tcg/getpc.h" +#include "accel/tcg/probe.h" #ifndef QEMU_GENERATE #define VdV (*(MMVector *restrict)(VdV_void)) diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index 3f3d86db2b..444799d3ad 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -17,8 +17,8 @@ #include "qemu/osdep.h" #include "qemu/log.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" #include "cpu.h" diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index b792cb247a..6465181543 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -24,12 +24,12 @@ #include "qemu/timer.h" #include "cpu.h" #include "qemu/module.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "exec/target_page.h" #include "fpu/softfloat.h" #include "tcg/tcg.h" #include "hw/hppa/hppa_hardware.h" +#include "accel/tcg/cpu-ops.h" static void hppa_cpu_set_pc(CPUState *cs, vaddr value) { @@ -51,11 +51,12 @@ static vaddr hppa_cpu_get_pc(CPUState *cs) env->iaoq_f & -4); } -void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc, - uint64_t *pcsbase, uint32_t *pflags) +static TCGTBCPUState hppa_get_tb_cpu_state(CPUState *cs) { + CPUHPPAState *env = cpu_env(cs); uint32_t flags = 0; uint64_t cs_base = 0; + vaddr pc; /* * TB lookup assumes that PC contains the complete virtual address. @@ -63,7 +64,7 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc, * incomplete virtual address. This also means that we must separate * out current cpu privilege from the low bits of IAOQ_F. */ - *pc = hppa_cpu_get_pc(env_cpu(env)); + pc = hppa_cpu_get_pc(env_cpu(env)); flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT; /* @@ -99,8 +100,7 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc, } #endif - *pcsbase = cs_base; - *pflags = flags; + return (TCGTBCPUState){ .pc = pc, .flags = flags, .cs_base = cs_base }; } static void hppa_cpu_synchronize_from_tb(CPUState *cs, @@ -250,8 +250,6 @@ static const struct SysemuCPUOps hppa_sysemu_ops = { }; #endif -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps hppa_tcg_ops = { /* PA-RISC 1.x processors have a strong memory model. */ /* @@ -264,6 +262,7 @@ static const TCGCPUOps hppa_tcg_ops = { .initialize = hppa_translate_init, .translate_code = hppa_translate_code, + .get_tb_cpu_state = hppa_get_tb_cpu_state, .synchronize_from_tb = hppa_cpu_synchronize_from_tb, .restore_state_to_opc = hppa_restore_state_to_opc, .mmu_index = hppa_cpu_mmu_index, @@ -272,6 +271,7 @@ static const TCGCPUOps hppa_tcg_ops = { .tlb_fill_align = hppa_cpu_tlb_fill_align, .cpu_exec_interrupt = hppa_cpu_exec_interrupt, .cpu_exec_halt = hppa_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = hppa_cpu_do_interrupt, .do_unaligned_access = hppa_cpu_do_unaligned_access, .do_transaction_failed = hppa_cpu_do_transaction_failed, diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index acc9937240..11d59d11ca 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -351,9 +351,6 @@ hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr); #define CS_BASE_DIFFPAGE (1 << 12) #define CS_BASE_DIFFSPACE (1 << 13) -void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags); - target_ulong cpu_hppa_get_psw(CPUHPPAState *env); void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong); void update_gva_offset_mask(CPUHPPAState *env); diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c index a62d9d3083..ddd0a343d6 100644 --- a/target/hppa/fpu_helper.c +++ b/target/hppa/fpu_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/hppa/helper.c b/target/hppa/helper.c index ac7f58f0af..d7f8495d98 100644 --- a/target/hppa/helper.c +++ b/target/hppa/helper.c @@ -21,7 +21,6 @@ #include "qemu/log.h" #include "cpu.h" #include "fpu/softfloat.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qemu/qemu-print.h" #include "hw/hppa/hppa_hardware.h" diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index 554d7bf4d1..9bdd0a6f23 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -20,9 +20,9 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "accel/tcg/cpu-mmu-index.h" +#include "accel/tcg/probe.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "exec/helper-proto.h" diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index 2398ce2c64..0458378abb 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -20,9 +20,9 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "qemu/timer.h" #include "trace.h" #ifdef CONFIG_USER_ONLY diff --git a/target/hppa/sys_helper.c b/target/hppa/sys_helper.c index 052a6a88a2..6e65fadcc7 100644 --- a/target/hppa/sys_helper.c +++ b/target/hppa/sys_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qemu/timer.h" #include "system/runstate.h" diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 88a7d339eb..7a81cfcb88 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 54bf9639f1..4f8ed8868e 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -35,10 +35,6 @@ #define XEN_NR_VIRQS 24 -/* support for self modifying code even if the modified instruction is - close to the modifying instruction */ -#define TARGET_HAS_PRECISE_SMC - #ifdef TARGET_X86_64 #define I386_ELF_MACHINE EM_X86_64 #define ELF_MACHINE_UNAME "x86_64" @@ -2603,20 +2599,6 @@ static inline bool is_mmu_index_32(int mmu_index) #include "hw/i386/apic.h" #endif -static inline void cpu_get_tb_cpu_state(CPUX86State *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *flags = env->hflags | - (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK | AC_MASK)); - if (env->hflags & HF_CS64_MASK) { - *cs_base = 0; - *pc = env->eip; - } else { - *cs_base = env->segs[R_CS].base; - *pc = (uint32_t)(*cs_base + env->eip); - } -} - void do_cpu_init(X86CPU *cpu); #define MCE_INJECT_BROADCAST 1 diff --git a/target/i386/helper.c b/target/i386/helper.c index 197fdac7dd..e0aaed3c4c 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -526,7 +526,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, static inline target_ulong get_memio_eip(CPUX86State *env) { #ifdef CONFIG_TCG - uint64_t data[TARGET_INSN_START_WORDS]; + uint64_t data[INSN_START_WORDS]; CPUState *cs = env_cpu(env); if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { diff --git a/target/i386/tcg/access.c b/target/i386/tcg/access.c index 0fdd587edd..97e3f0e756 100644 --- a/target/i386/tcg/access.c +++ b/target/i386/tcg/access.c @@ -4,7 +4,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" +#include "accel/tcg/probe.h" #include "exec/target_page.h" #include "access.h" diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c index de71e68f98..6fb8036d98 100644 --- a/target/i386/tcg/excp_helper.c +++ b/target/i386/tcg/excp_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "qemu/log.h" #include "system/runstate.h" #include "exec/helper-proto.h" diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h index 54d845379c..6b3f19855f 100644 --- a/target/i386/tcg/helper-tcg.h +++ b/target/i386/tcg/helper-tcg.h @@ -20,7 +20,6 @@ #ifndef I386_HELPER_TCG_H #define I386_HELPER_TCG_H -#include "exec/exec-all.h" #include "qemu/host-utils.h" /* Maximum instruction code size */ diff --git a/target/i386/tcg/int_helper.c b/target/i386/tcg/int_helper.c index 1a02e9d843..46741d9f68 100644 --- a/target/i386/tcg/int_helper.c +++ b/target/i386/tcg/int_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" -#include "exec/exec-all.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" #include "qapi/error.h" diff --git a/target/i386/tcg/mem_helper.c b/target/i386/tcg/mem_helper.c index 84a0815217..9e7c2d8029 100644 --- a/target/i386/tcg/mem_helper.c +++ b/target/i386/tcg/mem_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "qemu/int128.h" #include "qemu/atomic128.h" diff --git a/target/i386/tcg/mpx_helper.c b/target/i386/tcg/mpx_helper.c index a0f816dfae..fa8abcc482 100644 --- a/target/i386/tcg/mpx_helper.c +++ b/target/i386/tcg/mpx_helper.c @@ -21,7 +21,6 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "helper-tcg.h" diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 3af902e0ec..0ca081b286 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -22,8 +22,8 @@ #include "cpu.h" #include "qemu/log.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/log.h" #include "helper-tcg.h" #include "seg_helper.h" diff --git a/target/i386/tcg/system/bpt_helper.c b/target/i386/tcg/system/bpt_helper.c index 08ccd3f5e6..aebb5caac3 100644 --- a/target/i386/tcg/system/bpt_helper.c +++ b/target/i386/tcg/system/bpt_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "exec/watchpoint.h" #include "tcg/helper-tcg.h" diff --git a/target/i386/tcg/system/excp_helper.c b/target/i386/tcg/system/excp_helper.c index 93614aa3e5..c162621587 100644 --- a/target/i386/tcg/system/excp_helper.c +++ b/target/i386/tcg/system/excp_helper.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/cputlb.h" #include "exec/page-protection.h" #include "exec/target_page.h" diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index e53aaa31bf..179dfdf064 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -24,6 +24,7 @@ #include "accel/accel-cpu-target.h" #include "exec/translation-block.h" #include "exec/target_page.h" +#include "accel/tcg/cpu-ops.h" #include "tcg-cpu.h" /* Frob eflags into and out of the CPU temporary format. */ @@ -47,6 +48,25 @@ static void x86_cpu_exec_exit(CPUState *cs) env->eflags = cpu_compute_eflags(env); } +static TCGTBCPUState x86_get_tb_cpu_state(CPUState *cs) +{ + CPUX86State *env = cpu_env(cs); + uint32_t flags, cs_base; + vaddr pc; + + flags = env->hflags | + (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK | AC_MASK)); + if (env->hflags & HF_CS64_MASK) { + cs_base = 0; + pc = env->eip; + } else { + cs_base = env->segs[R_CS].base; + pc = (uint32_t)(cs_base + env->eip); + } + + return (TCGTBCPUState){ .pc = pc, .flags = flags, .cs_base = cs_base }; +} + static void x86_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -120,18 +140,27 @@ static bool x86_debug_check_breakpoint(CPUState *cs) /* RF disables all architectural breakpoints. */ return !(env->eflags & RF_MASK); } -#endif -#include "accel/tcg/cpu-ops.h" +static void x86_cpu_exec_reset(CPUState *cs) +{ + CPUArchState *env = cpu_env(cs); + + cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0, 0); + do_cpu_init(env_archcpu(env)); + cs->exception_index = EXCP_HALTED; +} +#endif const TCGCPUOps x86_tcg_ops = { .mttcg_supported = true, + .precise_smc = true, /* * The x86 has a strong memory model with some store-after-load re-ordering */ .guest_default_memory_order = TCG_MO_ALL & ~TCG_MO_ST_LD, .initialize = tcg_x86_init, .translate_code = x86_translate_code, + .get_tb_cpu_state = x86_get_tb_cpu_state, .synchronize_from_tb = x86_cpu_synchronize_from_tb, .restore_state_to_opc = x86_restore_state_to_opc, .mmu_index = x86_cpu_mmu_index, @@ -146,6 +175,7 @@ const TCGCPUOps x86_tcg_ops = { .do_interrupt = x86_cpu_do_interrupt, .cpu_exec_halt = x86_cpu_exec_halt, .cpu_exec_interrupt = x86_cpu_exec_interrupt, + .cpu_exec_reset = x86_cpu_exec_reset, .do_unaligned_access = x86_cpu_do_unaligned_access, .debug_excp_handler = breakpoint_handler, .debug_check_breakpoint = x86_debug_check_breakpoint, diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index ed43c95c1d..0fcddc2ec0 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -21,7 +21,6 @@ #include "qemu/host-utils.h" #include "cpu.h" #include "accel/tcg/cpu-mmu-index.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" diff --git a/target/i386/tcg/user/excp_helper.c b/target/i386/tcg/user/excp_helper.c index b3bdb7831a..98fab4cbc3 100644 --- a/target/i386/tcg/user/excp_helper.c +++ b/target/i386/tcg/user/excp_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "tcg/helper-tcg.h" void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr, diff --git a/target/i386/tcg/user/seg_helper.c b/target/i386/tcg/user/seg_helper.c index 5692dd5195..263f59937f 100644 --- a/target/i386/tcg/user/seg_helper.c +++ b/target/i386/tcg/user/seg_helper.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "tcg/helper-tcg.h" #include "tcg/seg_helper.h" diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 8ad45b453d..f7535d1be7 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -15,7 +15,6 @@ #include "system/kvm.h" #include "kvm/kvm_loongarch.h" #include "hw/qdev-properties.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "cpu.h" #include "internals.h" @@ -30,6 +29,7 @@ #endif #ifdef CONFIG_TCG #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/cpu-ops.h" #include "tcg/tcg.h" #endif #include "tcg/tcg_loongarch.h" @@ -336,6 +336,20 @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } #endif +static TCGTBCPUState loongarch_get_tb_cpu_state(CPUState *cs) +{ + CPULoongArchState *env = cpu_env(cs); + uint32_t flags; + + flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); + flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; + flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; + flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; + flags |= is_va32(env) * HW_FLAGS_VA32; + + return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; +} + static void loongarch_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -862,14 +876,13 @@ static void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) } #ifdef CONFIG_TCG -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps loongarch_tcg_ops = { .guest_default_memory_order = 0, .mttcg_supported = true, .initialize = loongarch_translate_init, .translate_code = loongarch_translate_code, + .get_tb_cpu_state = loongarch_get_tb_cpu_state, .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, .restore_state_to_opc = loongarch_restore_state_to_opc, .mmu_index = loongarch_cpu_mmu_index, @@ -878,6 +891,7 @@ static const TCGCPUOps loongarch_tcg_ops = { .tlb_fill = loongarch_cpu_tlb_fill, .cpu_exec_interrupt = loongarch_cpu_exec_interrupt, .cpu_exec_halt = loongarch_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = loongarch_cpu_do_interrupt, .do_transaction_failed = loongarch_cpu_do_transaction_failed, #endif diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 70ff56e60c..262bf87f7b 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -492,18 +492,6 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value) #define HW_FLAGS_VA32 0x20 #define HW_FLAGS_EUEN_ASXE 0x40 -static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - *cs_base = 0; - *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); - *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; - *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; - *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; - *flags |= is_va32(env) * HW_FLAGS_VA32; -} - #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU void loongarch_cpu_post_init(Object *obj); diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c index fc3fd0561e..fc9c64c20a 100644 --- a/target/loongarch/tcg/fpu_helper.c +++ b/target/loongarch/tcg/fpu_helper.c @@ -8,7 +8,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "fpu/softfloat.h" #include "internals.h" diff --git a/target/loongarch/tcg/iocsr_helper.c b/target/loongarch/tcg/iocsr_helper.c index e62170de3c..c155f48564 100644 --- a/target/loongarch/tcg/iocsr_helper.c +++ b/target/loongarch/tcg/iocsr_helper.c @@ -9,7 +9,6 @@ #include "cpu.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #define GET_MEMTXATTRS(cas) \ diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c index 94e3b28016..16ac0d43bc 100644 --- a/target/loongarch/tcg/op_helper.c +++ b/target/loongarch/tcg/op_helper.c @@ -10,7 +10,6 @@ #include "cpu.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "internals.h" #include "qemu/crc32c.h" diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index af208d75ae..dc48b0f4d2 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -13,7 +13,6 @@ #include "internals.h" #include "exec/helper-proto.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "accel/tcg/cpu-ldst.h" diff --git a/target/loongarch/tcg/vec_helper.c b/target/loongarch/tcg/vec_helper.c index 3faf52cbc4..a270998e63 100644 --- a/target/loongarch/tcg/vec_helper.c +++ b/target/loongarch/tcg/vec_helper.c @@ -7,7 +7,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" #include "internals.h" diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 6f33b86c7d..c5196a612e 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -23,6 +23,8 @@ #include "cpu.h" #include "migration/vmstate.h" #include "fpu/softfloat.h" +#include "exec/translation-block.h" +#include "accel/tcg/cpu-ops.h" static void m68k_cpu_set_pc(CPUState *cs, vaddr value) { @@ -38,6 +40,24 @@ static vaddr m68k_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static TCGTBCPUState m68k_get_tb_cpu_state(CPUState *cs) +{ + CPUM68KState *env = cpu_env(cs); + uint32_t flags; + + flags = (env->macsr >> 4) & TB_FLAGS_MACSR; + if (env->sr & SR_S) { + flags |= TB_FLAGS_MSR_S; + flags |= (env->sfc << (TB_FLAGS_SFC_S_BIT - 2)) & TB_FLAGS_SFC_S; + flags |= (env->dfc << (TB_FLAGS_DFC_S_BIT - 2)) & TB_FLAGS_DFC_S; + } + if (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS) { + flags |= TB_FLAGS_TRACE; + } + + return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; +} + static void m68k_restore_state_to_opc(CPUState *cs, const TranslationBlock *tb, const uint64_t *data) @@ -586,8 +606,6 @@ static const struct SysemuCPUOps m68k_sysemu_ops = { }; #endif /* !CONFIG_USER_ONLY */ -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps m68k_tcg_ops = { /* MTTCG not yet supported: require strict ordering */ .guest_default_memory_order = TCG_MO_ALL, @@ -595,6 +613,7 @@ static const TCGCPUOps m68k_tcg_ops = { .initialize = m68k_tcg_init, .translate_code = m68k_translate_code, + .get_tb_cpu_state = m68k_get_tb_cpu_state, .restore_state_to_opc = m68k_restore_state_to_opc, .mmu_index = m68k_cpu_mmu_index, @@ -602,6 +621,7 @@ static const TCGCPUOps m68k_tcg_ops = { .tlb_fill = m68k_cpu_tlb_fill, .cpu_exec_interrupt = m68k_cpu_exec_interrupt, .cpu_exec_halt = m68k_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = m68k_cpu_do_interrupt, .do_transaction_failed = m68k_cpu_transaction_failed, #endif /* !CONFIG_USER_ONLY */ diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 39d0b9d6d7..d9db6a486a 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -605,22 +605,6 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, #define TB_FLAGS_TRACE 16 #define TB_FLAGS_TRACE_BIT (1 << TB_FLAGS_TRACE) -static inline void cpu_get_tb_cpu_state(CPUM68KState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - *cs_base = 0; - *flags = (env->macsr >> 4) & TB_FLAGS_MACSR; - if (env->sr & SR_S) { - *flags |= TB_FLAGS_MSR_S; - *flags |= (env->sfc << (TB_FLAGS_SFC_S_BIT - 2)) & TB_FLAGS_SFC_S; - *flags |= (env->dfc << (TB_FLAGS_DFC_S_BIT - 2)) & TB_FLAGS_DFC_S; - } - if (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS) { - *flags |= TB_FLAGS_TRACE; - } -} - void dump_mmu(CPUM68KState *env); #endif diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index ac4a0d85be..56012863c8 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "softfloat.h" diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 3b880dd4d9..15f110fa7a 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "exec/gdbstub.h" diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 242aecccbb..f29ae12af8 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -20,7 +20,6 @@ #include "qemu/log.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "semihosting/semihost.h" diff --git a/target/m68k/translate.c b/target/m68k/translate.c index b1266a7875..97afceb129 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "exec/target_page.h" #include "tcg/tcg-op.h" diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index 00a2730de4..d069e40e70 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -27,11 +27,11 @@ #include "cpu.h" #include "qemu/module.h" #include "hw/qdev-properties.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "exec/gdbstub.h" #include "exec/translation-block.h" #include "fpu/softfloat-helpers.h" +#include "accel/tcg/cpu-ops.h" #include "tcg/tcg.h" static const struct { @@ -95,6 +95,17 @@ static vaddr mb_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static TCGTBCPUState mb_get_tb_cpu_state(CPUState *cs) +{ + CPUMBState *env = cpu_env(cs); + + return (TCGTBCPUState){ + .pc = env->pc, + .flags = (env->iflags & IFLAGS_TB_MASK) | (env->msr & MSR_TB_MASK), + .cs_base = (env->iflags & IMM_FLAG ? env->imm : 0), + }; +} + static void mb_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -424,8 +435,6 @@ static const struct SysemuCPUOps mb_sysemu_ops = { }; #endif -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps mb_tcg_ops = { /* MicroBlaze is always in-order. */ .guest_default_memory_order = TCG_MO_ALL, @@ -433,6 +442,7 @@ static const TCGCPUOps mb_tcg_ops = { .initialize = mb_tcg_init, .translate_code = mb_translate_code, + .get_tb_cpu_state = mb_get_tb_cpu_state, .synchronize_from_tb = mb_cpu_synchronize_from_tb, .restore_state_to_opc = mb_restore_state_to_opc, .mmu_index = mb_cpu_mmu_index, @@ -441,6 +451,7 @@ static const TCGCPUOps mb_tcg_ops = { .tlb_fill = mb_cpu_tlb_fill, .cpu_exec_interrupt = mb_cpu_exec_interrupt, .cpu_exec_halt = mb_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = mb_cpu_do_interrupt, .do_transaction_failed = mb_cpu_transaction_failed, .do_unaligned_access = mb_cpu_do_unaligned_access, diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index d511f22a55..6ad8643f2e 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -419,14 +419,6 @@ static inline bool mb_cpu_is_big_endian(CPUState *cs) return !cpu->cfg.endi; } -static inline void cpu_get_tb_cpu_state(CPUMBState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - *flags = (env->iflags & IFLAGS_TB_MASK) | (env->msr & MSR_TB_MASK); - *cs_base = (*flags & IMM_FLAG ? env->imm : 0); -} - #if !defined(CONFIG_USER_ONLY) bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c index 4624ce5b67..9e838dfa15 100644 --- a/target/microblaze/op_helper.c +++ b/target/microblaze/op_helper.c @@ -23,7 +23,6 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "fpu/softfloat.h" diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index 23f1037236..671b1ae4db 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "tcg/tcg-op.h" #include "exec/helper-proto.h" diff --git a/target/mips/cpu.c b/target/mips/cpu.c index d13361a150..4cbfb9435a 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -29,7 +29,6 @@ #include "qemu/module.h" #include "system/kvm.h" #include "system/qtest.h" -#include "exec/exec-all.h" #include "hw/qdev-properties.h" #include "hw/qdev-clock.h" #include "fpu_helper.h" @@ -550,12 +549,24 @@ static int mips_cpu_mmu_index(CPUState *cs, bool ifunc) return mips_env_mmu_index(cpu_env(cs)); } +static TCGTBCPUState mips_get_tb_cpu_state(CPUState *cs) +{ + CPUMIPSState *env = cpu_env(cs); + + return (TCGTBCPUState){ + .pc = env->active_tc.PC, + .flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK | + MIPS_HFLAG_HWRENA_ULR), + }; +} + static const TCGCPUOps mips_tcg_ops = { .mttcg_supported = TARGET_LONG_BITS == 32, .guest_default_memory_order = 0, .initialize = mips_tcg_init, .translate_code = mips_translate_code, + .get_tb_cpu_state = mips_get_tb_cpu_state, .synchronize_from_tb = mips_cpu_synchronize_from_tb, .restore_state_to_opc = mips_restore_state_to_opc, .mmu_index = mips_cpu_mmu_index, @@ -564,6 +575,7 @@ static const TCGCPUOps mips_tcg_ops = { .tlb_fill = mips_cpu_tlb_fill, .cpu_exec_interrupt = mips_cpu_exec_interrupt, .cpu_exec_halt = mips_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = mips_cpu_do_interrupt, .do_transaction_failed = mips_cpu_do_transaction_failed, .do_unaligned_access = mips_cpu_do_unaligned_access, diff --git a/target/mips/cpu.h b/target/mips/cpu.h index d16f9a7220..5cd4c6c818 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1366,15 +1366,6 @@ void cpu_mips_clock_init(MIPSCPU *cpu); /* helper.c */ target_ulong exception_resume_pc(CPUMIPSState *env); -static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->active_tc.PC; - *cs_base = 0; - *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK | - MIPS_HFLAG_HWRENA_ULR); -} - /** * mips_cpu_create_with_clock: * @typename: a MIPS CPU type. diff --git a/target/mips/system/physaddr.c b/target/mips/system/physaddr.c index 505781d84c..b8e1a5ac98 100644 --- a/target/mips/system/physaddr.c +++ b/target/mips/system/physaddr.c @@ -18,7 +18,6 @@ */ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "../internal.h" diff --git a/target/mips/tcg/exception.c b/target/mips/tcg/exception.c index 1a8902ea1b..d32bcebf46 100644 --- a/target/mips/tcg/exception.c +++ b/target/mips/tcg/exception.c @@ -23,7 +23,6 @@ #include "cpu.h" #include "internal.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" target_ulong exception_resume_pc(CPUMIPSState *env) diff --git a/target/mips/tcg/fpu_helper.c b/target/mips/tcg/fpu_helper.c index 45d593de48..36af980802 100644 --- a/target/mips/tcg/fpu_helper.c +++ b/target/mips/tcg/fpu_helper.c @@ -24,7 +24,6 @@ #include "cpu.h" #include "internal.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "fpu/softfloat.h" #include "fpu_helper.h" diff --git a/target/mips/tcg/ldst_helper.c b/target/mips/tcg/ldst_helper.c index 2fb879fcbc..10319bf03a 100644 --- a/target/mips/tcg/ldst_helper.c +++ b/target/mips/tcg/ldst_helper.c @@ -23,7 +23,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "exec/memop.h" #include "internal.h" diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c index e349344647..f554b3d10e 100644 --- a/target/mips/tcg/msa_helper.c +++ b/target/mips/tcg/msa_helper.c @@ -21,8 +21,8 @@ #include "cpu.h" #include "internal.h" #include "tcg/tcg.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/helper-proto.h" #include "exec/memop.h" #include "exec/target_page.h" diff --git a/target/mips/tcg/op_helper.c b/target/mips/tcg/op_helper.c index 65403f1a87..b906d10204 100644 --- a/target/mips/tcg/op_helper.c +++ b/target/mips/tcg/op_helper.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "internal.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "exec/memop.h" #include "fpu_helper.h" diff --git a/target/mips/tcg/system/special_helper.c b/target/mips/tcg/system/special_helper.c index 3ce3ae1e12..b54cbe88a3 100644 --- a/target/mips/tcg/system/special_helper.c +++ b/target/mips/tcg/system/special_helper.c @@ -22,7 +22,6 @@ #include "qemu/log.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "internal.h" diff --git a/target/mips/tcg/system/tlb_helper.c b/target/mips/tcg/system/tlb_helper.c index e477ef812a..eccaf3624c 100644 --- a/target/mips/tcg/system/tlb_helper.c +++ b/target/mips/tcg/system/tlb_helper.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "internal.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "accel/tcg/cpu-ldst.h" diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index 2ec267efec..054ad33360 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -21,9 +21,9 @@ #include "qapi/error.h" #include "qemu/qemu-print.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "fpu/softfloat-helpers.h" +#include "accel/tcg/cpu-ops.h" #include "tcg/tcg.h" static void openrisc_cpu_set_pc(CPUState *cs, vaddr value) @@ -41,6 +41,18 @@ static vaddr openrisc_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static TCGTBCPUState openrisc_get_tb_cpu_state(CPUState *cs) +{ + CPUOpenRISCState *env = cpu_env(cs); + + return (TCGTBCPUState){ + .pc = env->pc, + .flags = ((env->dflag ? TB_FLAGS_DFLAG : 0) + | (cpu_get_gpr(env, 0) ? 0 : TB_FLAGS_R0_0) + | (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE))), + }; +} + static void openrisc_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -240,14 +252,13 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = { }; #endif -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps openrisc_tcg_ops = { .guest_default_memory_order = 0, .mttcg_supported = true, .initialize = openrisc_translate_init, .translate_code = openrisc_translate_code, + .get_tb_cpu_state = openrisc_get_tb_cpu_state, .synchronize_from_tb = openrisc_cpu_synchronize_from_tb, .restore_state_to_opc = openrisc_restore_state_to_opc, .mmu_index = openrisc_cpu_mmu_index, @@ -256,6 +267,7 @@ static const TCGCPUOps openrisc_tcg_ops = { .tlb_fill = openrisc_cpu_tlb_fill, .cpu_exec_interrupt = openrisc_cpu_exec_interrupt, .cpu_exec_halt = openrisc_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = openrisc_cpu_do_interrupt, #endif /* !CONFIG_USER_ONLY */ }; diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 569819bfb0..f4bcf00b07 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -349,16 +349,6 @@ static inline void cpu_set_gpr(CPUOpenRISCState *env, int i, uint32_t val) env->shadow_gpr[0][i] = val; } -static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - *cs_base = 0; - *flags = (env->dflag ? TB_FLAGS_DFLAG : 0) - | (cpu_get_gpr(env, 0) ? 0 : TB_FLAGS_R0_0) - | (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE)); -} - static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env) { return (env->sr diff --git a/target/openrisc/exception.c b/target/openrisc/exception.c index 8699c3dcea..e213be36b6 100644 --- a/target/openrisc/exception.c +++ b/target/openrisc/exception.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exception.h" G_NORETURN void raise_exception(OpenRISCCPU *cpu, uint32_t excp) diff --git a/target/openrisc/exception_helper.c b/target/openrisc/exception_helper.c index 1f5be4bed9..c2c9d13652 100644 --- a/target/openrisc/exception_helper.c +++ b/target/openrisc/exception_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "exception.h" diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c index 8b81d2f62f..dba997255c 100644 --- a/target/openrisc/fpu_helper.c +++ b/target/openrisc/fpu_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c index b3b5b40577..486823094c 100644 --- a/target/openrisc/interrupt.c +++ b/target/openrisc/interrupt.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" -#include "exec/exec-all.h" #include "gdbstub/helpers.h" #include "qemu/host-utils.h" #ifndef CONFIG_USER_ONLY diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c index ab4ea88b69..1553ebc71b 100644 --- a/target/openrisc/interrupt_helper.c +++ b/target/openrisc/interrupt_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" void HELPER(rfe)(CPUOpenRISCState *env) diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index 92badf017f..d96b41a01c 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/target_page.h" #include "exec/helper-proto.h" @@ -219,7 +218,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, { OpenRISCCPU *cpu = env_archcpu(env); #ifndef CONFIG_USER_ONLY - uint64_t data[TARGET_INSN_START_WORDS]; + uint64_t data[INSN_START_WORDS]; MachineState *ms = MACHINE(qdev_get_machine()); CPUState *cs = env_cpu(env); int idx; diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c index baadea4448..5ab3bc7021 100644 --- a/target/openrisc/translate.c +++ b/target/openrisc/translate.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "accel/tcg/cpu-mmu-index.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "qemu/log.h" #include "qemu/bitops.h" diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 13115a89ff..6b90543811 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2751,19 +2751,6 @@ void cpu_write_xer(CPUPPCState *env, target_ulong xer); */ #define is_book3s_arch2x(ctx) (!!((ctx)->insns_flags & PPC_SEGMENT_64B)) -#ifdef CONFIG_DEBUG_TCG -void cpu_get_tb_cpu_state(CPUPPCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags); -#else -static inline void cpu_get_tb_cpu_state(CPUPPCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->nip; - *cs_base = 0; - *flags = env->hflags; -} -#endif - G_NORETURN void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, uint32_t error_code, uintptr_t raddr); diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 09a8d4ff72..9642812a71 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -45,7 +45,6 @@ #include "internal.h" #include "spr_common.h" #include "power8-pmu.h" - #ifndef CONFIG_USER_ONLY #include "hw/boards.h" #include "hw/intc/intc.h" @@ -7483,6 +7482,7 @@ static const TCGCPUOps ppc_tcg_ops = { .guest_default_memory_order = 0, .initialize = ppc_translate_init, .translate_code = ppc_translate_code, + .get_tb_cpu_state = ppc_get_tb_cpu_state, .restore_state_to_opc = ppc_restore_state_to_opc, .mmu_index = ppc_cpu_mmu_index, @@ -7492,6 +7492,7 @@ static const TCGCPUOps ppc_tcg_ops = { .tlb_fill = ppc_cpu_tlb_fill, .cpu_exec_interrupt = ppc_cpu_exec_interrupt, .cpu_exec_halt = ppc_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = ppc_cpu_do_interrupt, .cpu_exec_enter = ppc_cpu_exec_enter, .cpu_exec_exit = ppc_cpu_exec_exit, diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index da8b525a41..1efdc4066e 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -24,7 +24,6 @@ #include "system/system.h" #include "system/runstate.h" #include "cpu.h" -#include "exec/exec-all.h" #include "internal.h" #include "helper_regs.h" #include "hw/ppc/ppc.h" diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index d93cfed17b..07b782f971 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "internal.h" #include "fpu/softfloat.h" diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index f211bc9830..7e5726871e 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -27,6 +27,8 @@ #include "power8-pmu.h" #include "cpu-models.h" #include "spr_common.h" +#include "accel/tcg/cpu-ops.h" +#include "internal.h" /* Swap temporary saved registers with GPRs */ void hreg_swap_gpr_tgpr(CPUPPCState *env) @@ -255,26 +257,23 @@ void hreg_update_pmu_hflags(CPUPPCState *env) env->hflags |= hreg_compute_pmu_hflags_value(env); } -#ifdef CONFIG_DEBUG_TCG -void cpu_get_tb_cpu_state(CPUPPCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) +TCGTBCPUState ppc_get_tb_cpu_state(CPUState *cs) { + CPUPPCState *env = cpu_env(cs); uint32_t hflags_current = env->hflags; - uint32_t hflags_rebuilt; - - *pc = env->nip; - *cs_base = 0; - *flags = hflags_current; - hflags_rebuilt = hreg_compute_hflags_value(env); +#ifdef CONFIG_DEBUG_TCG + uint32_t hflags_rebuilt = hreg_compute_hflags_value(env); if (unlikely(hflags_current != hflags_rebuilt)) { cpu_abort(env_cpu(env), "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n", hflags_current, hflags_rebuilt); } -} #endif + return (TCGTBCPUState){ .pc = env->nip, .flags = hflags_current }; +} + void cpu_interrupt_exittb(CPUState *cs) { /* diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 9012d3809c..7723350227 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -21,6 +21,7 @@ #include "exec/breakpoint.h" #include "hw/registerfields.h" #include "exec/page-protection.h" +#include "accel/tcg/tb-cpu-state.h" /* PM instructions */ typedef enum { @@ -308,4 +309,6 @@ static inline int ger_pack_masks(int pmsk, int ymsk, int xmsk) return msk; } +TCGTBCPUState ppc_get_tb_cpu_state(CPUState *cs); + #endif /* PPC_INTERNAL_H */ diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 98df5b4a3a..d72e5ecb94 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "system/kvm.h" #include "system/tcg.h" #include "helper_regs.h" diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c index d7e8d678f4..6ab71a6fcb 100644 --- a/target/ppc/mem_helper.c +++ b/target/ppc/mem_helper.c @@ -19,12 +19,13 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" #include "helper_regs.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/helper-retaddr.h" +#include "accel/tcg/probe.h" #include "internal.h" #include "qemu/atomic128.h" diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 46ae454afd..e7d9462518 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/helper-proto.h" #include "qemu/error-report.h" diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c index 5bd3efe70e..8b980a5aa9 100644 --- a/target/ppc/mmu-hash32.c +++ b/target/ppc/mmu-hash32.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "system/kvm.h" diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 3ba4810497..dd337558aa 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "qemu/error-report.h" #include "qemu/qemu-print.h" diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 4ab5f3bb92..33ac341290 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "qemu/error-report.h" #include "system/kvm.h" diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c index 394a0c9bb6..52d48615ac 100644 --- a/target/ppc/mmu_common.c +++ b/target/ppc/mmu_common.c @@ -24,7 +24,6 @@ #include "kvm_ppc.h" #include "mmu-hash64.h" #include "mmu-hash32.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "exec/log.h" diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index 2138666122..ac60705402 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -25,7 +25,6 @@ #include "mmu-hash64.h" #include "mmu-hash32.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "exec/log.h" diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c index db9ee8e96b..2a7a5b493a 100644 --- a/target/ppc/power8-pmu.c +++ b/target/ppc/power8-pmu.c @@ -13,7 +13,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "helper_regs.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qemu/error-report.h" #include "qemu/timer.h" diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 2b15e5f2f0..f835be5156 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -21,7 +21,6 @@ #include "qemu/log.h" #include "target/ppc/cpu.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "system/runstate.h" diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c index 73120323b4..7209b418fb 100644 --- a/target/ppc/timebase_helper.c +++ b/target/ppc/timebase_helper.c @@ -20,7 +20,6 @@ #include "cpu.h" #include "hw/ppc/ppc.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "qemu/log.h" #include "qemu/main-loop.h" diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 62dd008e36..27f90c3cc5 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "internal.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" diff --git a/target/ppc/user_only_helper.c b/target/ppc/user_only_helper.c index a4d07a0d0d..ae210eb847 100644 --- a/target/ppc/user_only_helper.c +++ b/target/ppc/user_only_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "internal.h" void ppc_cpu_record_sigsegv(CPUState *cs, vaddr address, diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index e0604f4c78..d92874baa0 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -24,7 +24,6 @@ #include "cpu.h" #include "cpu_vendorid.h" #include "internals.h" -#include "exec/exec-all.h" #include "qapi/error.h" #include "qapi/visitor.h" #include "qemu/error-report.h" diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 167909c89b..c66ac3bc27 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -802,9 +802,6 @@ static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew, return vlen >> (vsew + 3 - lmul); } -void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags); - bool riscv_cpu_is_32bit(RISCVCPU *cpu); bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 619c76cc00..d5039f69a9 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -24,7 +24,6 @@ #include "internals.h" #include "pmu.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "system/memory.h" @@ -136,103 +135,6 @@ bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt) #endif } -void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) -{ - RISCVCPU *cpu = env_archcpu(env); - RISCVExtStatus fs, vs; - uint32_t flags = 0; - bool pm_signext = riscv_cpu_virt_mem_enabled(env); - - *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; - *cs_base = 0; - - if (cpu->cfg.ext_zve32x) { - /* - * If env->vl equals to VLMAX, we can use generic vector operation - * expanders (GVEC) to accerlate the vector operations. - * However, as LMUL could be a fractional number. The maximum - * vector size can be operated might be less than 8 bytes, - * which is not supported by GVEC. So we set vl_eq_vlmax flag to true - * only when maxsz >= 8 bytes. - */ - - /* lmul encoded as in DisasContext::lmul */ - int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3); - uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW); - uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul); - uint32_t maxsz = vlmax << vsew; - bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) && - (maxsz >= 8); - flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill); - flags = FIELD_DP32(flags, TB_FLAGS, SEW, vsew); - flags = FIELD_DP32(flags, TB_FLAGS, LMUL, - FIELD_EX64(env->vtype, VTYPE, VLMUL)); - flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); - flags = FIELD_DP32(flags, TB_FLAGS, VTA, - FIELD_EX64(env->vtype, VTYPE, VTA)); - flags = FIELD_DP32(flags, TB_FLAGS, VMA, - FIELD_EX64(env->vtype, VTYPE, VMA)); - flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0); - } else { - flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); - } - - if (cpu_get_fcfien(env)) { - /* - * For Forward CFI, only the expectation of a lpad at - * the start of the block is tracked via env->elp. env->elp - * is turned on during jalr translation. - */ - flags = FIELD_DP32(flags, TB_FLAGS, FCFI_LP_EXPECTED, env->elp); - flags = FIELD_DP32(flags, TB_FLAGS, FCFI_ENABLED, 1); - } - - if (cpu_get_bcfien(env)) { - flags = FIELD_DP32(flags, TB_FLAGS, BCFI_ENABLED, 1); - } - -#ifdef CONFIG_USER_ONLY - fs = EXT_STATUS_DIRTY; - vs = EXT_STATUS_DIRTY; -#else - flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv); - - flags |= riscv_env_mmu_index(env, 0); - fs = get_field(env->mstatus, MSTATUS_FS); - vs = get_field(env->mstatus, MSTATUS_VS); - - if (env->virt_enabled) { - flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1); - /* - * Merge DISABLED and !DIRTY states using MIN. - * We will set both fields when dirtying. - */ - fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS)); - vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS)); - } - - /* With Zfinx, floating point is enabled/disabled by Smstateen. */ - if (!riscv_has_ext(env, RVF)) { - fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE) - ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED; - } - - if (cpu->cfg.debug && !icount_enabled()) { - flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled); - } -#endif - - flags = FIELD_DP32(flags, TB_FLAGS, FS, fs); - flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); - flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); - flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); - flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); - flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); - - *pflags = flags; -} - RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) { #ifndef CONFIG_USER_ONLY diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c index bb084e00ef..a0fb54bc50 100644 --- a/target/riscv/crypto_helper.c +++ b/target/riscv/crypto_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "crypto/aes.h" #include "crypto/aes-round.h" diff --git a/target/riscv/csr.c b/target/riscv/csr.c index c52c87faae..a32e1455c9 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -24,10 +24,10 @@ #include "tcg/tcg-cpu.h" #include "pmu.h" #include "time_helper.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/tb-flush.h" #include "exec/icount.h" +#include "accel/tcg/getpc.h" #include "qemu/guest-random.h" #include "qapi/error.h" #include <stdbool.h> diff --git a/target/riscv/debug.c b/target/riscv/debug.c index 8564f0b371..5664466749 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -28,7 +28,6 @@ #include "qapi/error.h" #include "cpu.h" #include "trace.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "exec/watchpoint.h" #include "system/cpu-timers.h" diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c index 91b1a56d10..706bdfa61d 100644 --- a/target/riscv/fpu_helper.c +++ b/target/riscv/fpu_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" #include "internals.h" diff --git a/target/riscv/m128_helper.c b/target/riscv/m128_helper.c index ec14aaa901..7d9b83b1b2 100644 --- a/target/riscv/m128_helper.c +++ b/target/riscv/m128_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" target_ulong HELPER(divu_i128)(CPURISCVState *env, diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 5b0db2c45a..05316f2088 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -21,9 +21,9 @@ #include "qemu/osdep.h" #include "cpu.h" #include "internals.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/helper-proto.h" #include "exec/tlb-flags.h" #include "trace.h" diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 54ac54f2e1..55e00972b7 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -18,7 +18,6 @@ */ #include "qemu/osdep.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "tcg-cpu.h" #include "cpu.h" @@ -37,6 +36,7 @@ #ifndef CONFIG_USER_ONLY #include "hw/boards.h" #include "system/tcg.h" +#include "exec/icount.h" #endif /* Hash that stores user set extensions */ @@ -98,6 +98,103 @@ static int riscv_cpu_mmu_index(CPUState *cs, bool ifetch) return riscv_env_mmu_index(cpu_env(cs), ifetch); } +static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs) +{ + CPURISCVState *env = cpu_env(cs); + RISCVCPU *cpu = env_archcpu(env); + RISCVExtStatus fs, vs; + uint32_t flags = 0; + bool pm_signext = riscv_cpu_virt_mem_enabled(env); + + if (cpu->cfg.ext_zve32x) { + /* + * If env->vl equals to VLMAX, we can use generic vector operation + * expanders (GVEC) to accerlate the vector operations. + * However, as LMUL could be a fractional number. The maximum + * vector size can be operated might be less than 8 bytes, + * which is not supported by GVEC. So we set vl_eq_vlmax flag to true + * only when maxsz >= 8 bytes. + */ + + /* lmul encoded as in DisasContext::lmul */ + int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3); + uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW); + uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul); + uint32_t maxsz = vlmax << vsew; + bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) && + (maxsz >= 8); + flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill); + flags = FIELD_DP32(flags, TB_FLAGS, SEW, vsew); + flags = FIELD_DP32(flags, TB_FLAGS, LMUL, + FIELD_EX64(env->vtype, VTYPE, VLMUL)); + flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); + flags = FIELD_DP32(flags, TB_FLAGS, VTA, + FIELD_EX64(env->vtype, VTYPE, VTA)); + flags = FIELD_DP32(flags, TB_FLAGS, VMA, + FIELD_EX64(env->vtype, VTYPE, VMA)); + flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0); + } else { + flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); + } + + if (cpu_get_fcfien(env)) { + /* + * For Forward CFI, only the expectation of a lpad at + * the start of the block is tracked via env->elp. env->elp + * is turned on during jalr translation. + */ + flags = FIELD_DP32(flags, TB_FLAGS, FCFI_LP_EXPECTED, env->elp); + flags = FIELD_DP32(flags, TB_FLAGS, FCFI_ENABLED, 1); + } + + if (cpu_get_bcfien(env)) { + flags = FIELD_DP32(flags, TB_FLAGS, BCFI_ENABLED, 1); + } + +#ifdef CONFIG_USER_ONLY + fs = EXT_STATUS_DIRTY; + vs = EXT_STATUS_DIRTY; +#else + flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv); + + flags |= riscv_env_mmu_index(env, 0); + fs = get_field(env->mstatus, MSTATUS_FS); + vs = get_field(env->mstatus, MSTATUS_VS); + + if (env->virt_enabled) { + flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1); + /* + * Merge DISABLED and !DIRTY states using MIN. + * We will set both fields when dirtying. + */ + fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS)); + vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS)); + } + + /* With Zfinx, floating point is enabled/disabled by Smstateen. */ + if (!riscv_has_ext(env, RVF)) { + fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE) + ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED; + } + + if (cpu->cfg.debug && !icount_enabled()) { + flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled); + } +#endif + + flags = FIELD_DP32(flags, TB_FLAGS, FS, fs); + flags = FIELD_DP32(flags, TB_FLAGS, VS, vs); + flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl); + flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env)); + flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env)); + flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext); + + return (TCGTBCPUState){ + .pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc, + .flags = flags + }; +} + static void riscv_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -146,6 +243,7 @@ const TCGCPUOps riscv_tcg_ops = { .initialize = riscv_translate_init, .translate_code = riscv_translate_code, + .get_tb_cpu_state = riscv_get_tb_cpu_state, .synchronize_from_tb = riscv_cpu_synchronize_from_tb, .restore_state_to_opc = riscv_restore_state_to_opc, .mmu_index = riscv_cpu_mmu_index, @@ -154,6 +252,7 @@ const TCGCPUOps riscv_tcg_ops = { .tlb_fill = riscv_cpu_tlb_fill, .cpu_exec_interrupt = riscv_cpu_exec_interrupt, .cpu_exec_halt = riscv_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = riscv_cpu_do_interrupt, .do_transaction_failed = riscv_cpu_do_transaction_failed, .do_unaligned_access = riscv_cpu_do_unaligned_access, diff --git a/target/riscv/translate.c b/target/riscv/translate.c index cef61b5b29..85128f997b 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -20,7 +20,6 @@ #include "qemu/log.h" #include "cpu.h" #include "tcg/tcg-op.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "exec/target_page.h" diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c index 1526de96f5..9a0d9b4f53 100644 --- a/target/riscv/vcrypto_helper.c +++ b/target/riscv/vcrypto_helper.c @@ -26,7 +26,6 @@ #include "crypto/aes-round.h" #include "crypto/sm4.h" #include "exec/memop.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "internals.h" #include "vector_internals.h" diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index b8ae704457..8eea3e6df0 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -21,8 +21,8 @@ #include "qemu/bitops.h" #include "cpu.h" #include "exec/memop.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/page-protection.h" #include "exec/helper-proto.h" #include "exec/tlb-flags.h" diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c index 50d65f386c..55221f5f37 100644 --- a/target/riscv/zce_helper.c +++ b/target/riscv/zce_helper.c @@ -18,7 +18,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" diff --git a/target/rx/cpu.c b/target/rx/cpu.c index a51b543028..36eba75545 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -28,6 +28,7 @@ #include "hw/loader.h" #include "fpu/softfloat.h" #include "tcg/debug-assert.h" +#include "accel/tcg/cpu-ops.h" static void rx_cpu_set_pc(CPUState *cs, vaddr value) { @@ -43,6 +44,17 @@ static vaddr rx_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static TCGTBCPUState rx_get_tb_cpu_state(CPUState *cs) +{ + CPURXState *env = cpu_env(cs); + uint32_t flags = 0; + + flags = FIELD_DP32(flags, PSW, PM, env->psw_pm); + flags = FIELD_DP32(flags, PSW, U, env->psw_u); + + return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; +} + static void rx_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -201,8 +213,6 @@ static const struct SysemuCPUOps rx_sysemu_ops = { .get_phys_page_debug = rx_cpu_get_phys_page_debug, }; -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps rx_tcg_ops = { /* MTTCG not yet supported: require strict ordering */ .guest_default_memory_order = TCG_MO_ALL, @@ -210,6 +220,7 @@ static const TCGCPUOps rx_tcg_ops = { .initialize = rx_translate_init, .translate_code = rx_translate_code, + .get_tb_cpu_state = rx_get_tb_cpu_state, .synchronize_from_tb = rx_cpu_synchronize_from_tb, .restore_state_to_opc = rx_restore_state_to_opc, .mmu_index = rx_cpu_mmu_index, @@ -217,6 +228,7 @@ static const TCGCPUOps rx_tcg_ops = { .cpu_exec_interrupt = rx_cpu_exec_interrupt, .cpu_exec_halt = rx_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = rx_cpu_do_interrupt, }; diff --git a/target/rx/cpu.h b/target/rx/cpu.h index 5c19c83219..ba5761b647 100644 --- a/target/rx/cpu.h +++ b/target/rx/cpu.h @@ -153,15 +153,6 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte); #define RX_CPU_IRQ 0 #define RX_CPU_FIR 1 -static inline void cpu_get_tb_cpu_state(CPURXState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - *cs_base = 0; - *flags = FIELD_DP32(0, PSW, PM, env->psw_pm); - *flags = FIELD_DP32(*flags, PSW, U, env->psw_u); -} - static inline uint32_t rx_cpu_pack_psw(CPURXState *env) { uint32_t psw = 0; diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c index a2f1f3824d..2b190a4b2c 100644 --- a/target/rx/op_helper.c +++ b/target/rx/op_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "qemu/bitops.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" #include "fpu/softfloat.h" diff --git a/target/rx/translate.c b/target/rx/translate.c index bbda703be8..19a9584a82 100644 --- a/target/rx/translate.c +++ b/target/rx/translate.c @@ -20,7 +20,6 @@ #include "qemu/bswap.h" #include "qemu/qemu-print.h" #include "cpu.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 3d644f5e23..9c1158ebcc 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -302,15 +302,16 @@ static const Property s390x_cpu_properties[] = { #ifdef CONFIG_TCG #include "accel/tcg/cpu-ops.h" +#include "tcg/tcg_s390x.h" static int s390x_cpu_mmu_index(CPUState *cs, bool ifetch) { return s390x_env_mmu_index(cpu_env(cs), ifetch); } -void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) +static TCGTBCPUState s390x_get_tb_cpu_state(CPUState *cs) { + CPUS390XState *env = cpu_env(cs); uint32_t flags; if (env->psw.addr & 1) { @@ -322,9 +323,6 @@ void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc, tcg_s390_program_interrupt(env, PGM_SPECIFICATION, 0); } - *pc = env->psw.addr; - *cs_base = env->ex_value; - flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW; if (env->psw.mask & PSW_MASK_PER) { flags |= env->cregs[9] & (FLAG_MASK_PER_BRANCH | @@ -341,11 +339,17 @@ void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc, if (env->cregs[0] & CR0_VECTOR) { flags |= FLAG_MASK_VECTOR; } - *pflags = flags; + + return (TCGTBCPUState){ + .pc = env->psw.addr, + .flags = flags, + .cs_base = env->ex_value, + }; } static const TCGCPUOps s390_tcg_ops = { .mttcg_supported = true, + .precise_smc = true, /* * The z/Architecture has a strong memory model with some * store-after-load re-ordering. @@ -354,6 +358,7 @@ static const TCGCPUOps s390_tcg_ops = { .initialize = s390x_translate_init, .translate_code = s390x_translate_code, + .get_tb_cpu_state = s390x_get_tb_cpu_state, .restore_state_to_opc = s390x_restore_state_to_opc, .mmu_index = s390x_cpu_mmu_index, @@ -364,6 +369,7 @@ static const TCGCPUOps s390_tcg_ops = { .tlb_fill = s390_cpu_tlb_fill, .cpu_exec_interrupt = s390_cpu_exec_interrupt, .cpu_exec_halt = s390_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = s390_cpu_do_interrupt, .debug_excp_handler = s390x_cpu_debug_excp_handler, .do_unaligned_access = s390x_cpu_do_unaligned_access, diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index d9ca2506e2..aa931cb674 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -35,8 +35,6 @@ #define ELF_MACHINE_UNAME "S390X" -#define TARGET_HAS_PRECISE_SMC - #define MMU_USER_IDX 0 #define S390_MAX_CPUS 248 @@ -413,15 +411,6 @@ static inline int s390x_env_mmu_index(CPUS390XState *env, bool ifetch) #endif } -#ifdef CONFIG_TCG - -#include "tcg/tcg_s390x.h" - -void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags); - -#endif /* CONFIG_TCG */ - /* PER bits from control register 9 */ #define PER_CR9_EVENT_BRANCH 0x80000000 #define PER_CR9_EVENT_IFETCH 0x40000000 diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c index 4ae6e2ddea..1dca835c5d 100644 --- a/target/s390x/interrupt.c +++ b/target/s390x/interrupt.c @@ -11,7 +11,6 @@ #include "cpu.h" #include "kvm/kvm_s390x.h" #include "s390x-internal.h" -#include "exec/exec-all.h" #include "system/kvm.h" #include "system/tcg.h" #include "hw/s390x/ioinst.h" diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 0e133cb9a5..00946e9c0f 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -23,7 +23,6 @@ #include "kvm/kvm_s390x.h" #include "system/kvm.h" #include "system/tcg.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "hw/hw.h" diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c index a3347f1236..5e95c4978f 100644 --- a/target/s390x/sigp.c +++ b/target/s390x/sigp.c @@ -16,7 +16,6 @@ #include "system/runstate.h" #include "system/address-spaces.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "system/tcg.h" #include "trace.h" #include "qapi/qapi-types-machine.h" diff --git a/target/s390x/tcg/cc_helper.c b/target/s390x/tcg/cc_helper.c index b36f8cdc8b..6595ac763c 100644 --- a/target/s390x/tcg/cc_helper.c +++ b/target/s390x/tcg/cc_helper.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "s390x-internal.h" #include "tcg_s390x.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_helper.c index 642c1b18c4..4447bb66ee 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -17,7 +17,6 @@ #include "s390x-internal.h" #include "tcg_s390x.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" static uint64_t R(uint64_t x, int c) diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c index 6cd813e1ab..e4c75d0ce0 100644 --- a/target/s390x/tcg/excp_helper.c +++ b/target/s390x/tcg/excp_helper.c @@ -23,7 +23,6 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "exec/watchpoint.h" #include "s390x-internal.h" diff --git a/target/s390x/tcg/fpu_helper.c b/target/s390x/tcg/fpu_helper.c index 5041c13962..1ba43715ac 100644 --- a/target/s390x/tcg/fpu_helper.c +++ b/target/s390x/tcg/fpu_helper.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "s390x-internal.h" #include "tcg_s390x.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/s390x/tcg/int_helper.c b/target/s390x/tcg/int_helper.c index 253c036415..fbda396f5b 100644 --- a/target/s390x/tcg/int_helper.c +++ b/target/s390x/tcg/int_helper.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "s390x-internal.h" #include "tcg_s390x.h" -#include "exec/exec-all.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c index 0cdfd380ce..a03609a140 100644 --- a/target/s390x/tcg/mem_helper.c +++ b/target/s390x/tcg/mem_helper.c @@ -25,13 +25,14 @@ #include "tcg_s390x.h" #include "exec/helper-proto.h" #include "exec/cpu-common.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/page-protection.h" #include "accel/tcg/cpu-ldst.h" +#include "accel/tcg/probe.h" #include "exec/target_page.h" #include "exec/tlb-flags.h" #include "accel/tcg/cpu-ops.h" +#include "accel/tcg/helper-retaddr.h" #include "qemu/int128.h" #include "qemu/atomic128.h" diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c index d5088493ea..f7101be574 100644 --- a/target/s390x/tcg/misc_helper.c +++ b/target/s390x/tcg/misc_helper.c @@ -26,7 +26,6 @@ #include "qemu/host-utils.h" #include "exec/helper-proto.h" #include "qemu/timer.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "accel/tcg/cpu-ldst.h" #include "exec/target_page.h" diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index a714f9c0c2..c7e8574438 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -31,7 +31,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "s390x-internal.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" #include "qemu/log.h" diff --git a/target/s390x/tcg/vec_fpu_helper.c b/target/s390x/tcg/vec_fpu_helper.c index 1bbaa82fe8..744f800fb6 100644 --- a/target/s390x/tcg/vec_fpu_helper.c +++ b/target/s390x/tcg/vec_fpu_helper.c @@ -15,7 +15,6 @@ #include "vec.h" #include "tcg_s390x.h" #include "tcg/tcg-gvec-desc.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/s390x/tcg/vec_helper.c b/target/s390x/tcg/vec_helper.c index 781ccc565b..46ec4a947d 100644 --- a/target/s390x/tcg/vec_helper.c +++ b/target/s390x/tcg/vec_helper.c @@ -17,7 +17,6 @@ #include "tcg/tcg-gvec-desc.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" -#include "exec/exec-all.h" void HELPER(gvec_vbperm)(void *v1, const void *v2, const void *v3, uint32_t desc) diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index 57d7b5fbc8..b35f18e250 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -24,9 +24,9 @@ #include "qemu/qemu-print.h" #include "cpu.h" #include "migration/vmstate.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "fpu/softfloat-helpers.h" +#include "accel/tcg/cpu-ops.h" #include "tcg/tcg.h" static void superh_cpu_set_pc(CPUState *cs, vaddr value) @@ -43,6 +43,29 @@ static vaddr superh_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static TCGTBCPUState superh_get_tb_cpu_state(CPUState *cs) +{ + CPUSH4State *env = cpu_env(cs); + uint32_t flags; + + flags = env->flags + | (env->fpscr & TB_FLAG_FPSCR_MASK) + | (env->sr & TB_FLAG_SR_MASK) + | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 3 */ +#ifdef CONFIG_USER_ONLY + flags |= TB_FLAG_UNALIGN * !cs->prctl_unalign_sigbus; +#endif + + return (TCGTBCPUState){ + .pc = env->pc, + .flags = flags, +#ifdef CONFIG_USER_ONLY + /* For a gUSA region, notice the end of the region. */ + .cs_base = flags & TB_FLAG_GUSA_MASK ? env->gregs[0] : 0, +#endif + }; +} + static void superh_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -259,8 +282,6 @@ static const struct SysemuCPUOps sh4_sysemu_ops = { }; #endif -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps superh_tcg_ops = { /* MTTCG not yet supported: require strict ordering */ .guest_default_memory_order = TCG_MO_ALL, @@ -268,6 +289,7 @@ static const TCGCPUOps superh_tcg_ops = { .initialize = sh4_translate_init, .translate_code = sh4_translate_code, + .get_tb_cpu_state = superh_get_tb_cpu_state, .synchronize_from_tb = superh_cpu_synchronize_from_tb, .restore_state_to_opc = superh_restore_state_to_opc, .mmu_index = sh4_cpu_mmu_index, @@ -276,6 +298,7 @@ static const TCGCPUOps superh_tcg_ops = { .tlb_fill = superh_cpu_tlb_fill, .cpu_exec_interrupt = superh_cpu_exec_interrupt, .cpu_exec_halt = superh_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = superh_cpu_do_interrupt, .do_unaligned_access = superh_cpu_do_unaligned_access, .io_recompile_replay_branch = superh_io_recompile_replay_branch, diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 906f99ddf0..c41ab70dd7 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -380,19 +380,4 @@ static inline void cpu_write_sr(CPUSH4State *env, target_ulong sr) env->sr = sr & ~((1u << SR_M) | (1u << SR_Q) | (1u << SR_T)); } -static inline void cpu_get_tb_cpu_state(CPUSH4State *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - /* For a gUSA region, notice the end of the region. */ - *cs_base = env->flags & TB_FLAG_GUSA_MASK ? env->gregs[0] : 0; - *flags = env->flags - | (env->fpscr & TB_FLAG_FPSCR_MASK) - | (env->sr & TB_FLAG_SR_MASK) - | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 3 */ -#ifdef CONFIG_USER_ONLY - *flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus; -#endif -} - #endif /* SH4_CPU_H */ diff --git a/target/sh4/helper.c b/target/sh4/helper.c index b41d14d5d7..fb7642bda1 100644 --- a/target/sh4/helper.c +++ b/target/sh4/helper.c @@ -21,7 +21,6 @@ #include "cpu.h" #include "exec/cputlb.h" -#include "exec/exec-all.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "exec/log.h" diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c index e7fcad3c1b..557b1bf497 100644 --- a/target/sh4/op_helper.c +++ b/target/sh4/op_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include "fpu/softfloat.h" diff --git a/target/sh4/translate.c b/target/sh4/translate.c index 712117be22..bf8828fce8 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index bc753d5f62..2a3e408923 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -23,7 +23,6 @@ #include "qemu/module.h" #include "qemu/qemu-print.h" #include "accel/tcg/cpu-mmu-index.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "hw/qdev-properties.h" #include "qapi/visitor.h" @@ -717,13 +716,11 @@ static void sparc_cpu_synchronize_from_tb(CPUState *cs, cpu->env.npc = tb->cs_base; } -void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags) +static TCGTBCPUState sparc_get_tb_cpu_state(CPUState *cs) { - uint32_t flags; - *pc = env->pc; - *cs_base = env->npc; - flags = cpu_mmu_index(env_cpu(env), false); + CPUSPARCState *env = cpu_env(cs); + uint32_t flags = cpu_mmu_index(cs, false); + #ifndef CONFIG_USER_ONLY if (cpu_supervisor_mode(env)) { flags |= TB_FLAG_SUPER; @@ -752,7 +749,12 @@ void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc, } #endif /* !CONFIG_USER_ONLY */ #endif /* TARGET_SPARC64 */ - *pflags = flags; + + return (TCGTBCPUState){ + .pc = env->pc, + .flags = flags, + .cs_base = env->npc, + }; } static void sparc_restore_state_to_opc(CPUState *cs, @@ -1027,6 +1029,7 @@ static const TCGCPUOps sparc_tcg_ops = { .initialize = sparc_tcg_init, .translate_code = sparc_translate_code, + .get_tb_cpu_state = sparc_get_tb_cpu_state, .synchronize_from_tb = sparc_cpu_synchronize_from_tb, .restore_state_to_opc = sparc_restore_state_to_opc, .mmu_index = sparc_cpu_mmu_index, @@ -1035,6 +1038,7 @@ static const TCGCPUOps sparc_tcg_ops = { .tlb_fill = sparc_cpu_tlb_fill, .cpu_exec_interrupt = sparc_cpu_exec_interrupt, .cpu_exec_halt = sparc_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = sparc_cpu_do_interrupt, .do_transaction_failed = sparc_cpu_do_transaction_failed, .do_unaligned_access = sparc_cpu_do_unaligned_access, diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index 37fd1e066e..31cb3d97eb 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -741,9 +741,6 @@ trap_state* cpu_tsptr(CPUSPARCState* env); #define TB_FLAG_FSR_QNE (1 << 8) #define TB_FLAG_ASI_SHIFT 24 -void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *pflags); - static inline bool tb_fpu_enabled(int tb_flags) { #if defined(CONFIG_USER_ONLY) diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c index c25097d07f..a49334150d 100644 --- a/target/sparc/fop_helper.c +++ b/target/sparc/fop_helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "fpu/softfloat.h" diff --git a/target/sparc/helper.c b/target/sparc/helper.c index 7846ddd6f6..9163b9d46a 100644 --- a/target/sparc/helper.c +++ b/target/sparc/helper.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "qemu/timer.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c index 4c5dba19d1..2c63eb9e03 100644 --- a/target/sparc/ldst_helper.c +++ b/target/sparc/ldst_helper.c @@ -23,7 +23,6 @@ #include "cpu.h" #include "tcg/tcg.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "exec/page-protection.h" #include "exec/target_page.h" diff --git a/target/sparc/machine.c b/target/sparc/machine.c index 222e5709c5..4dd75aff74 100644 --- a/target/sparc/machine.c +++ b/target/sparc/machine.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "qemu/timer.h" #include "migration/cpu.h" diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 63dd90447b..b922e53bf1 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -22,7 +22,6 @@ #include "cpu.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "exec/target_page.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c index 0c4b09f2c1..9ad9d01e8b 100644 --- a/target/sparc/win_helper.c +++ b/target/sparc/win_helper.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "trace.h" diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c index 098cd06c54..e56f90fde9 100644 --- a/target/tricore/cpu.c +++ b/target/tricore/cpu.c @@ -20,10 +20,10 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/translation-block.h" #include "qemu/error-report.h" #include "tcg/debug-assert.h" +#include "accel/tcg/cpu-ops.h" static inline void set_feature(CPUTriCoreState *env, int feature) { @@ -45,6 +45,16 @@ static vaddr tricore_cpu_get_pc(CPUState *cs) return cpu_env(cs)->PC; } +static TCGTBCPUState tricore_get_tb_cpu_state(CPUState *cs) +{ + CPUTriCoreState *env = cpu_env(cs); + + return (TCGTBCPUState){ + .pc = env->PC, + .flags = FIELD_DP32(0, TB_FLAGS, PRIV, extract32(env->PSW, 10, 2)), + }; +} + static void tricore_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -169,20 +179,20 @@ static const struct SysemuCPUOps tricore_sysemu_ops = { .get_phys_page_debug = tricore_cpu_get_phys_page_debug, }; -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps tricore_tcg_ops = { /* MTTCG not yet supported: require strict ordering */ .guest_default_memory_order = TCG_MO_ALL, .mttcg_supported = false, .initialize = tricore_tcg_init, .translate_code = tricore_translate_code, + .get_tb_cpu_state = tricore_get_tb_cpu_state, .synchronize_from_tb = tricore_cpu_synchronize_from_tb, .restore_state_to_opc = tricore_restore_state_to_opc, .mmu_index = tricore_cpu_mmu_index, .tlb_fill = tricore_cpu_tlb_fill, .cpu_exec_interrupt = tricore_cpu_exec_interrupt, .cpu_exec_halt = tricore_cpu_has_work, + .cpu_exec_reset = cpu_reset, }; static void tricore_cpu_class_init(ObjectClass *c, const void *data) diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h index c76e65f818..82085fbc32 100644 --- a/target/tricore/cpu.h +++ b/target/tricore/cpu.h @@ -258,18 +258,6 @@ void tricore_tcg_init(void); void tricore_translate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, vaddr pc, void *host_pc); -static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - uint32_t new_flags = 0; - *pc = env->PC; - *cs_base = 0; - - new_flags |= FIELD_DP32(new_flags, TB_FLAGS, PRIV, - extract32(env->PSW, 10, 2)); - *flags = new_flags; -} - #define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU /* helpers.c */ diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index ae559b6922..9910c13f4b 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -18,7 +18,6 @@ #include "cpu.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" -#include "exec/exec-all.h" #include "accel/tcg/cpu-ldst.h" #include <zlib.h> /* for crc32 */ diff --git a/target/tricore/translate.c b/target/tricore/translate.c index ba36c9fcc8..3d0e7a10bd 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "accel/tcg/cpu-ldst.h" #include "qemu/qemu-print.h" diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 27d6e40195..91b71b6caa 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -35,6 +35,7 @@ #include "qemu/module.h" #include "migration/vmstate.h" #include "hw/qdev-clock.h" +#include "accel/tcg/cpu-ops.h" #ifndef CONFIG_USER_ONLY #include "system/memory.h" #endif @@ -54,6 +55,80 @@ static vaddr xtensa_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static TCGTBCPUState xtensa_get_tb_cpu_state(CPUState *cs) +{ + CPUXtensaState *env = cpu_env(cs); + uint32_t flags = 0; + target_ulong cs_base = 0; + + flags |= xtensa_get_ring(env); + if (env->sregs[PS] & PS_EXCM) { + flags |= XTENSA_TBFLAG_EXCM; + } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_LOOP)) { + target_ulong lend_dist = + env->sregs[LEND] - (env->pc & -(1u << TARGET_PAGE_BITS)); + + /* + * 0 in the csbase_lend field means that there may not be a loopback + * for any instruction that starts inside this page. Any other value + * means that an instruction that ends at this offset from the page + * start may loop back and will need loopback code to be generated. + * + * lend_dist is 0 when LEND points to the start of the page, but + * no instruction that starts inside this page may end at offset 0, + * so it's still correct. + * + * When an instruction ends at a page boundary it may only start in + * the previous page. lend_dist will be encoded as TARGET_PAGE_SIZE + * for the TB that contains this instruction. + */ + if (lend_dist < (1u << TARGET_PAGE_BITS) + env->config->max_insn_size) { + target_ulong lbeg_off = env->sregs[LEND] - env->sregs[LBEG]; + + cs_base = lend_dist; + if (lbeg_off < 256) { + cs_base |= lbeg_off << XTENSA_CSBASE_LBEG_OFF_SHIFT; + } + } + } + if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) && + (env->sregs[LITBASE] & 1)) { + flags |= XTENSA_TBFLAG_LITBASE; + } + if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) { + if (xtensa_get_cintlevel(env) < env->config->debug_level) { + flags |= XTENSA_TBFLAG_DEBUG; + } + if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) { + flags |= XTENSA_TBFLAG_ICOUNT; + } + } + if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) { + flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT; + } + if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER) && + (env->sregs[PS] & (PS_WOE | PS_EXCM)) == PS_WOE) { + uint32_t windowstart = xtensa_replicate_windowstart(env) >> + (env->sregs[WINDOW_BASE] + 1); + uint32_t w = ctz32(windowstart | 0x8); + + flags |= (w << XTENSA_TBFLAG_WINDOW_SHIFT) | XTENSA_TBFLAG_CWOE; + flags |= extract32(env->sregs[PS], PS_CALLINC_SHIFT, + PS_CALLINC_LEN) << XTENSA_TBFLAG_CALLINC_SHIFT; + } else { + flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT; + } + if (env->yield_needed) { + flags |= XTENSA_TBFLAG_YIELD; + } + + return (TCGTBCPUState){ + .pc = env->pc, + .flags = flags, + .cs_base = cs_base, + }; +} + static void xtensa_restore_state_to_opc(CPUState *cs, const TranslationBlock *tb, const uint64_t *data) @@ -229,8 +304,6 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = { }; #endif -#include "accel/tcg/cpu-ops.h" - static const TCGCPUOps xtensa_tcg_ops = { /* Xtensa processors have a weak memory model */ .guest_default_memory_order = 0, @@ -239,6 +312,7 @@ static const TCGCPUOps xtensa_tcg_ops = { .initialize = xtensa_translate_init, .translate_code = xtensa_translate_code, .debug_excp_handler = xtensa_breakpoint_handler, + .get_tb_cpu_state = xtensa_get_tb_cpu_state, .restore_state_to_opc = xtensa_restore_state_to_opc, .mmu_index = xtensa_cpu_mmu_index, @@ -246,6 +320,7 @@ static const TCGCPUOps xtensa_tcg_ops = { .tlb_fill = xtensa_cpu_tlb_fill, .cpu_exec_interrupt = xtensa_cpu_exec_interrupt, .cpu_exec_halt = xtensa_cpu_has_work, + .cpu_exec_reset = cpu_reset, .do_interrupt = xtensa_cpu_do_interrupt, .do_transaction_failed = xtensa_cpu_do_transaction_failed, .do_unaligned_access = xtensa_cpu_do_unaligned_access, diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index c03ed71c94..74122ebe15 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -733,74 +733,6 @@ static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) #define XTENSA_CSBASE_LBEG_OFF_MASK 0x00ff0000 #define XTENSA_CSBASE_LBEG_OFF_SHIFT 16 -static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, vaddr *pc, - uint64_t *cs_base, uint32_t *flags) -{ - *pc = env->pc; - *cs_base = 0; - *flags = 0; - *flags |= xtensa_get_ring(env); - if (env->sregs[PS] & PS_EXCM) { - *flags |= XTENSA_TBFLAG_EXCM; - } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_LOOP)) { - target_ulong lend_dist = - env->sregs[LEND] - (env->pc & -(1u << TARGET_PAGE_BITS)); - - /* - * 0 in the csbase_lend field means that there may not be a loopback - * for any instruction that starts inside this page. Any other value - * means that an instruction that ends at this offset from the page - * start may loop back and will need loopback code to be generated. - * - * lend_dist is 0 when LEND points to the start of the page, but - * no instruction that starts inside this page may end at offset 0, - * so it's still correct. - * - * When an instruction ends at a page boundary it may only start in - * the previous page. lend_dist will be encoded as TARGET_PAGE_SIZE - * for the TB that contains this instruction. - */ - if (lend_dist < (1u << TARGET_PAGE_BITS) + env->config->max_insn_size) { - target_ulong lbeg_off = env->sregs[LEND] - env->sregs[LBEG]; - - *cs_base = lend_dist; - if (lbeg_off < 256) { - *cs_base |= lbeg_off << XTENSA_CSBASE_LBEG_OFF_SHIFT; - } - } - } - if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) && - (env->sregs[LITBASE] & 1)) { - *flags |= XTENSA_TBFLAG_LITBASE; - } - if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) { - if (xtensa_get_cintlevel(env) < env->config->debug_level) { - *flags |= XTENSA_TBFLAG_DEBUG; - } - if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) { - *flags |= XTENSA_TBFLAG_ICOUNT; - } - } - if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) { - *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT; - } - if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER) && - (env->sregs[PS] & (PS_WOE | PS_EXCM)) == PS_WOE) { - uint32_t windowstart = xtensa_replicate_windowstart(env) >> - (env->sregs[WINDOW_BASE] + 1); - uint32_t w = ctz32(windowstart | 0x8); - - *flags |= (w << XTENSA_TBFLAG_WINDOW_SHIFT) | XTENSA_TBFLAG_CWOE; - *flags |= extract32(env->sregs[PS], PS_CALLINC_SHIFT, - PS_CALLINC_LEN) << XTENSA_TBFLAG_CALLINC_SHIFT; - } else { - *flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT; - } - if (env->yield_needed) { - *flags |= XTENSA_TBFLAG_YIELD; - } -} - XtensaCPU *xtensa_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk); diff --git a/target/xtensa/dbg_helper.c b/target/xtensa/dbg_helper.c index c4f4298a50..3b91f7c38a 100644 --- a/target/xtensa/dbg_helper.c +++ b/target/xtensa/dbg_helper.c @@ -30,7 +30,6 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "exec/watchpoint.h" #include "system/address-spaces.h" diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c index ca629f071d..b611c9bf97 100644 --- a/target/xtensa/exc_helper.c +++ b/target/xtensa/exc_helper.c @@ -32,7 +32,6 @@ #include "exec/helper-proto.h" #include "qemu/host-utils.h" #include "qemu/atomic.h" -#include "exec/exec-all.h" void HELPER(exception)(CPUXtensaState *env, uint32_t excp) { diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c index 53fc7cfd2a..5358060c50 100644 --- a/target/xtensa/fpu_helper.c +++ b/target/xtensa/fpu_helper.c @@ -30,7 +30,6 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "fpu/softfloat.h" enum { diff --git a/target/xtensa/mmu_helper.c b/target/xtensa/mmu_helper.c index a7dd810055..71330fc84b 100644 --- a/target/xtensa/mmu_helper.c +++ b/target/xtensa/mmu_helper.c @@ -34,7 +34,7 @@ #include "qemu/host-utils.h" #include "exec/cputlb.h" #include "accel/tcg/cpu-mmu-index.h" -#include "exec/exec-all.h" +#include "accel/tcg/probe.h" #include "exec/page-protection.h" #include "exec/target_page.h" #include "system/memory.h" diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index c125fa4946..fc47ebaaf5 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -30,7 +30,6 @@ #include "exec/helper-proto.h" #include "exec/page-protection.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" #include "system/memory.h" #include "qemu/atomic.h" #include "qemu/timer.h" diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 2af83c07c2..34ae2f4e16 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -31,7 +31,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "qemu/log.h" #include "qemu/qemu-print.h" diff --git a/target/xtensa/win_helper.c b/target/xtensa/win_helper.c index ec9ff44db0..4b25f8f4de 100644 --- a/target/xtensa/win_helper.c +++ b/target/xtensa/win_helper.c @@ -30,7 +30,6 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" -#include "exec/exec-all.h" static void copy_window_from_phys(CPUXtensaState *env, uint32_t window, uint32_t phys, uint32_t n) diff --git a/tcg/perf.c b/tcg/perf.c index 412a987d95..4e8d2c1bee 100644 --- a/tcg/perf.c +++ b/tcg/perf.c @@ -313,7 +313,7 @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb, const void *start) { struct debuginfo_query *q; - size_t insn, start_words; + size_t insn; uint64_t *gen_insn_data; if (!perfmap && !jitdump) { @@ -329,11 +329,10 @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb, /* Query debuginfo for each guest instruction. */ gen_insn_data = tcg_ctx->gen_insn_data; - start_words = tcg_ctx->insn_start_words; for (insn = 0; insn < tb->icount; insn++) { /* FIXME: This replicates the restore_state_to_opc() logic. */ - q[insn].address = gen_insn_data[insn * start_words + 0]; + q[insn].address = gen_insn_data[insn * INSN_START_WORDS + 0]; if (tb_cflags(tb) & CF_PCREL) { q[insn].address |= (guest_pc & qemu_target_page_mask()); } diff --git a/tcg/tcg.c b/tcg/tcg.c index c4e866e9c3..648333a9fb 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1989,7 +1989,6 @@ void tcg_func_start(TCGContext *s) QSIMPLEQ_INIT(&s->labels); tcg_debug_assert(s->addr_type <= TCG_TYPE_REG); - tcg_debug_assert(s->insn_start_words > 0); } static TCGTemp *tcg_temp_alloc(TCGContext *s) @@ -2943,7 +2942,7 @@ void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs) nb_oargs = 0; col += ne_fprintf(f, "\n ----"); - for (i = 0, k = s->insn_start_words; i < k; ++i) { + for (i = 0, k = INSN_START_WORDS; i < k; ++i) { col += ne_fprintf(f, " %016" PRIx64, tcg_get_insn_start_param(op, i)); } @@ -6835,7 +6834,7 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst, int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) { - int i, start_words, num_insns; + int i, num_insns; TCGOp *op; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) @@ -6925,9 +6924,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) QSIMPLEQ_INIT(&s->ldst_labels); s->pool_labels = NULL; - start_words = s->insn_start_words; s->gen_insn_data = - tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * start_words); + tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * INSN_START_WORDS); tcg_out_tb_start(s); @@ -6969,8 +6967,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) assert(s->gen_insn_end_off[num_insns] == off); } num_insns++; - for (i = 0; i < start_words; ++i) { - s->gen_insn_data[num_insns * start_words + i] = + for (i = 0; i < INSN_START_WORDS; ++i) { + s->gen_insn_data[num_insns * INSN_START_WORDS + i] = tcg_get_insn_start_param(op, i); } break; diff --git a/tests/functional/meson.build b/tests/functional/meson.build index ab9df03b1f..52b4706cfe 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -13,6 +13,7 @@ endif test_timeouts = { 'aarch64_aspeed_ast2700' : 600, 'aarch64_aspeed_ast2700fc' : 600, + 'aarch64_imx8mp_evk' : 240, 'aarch64_raspi4' : 480, 'aarch64_reverse_debug' : 180, 'aarch64_rme_virt' : 1200, @@ -82,6 +83,7 @@ tests_aarch64_system_quick = [ tests_aarch64_system_thorough = [ 'aarch64_aspeed_ast2700', 'aarch64_aspeed_ast2700fc', + 'aarch64_imx8mp_evk', 'aarch64_raspi3', 'aarch64_raspi4', 'aarch64_replay', diff --git a/tests/functional/test_aarch64_imx8mp_evk.py b/tests/functional/test_aarch64_imx8mp_evk.py new file mode 100755 index 0000000000..638bf9e131 --- /dev/null +++ b/tests/functional/test_aarch64_imx8mp_evk.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import LinuxKernelTest, Asset + + +class Imx8mpEvkMachine(LinuxKernelTest): + + ASSET_IMAGE = Asset( + ('https://cloud.debian.org/images/cloud/bookworm/20231210-1590/' + 'debian-12-generic-arm64-20231210-1590.tar.xz'), + '7ebf1577b32d5af6204df74b54ca2e4675de9b5a9fa14f3ff70b88eeb7b3b359') + + KERNEL_OFFSET = 0x51000000 + KERNEL_SIZE = 32622528 + INITRD_OFFSET = 0x76000000 + INITRD_SIZE = 30987766 + DTB_OFFSET = 0x64F51000 + DTB_SIZE = 45 * 1024 + + def extract(self, in_path, out_path, offset, size): + try: + with open(in_path, "rb") as source: + source.seek(offset) + data = source.read(size) + with open(out_path, "wb") as target: + target.write(data) + except (IOError, ValueError) as e: + self.log.error(f"Failed to extract {out_path}: {e}") + raise + + def setUp(self): + super().setUp() + + self.image_path = self.scratch_file("disk.raw") + self.kernel_path = self.scratch_file("linux") + self.initrd_path = self.scratch_file("initrd.zstd") + self.dtb_path = self.scratch_file("imx8mp-evk.dtb") + + self.archive_extract(self.ASSET_IMAGE) + self.extract(self.image_path, self.kernel_path, + self.KERNEL_OFFSET, self.KERNEL_SIZE) + self.extract(self.image_path, self.initrd_path, + self.INITRD_OFFSET, self.INITRD_SIZE) + self.extract(self.image_path, self.dtb_path, + self.DTB_OFFSET, self.DTB_SIZE) + + def test_aarch64_imx8mp_evk_usdhc(self): + self.set_machine('imx8mp-evk') + self.vm.set_console(console_index=1) + self.vm.add_args('-m', '2G', + '-smp', '4', + '-kernel', self.kernel_path, + '-initrd', self.initrd_path, + '-dtb', self.dtb_path, + '-append', 'root=/dev/mmcblk2p1', + '-drive', f'file={self.image_path},if=sd,bus=2,' + 'format=raw,id=mmcblk2,snapshot=on') + + self.vm.launch() + self.wait_for_console_pattern('Welcome to ') + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/tcg/loongarch64/system/kernel.ld b/tests/tcg/loongarch64/system/kernel.ld index f1a7c0168c..56d8588f1a 100644 --- a/tests/tcg/loongarch64/system/kernel.ld +++ b/tests/tcg/loongarch64/system/kernel.ld @@ -3,7 +3,7 @@ ENTRY(_start) SECTIONS { /* Linux kernel legacy start address. */ - . = 0x9000000000200000; + . = 0x200000; _text = .; .text : { *(.text) |