From 199fc85acd0571902eeefef6ea861b8ba4c8201f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 27 Apr 2015 17:00:31 -0300 Subject: [PATCH 01/22] cpu: No need to zero-initialize CPUState::numa_node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QOM objects are already zero-filled when instantiated, there's no need to explicitly set numa_node to 0. Reviewed-by: Igor Mammedov Signed-off-by: Eduardo Habkost Signed-off-by: Andreas Färber --- exec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/exec.c b/exec.c index b7f7f9818f..44bebe9ee1 100644 --- a/exec.c +++ b/exec.c @@ -541,7 +541,6 @@ void cpu_exec_init(CPUArchState *env) cpu_index++; } cpu->cpu_index = cpu_index; - cpu->numa_node = 0; QTAILQ_INIT(&cpu->breakpoints); QTAILQ_INIT(&cpu->watchpoints); #ifndef CONFIG_USER_ONLY From 7c39163e389e6e6e16965606fb5a26abcdb6ad73 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 27 Apr 2015 17:00:32 -0300 Subject: [PATCH 02/22] cpu: Initialize breakpoint/watchpoint lists in cpu_common_initfn() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One small step in the simplification of cpu_exec_init(). Reviewed-by: Igor Mammedov Signed-off-by: Eduardo Habkost Signed-off-by: Andreas Färber --- exec.c | 2 -- qom/cpu.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 44bebe9ee1..e2caee98b6 100644 --- a/exec.c +++ b/exec.c @@ -541,8 +541,6 @@ void cpu_exec_init(CPUArchState *env) cpu_index++; } cpu->cpu_index = cpu_index; - QTAILQ_INIT(&cpu->breakpoints); - QTAILQ_INIT(&cpu->watchpoints); #ifndef CONFIG_USER_ONLY cpu->as = &address_space_memory; cpu->thread_id = qemu_get_thread_id(); diff --git a/qom/cpu.c b/qom/cpu.c index 108bfa205a..56c53a809f 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -313,6 +313,8 @@ static void cpu_common_initfn(Object *obj) CPUClass *cc = CPU_GET_CLASS(obj); cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs; + QTAILQ_INIT(&cpu->breakpoints); + QTAILQ_INIT(&cpu->watchpoints); } static int64_t cpu_common_get_arch_id(CPUState *cpu) From 291135b5da228e58900c120e12354cc0a23608e3 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 27 Apr 2015 17:00:33 -0300 Subject: [PATCH 03/22] cpu: Reorder cpu->as, cpu->thread_id, cpu->memory_dispatch init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of initializing cpu->as, cpu->thread_id, and reloading memory map while holding cpu_list_lock(), do it earlier, before locking the CPU list and initializing cpu_index. This allows the code handling cpu_index and global CPU list to be isolated from the rest. Cc: Paolo Bonzini Signed-off-by: Eduardo Habkost Signed-off-by: Andreas Färber --- exec.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/exec.c b/exec.c index e2caee98b6..442df0dd5b 100644 --- a/exec.c +++ b/exec.c @@ -533,6 +533,12 @@ void cpu_exec_init(CPUArchState *env) CPUState *some_cpu; int cpu_index; +#ifndef CONFIG_USER_ONLY + cpu->as = &address_space_memory; + cpu->thread_id = qemu_get_thread_id(); + cpu_reload_memory_map(cpu); +#endif + #if defined(CONFIG_USER_ONLY) cpu_list_lock(); #endif @@ -541,11 +547,6 @@ void cpu_exec_init(CPUArchState *env) cpu_index++; } cpu->cpu_index = cpu_index; -#ifndef CONFIG_USER_ONLY - cpu->as = &address_space_memory; - cpu->thread_id = qemu_get_thread_id(); - cpu_reload_memory_map(cpu); -#endif QTAILQ_INSERT_TAIL(&cpus, cpu, node); #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); From 5a790cc4b942e651fec7edc597c19b637fad5a76 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Tue, 23 Jun 2015 19:31:12 -0700 Subject: [PATCH 04/22] cpu: Add Error argument to cpu_exec_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an Error argument to cpu_exec_init() to let users collect the error. This is in preparation to change the CPU enumeration logic in cpu_exec_init(). With the new enumeration logic, cpu_exec_init() can fail if cpu_index values corresponding to max_cpus have already been handed out. Since all current callers of cpu_exec_init() are from instance_init, use error_abort Error argument to abort in case of an error. Signed-off-by: Bharata B Rao Reviewed-by: Eduardo Habkost Reviewed-by: Igor Mammedov Reviewed-by: David Gibson Reviewed-by: Peter Crosthwaite Acked-by: Paolo Bonzini Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- exec.c | 2 +- include/exec/exec-all.h | 2 +- target-alpha/cpu.c | 2 +- target-arm/cpu.c | 2 +- target-cris/cpu.c | 2 +- target-i386/cpu.c | 2 +- target-lm32/cpu.c | 2 +- target-m68k/cpu.c | 2 +- target-microblaze/cpu.c | 2 +- target-mips/cpu.c | 2 +- target-moxie/cpu.c | 2 +- target-openrisc/cpu.c | 2 +- target-ppc/translate_init.c | 2 +- target-s390x/cpu.c | 2 +- target-sh4/cpu.c | 2 +- target-sparc/cpu.c | 2 +- target-tricore/cpu.c | 2 +- target-unicore32/cpu.c | 2 +- target-xtensa/cpu.c | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/exec.c b/exec.c index 442df0dd5b..ce5fadd88a 100644 --- a/exec.c +++ b/exec.c @@ -526,7 +526,7 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) } #endif -void cpu_exec_init(CPUArchState *env) +void cpu_exec_init(CPUArchState *env, Error **errp) { CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 2e74760ade..44b89551c9 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -88,7 +88,7 @@ void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, int flags, int cflags); -void cpu_exec_init(CPUArchState *env); +void cpu_exec_init(CPUArchState *env, Error **errp); void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); #if !defined(CONFIG_USER_ONLY) diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index a98b7d8d72..e865ba7aec 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -257,7 +257,7 @@ static void alpha_cpu_initfn(Object *obj) CPUAlphaState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); tlb_flush(cs, 1); alpha_translate_init(); diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 80669a6d1b..1c40cc0395 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -392,7 +392,7 @@ static void arm_cpu_initfn(Object *obj) uint32_t Aff1, Aff0; cs->env_ptr = &cpu->env; - cpu_exec_init(&cpu->env); + cpu_exec_init(&cpu->env, &error_abort); cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 16cfba95ff..bb8e7ea557 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -170,7 +170,7 @@ static void cris_cpu_initfn(Object *obj) static bool tcg_initialized; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); env->pregs[PR_VR] = ccc->vr; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index b4f9461969..4d0f7df040 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3038,7 +3038,7 @@ static void x86_cpu_initfn(Object *obj) static int inited; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); object_property_add(obj, "family", "int", x86_cpuid_version_get_family, diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index f8081f52c1..da4fde176e 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -151,7 +151,7 @@ static void lm32_cpu_initfn(Object *obj) static bool tcg_initialized; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); env->flags = 0; diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 4cfb7256c6..ae3d765046 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -168,7 +168,7 @@ static void m68k_cpu_initfn(Object *obj) static bool inited; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); if (tcg_enabled() && !inited) { inited = true; diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index c592bf76e4..967ea015a9 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -190,7 +190,7 @@ static void mb_cpu_initfn(Object *obj) static bool tcg_initialized; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); set_float_rounding_mode(float_round_nearest_even, &env->fp_status); diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 958c999f0a..1fd9f22186 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -115,7 +115,7 @@ static void mips_cpu_initfn(Object *obj) CPUMIPSState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); if (tcg_enabled()) { mips_tcg_init(); diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 47b617f5cd..415c65a969 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -66,7 +66,7 @@ static void moxie_cpu_initfn(Object *obj) static int inited; cs->env_ptr = &cpu->env; - cpu_exec_init(&cpu->env); + cpu_exec_init(&cpu->env, &error_abort); if (tcg_enabled() && !inited) { inited = 1; diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 39bedc108e..cd6c657873 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -92,7 +92,7 @@ static void openrisc_cpu_initfn(Object *obj) static int inited; cs->env_ptr = &cpu->env; - cpu_exec_init(&cpu->env); + cpu_exec_init(&cpu->env, &error_abort); #ifndef CONFIG_USER_ONLY cpu_openrisc_mmu_init(cpu); diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index d74f4f024d..52d95ce1b8 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -9633,7 +9633,7 @@ static void ppc_cpu_initfn(Object *obj) CPUPPCState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); cpu->cpu_dt_id = cs->cpu_index; env->msr_mask = pcc->msr_mask; diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 69bac35349..ced5592204 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -212,7 +212,7 @@ static void s390_cpu_initfn(Object *obj) #endif cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); #if !defined(CONFIG_USER_ONLY) qemu_register_reset(s390_cpu_machine_reset_cb, cpu); qemu_get_timedate(&tm, 0); diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index cccb14fe7b..2c2060b5a3 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -248,7 +248,7 @@ static void superh_cpu_initfn(Object *obj) CPUSH4State *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); env->movcal_backup_tail = &(env->movcal_backup); diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index a952097096..4d1da7c9de 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -802,7 +802,7 @@ static void sparc_cpu_initfn(Object *obj) CPUSPARCState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); if (tcg_enabled()) { gen_intermediate_code_init(env); diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c index b3e5512bbf..6fa60b1f30 100644 --- a/target-tricore/cpu.c +++ b/target-tricore/cpu.c @@ -92,7 +92,7 @@ static void tricore_cpu_initfn(Object *obj) CPUTriCoreState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); if (tcg_enabled()) { tricore_tcg_init(); diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 5b32987173..eda039c60e 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -111,7 +111,7 @@ static void uc32_cpu_initfn(Object *obj) static bool inited; cs->env_ptr = env; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); #ifdef CONFIG_USER_ONLY env->uncached_asr = ASR_MODE_USER; diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 2b75678995..8d69d237d1 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -114,7 +114,7 @@ static void xtensa_cpu_initfn(Object *obj) cs->env_ptr = env; env->config = xcc->config; - cpu_exec_init(env); + cpu_exec_init(env, &error_abort); if (tcg_enabled() && !tcg_inited) { tcg_inited = true; From b7bca7333411bd19c449147e8202ae6b0e4a8e09 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Tue, 23 Jun 2015 19:31:13 -0700 Subject: [PATCH 05/22] cpu: Convert cpu_index into a bitmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently CPUState::cpu_index is monotonically increasing and a newly created CPU always gets the next higher index. The next available index is calculated by counting the existing number of CPUs. This is fine as long as we only add CPUs, but there are architectures which are starting to support CPU removal, too. For an architecture like PowerPC which derives its CPU identifier (device tree ID) from cpu_index, the existing logic of generating cpu_index values causes problems. With the currently proposed method of handling vCPU removal by parking the vCPU fd in QEMU (Ref: http://lists.gnu.org/archive/html/qemu-devel/2015-02/msg02604.html), generating cpu_index this way will not work for PowerPC. This patch changes the way cpu_index is handed out by maintaining a bit map of the CPUs that tracks both addition and removal of CPUs. The CPU bitmap allocation logic is part of cpu_exec_init(), which is called by instance_init routines of various CPU targets. Newly added cpu_exec_exit() API handles the deallocation part and this routine is called from generic CPU instance_finalize. Note: This new CPU enumeration is for !CONFIG_USER_ONLY only. CONFIG_USER_ONLY continues to have the old enumeration logic. Signed-off-by: Bharata B Rao Reviewed-by: Eduardo Habkost Reviewed-by: Igor Mammedov Reviewed-by: David Gibson Reviewed-by: Peter Crosthwaite Acked-by: Paolo Bonzini Signed-off-by: Peter Crosthwaite [AF: max_cpus -> MAX_CPUMASK_BITS] Signed-off-by: Andreas Färber --- exec.c | 58 +++++++++++++++++++++++++++++++++++++++++++---- include/qom/cpu.h | 1 + qom/cpu.c | 7 ++++++ 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/exec.c b/exec.c index ce5fadd88a..d817e5f025 100644 --- a/exec.c +++ b/exec.c @@ -526,12 +526,57 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) } #endif +#ifndef CONFIG_USER_ONLY +static DECLARE_BITMAP(cpu_index_map, MAX_CPUMASK_BITS); + +static int cpu_get_free_index(Error **errp) +{ + int cpu = find_first_zero_bit(cpu_index_map, MAX_CPUMASK_BITS); + + if (cpu >= MAX_CPUMASK_BITS) { + error_setg(errp, "Trying to use more CPUs than max of %d", + MAX_CPUMASK_BITS); + return -1; + } + + bitmap_set(cpu_index_map, cpu, 1); + return cpu; +} + +void cpu_exec_exit(CPUState *cpu) +{ + if (cpu->cpu_index == -1) { + /* cpu_index was never allocated by this @cpu or was already freed. */ + return; + } + + bitmap_clear(cpu_index_map, cpu->cpu_index, 1); + cpu->cpu_index = -1; +} +#else + +static int cpu_get_free_index(Error **errp) +{ + CPUState *some_cpu; + int cpu_index = 0; + + CPU_FOREACH(some_cpu) { + cpu_index++; + } + return cpu_index; +} + +void cpu_exec_exit(CPUState *cpu) +{ +} +#endif + void cpu_exec_init(CPUArchState *env, Error **errp) { CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); - CPUState *some_cpu; int cpu_index; + Error *local_err = NULL; #ifndef CONFIG_USER_ONLY cpu->as = &address_space_memory; @@ -542,11 +587,14 @@ void cpu_exec_init(CPUArchState *env, Error **errp) #if defined(CONFIG_USER_ONLY) cpu_list_lock(); #endif - cpu_index = 0; - CPU_FOREACH(some_cpu) { - cpu_index++; + cpu_index = cpu->cpu_index = cpu_get_free_index(&local_err); + if (local_err) { + error_propagate(errp, local_err); +#if defined(CONFIG_USER_ONLY) + cpu_list_unlock(); +#endif + return; } - cpu->cpu_index = cpu_index; QTAILQ_INSERT_TAIL(&cpus, cpu, node); #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 42f42f5a2d..3993042667 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -674,6 +674,7 @@ void cpu_watchpoint_remove_all(CPUState *cpu, int mask); void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...) GCC_FMT_ATTR(2, 3); +void cpu_exec_exit(CPUState *cpu); #ifdef CONFIG_SOFTMMU extern const struct VMStateDescription vmstate_cpu_common; diff --git a/qom/cpu.c b/qom/cpu.c index 56c53a809f..eb9cfeca18 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -312,11 +312,17 @@ static void cpu_common_initfn(Object *obj) CPUState *cpu = CPU(obj); CPUClass *cc = CPU_GET_CLASS(obj); + cpu->cpu_index = -1; cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs; QTAILQ_INIT(&cpu->breakpoints); QTAILQ_INIT(&cpu->watchpoints); } +static void cpu_common_finalize(Object *obj) +{ + cpu_exec_exit(CPU(obj)); +} + static int64_t cpu_common_get_arch_id(CPUState *cpu) { return cpu->cpu_index; @@ -358,6 +364,7 @@ static const TypeInfo cpu_type_info = { .parent = TYPE_DEVICE, .instance_size = sizeof(CPUState), .instance_init = cpu_common_initfn, + .instance_finalize = cpu_common_finalize, .abstract = true, .class_size = sizeof(CPUClass), .class_init = cpu_class_init, From 6dd0f8342ddfbd8db3e3de1a17686cedbc14e9f1 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Tue, 23 Jun 2015 19:31:14 -0700 Subject: [PATCH 06/22] target-ppc: Move cpu_exec_init() call to realize function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move cpu_exec_init() call from instance_init to realize. This allows any failures from cpu_exec_init() to be handled appropriately. Also add corresponding cpu_exec_exit() call from unrealize. cpu_dt_id assignment from instance_init is no longer needed since correct assignment for cpu_dt_id is already present in realizefn. Signed-off-by: Bharata B Rao Reviewed-by: David Gibson Reviewed-by: Peter Crosthwaite Acked-by: Paolo Bonzini Signed-off-by: Peter Crosthwaite [AF: Keep calling cpu_exec_init() for CONFIG_USER_ONLY] Signed-off-by: Andreas Färber --- target-ppc/translate_init.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 52d95ce1b8..82854a8a8d 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8927,7 +8927,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) smp_threads, kvm_enabled() ? "KVM" : "TCG"); return; } +#endif + cpu_exec_init(&cpu->env, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + return; + } + +#if !defined(CONFIG_USER_ONLY) cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt + (cs->cpu_index % smp_threads); #endif @@ -9141,6 +9149,8 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp) opc_handler_t **table; int i, j; + cpu_exec_exit(CPU(dev)); + for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { if (env->opcodes[i] == &invalid_handler) { continue; @@ -9633,8 +9643,6 @@ static void ppc_cpu_initfn(Object *obj) CPUPPCState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); - cpu->cpu_dt_id = cs->cpu_index; env->msr_mask = pcc->msr_mask; env->mmu_model = pcc->mmu_model; From bbd77c180d7ff1b04a7661bb878939b2e1d23798 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 19:31:15 -0700 Subject: [PATCH 07/22] translate-all: Change tb_flush() env argument to cpu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All of the core-code usages of this API have the cpu pointer handy so pass it in. There are only 3 architecture specific usages (2 of which are commented out) which can just use ENV_GET_CPU() locally to get the cpu pointer. The reduces core code usage of the CPU env, which brings us closer to common-obj'ing these core files. Cc: Riku Voipio Cc: Paolo Bonzini Reviewed-by: Eduardo Habkost Acked-by: Eduardo Habkost Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- exec.c | 3 +-- gdbstub.c | 6 ++---- include/exec/exec-all.h | 2 +- linux-user/signal.c | 2 +- target-alpha/sys_helper.c | 2 +- target-i386/translate.c | 2 +- translate-all.c | 6 ++---- 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/exec.c b/exec.c index d817e5f025..b92c74d707 100644 --- a/exec.c +++ b/exec.c @@ -816,8 +816,7 @@ void cpu_single_step(CPUState *cpu, int enabled) } else { /* must flush all the translated code to avoid inconsistencies */ /* XXX: only flush what is necessary */ - CPUArchState *env = cpu->env_ptr; - tb_flush(env); + tb_flush(cpu); } } } diff --git a/gdbstub.c b/gdbstub.c index cea2a847e0..0fa8dd8352 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1226,7 +1226,6 @@ void gdb_set_stop_cpu(CPUState *cpu) static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; - CPUArchState *env = s->c_cpu->env_ptr; CPUState *cpu = s->c_cpu; char buf[256]; const char *type; @@ -1261,7 +1260,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) cpu->watchpoint_hit = NULL; goto send_packet; } - tb_flush(env); + tb_flush(cpu); ret = GDB_SIGNAL_TRAP; break; case RUN_STATE_PAUSED: @@ -1490,7 +1489,6 @@ gdb_queuesig (void) int gdb_handlesig(CPUState *cpu, int sig) { - CPUArchState *env = cpu->env_ptr; GDBState *s; char buf[256]; int n; @@ -1502,7 +1500,7 @@ gdb_handlesig(CPUState *cpu, int sig) /* disable single step if it was enabled */ cpu_single_step(cpu, 0); - tb_flush(env); + tb_flush(cpu); if (sig != 0) { snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig)); diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 44b89551c9..9f74abd98c 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -196,7 +196,7 @@ struct TBContext { }; void tb_free(TranslationBlock *tb); -void tb_flush(CPUArchState *env); +void tb_flush(CPUState *cpu); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); #if defined(USE_DIRECT_JUMP) diff --git a/linux-user/signal.c b/linux-user/signal.c index 1166f2fdb2..9d4cef409e 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -2348,7 +2348,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, /* Flush instruction space. */ //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); - // tb_flush(env); + // tb_flush(CPU(sparc_env_get_cpu(env))); } unlock_user(sf, sf_addr, sizeof(struct target_signal_frame)); return; diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c index ae2e174f32..1c59e108b9 100644 --- a/target-alpha/sys_helper.c +++ b/target-alpha/sys_helper.c @@ -74,7 +74,7 @@ void helper_tbis(CPUAlphaState *env, uint64_t p) void helper_tb_flush(CPUAlphaState *env) { - tb_flush(env); + tb_flush(CPU(alpha_env_get_cpu(env))); } void helper_halt(uint64_t restart) diff --git a/target-i386/translate.c b/target-i386/translate.c index 7a1bdee271..82e2245bfd 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -6925,7 +6925,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_debug(s, pc_start - s->cs_base); #else /* start debug */ - tb_flush(env); + tb_flush(CPU(x86_env_get_cpu(env))); qemu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM); #endif break; diff --git a/translate-all.c b/translate-all.c index 50d53fdac0..60a3d8b2bd 100644 --- a/translate-all.c +++ b/translate-all.c @@ -772,10 +772,8 @@ static void page_flush_tb(void) /* flush all the translation blocks */ /* XXX: tb_flush is currently not thread safe */ -void tb_flush(CPUArchState *env1) +void tb_flush(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env1); - #if defined(DEBUG_FLUSH) printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n", (unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer), @@ -1014,7 +1012,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb = tb_alloc(pc); if (!tb) { /* flush must be done */ - tb_flush(env); + tb_flush(cpu); /* cannot fail at this point */ tb = tb_alloc(pc); /* Don't forget to invalidate previous TB info. */ From f7ec7f7b269813603b1d64bb9833f9e711f0115c Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 19:31:16 -0700 Subject: [PATCH 08/22] gdbstub: Change gdbserver_fork() to accept cpu instead of env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callsites to this function navigate the cpu->env_ptr only for the function to take the env ptr back to the original cpu ptr. Change the function to just pass in the CPU pointer instead. Removes a core code usage of ENV_GET_CPU() (in gdbstub.c). Cc: Riku Voipio Reviewed-by: Andreas Färber Reviewed-by: Eduardo Habkost Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- bsd-user/main.c | 2 +- gdbstub.c | 3 +-- include/exec/gdbstub.h | 2 +- linux-user/main.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index ba0b9981f5..45a1436dd1 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -92,7 +92,7 @@ void fork_start(void) void fork_end(int child) { if (child) { - gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); + gdbserver_fork(thread_cpu); } } diff --git a/gdbstub.c b/gdbstub.c index 0fa8dd8352..aa5ba5174d 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1629,9 +1629,8 @@ int gdbserver_start(int port) } /* Disable gdb stub for child processes. */ -void gdbserver_fork(CPUArchState *env) +void gdbserver_fork(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); GDBState *s = gdbserver_state; if (gdbserver_fd < 0 || s->fd < 0) { diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index a608a26c30..05f57c2432 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -22,7 +22,7 @@ void gdb_exit(CPUArchState *, int); int gdb_queuesig (void); int gdb_handlesig(CPUState *, int); void gdb_signalled(CPUArchState *, int); -void gdbserver_fork(CPUArchState *); +void gdbserver_fork(CPUState *); #endif /* Get or set a register. Returns the size of the register. */ typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); diff --git a/linux-user/main.c b/linux-user/main.c index 6c5c2effbf..2b4b276356 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -130,7 +130,7 @@ void fork_end(int child) pthread_cond_init(&exclusive_cond, NULL); pthread_cond_init(&exclusive_resume, NULL); pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL); - gdbserver_fork((CPUArchState *)thread_cpu->env_ptr); + gdbserver_fork(thread_cpu); } else { pthread_mutex_unlock(&exclusive_lock); pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock); From 3d57f7893c90d911d786cb2c622b0926fc808b57 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 19:31:17 -0700 Subject: [PATCH 09/22] cpu: Change tcg_cpu_exec() arg to cpu, not env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sole caller of this function navigates the cpu->env_ptr only for this function to take it back the cpu pointer straight away. Pass in cpu pointer instead and grab the env pointer locally in the function. Removes a core code usage of ENV_GET_CPU(). Reviewed-by: Andreas Färber Reviewed-by: Eduardo Habkost Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- cpus.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpus.c b/cpus.c index f547aebeaf..24cac2eebf 100644 --- a/cpus.c +++ b/cpus.c @@ -1357,9 +1357,9 @@ int vm_stop_force_state(RunState state) } } -static int tcg_cpu_exec(CPUArchState *env) +static int tcg_cpu_exec(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = cpu->env_ptr; int ret; #ifdef CONFIG_PROFILER int64_t ti; @@ -1421,13 +1421,12 @@ static void tcg_exec_all(void) } for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) { CPUState *cpu = next_cpu; - CPUArchState *env = cpu->env_ptr; qemu_clock_enable(QEMU_CLOCK_VIRTUAL, (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); if (cpu_can_run(cpu)) { - r = tcg_cpu_exec(env); + r = tcg_cpu_exec(cpu); if (r == EXCP_DEBUG) { cpu_handle_guest_debug(cpu); break; From 4bad9e392e788a218967167a38ce2ae7a32a6231 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 19:31:18 -0700 Subject: [PATCH 10/22] cpu: Change cpu_exec_init() arg to cpu, not env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The callers (most of them in target-foo/cpu.c) to this function all have the cpu pointer handy. Just pass it to avoid an ENV_GET_CPU() from core code (in exec.c). Cc: Paolo Bonzini Cc: Richard Henderson Cc: Peter Maydell Cc: "Edgar E. Iglesias" Cc: Eduardo Habkost Cc: Michael Walle Cc: Leon Alrae Cc: Anthony Green Cc: Jia Liu Cc: Alexander Graf Cc: Blue Swirl Cc: Mark Cave-Ayland Cc: Bastian Koppelmann Cc: Guan Xuetao Cc: Max Filippov Reviewed-by: Andreas Färber Reviewed-by: Aurelien Jarno Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- exec.c | 5 ++--- include/exec/exec-all.h | 2 +- target-alpha/cpu.c | 2 +- target-arm/cpu.c | 2 +- target-cris/cpu.c | 2 +- target-i386/cpu.c | 2 +- target-lm32/cpu.c | 2 +- target-m68k/cpu.c | 2 +- target-microblaze/cpu.c | 2 +- target-mips/cpu.c | 2 +- target-moxie/cpu.c | 2 +- target-openrisc/cpu.c | 2 +- target-ppc/translate_init.c | 2 +- target-s390x/cpu.c | 2 +- target-sh4/cpu.c | 2 +- target-sparc/cpu.c | 2 +- target-tricore/cpu.c | 2 +- target-unicore32/cpu.c | 2 +- target-xtensa/cpu.c | 2 +- 19 files changed, 20 insertions(+), 21 deletions(-) diff --git a/exec.c b/exec.c index b92c74d707..7d60e1530c 100644 --- a/exec.c +++ b/exec.c @@ -571,9 +571,8 @@ void cpu_exec_exit(CPUState *cpu) } #endif -void cpu_exec_init(CPUArchState *env, Error **errp) +void cpu_exec_init(CPUState *cpu, Error **errp) { - CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); int cpu_index; Error *local_err = NULL; @@ -604,7 +603,7 @@ void cpu_exec_init(CPUArchState *env, Error **errp) } #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION, - cpu_save, cpu_load, env); + cpu_save, cpu_load, cpu->env_ptr); assert(cc->vmsd == NULL); assert(qdev_get_vmsd(DEVICE(cpu)) == NULL); #endif diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 9f74abd98c..a6fce04f65 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -88,7 +88,7 @@ void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, int flags, int cflags); -void cpu_exec_init(CPUArchState *env, Error **errp); +void cpu_exec_init(CPUState *cpu, Error **errp); void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); #if !defined(CONFIG_USER_ONLY) diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index e865ba7aec..421d7e5364 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -257,7 +257,7 @@ static void alpha_cpu_initfn(Object *obj) CPUAlphaState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); tlb_flush(cs, 1); alpha_translate_init(); diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 1c40cc0395..5a8cdb5238 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -392,7 +392,7 @@ static void arm_cpu_initfn(Object *obj) uint32_t Aff1, Aff0; cs->env_ptr = &cpu->env; - cpu_exec_init(&cpu->env, &error_abort); + cpu_exec_init(cs, &error_abort); cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); diff --git a/target-cris/cpu.c b/target-cris/cpu.c index bb8e7ea557..0db209bf88 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -170,7 +170,7 @@ static void cris_cpu_initfn(Object *obj) static bool tcg_initialized; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); env->pregs[PR_VR] = ccc->vr; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 4d0f7df040..f9b1788cbd 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3038,7 +3038,7 @@ static void x86_cpu_initfn(Object *obj) static int inited; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); object_property_add(obj, "family", "int", x86_cpuid_version_get_family, diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index da4fde176e..c2b77c6986 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -151,7 +151,7 @@ static void lm32_cpu_initfn(Object *obj) static bool tcg_initialized; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); env->flags = 0; diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index ae3d765046..4f246da748 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -168,7 +168,7 @@ static void m68k_cpu_initfn(Object *obj) static bool inited; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); if (tcg_enabled() && !inited) { inited = true; diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 967ea015a9..128d0320d4 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -190,7 +190,7 @@ static void mb_cpu_initfn(Object *obj) static bool tcg_initialized; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); set_float_rounding_mode(float_round_nearest_even, &env->fp_status); diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 1fd9f22186..4027d0f417 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -115,7 +115,7 @@ static void mips_cpu_initfn(Object *obj) CPUMIPSState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); if (tcg_enabled()) { mips_tcg_init(); diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 415c65a969..6b035aaab3 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -66,7 +66,7 @@ static void moxie_cpu_initfn(Object *obj) static int inited; cs->env_ptr = &cpu->env; - cpu_exec_init(&cpu->env, &error_abort); + cpu_exec_init(cs, &error_abort); if (tcg_enabled() && !inited) { inited = 1; diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index cd6c657873..d97f3c03c2 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -92,7 +92,7 @@ static void openrisc_cpu_initfn(Object *obj) static int inited; cs->env_ptr = &cpu->env; - cpu_exec_init(&cpu->env, &error_abort); + cpu_exec_init(cs, &error_abort); #ifndef CONFIG_USER_ONLY cpu_openrisc_mmu_init(cpu); diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 82854a8a8d..16d7b16ac2 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8929,7 +8929,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) } #endif - cpu_exec_init(&cpu->env, &local_err); + cpu_exec_init(cs, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); return; diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index ced5592204..c3e21b445c 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -212,7 +212,7 @@ static void s390_cpu_initfn(Object *obj) #endif cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); #if !defined(CONFIG_USER_ONLY) qemu_register_reset(s390_cpu_machine_reset_cb, cpu); qemu_get_timedate(&tm, 0); diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 2c2060b5a3..5c65ab4df5 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -248,7 +248,7 @@ static void superh_cpu_initfn(Object *obj) CPUSH4State *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); env->movcal_backup_tail = &(env->movcal_backup); diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 4d1da7c9de..9528e3afbb 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -802,7 +802,7 @@ static void sparc_cpu_initfn(Object *obj) CPUSPARCState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); if (tcg_enabled()) { gen_intermediate_code_init(env); diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c index 6fa60b1f30..2029ef651a 100644 --- a/target-tricore/cpu.c +++ b/target-tricore/cpu.c @@ -92,7 +92,7 @@ static void tricore_cpu_initfn(Object *obj) CPUTriCoreState *env = &cpu->env; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); if (tcg_enabled()) { tricore_tcg_init(); diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index eda039c60e..fc451a1a35 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -111,7 +111,7 @@ static void uc32_cpu_initfn(Object *obj) static bool inited; cs->env_ptr = env; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); #ifdef CONFIG_USER_ONLY env->uncached_asr = ASR_MODE_USER; diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 8d69d237d1..da8129db50 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -114,7 +114,7 @@ static void xtensa_cpu_initfn(Object *obj) cs->env_ptr = env; env->config = xcc->config; - cpu_exec_init(env, &error_abort); + cpu_exec_init(cs, &error_abort); if (tcg_enabled() && !tcg_inited) { tcg_inited = true; From ea3e9847408131abc840240bd61e892d28459452 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 18 Jun 2015 10:24:55 -0700 Subject: [PATCH 11/22] cpu-exec: Purge all uses of ENV_GET_CPU() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove un-needed usages of ENV_GET_CPU() by converting the APIs to use CPUState pointers and retrieving the env_ptr as minimally needed. Scripted conversion for target-* change: for I in target-*/cpu.h; do sed -i \ 's/\(^int cpu_[^_]*_exec(\)[^ ][^ ]* \*s);$/\1CPUState *cpu);/' \ $I; done Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- bsd-user/main.c | 4 +++- cpu-exec.c | 28 +++++++++++++--------------- cpus.c | 3 +-- linux-user/main.c | 28 ++++++++++++++-------------- target-alpha/cpu.h | 2 +- target-arm/cpu.h | 2 +- target-cris/cpu.h | 2 +- target-i386/cpu.h | 2 +- target-lm32/cpu.h | 2 +- target-m68k/cpu.h | 2 +- target-microblaze/cpu.h | 2 +- target-mips/cpu.h | 2 +- target-moxie/cpu.h | 2 +- target-openrisc/cpu.h | 2 +- target-ppc/cpu.h | 2 +- target-s390x/cpu.h | 2 +- target-sh4/cpu.h | 2 +- target-sparc/cpu.h | 2 +- target-tricore/cpu.h | 2 +- target-unicore32/cpu.h | 3 ++- target-xtensa/cpu.h | 2 +- 21 files changed, 49 insertions(+), 49 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index 45a1436dd1..f46728bad8 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -166,6 +166,8 @@ static void set_idt(int n, unsigned int dpl) void cpu_loop(CPUX86State *env) { + X86CPU *cpu = x86_env_get_cpu(env); + CPUState *cs = CPU(cpu); int trapnr; abi_ulong pc; //target_siginfo_t info; @@ -512,7 +514,7 @@ void cpu_loop(CPUSPARCState *env) //target_siginfo_t info; while (1) { - trapnr = cpu_sparc_exec (env); + trapnr = cpu_sparc_exec(cs); switch (trapnr) { #ifndef TARGET_SPARC64 diff --git a/cpu-exec.c b/cpu-exec.c index b2724c18c1..75694f3bb3 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -227,10 +227,9 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) /* Execute the code without caching the generated code. An interpreter could be used if available. */ -static void cpu_exec_nocache(CPUArchState *env, int max_cycles, +static void cpu_exec_nocache(CPUState *cpu, int max_cycles, TranslationBlock *orig_tb) { - CPUState *cpu = ENV_GET_CPU(env); TranslationBlock *tb; target_ulong pc = orig_tb->pc; target_ulong cs_base = orig_tb->cs_base; @@ -254,12 +253,12 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles, tb_free(tb); } -static TranslationBlock *tb_find_slow(CPUArchState *env, +static TranslationBlock *tb_find_slow(CPUState *cpu, target_ulong pc, target_ulong cs_base, uint64_t flags) { - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = (CPUArchState *)cpu->env_ptr; TranslationBlock *tb, **ptb1; unsigned int h; tb_page_addr_t phys_pc, phys_page1; @@ -311,9 +310,9 @@ static TranslationBlock *tb_find_slow(CPUArchState *env, return tb; } -static inline TranslationBlock *tb_find_fast(CPUArchState *env) +static inline TranslationBlock *tb_find_fast(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = (CPUArchState *)cpu->env_ptr; TranslationBlock *tb; target_ulong cs_base, pc; int flags; @@ -325,14 +324,13 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env) tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || tb->flags != flags)) { - tb = tb_find_slow(env, pc, cs_base, flags); + tb = tb_find_slow(cpu, pc, cs_base, flags); } return tb; } -static void cpu_handle_debug_exception(CPUArchState *env) +static void cpu_handle_debug_exception(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); CPUWatchpoint *wp; @@ -349,12 +347,12 @@ static void cpu_handle_debug_exception(CPUArchState *env) volatile sig_atomic_t exit_request; -int cpu_exec(CPUArchState *env) +int cpu_exec(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); CPUClass *cc = CPU_GET_CLASS(cpu); #ifdef TARGET_I386 X86CPU *x86_cpu = X86_CPU(cpu); + CPUArchState *env = &x86_cpu->env; #endif int ret, interrupt_request; TranslationBlock *tb; @@ -407,7 +405,7 @@ int cpu_exec(CPUArchState *env) /* exit request from the cpu execution loop */ ret = cpu->exception_index; if (ret == EXCP_DEBUG) { - cpu_handle_debug_exception(env); + cpu_handle_debug_exception(cpu); } cpu->exception_index = -1; break; @@ -483,7 +481,7 @@ int cpu_exec(CPUArchState *env) } spin_lock(&tcg_ctx.tb_ctx.tb_lock); have_tb_lock = true; - tb = tb_find_fast(env); + tb = tb_find_fast(cpu); /* Note: we do it here to avoid a gcc bug on Mac OS X when doing it in tb_find_slow */ if (tcg_ctx.tb_ctx.tb_invalidated_flag) { @@ -543,7 +541,7 @@ int cpu_exec(CPUArchState *env) if (insns_left > 0) { /* Execute remaining instructions. */ tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); - cpu_exec_nocache(env, insns_left, tb); + cpu_exec_nocache(cpu, insns_left, tb); align_clocks(&sc, cpu); } cpu->exception_index = EXCP_INTERRUPT; @@ -567,11 +565,11 @@ int cpu_exec(CPUArchState *env) /* Reload env after longjmp - the compiler may have smashed all * local variables as longjmp is marked 'noreturn'. */ cpu = current_cpu; - env = cpu->env_ptr; cc = CPU_GET_CLASS(cpu); cpu->can_do_io = 1; #ifdef TARGET_I386 x86_cpu = X86_CPU(cpu); + env = &x86_cpu->env; #endif if (have_tb_lock) { spin_unlock(&tcg_ctx.tb_ctx.tb_lock); diff --git a/cpus.c b/cpus.c index 24cac2eebf..b00a42379b 100644 --- a/cpus.c +++ b/cpus.c @@ -1359,7 +1359,6 @@ int vm_stop_force_state(RunState state) static int tcg_cpu_exec(CPUState *cpu) { - CPUArchState *env = cpu->env_ptr; int ret; #ifdef CONFIG_PROFILER int64_t ti; @@ -1394,7 +1393,7 @@ static int tcg_cpu_exec(CPUState *cpu) cpu->icount_decr.u16.low = decr; cpu->icount_extra = count; } - ret = cpu_exec(env); + ret = cpu_exec(cpu); #ifdef CONFIG_PROFILER tcg_time += profile_getclock() - ti; #endif diff --git a/linux-user/main.c b/linux-user/main.c index 2b4b276356..05914b11e4 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -280,7 +280,7 @@ void cpu_loop(CPUX86State *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_x86_exec(env); + trapnr = cpu_x86_exec(cs); cpu_exec_end(cs); switch(trapnr) { case 0x80: @@ -674,7 +674,7 @@ void cpu_loop(CPUARMState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_arm_exec(env); + trapnr = cpu_arm_exec(cs); cpu_exec_end(cs); switch(trapnr) { case EXCP_UDEF: @@ -1005,7 +1005,7 @@ void cpu_loop(CPUARMState *env) for (;;) { cpu_exec_start(cs); - trapnr = cpu_arm_exec(env); + trapnr = cpu_arm_exec(cs); cpu_exec_end(cs); switch (trapnr) { @@ -1084,7 +1084,7 @@ void cpu_loop(CPUUniCore32State *env) for (;;) { cpu_exec_start(cs); - trapnr = uc32_cpu_exec(env); + trapnr = uc32_cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case UC32_EXCP_PRIV: @@ -1285,7 +1285,7 @@ void cpu_loop (CPUSPARCState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_sparc_exec (env); + trapnr = cpu_sparc_exec(cs); cpu_exec_end(cs); /* Compute PSR before exposing state. */ @@ -1565,7 +1565,7 @@ void cpu_loop(CPUPPCState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_ppc_exec(env); + trapnr = cpu_ppc_exec(cs); cpu_exec_end(cs); switch(trapnr) { case POWERPC_EXCP_NONE: @@ -2417,7 +2417,7 @@ void cpu_loop(CPUMIPSState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_mips_exec(env); + trapnr = cpu_mips_exec(cs); cpu_exec_end(cs); switch(trapnr) { case EXCP_SYSCALL: @@ -2654,7 +2654,7 @@ void cpu_loop(CPUOpenRISCState *env) for (;;) { cpu_exec_start(cs); - trapnr = cpu_exec(env); + trapnr = cpu_openrisc_exec(cs); cpu_exec_end(cs); gdbsig = 0; @@ -2744,7 +2744,7 @@ void cpu_loop(CPUSH4State *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_sh4_exec (env); + trapnr = cpu_sh4_exec(cs); cpu_exec_end(cs); switch (trapnr) { @@ -2806,7 +2806,7 @@ void cpu_loop(CPUCRISState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_cris_exec (env); + trapnr = cpu_cris_exec(cs); cpu_exec_end(cs); switch (trapnr) { case 0xaa: @@ -2867,7 +2867,7 @@ void cpu_loop(CPUMBState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_mb_exec (env); + trapnr = cpu_mb_exec(cs); cpu_exec_end(cs); switch (trapnr) { case 0xaa: @@ -2972,7 +2972,7 @@ void cpu_loop(CPUM68KState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_m68k_exec(env); + trapnr = cpu_m68k_exec(cs); cpu_exec_end(cs); switch(trapnr) { case EXCP_ILLEGAL: @@ -3111,7 +3111,7 @@ void cpu_loop(CPUAlphaState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_alpha_exec (env); + trapnr = cpu_alpha_exec(cs); cpu_exec_end(cs); /* All of the traps imply a transition through PALcode, which @@ -3299,7 +3299,7 @@ void cpu_loop(CPUS390XState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_s390x_exec(env); + trapnr = cpu_s390x_exec(cs); cpu_exec_end(cs); switch (trapnr) { case EXCP_INTERRUPT: diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 2a4d5cb1e2..91c56d6bcf 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -431,7 +431,7 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model); #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model)) void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf); -int cpu_alpha_exec(CPUAlphaState *s); +int cpu_alpha_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 80297b342e..7e89152bde 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -499,7 +499,7 @@ typedef struct CPUARMState { #include "cpu-qom.h" ARMCPU *cpu_arm_init(const char *cpu_model); -int cpu_arm_exec(CPUARMState *s); +int cpu_arm_exec(CPUState *cpu); uint32_t do_arm_semihosting(CPUARMState *env); void aarch64_sync_32_to_64(CPUARMState *env); void aarch64_sync_64_to_32(CPUARMState *env); diff --git a/target-cris/cpu.h b/target-cris/cpu.h index 677b38c68f..d422e3571c 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -176,7 +176,7 @@ typedef struct CPUCRISState { #include "cpu-qom.h" CRISCPU *cpu_cris_init(const char *cpu_model); -int cpu_cris_exec(CPUCRISState *s); +int cpu_cris_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 14dced08a7..ead28325bd 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -987,7 +987,7 @@ typedef struct CPUX86State { X86CPU *cpu_x86_init(const char *cpu_model); X86CPU *cpu_x86_create(const char *cpu_model, Error **errp); -int cpu_x86_exec(CPUX86State *s); +int cpu_x86_exec(CPUState *cpu); void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf); void x86_cpudef_setup(void); int cpu_x86_support_mca_broadcast(CPUX86State *env); diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 11ae68d22e..944777d052 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -199,7 +199,7 @@ static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx) #include "cpu-qom.h" LM32CPU *cpu_lm32_init(const char *cpu_model); -int cpu_lm32_exec(CPULM32State *s); +int cpu_lm32_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 5f165da90d..9a62f6cb52 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -117,7 +117,7 @@ typedef struct CPUM68KState { void m68k_tcg_init(void); void m68k_cpu_init_gdb(M68kCPU *cpu); M68kCPU *cpu_m68k_init(const char *cpu_model); -int cpu_m68k_exec(CPUM68KState *s); +int cpu_m68k_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 0dd164ff15..7e20e59b89 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -281,7 +281,7 @@ struct CPUMBState { void mb_tcg_init(void); MicroBlazeCPU *cpu_mb_init(const char *cpu_model); -int cpu_mb_exec(CPUMBState *s); +int cpu_mb_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 474a0e327d..075c561c81 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -746,7 +746,7 @@ enum { */ #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 -int cpu_mips_exec(CPUMIPSState *s); +int cpu_mips_exec(CPUState *cpu); void mips_tcg_init(void); MIPSCPU *cpu_mips_init(const char *cpu_model); int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h index c2733a23d0..29572aaba3 100644 --- a/target-moxie/cpu.h +++ b/target-moxie/cpu.h @@ -112,7 +112,7 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env) #define ENV_OFFSET offsetof(MoxieCPU, env) MoxieCPU *cpu_moxie_init(const char *cpu_model); -int cpu_moxie_exec(CPUMoxieState *s); +int cpu_moxie_exec(CPUState *cpu); void moxie_cpu_do_interrupt(CPUState *cs); void moxie_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 9e23cd0500..36c4f20e20 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -346,7 +346,7 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env) OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); -int cpu_openrisc_exec(CPUOpenRISCState *s); +int cpu_openrisc_exec(CPUState *cpu); void openrisc_cpu_do_interrupt(CPUState *cpu); bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index c05c503305..6f76674a4c 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1164,7 +1164,7 @@ do { \ PowerPCCPU *cpu_ppc_init(const char *cpu_model); void ppc_translate_init(void); void gen_update_current_nip(void *opaque); -int cpu_ppc_exec (CPUPPCState *s); +int cpu_ppc_exec (CPUState *s); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 7b87c7dcfb..63aebf4846 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -417,7 +417,7 @@ void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen); S390CPU *cpu_s390x_init(const char *cpu_model); void s390x_translate_init(void); -int cpu_s390x_exec(CPUS390XState *s); +int cpu_s390x_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 4a027a6c1c..34bb3d7799 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -193,7 +193,7 @@ typedef struct CPUSH4State { void sh4_translate_init(void); SuperHCPU *cpu_sh4_init(const char *cpu_model); -int cpu_sh4_exec(CPUSH4State * s); +int cpu_sh4_exec(CPUState *s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc); int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index f5c9006b3d..0522b65f19 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -537,7 +537,7 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, void gen_intermediate_code_init(CPUSPARCState *env); /* cpu-exec.c */ -int cpu_sparc_exec(CPUSPARCState *s); +int cpu_sparc_exec(CPUState *cpu); /* win_helper.c */ target_ulong cpu_get_psr(CPUSPARCState *env1); diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h index 504f15623d..916ee27ad4 100644 --- a/target-tricore/cpu.h +++ b/target-tricore/cpu.h @@ -372,7 +372,7 @@ enum { }; void cpu_state_reset(CPUTriCoreState *s); -int cpu_tricore_exec(CPUTriCoreState *s); +int cpu_tricore_exec(CPUState *cpu); void tricore_tcg_init(void); int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index 14dc8627c0..45e31e54ba 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -125,7 +125,6 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask) #define cpu_exec uc32_cpu_exec #define cpu_signal_handler uc32_cpu_signal_handler -int uc32_cpu_exec(CPUUniCore32State *s); int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc); /* MMU modes definitions */ @@ -141,6 +140,8 @@ static inline int cpu_mmu_index(CPUUniCore32State *env) #include "cpu-qom.h" #include "exec/exec-all.h" +int uc32_cpu_exec(CPUState *s); + UniCore32CPU *uc32_cpu_init(const char *cpu_model); #define cpu_init(cpu_model) CPU(uc32_cpu_init(cpu_model)) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index b89c60245d..96bfc82e92 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -399,7 +399,7 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model); void xtensa_translate_init(void); void xtensa_breakpoint_handler(CPUState *cs); -int cpu_xtensa_exec(CPUXtensaState *s); +int cpu_xtensa_exec(CPUState *cpu); void xtensa_finalize_config(XtensaConfig *config); void xtensa_register_core(XtensaConfigList *node); void check_interrupts(CPUXtensaState *s); From 2991b8904730d663f12ad42e35798ecc22fe151c Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:19:20 -0700 Subject: [PATCH 12/22] cpu: Add wrapper for the set_pc() hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a wrapper around the CPUClass::set_pc() hook. Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- include/qom/cpu.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 3993042667..b120574df0 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -601,6 +601,20 @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr, } #endif +/** + * cpu_set_pc: + * @cpu: The CPU to set the program counter for. + * @addr: Program counter value. + * + * Sets the program counter for a CPU. + */ +static inline void cpu_set_pc(CPUState *cpu, vaddr addr) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + cc->set_pc(cpu, addr); +} + /** * cpu_reset_interrupt: * @cpu: The CPU to clear the interrupt on. From 4a2b24edb73f98fa58fd8965db5b312617de7a02 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:19:21 -0700 Subject: [PATCH 13/22] gdbstub: Use cpu_set_pc() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the cpu_set_pc() helper which will take care of CPUClass retrieval for us. Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- gdbstub.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index aa5ba5174d..92b2f81584 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -754,12 +754,9 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { CPUState *cpu = s->c_cpu; - CPUClass *cc = CPU_GET_CLASS(cpu); cpu_synchronize_state(cpu); - if (cc->set_pc) { - cc->set_pc(cpu, pc); - } + cpu_set_pc(cpu, pc); } static CPUState *find_cpu(uint32_t thread_id) From 4df81c6ed1eddcbbb920a977e76f599e05b39b77 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:19:22 -0700 Subject: [PATCH 14/22] hw/arm/boot: Use cpu_set_pc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use cpu_set_pc() across the board for setting program counters. This removes instances of system level code having to reach into the CPU env. Reviewed-by: Peter Maydell Reviewed-by: Andreas Färber Signed-off-by: Peter Crosthwaite [AF: Avoid repeated casts with local variables] Signed-off-by: Andreas Färber --- hw/arm/boot.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 1e7fd28daa..f48ed2d34d 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -168,11 +168,11 @@ static void default_write_secondary(ARMCPU *cpu, static void default_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info) { - CPUARMState *env = &cpu->env; + CPUState *cs = CPU(cpu); address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr, 0, MEMTXATTRS_UNSPECIFIED, NULL); - env->regs[15] = info->smp_loader_start; + cpu_set_pc(cs, info->smp_loader_start); } static inline bool have_dtb(const struct arm_boot_info *info) @@ -445,19 +445,21 @@ fail: static void do_cpu_reset(void *opaque) { ARMCPU *cpu = opaque; + CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; const struct arm_boot_info *info = env->boot_info; - cpu_reset(CPU(cpu)); + cpu_reset(cs); if (info) { if (!info->is_linux) { /* Jump to the entry point. */ - if (env->aarch64) { - env->pc = info->entry; - } else { - env->regs[15] = info->entry & 0xfffffffe; + uint64_t entry = info->entry; + + if (!env->aarch64) { env->thumb = info->entry & 1; + entry &= 0xfffffffe; } + cpu_set_pc(cs, entry); } else { /* If we are booting Linux then we need to check whether we are * booting into secure or non-secure state and adjust the state @@ -487,12 +489,8 @@ static void do_cpu_reset(void *opaque) } } - if (CPU(cpu) == first_cpu) { - if (env->aarch64) { - env->pc = info->loader_start; - } else { - env->regs[15] = info->loader_start; - } + if (cs == first_cpu) { + cpu_set_pc(cs, info->loader_start); if (!have_dtb(info)) { if (old_param) { From 691b9572e337f2d74b4b527c3dc76f542c6a5734 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:19:23 -0700 Subject: [PATCH 15/22] microblaze: boot: Use cpu_set_pc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use cpu_set_pc() for setting program counters when bootloading. This removes an instance of system level code having to reach into the CPU env. Reviewed-by: Andreas Färber Signed-off-by: Peter Crosthwaite [AF: Avoid duplicated CPU() casts through local variable] Signed-off-by: Andreas Färber --- hw/microblaze/boot.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 4c44317b65..3e8820f365 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -48,13 +48,14 @@ static struct static void main_cpu_reset(void *opaque) { MicroBlazeCPU *cpu = opaque; + CPUState *cs = CPU(cpu); CPUMBState *env = &cpu->env; - cpu_reset(CPU(cpu)); + cpu_reset(cs); env->regs[5] = boot_info.cmdline; env->regs[6] = boot_info.initrd_start; env->regs[7] = boot_info.fdt; - env->sregs[SR_PC] = boot_info.bootstrap_pc; + cpu_set_pc(cs, boot_info.bootstrap_pc); if (boot_info.machine_cpu_reset) { boot_info.machine_cpu_reset(cpu); } From 2de295c544dda8680a82fe465c92d236d49c4d4f Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:32 -0700 Subject: [PATCH 16/22] disas: Add print_insn to disassemble info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the print_insn pointer to the disassemble info structure. This is to prepare for QOMification support, where a QOM CPU hook function will be responsible for setting the print_insn() function. Add this function to the existing struct to consolidate such that only the one struct needs to be passed to the new QOM API. Reviewed-by: Richard Henderson Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas.c | 68 ++++++++++++++++++++++----------------------- include/disas/bfd.h | 6 ++++ 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/disas.c b/disas.c index 576c6a437b..363c3bfb58 100644 --- a/disas.c +++ b/disas.c @@ -201,7 +201,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, target_ulong pc; int count; CPUDebug s; - int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL; INIT_DISASSEMBLE_INFO(s.info, out, fprintf); @@ -224,7 +223,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, } else { s.info.mach = bfd_mach_i386_i386; } - print_insn = print_insn_i386; + s.info.print_insn = print_insn_i386; #elif defined(TARGET_ARM) if (flags & 4) { /* We might not be compiled with the A64 disassembler @@ -232,12 +231,12 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, * fall through to the default print_insn_od case. */ #if defined(CONFIG_ARM_A64_DIS) - print_insn = print_insn_arm_a64; + s.info.print_insn = print_insn_arm_a64; #endif } else if (flags & 1) { - print_insn = print_insn_thumb1; + s.info.print_insn = print_insn_thumb1; } else { - print_insn = print_insn_arm; + s.info.print_insn = print_insn_arm; } if (flags & 2) { #ifdef TARGET_WORDS_BIGENDIAN @@ -247,7 +246,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, #endif } #elif defined(TARGET_SPARC) - print_insn = print_insn_sparc; + s.info.print_insn = print_insn_sparc; #ifdef TARGET_SPARC64 s.info.mach = bfd_mach_sparc_v9b; #endif @@ -266,49 +265,49 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, #endif } s.info.disassembler_options = (char *)"any"; - print_insn = print_insn_ppc; + s.info.print_insn = print_insn_ppc; #elif defined(TARGET_M68K) - print_insn = print_insn_m68k; + s.info.print_insn = print_insn_m68k; #elif defined(TARGET_MIPS) #ifdef TARGET_WORDS_BIGENDIAN - print_insn = print_insn_big_mips; + s.info.print_insn = print_insn_big_mips; #else - print_insn = print_insn_little_mips; + s.info.print_insn = print_insn_little_mips; #endif #elif defined(TARGET_SH4) s.info.mach = bfd_mach_sh4; - print_insn = print_insn_sh; + s.info.print_insn = print_insn_sh; #elif defined(TARGET_ALPHA) s.info.mach = bfd_mach_alpha_ev6; - print_insn = print_insn_alpha; + s.info.print_insn = print_insn_alpha; #elif defined(TARGET_CRIS) if (flags != 32) { s.info.mach = bfd_mach_cris_v0_v10; - print_insn = print_insn_crisv10; + s.info.print_insn = print_insn_crisv10; } else { s.info.mach = bfd_mach_cris_v32; - print_insn = print_insn_crisv32; + s.info.print_insn = print_insn_crisv32; } #elif defined(TARGET_S390X) s.info.mach = bfd_mach_s390_64; - print_insn = print_insn_s390; + s.info.print_insn = print_insn_s390; #elif defined(TARGET_MICROBLAZE) s.info.mach = bfd_arch_microblaze; - print_insn = print_insn_microblaze; + s.info.print_insn = print_insn_microblaze; #elif defined(TARGET_MOXIE) s.info.mach = bfd_arch_moxie; - print_insn = print_insn_moxie; + s.info.print_insn = print_insn_moxie; #elif defined(TARGET_LM32) s.info.mach = bfd_mach_lm32; - print_insn = print_insn_lm32; + s.info.print_insn = print_insn_lm32; #endif - if (print_insn == NULL) { - print_insn = print_insn_od_target; + if (s.info.print_insn == NULL) { + s.info.print_insn = print_insn_od_target; } for (pc = code; size > 0; pc += count, size -= count) { fprintf(out, "0x" TARGET_FMT_lx ": ", pc); - count = print_insn(pc, &s.info); + count = s.info.print_insn(pc, &s.info); #if 0 { int i; @@ -452,7 +451,6 @@ void monitor_disas(Monitor *mon, CPUState *cpu, { int count, i; CPUDebug s; - int (*print_insn)(bfd_vma pc, disassemble_info *info); INIT_DISASSEMBLE_INFO(s.info, (FILE *)mon, monitor_fprintf); @@ -476,13 +474,13 @@ void monitor_disas(Monitor *mon, CPUState *cpu, } else { s.info.mach = bfd_mach_i386_i386; } - print_insn = print_insn_i386; + s.info.print_insn = print_insn_i386; #elif defined(TARGET_ARM) - print_insn = print_insn_arm; + s.info.print_insn = print_insn_arm; #elif defined(TARGET_ALPHA) - print_insn = print_insn_alpha; + s.info.print_insn = print_insn_alpha; #elif defined(TARGET_SPARC) - print_insn = print_insn_sparc; + s.info.print_insn = print_insn_sparc; #ifdef TARGET_SPARC64 s.info.mach = bfd_mach_sparc_v9b; #endif @@ -500,27 +498,27 @@ void monitor_disas(Monitor *mon, CPUState *cpu, if ((flags >> 16) & 1) { s.info.endian = BFD_ENDIAN_LITTLE; } - print_insn = print_insn_ppc; + s.info.print_insn = print_insn_ppc; #elif defined(TARGET_M68K) - print_insn = print_insn_m68k; + s.info.print_insn = print_insn_m68k; #elif defined(TARGET_MIPS) #ifdef TARGET_WORDS_BIGENDIAN - print_insn = print_insn_big_mips; + s.info.print_insn = print_insn_big_mips; #else - print_insn = print_insn_little_mips; + s.info.print_insn = print_insn_little_mips; #endif #elif defined(TARGET_SH4) s.info.mach = bfd_mach_sh4; - print_insn = print_insn_sh; + s.info.print_insn = print_insn_sh; #elif defined(TARGET_S390X) s.info.mach = bfd_mach_s390_64; - print_insn = print_insn_s390; + s.info.print_insn = print_insn_s390; #elif defined(TARGET_MOXIE) s.info.mach = bfd_arch_moxie; - print_insn = print_insn_moxie; + s.info.print_insn = print_insn_moxie; #elif defined(TARGET_LM32) s.info.mach = bfd_mach_lm32; - print_insn = print_insn_lm32; + s.info.print_insn = print_insn_lm32; #else monitor_printf(mon, "0x" TARGET_FMT_lx ": Asm output not supported on this arch\n", pc); @@ -529,7 +527,7 @@ void monitor_disas(Monitor *mon, CPUState *cpu, for(i = 0; i < nb_insn; i++) { monitor_printf(mon, "0x" TARGET_FMT_lx ": ", pc); - count = print_insn(pc, &s.info); + count = s.info.print_insn(pc, &s.info); monitor_printf(mon, "\n"); if (count < 0) break; diff --git a/include/disas/bfd.h b/include/disas/bfd.h index 8bd703cb1a..a112e9c8c3 100644 --- a/include/disas/bfd.h +++ b/include/disas/bfd.h @@ -313,6 +313,11 @@ typedef struct disassemble_info { void (*print_address_func) (bfd_vma addr, struct disassemble_info *info); + /* Function called to print an instruction. The function is architecture + * specific. + */ + int (*print_insn)(bfd_vma addr, struct disassemble_info *info); + /* Function called to determine if there is a symbol at the given ADDR. If there is, the function returns 1, otherwise it returns 0. This is used by ports which support an overlay manager where @@ -463,6 +468,7 @@ int generic_symbol_at_address(bfd_vma, struct disassemble_info *); (INFO).read_memory_func = buffer_read_memory, \ (INFO).memory_error_func = perror_memory, \ (INFO).print_address_func = generic_print_address, \ + (INFO).print_insn = NULL, \ (INFO).symbol_at_address_func = generic_symbol_at_address, \ (INFO).flags = 0, \ (INFO).bytes_per_line = 0, \ From 37b9de463bff4fc786bb5f0778829e68d2c97bd0 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:33 -0700 Subject: [PATCH 17/22] disas: QOMify target specific setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a QOM function hook for target-specific disassembly setup. This allows removal of the #ifdeffery currently implementing target specific disas setup from disas.c. Reviewed-by: Richard Henderson Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas.c | 22 ++++++++++++++++++---- include/qom/cpu.h | 4 ++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/disas.c b/disas.c index 363c3bfb58..ff5425d9b4 100644 --- a/disas.c +++ b/disas.c @@ -1,5 +1,6 @@ /* General "disassemble this chunk" code. Used for debugging. */ #include "config.h" +#include "qemu-common.h" #include "disas/bfd.h" #include "elf.h" #include @@ -198,6 +199,7 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info) void target_disas(FILE *out, CPUState *cpu, target_ulong code, target_ulong size, int flags) { + CPUClass *cc = CPU_GET_CLASS(cpu); target_ulong pc; int count; CPUDebug s; @@ -215,6 +217,11 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, #else s.info.endian = BFD_ENDIAN_LITTLE; #endif + + if (cc->disas_set_info) { + cc->disas_set_info(cpu, &s.info); + } + #if defined(TARGET_I386) if (flags == 2) { s.info.mach = bfd_mach_x86_64; @@ -449,6 +456,7 @@ monitor_fprintf(FILE *stream, const char *fmt, ...) void monitor_disas(Monitor *mon, CPUState *cpu, target_ulong pc, int nb_insn, int is_physical, int flags) { + CPUClass *cc = CPU_GET_CLASS(cpu); int count, i; CPUDebug s; @@ -466,6 +474,11 @@ void monitor_disas(Monitor *mon, CPUState *cpu, #else s.info.endian = BFD_ENDIAN_LITTLE; #endif + + if (cc->disas_set_info) { + cc->disas_set_info(cpu, &s.info); + } + #if defined(TARGET_I386) if (flags == 2) { s.info.mach = bfd_mach_x86_64; @@ -519,11 +532,12 @@ void monitor_disas(Monitor *mon, CPUState *cpu, #elif defined(TARGET_LM32) s.info.mach = bfd_mach_lm32; s.info.print_insn = print_insn_lm32; -#else - monitor_printf(mon, "0x" TARGET_FMT_lx - ": Asm output not supported on this arch\n", pc); - return; #endif + if (!s.info.print_insn) { + monitor_printf(mon, "0x" TARGET_FMT_lx + ": Asm output not supported on this arch\n", pc); + return; + } for(i = 0; i < nb_insn; i++) { monitor_printf(mon, "0x" TARGET_FMT_lx ": ", pc); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index b120574df0..20aabc9cb3 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -23,6 +23,7 @@ #include #include #include "hw/qdev-core.h" +#include "disas/bfd.h" #include "exec/hwaddr.h" #include "exec/memattrs.h" #include "qemu/queue.h" @@ -117,6 +118,7 @@ struct TranslationBlock; * @cpu_exec_enter: Callback for cpu_exec preparation. * @cpu_exec_exit: Callback for cpu_exec cleanup. * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec. + * @disas_set_info: Setup architecture specific components of disassembly info * * Represents a CPU family or model. */ @@ -172,6 +174,8 @@ typedef struct CPUClass { void (*cpu_exec_enter)(CPUState *cpu); void (*cpu_exec_exit)(CPUState *cpu); bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); + + void (*disas_set_info)(CPUState *cpu, disassemble_info *info); } CPUClass; #ifdef HOST_WORDS_BIGENDIAN From fb200d5f003118f63205f34bbe553efcf3a66a81 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:34 -0700 Subject: [PATCH 18/22] disas: arm-a64: Make printfer and stream variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a normal disassembly flow, the printf() and stream being used varies from disas job to job. In particular it varies if mixing monitor_disas and target_disas. Make both the printf() function and target stream settable in the QEMUDisassmbler class. Reviewed-by: Claudio Fontana Tested-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas/arm-a64.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc index e04f946ca3..b0803f9cc3 100644 --- a/disas/arm-a64.cc +++ b/disas/arm-a64.cc @@ -35,16 +35,25 @@ static Disassembler *vixl_disasm = NULL; */ class QEMUDisassembler : public Disassembler { public: - explicit QEMUDisassembler(FILE *stream) : stream_(stream) { } + QEMUDisassembler() : printf_(NULL), stream_(NULL) { } ~QEMUDisassembler() { } + void SetStream(FILE *stream) { + stream_ = stream; + } + + void SetPrintf(int (*printf_fn)(FILE *, const char *, ...)) { + printf_ = printf_fn; + } + protected: virtual void ProcessOutput(const Instruction *instr) { - fprintf(stream_, "%08" PRIx32 " %s", + printf_(stream_, "%08" PRIx32 " %s", instr->InstructionBits(), GetOutput()); } private: + int (*printf_)(FILE *, const char *, ...); FILE *stream_; }; @@ -53,9 +62,9 @@ static int vixl_is_initialized(void) return vixl_decoder != NULL; } -static void vixl_init(FILE *f) { +static void vixl_init() { vixl_decoder = new Decoder(); - vixl_disasm = new QEMUDisassembler(f); + vixl_disasm = new QEMUDisassembler(); vixl_decoder->AppendVisitor(vixl_disasm); } @@ -78,9 +87,12 @@ int print_insn_arm_a64(uint64_t addr, disassemble_info *info) } if (!vixl_is_initialized()) { - vixl_init(info->stream); + vixl_init(); } + ((QEMUDisassembler *)vixl_disasm)->SetPrintf(info->fprintf_func); + ((QEMUDisassembler *)vixl_disasm)->SetStream(info->stream); + instrval = bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24; instr = reinterpret_cast(&instrval); vixl_disasm->MapCodeAddress(addr, instr); From 484406200e51eac023b346fdf987f86af1f6fe75 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:35 -0700 Subject: [PATCH 19/22] disas: arm: QOMify target specific disas setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the target_disas() ARM specifics to the QOM disas_set_info hook and delete the ARM specific code in disas.c. This has the extra advantage of the more fully featured target_disas() implementation now applying to monitor_disas(). Currently, target_disas() has multi-endian, thumb and AArch64 support whereas the existing monitor_disas() support only has vanilla AA32 support. E.G. Running an AA64 linux kernel the following -d in_asm disas happens (taget_disas()): IN: 0x0000000040000000: 580000c0 ldr x0, pc+24 (addr 0x40000018) 0x0000000040000004: aa1f03e1 mov x1, xzr However before this patch, disasing the same from the monitor: (qemu) xp/i 0x40000000 0x0000000040000000: 580000c0 stmdapl r0, {r6, r7} After this patch: (qemu) xp/i 0x40000000 0x0000000040000000: 580000c0 ldr x0, pc+24 (addr 0x40000018) Reviewed-by: Peter Maydell Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas.c | 32 -------------------------------- target-arm/cpu.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/disas.c b/disas.c index ff5425d9b4..fde5029ba5 100644 --- a/disas.c +++ b/disas.c @@ -151,14 +151,6 @@ bfd_vma bfd_getb16 (const bfd_byte *addr) return (bfd_vma) v; } -#ifdef TARGET_ARM -static int -print_insn_thumb1(bfd_vma pc, disassemble_info *info) -{ - return print_insn_arm(pc | 1, info); -} -#endif - static int print_insn_objdump(bfd_vma pc, disassemble_info *info, const char *prefix) { @@ -191,7 +183,6 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info) /* Disassemble this for me please... (debugging). 'flags' has the following values: i386 - 1 means 16 bit code, 2 means 64 bit code - arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64 ppc - bits 0:15 specify (optionally) the machine instruction set; bit 16 indicates little endian. other targets - unused @@ -231,27 +222,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, s.info.mach = bfd_mach_i386_i386; } s.info.print_insn = print_insn_i386; -#elif defined(TARGET_ARM) - if (flags & 4) { - /* We might not be compiled with the A64 disassembler - * because it needs a C++ compiler; in that case we will - * fall through to the default print_insn_od case. - */ -#if defined(CONFIG_ARM_A64_DIS) - s.info.print_insn = print_insn_arm_a64; -#endif - } else if (flags & 1) { - s.info.print_insn = print_insn_thumb1; - } else { - s.info.print_insn = print_insn_arm; - } - if (flags & 2) { -#ifdef TARGET_WORDS_BIGENDIAN - s.info.endian = BFD_ENDIAN_LITTLE; -#else - s.info.endian = BFD_ENDIAN_BIG; -#endif - } #elif defined(TARGET_SPARC) s.info.print_insn = print_insn_sparc; #ifdef TARGET_SPARC64 @@ -488,8 +458,6 @@ void monitor_disas(Monitor *mon, CPUState *cpu, s.info.mach = bfd_mach_i386_i386; } s.info.print_insn = print_insn_i386; -#elif defined(TARGET_ARM) - s.info.print_insn = print_insn_arm; #elif defined(TARGET_ALPHA) s.info.print_insn = print_insn_alpha; #elif defined(TARGET_SPARC) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 5a8cdb5238..8b4323dd08 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -382,6 +382,39 @@ static inline void unset_feature(CPUARMState *env, int feature) env->features &= ~(1ULL << feature); } +static int +print_insn_thumb1(bfd_vma pc, disassemble_info *info) +{ + return print_insn_arm(pc | 1, info); +} + +static void arm_disas_set_info(CPUState *cpu, disassemble_info *info) +{ + ARMCPU *ac = ARM_CPU(cpu); + CPUARMState *env = &ac->env; + + if (is_a64(env)) { + /* We might not be compiled with the A64 disassembler + * because it needs a C++ compiler. Leave print_insn + * unset in this case to use the caller default behaviour. + */ +#if defined(CONFIG_ARM_A64_DIS) + info->print_insn = print_insn_arm_a64; +#endif + } else if (env->thumb) { + info->print_insn = print_insn_thumb1; + } else { + info->print_insn = print_insn_arm; + } + if (env->bswap_code) { +#ifdef TARGET_WORDS_BIGENDIAN + info->endian = BFD_ENDIAN_LITTLE; +#else + info->endian = BFD_ENDIAN_BIG; +#endif + } +} + #define ARM_CPUS_PER_CLUSTER 8 static void arm_cpu_initfn(Object *obj) @@ -1368,6 +1401,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->gdb_core_xml_file = "arm-core.xml"; cc->gdb_stop_before_watchpoint = true; cc->debug_excp_handler = arm_debug_excp_handler; + + cc->disas_set_info = arm_disas_set_info; } static void cpu_register(const ARMCPUInfo *info) From efc6674be845e40d443b62e80eb9ea9a9adfee3c Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:36 -0700 Subject: [PATCH 20/22] disas: microblaze: QOMify target specific disas setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the target_disas() MB specifics to the QOM disas_set_info hook and delete the MB specific code in disas.c. This also now adds support for monitor_disas() to Microblaze. E.g. (qemu) xp 0x90000000 0000000090000000: 0x94208001 And before this patch: (qemu) xp/i 0x90000000 0x90000000: Asm output not supported on this arch After: (qemu) xp/i 0x90000000 0x90000000: mfs r1, rmsr Reviewed-by: Edgar E. Iglesias Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas.c | 3 --- target-microblaze/cpu.c | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/disas.c b/disas.c index fde5029ba5..937e08b743 100644 --- a/disas.c +++ b/disas.c @@ -268,9 +268,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, #elif defined(TARGET_S390X) s.info.mach = bfd_mach_s390_64; s.info.print_insn = print_insn_s390; -#elif defined(TARGET_MICROBLAZE) - s.info.mach = bfd_arch_microblaze; - s.info.print_insn = print_insn_microblaze; #elif defined(TARGET_MOXIE) s.info.mach = bfd_arch_moxie; s.info.print_insn = print_insn_moxie; diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 128d0320d4..9ac509af3e 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -119,6 +119,12 @@ static void mb_cpu_reset(CPUState *s) #endif } +static void mb_disas_set_info(CPUState *cpu, disassemble_info *info) +{ + info->mach = bfd_arch_microblaze; + info->print_insn = print_insn_microblaze; +} + static void mb_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -256,6 +262,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) dc->vmsd = &vmstate_mb_cpu; dc->props = mb_properties; cc->gdb_num_core_regs = 32 + 5; + + cc->disas_set_info = mb_disas_set_info; } static const TypeInfo mb_cpu_type_info = { From 51d373cf5f5a39fa315342d12ec910fe59d87090 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:37 -0700 Subject: [PATCH 21/22] disas: cris: Fix 0 buffer length case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cris has the complication of variable length instructions and has a check in place to clamp memory reads in case the disas request doesn't have enough bytes for the instruction being disas'd. This breaks down in the case where disassembling for the monitor where the buffer length is defaulted to 0. The buffer length should never be zero for a regular target_disas, so we can safely assume the 0 case is for the monitor in which case consider the buffer length to be the max for cris instructions. Reviewed-by: Edgar E. Iglesias Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas/cris.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/disas/cris.c b/disas/cris.c index e6cff7a765..1b76a09dbf 100644 --- a/disas/cris.c +++ b/disas/cris.c @@ -2575,9 +2575,9 @@ print_insn_cris_generic (bfd_vma memaddr, If we can't get any data, or we do not get enough data, we print the error message. */ - nbytes = info->buffer_length; - if (nbytes > MAX_BYTES_PER_CRIS_INSN) - nbytes = MAX_BYTES_PER_CRIS_INSN; + nbytes = info->buffer_length ? info->buffer_length + : MAX_BYTES_PER_CRIS_INSN; + nbytes = MIN(nbytes, MAX_BYTES_PER_CRIS_INSN); status = (*info->read_memory_func) (memaddr, buffer, nbytes, info); /* If we did not get all we asked for, then clear the rest. From 6b625fde5eb8d1c969969392f1c92b58beed2183 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Tue, 23 Jun 2015 20:57:38 -0700 Subject: [PATCH 22/22] disas: cris: QOMify target specific disas setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the target_disas() cris specifics to the QOM disas_set_info() hook and delete the cris specific code in disas.c. This also now adds support for monitor_disas() to cris. E.g. (qemu) xp 0x40004000 0000000040004000: 0x1e6f25f0 And before this patch: (qemu) xp/i 0x40004000 0x40004000: Asm output not supported on this arch After: (qemu) xp/i 0x40004000 0x40004000: di (qemu) xp/i 0x40004002 0x40004002: move.d 0xb003c004,$r1 Note: second example is 6-byte misaligned instruction! Reviewed-by: Edgar E. Iglesias Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- disas.c | 8 -------- target-cris/cpu.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/disas.c b/disas.c index 937e08b743..69a6066914 100644 --- a/disas.c +++ b/disas.c @@ -257,14 +257,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code, #elif defined(TARGET_ALPHA) s.info.mach = bfd_mach_alpha_ev6; s.info.print_insn = print_insn_alpha; -#elif defined(TARGET_CRIS) - if (flags != 32) { - s.info.mach = bfd_mach_cris_v0_v10; - s.info.print_insn = print_insn_crisv10; - } else { - s.info.mach = bfd_mach_cris_v32; - s.info.print_insn = print_insn_crisv32; - } #elif defined(TARGET_S390X) s.info.mach = bfd_mach_s390_64; s.info.print_insn = print_insn_s390; diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 0db209bf88..b17e849e2a 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -161,6 +161,20 @@ static void cris_cpu_set_irq(void *opaque, int irq, int level) } #endif +static void cris_disas_set_info(CPUState *cpu, disassemble_info *info) +{ + CRISCPU *cc = CRIS_CPU(cpu); + CPUCRISState *env = &cc->env; + + if (env->pregs[PR_VR] != 32) { + info->mach = bfd_mach_cris_v0_v10; + info->print_insn = print_insn_crisv10; + } else { + info->mach = bfd_mach_cris_v32; + info->print_insn = print_insn_crisv32; + } +} + static void cris_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -292,6 +306,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->gdb_num_core_regs = 49; cc->gdb_stop_before_watchpoint = true; + + cc->disas_set_info = cris_disas_set_info; } static const TypeInfo cris_cpu_type_info = {