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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABAgAGBQJVnnXAAAoJEPou0S0+fgE/xvEP/RPxbi7zN4FlJOgR9QoDvBRv
 Gxwze3f9stIHsxGT2ws4sXelF63kin+zzaP3jO/+M6pumk6wnVhR+YYfHyeTQbgO
 EOLXDV6rqBe0HXtUp2CnrYqCsEIHiSu8HWy2fKHTv4BQQAWoUJC61Jy6bDiTGShT
 J69NENxDdFF0oJhVSZGmZeQQUPnwkpHWvb0MVs5dEUtyPOjHFIZLO85562N8FjEK
 xoTkSUUEoiiGDVacO9xGHY6RBKlVZKRw1VMaXWTn3nRs7QqdwKPR3R7ntoNinc/R
 Il1spIVbcmhcEeBKKLGyfbK/a6496S2c9vZbgKpf6W1l6OQ+n3WcGf93eH8s4ZSY
 98Q15Z2d3lmIS90SsPw9Wzig+++UsxBZmICf0sw2ZyZSQAXQbLtRU9lj0kTrJwuq
 QYjVKmVSRAKnDwpL3y2m31qcASOPeNU4Ga2RiqZeU5QU2pQ6i9uqoeESDYw8TGW5
 HpRAay/aA3fI6A0W3Uvr4LVmZ3y5FuRl2CQBs/LN2lUUf7unNTS1IgLBYMqPLgxd
 jCrTs0MSuui9i/iXEi4g+Lr9q8RR1iaFd+kwiqCoQ5LgGuj4iIqYRKiazTMkNzXn
 CeIFMjp2EeAboZkr2Fxl8yuPuENUvCKrownDivXQ84CikXg8fsVG+/k6HVpC3VSe
 RvhWfc7PXdsMXQCGIqME
 =RHHU
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2015-07-09 15:00:37 +01:00
commit 032624868d
54 changed files with 323 additions and 207 deletions

View file

@ -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

View file

@ -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);

8
cpus.c
View file

@ -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;

119
disas.c
View file

@ -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;

View file

@ -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);

View file

@ -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.

78
exec.c
View file

@ -526,29 +526,74 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as)
}
#endif
void cpu_exec_init(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
CPUClass *cc = CPU_GET_CLASS(cpu);
CPUState *some_cpu;
int cpu_index;
#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;
#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);
}
}
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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);
}

View file

@ -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, \

View file

@ -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)

View file

@ -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);

View file

@ -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
@ -601,6 +605,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.
@ -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;

View file

@ -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:

View file

@ -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;

View file

@ -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,

View file

@ -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();

View file

@ -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. */

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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 = {

View file

@ -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. */

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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. */

View file

@ -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;

View file

@ -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. */

View file

@ -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 = {

View file

@ -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. */

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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. */

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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);

View file

@ -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;

View file

@ -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))

View file

@ -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;

View file

@ -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);

View file

@ -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. */