summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-07-09 15:00:37 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-07-09 15:00:37 +0100
commit032624868df264d395ee9900331f08bad1431022 (patch)
tree3c265b22c87638dec3e52948428d70e5fe67484e
parent5a2db89615c8efabbeca74fe5e0f14f312d3bbe3 (diff)
parent6b625fde5eb8d1c969969392f1c92b58beed2183 (diff)
downloadqemu-032624868df264d395ee9900331f08bad1431022.zip
Merge remote-tracking branch 'remotes/afaerber/tags/qom-cpu-for-peter' into staging
QOM CPUState and X86CPU * Further QOM'ification of CPU initialization * Propagation of CPUState arguments and elimination of ENV_GET_CPU() usage * cpu_set_pc() abstraction * CPUClass::disas_set_info() hook # gpg: Signature made Thu Jul 9 14:23:12 2015 BST using RSA key ID 3E7E013F # gpg: Good signature from "Andreas Färber <afaerber@suse.de>" # gpg: aka "Andreas Färber <afaerber@suse.com>" * remotes/afaerber/tags/qom-cpu-for-peter: (22 commits) disas: cris: QOMify target specific disas setup disas: cris: Fix 0 buffer length case disas: microblaze: QOMify target specific disas setup disas: arm: QOMify target specific disas setup disas: arm-a64: Make printfer and stream variable disas: QOMify target specific setup disas: Add print_insn to disassemble info microblaze: boot: Use cpu_set_pc() hw/arm/boot: Use cpu_set_pc() gdbstub: Use cpu_set_pc() helper cpu: Add wrapper for the set_pc() hook cpu-exec: Purge all uses of ENV_GET_CPU() cpu: Change cpu_exec_init() arg to cpu, not env cpu: Change tcg_cpu_exec() arg to cpu, not env gdbstub: Change gdbserver_fork() to accept cpu instead of env translate-all: Change tb_flush() env argument to cpu target-ppc: Move cpu_exec_init() call to realize function cpu: Convert cpu_index into a bitmap cpu: Add Error argument to cpu_exec_init() cpu: Reorder cpu->as, cpu->thread_id, cpu->memory_dispatch init ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--bsd-user/main.c6
-rw-r--r--cpu-exec.c28
-rw-r--r--cpus.c8
-rw-r--r--disas.c119
-rw-r--r--disas/arm-a64.cc22
-rw-r--r--disas/cris.c6
-rw-r--r--exec.c74
-rw-r--r--gdbstub.c14
-rw-r--r--hw/arm/boot.c24
-rw-r--r--hw/microblaze/boot.c5
-rw-r--r--include/disas/bfd.h6
-rw-r--r--include/exec/exec-all.h4
-rw-r--r--include/exec/gdbstub.h2
-rw-r--r--include/qom/cpu.h19
-rw-r--r--linux-user/main.c30
-rw-r--r--linux-user/signal.c2
-rw-r--r--qom/cpu.c9
-rw-r--r--target-alpha/cpu.c2
-rw-r--r--target-alpha/cpu.h2
-rw-r--r--target-alpha/sys_helper.c2
-rw-r--r--target-arm/cpu.c37
-rw-r--r--target-arm/cpu.h2
-rw-r--r--target-cris/cpu.c18
-rw-r--r--target-cris/cpu.h2
-rw-r--r--target-i386/cpu.c2
-rw-r--r--target-i386/cpu.h2
-rw-r--r--target-i386/translate.c2
-rw-r--r--target-lm32/cpu.c2
-rw-r--r--target-lm32/cpu.h2
-rw-r--r--target-m68k/cpu.c2
-rw-r--r--target-m68k/cpu.h2
-rw-r--r--target-microblaze/cpu.c10
-rw-r--r--target-microblaze/cpu.h2
-rw-r--r--target-mips/cpu.c2
-rw-r--r--target-mips/cpu.h2
-rw-r--r--target-moxie/cpu.c2
-rw-r--r--target-moxie/cpu.h2
-rw-r--r--target-openrisc/cpu.c2
-rw-r--r--target-openrisc/cpu.h2
-rw-r--r--target-ppc/cpu.h2
-rw-r--r--target-ppc/translate_init.c12
-rw-r--r--target-s390x/cpu.c2
-rw-r--r--target-s390x/cpu.h2
-rw-r--r--target-sh4/cpu.c2
-rw-r--r--target-sh4/cpu.h2
-rw-r--r--target-sparc/cpu.c2
-rw-r--r--target-sparc/cpu.h2
-rw-r--r--target-tricore/cpu.c2
-rw-r--r--target-tricore/cpu.h2
-rw-r--r--target-unicore32/cpu.c2
-rw-r--r--target-unicore32/cpu.h3
-rw-r--r--target-xtensa/cpu.c2
-rw-r--r--target-xtensa/cpu.h2
-rw-r--r--translate-all.c6
54 files changed, 321 insertions, 205 deletions
diff --git a/bsd-user/main.c b/bsd-user/main.c
index ba0b9981f5..f46728bad8 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);
}
}
@@ -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 f547aebeaf..b00a42379b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1357,9 +1357,8 @@ 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);
int ret;
#ifdef CONFIG_PROFILER
int64_t ti;
@@ -1394,7 +1393,7 @@ static int tcg_cpu_exec(CPUArchState *env)
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
@@ -1421,13 +1420,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;
diff --git a/disas.c b/disas.c
index 576c6a437b..69a6066914 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 <errno.h>
@@ -150,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)
{
@@ -190,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
@@ -198,10 +190,10 @@ 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;
- int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
@@ -216,6 +208,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;
@@ -224,30 +221,9 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
} else {
s.info.mach = bfd_mach_i386_i386;
}
- 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)
- print_insn = print_insn_arm_a64;
-#endif
- } else if (flags & 1) {
- print_insn = print_insn_thumb1;
- } else {
- 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
- }
+ s.info.print_insn = print_insn_i386;
#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 +242,38 @@ 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;
-#elif defined(TARGET_CRIS)
- if (flags != 32) {
- s.info.mach = bfd_mach_cris_v0_v10;
- print_insn = print_insn_crisv10;
- } else {
- s.info.mach = bfd_mach_cris_v32;
- print_insn = print_insn_crisv32;
- }
+ s.info.print_insn = print_insn_alpha;
#elif defined(TARGET_S390X)
s.info.mach = bfd_mach_s390_64;
- 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_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;
#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;
@@ -450,9 +415,9 @@ 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;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
INIT_DISASSEMBLE_INFO(s.info, (FILE *)mon, monitor_fprintf);
@@ -468,6 +433,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;
@@ -476,13 +446,11 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
} else {
s.info.mach = bfd_mach_i386_i386;
}
- print_insn = print_insn_i386;
-#elif defined(TARGET_ARM)
- print_insn = print_insn_arm;
+ s.info.print_insn = print_insn_i386;
#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,36 +468,37 @@ 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;
-#else
- monitor_printf(mon, "0x" TARGET_FMT_lx
- ": Asm output not supported on this arch\n", pc);
- return;
+ s.info.print_insn = print_insn_lm32;
#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);
- 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/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<const Instruction *>(&instrval);
vixl_disasm->MapCodeAddress(addr, instr);
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.
diff --git a/exec.c b/exec.c
index b7f7f9818f..7d60e1530c 100644
--- a/exec.c
+++ b/exec.c
@@ -526,29 +526,74 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as)
}
#endif
-void cpu_exec_init(CPUArchState *env)
+#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 *cpu = ENV_GET_CPU(env);
- CPUClass *cc = CPU_GET_CLASS(cpu);
CPUState *some_cpu;
- int cpu_index;
+ int cpu_index = 0;
-#if defined(CONFIG_USER_ONLY)
- cpu_list_lock();
-#endif
- cpu_index = 0;
CPU_FOREACH(some_cpu) {
cpu_index++;
}
- cpu->cpu_index = cpu_index;
- cpu->numa_node = 0;
- QTAILQ_INIT(&cpu->breakpoints);
- QTAILQ_INIT(&cpu->watchpoints);
+ return cpu_index;
+}
+
+void cpu_exec_exit(CPUState *cpu)
+{
+}
+#endif
+
+void cpu_exec_init(CPUState *cpu, Error **errp)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+ int cpu_index;
+ Error *local_err = NULL;
+
#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
+ 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;
+ }
QTAILQ_INSERT_TAIL(&cpus, cpu, node);
#if defined(CONFIG_USER_ONLY)
cpu_list_unlock();
@@ -558,7 +603,7 @@ void cpu_exec_init(CPUArchState *env)
}
#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
@@ -770,8 +815,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..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)
@@ -1226,7 +1223,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 +1257,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 +1486,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 +1497,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));
@@ -1631,9 +1626,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/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) {
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);
}
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, \
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 2e74760ade..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);
+void cpu_exec_init(CPUState *cpu, Error **errp);
void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
#if !defined(CONFIG_USER_ONLY)
@@ -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/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/include/qom/cpu.h b/include/qom/cpu.h
index 42f42f5a2d..20aabc9cb3 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -23,6 +23,7 @@
#include <signal.h>
#include <setjmp.h>
#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
@@ -602,6 +606,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.
* @mask: The interrupt mask to clear.
@@ -674,6 +692,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/linux-user/main.c b/linux-user/main.c
index 6c5c2effbf..05914b11e4 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);
@@ -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/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/qom/cpu.c b/qom/cpu.c
index 108bfa205a..eb9cfeca18 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -312,7 +312,15 @@ 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)
@@ -356,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,
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index a98b7d8d72..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);
+ cpu_exec_init(cs, &error_abort);
tlb_flush(cs, 1);
alpha_translate_init();
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-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-arm/cpu.c b/target-arm/cpu.c
index 80669a6d1b..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)
@@ -392,7 +425,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(cs, &error_abort);
cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
g_free, g_free);
@@ -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)
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.c b/target-cris/cpu.c
index 16cfba95ff..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);
@@ -170,7 +184,7 @@ static void cris_cpu_initfn(Object *obj)
static bool tcg_initialized;
cs->env_ptr = env;
- cpu_exec_init(env);
+ cpu_exec_init(cs, &error_abort);
env->pregs[PR_VR] = ccc->vr;
@@ -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 = {
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.c b/target-i386/cpu.c
index b4f9461969..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);
+ cpu_exec_init(cs, &error_abort);
object_property_add(obj, "family", "int",
x86_cpuid_version_get_family,
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-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/target-lm32/cpu.c b/target-lm32/cpu.c
index f8081f52c1..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);
+ cpu_exec_init(cs, &error_abort);
env->flags = 0;
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.c b/target-m68k/cpu.c
index 4cfb7256c6..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);
+ cpu_exec_init(cs, &error_abort);
if (tcg_enabled() && !inited) {
inited = true;
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.c b/target-microblaze/cpu.c
index c592bf76e4..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);
@@ -190,7 +196,7 @@ static void mb_cpu_initfn(Object *obj)
static bool tcg_initialized;
cs->env_ptr = env;
- cpu_exec_init(env);
+ cpu_exec_init(cs, &error_abort);
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
@@ -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 = {
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.c b/target-mips/cpu.c
index 958c999f0a..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);
+ cpu_exec_init(cs, &error_abort);
if (tcg_enabled()) {
mips_tcg_init();
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.c b/target-moxie/cpu.c
index 47b617f5cd..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);
+ cpu_exec_init(cs, &error_abort);
if (tcg_enabled() && !inited) {
inited = 1;
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.c b/target-openrisc/cpu.c
index 39bedc108e..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);
+ cpu_exec_init(cs, &error_abort);
#ifndef CONFIG_USER_ONLY
cpu_openrisc_mmu_init(cpu);
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-ppc/translate_init.c b/target-ppc/translate_init.c
index d74f4f024d..16d7b16ac2 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(cs, &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);
- cpu->cpu_dt_id = cs->cpu_index;
env->msr_mask = pcc->msr_mask;
env->mmu_model = pcc->mmu_model;
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 69bac35349..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);
+ 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-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.c b/target-sh4/cpu.c
index cccb14fe7b..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);
+ cpu_exec_init(cs, &error_abort);
env->movcal_backup_tail = &(env->movcal_backup);
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.c b/target-sparc/cpu.c
index a952097096..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);
+ cpu_exec_init(cs, &error_abort);
if (tcg_enabled()) {
gen_intermediate_code_init(env);
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.c b/target-tricore/cpu.c
index b3e5512bbf..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);
+ cpu_exec_init(cs, &error_abort);
if (tcg_enabled()) {
tricore_tcg_init();
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.c b/target-unicore32/cpu.c
index 5b32987173..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);
+ cpu_exec_init(cs, &error_abort);
#ifdef CONFIG_USER_ONLY
env->uncached_asr = ASR_MODE_USER;
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.c b/target-xtensa/cpu.c
index 2b75678995..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);
+ cpu_exec_init(cs, &error_abort);
if (tcg_enabled() && !tcg_inited) {
tcg_inited = true;
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);
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. */