diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-07-23 10:57:04 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-07-23 10:57:04 -0500 |
commit | 3988982c82ad4173dea376fea30e5432d36146db (patch) | |
tree | a4f72b53b9db680859ecc16b43dae4f113e1b744 | |
parent | 931f0adf64261bf7eb3efaafb4430c04a6a3e6f6 (diff) | |
parent | 6f152e9bc80aed81ea89aa8ad345cd71326b71fb (diff) |
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
QOM CPUState refactorings
* Fix NULL pointer dereference in gdbstub
* Introduce vaddr type
* Introduce CPUClass::set_pc()
* Introduce CPUClass::synchronize_from_tb()
* Introduce CPUClass::get_phys_page_debug()
* Introduce CPUClass::memory_rw_debug()
* Move singlestep_enabled and gdb_regs fields out of CPU_COMMON
* Adopt CPUState in more APIs
* Propagate CPUState in gdbstub
# gpg: Signature made Mon 22 Jul 2013 07:50:17 PM CDT using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found
# By Andreas Färber (21) and others
# Via Andreas Färber
* afaerber/tags/qom-cpu-for-anthony: (24 commits)
linux-user: Use X86CPU property to retrieve CPUID family
gdbstub: Change gdb_register_coprocessor() argument to CPUState
cpu: Move gdb_regs field from CPU_COMMON to CPUState
gdbstub: Change GDBState::{c,g}_cpu and find_cpu() to CPUState
cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug()
exec: Change cpu_memory_rw_debug() argument to CPUState
cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
gdbstub: Change gdb_{read,write}_register() argument to CPUState
gdbstub: Change gdb_handlesig() argument to CPUState
gdbstub: Change syscall callback argument to CPUState
kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState
cpu: Change cpu_single_step() argument to CPUState
gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
target-alpha: Copy implver to DisasContext
target-alpha: Copy singlestep_enabled to DisasContext
cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb()
target-unicore32: Implement CPUClass::set_pc()
target-moxie: Implement CPUClass::set_pc()
target-m68k: Implement CPUClass::set_pc()
...
104 files changed, 783 insertions, 550 deletions
@@ -40,8 +40,23 @@ speaking, the size of guest memory can always fit into ram_addr_t but it would not be correct to store an actual guest physical address in a ram_addr_t. -Use target_ulong (or abi_ulong) for CPU virtual addresses, however -devices should not need to use target_ulong. +For CPU virtual addresses there are several possible types. +vaddr is the best type to use to hold a CPU virtual address in +target-independent code. It is guaranteed to be large enough to hold a +virtual address for any target, and it does not change size from target +to target. It is always unsigned. +target_ulong is a type the size of a virtual address on the CPU; this means +it may be 32 or 64 bits depending on which target is being built. It should +therefore be used only in target-specific code, and in some +performance-critical built-per-target core code such as the TLB code. +There is also a signed version, target_long. +abi_ulong is for the *-user targets, and represents a type the size of +'void *' in that target's ABI. (This may not be the same as the size of a +full CPU virtual address in the case of target ABIs which use 32 bit pointers +on 64 bit CPUs, like sparc32plus.) Definitions of structures that must match +the target's ABI must use this type for anything that on the target is defined +to be an 'unsigned long' or a pointer type. +There is also a signed version, abi_long. Of course, take all of the above with a grain of salt. If you're about to use some system interface that requires a type like size_t, pid_t or diff --git a/bsd-user/main.c b/bsd-user/main.c index 1e9255242c..f9246aa102 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -643,7 +643,7 @@ void cpu_loop(CPUSPARCState *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); #if 0 if (sig) { @@ -738,6 +738,7 @@ int main(int argc, char **argv) struct image_info info1, *info = &info1; TaskState ts1, *ts = &ts1; CPUArchState *env; + CPUState *cpu; int optind; const char *r; int gdbstub_port = 0; @@ -912,10 +913,11 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } + cpu = ENV_GET_CPU(env); #if defined(TARGET_SPARC) || defined(TARGET_PPC) - cpu_reset(ENV_GET_CPU(env)); + cpu_reset(cpu); #endif - thread_cpu = ENV_GET_CPU(env); + thread_cpu = cpu; if (getenv("QEMU_STRACE")) { do_strace = 1; @@ -1134,7 +1136,7 @@ int main(int argc, char **argv) if (gdbstub_port) { gdbserver_start (gdbstub_port); - gdb_handlesig(env, 0); + gdb_handlesig(cpu, 0); } cpu_loop(env); /* never exits */ diff --git a/cpu-exec.c b/cpu-exec.c index 6c784a7e09..301be28bf7 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -59,8 +59,14 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) * counter hit zero); we must restore the guest PC to the address * of the start of the TB. */ + CPUClass *cc = CPU_GET_CLASS(cpu); TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); - cpu_pc_from_tb(env, tb); + if (cc->synchronize_from_tb) { + cc->synchronize_from_tb(cpu, tb); + } else { + assert(cc->set_pc); + cc->set_pc(cpu, tb->pc); + } } if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) { /* We were asked to stop executing TBs (probably a pending @@ -291,7 +297,7 @@ int cpu_exec(CPUArchState *env) for(;;) { interrupt_request = cpu->interrupt_request; if (unlikely(interrupt_request)) { - if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) { + if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; } @@ -1186,7 +1186,7 @@ static void tcg_exec_all(void) CPUArchState *env = cpu->env_ptr; qemu_clock_enable(vm_clock, - (env->singlestep_enabled & SSTEP_NOTIMER) == 0); + (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); if (cpu_can_run(cpu)) { r = tcg_cpu_exec(env); @@ -1285,7 +1285,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, { FILE *f; uint32_t l; - CPUArchState *env; CPUState *cpu; uint8_t buf[1024]; @@ -1299,7 +1298,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, "a CPU number"); return; } - env = cpu->env_ptr; f = fopen(filename, "wb"); if (!f) { @@ -1311,7 +1309,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, l = sizeof(buf); if (l > size) l = size; - cpu_memory_rw_debug(env, addr, buf, l, 0); + cpu_memory_rw_debug(cpu, addr, buf, l, 0); if (fwrite(buf, 1, l, f) != l) { error_set(errp, QERR_IO_ERROR); goto exit; @@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr, { CPUDebug *s = container_of(info, CPUDebug, info); - cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0); + cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0); return 0; } @@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length, if (monitor_disas_is_physical) { cpu_physical_memory_read(memaddr, myaddr, length); } else { - cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0); + cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0); } return 0; } @@ -415,14 +415,14 @@ void cpu_exec_init(CPUArchState *env) #if defined(TARGET_HAS_ICE) #if defined(CONFIG_USER_ONLY) -static void breakpoint_invalidate(CPUArchState *env, target_ulong pc) +static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { tb_invalidate_phys_page_range(pc, pc + 1, 0); } #else -static void breakpoint_invalidate(CPUArchState *env, target_ulong pc) +static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { - tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) | + tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) | (pc & ~TARGET_PAGE_MASK)); } #endif @@ -525,15 +525,17 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags, bp->flags = flags; /* keep all GDB-injected breakpoints in front */ - if (flags & BP_GDB) + if (flags & BP_GDB) { QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry); - else + } else { QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry); + } - breakpoint_invalidate(env, pc); + breakpoint_invalidate(ENV_GET_CPU(env), pc); - if (breakpoint) + if (breakpoint) { *breakpoint = bp; + } return 0; #else return -ENOSYS; @@ -564,7 +566,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint) #if defined(TARGET_HAS_ICE) QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry); - breakpoint_invalidate(env, breakpoint->pc); + breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc); g_free(breakpoint); #endif @@ -585,14 +587,16 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask) /* enable or disable single step mode. EXCP_DEBUG is returned by the CPU loop after each instruction */ -void cpu_single_step(CPUArchState *env, int enabled) +void cpu_single_step(CPUState *cpu, int enabled) { #if defined(TARGET_HAS_ICE) - if (env->singlestep_enabled != enabled) { - env->singlestep_enabled = enabled; - if (kvm_enabled()) + CPUArchState *env = cpu->env_ptr; + + if (cpu->singlestep_enabled != enabled) { + cpu->singlestep_enabled = enabled; + if (kvm_enabled()) { kvm_update_guest_debug(env, 0); - else { + } else { /* must flush all the translated code to avoid inconsistencies */ /* XXX: only flush what is necessary */ tb_flush(env); @@ -1831,7 +1835,7 @@ MemoryRegion *get_system_io(void) /* physical memory access (slow version, mainly for debug) */ #if defined(CONFIG_USER_ONLY) -int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, +int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write) { int l, flags; @@ -2602,7 +2606,7 @@ void stq_be_phys(hwaddr addr, uint64_t val) } /* virtual memory access for debug (includes writing to ROM) */ -int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, +int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write) { int l; @@ -2611,7 +2615,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, while (len > 0) { page = addr & TARGET_PAGE_MASK; - phys_addr = cpu_get_phys_page_debug(env, page); + phys_addr = cpu_get_phys_page_debug(cpu, page); /* if no physical page mapped, return an error */ if (phys_addr == -1) return -1; @@ -42,15 +42,16 @@ #include "sysemu/kvm.h" #include "qemu/bitops.h" -#ifndef TARGET_CPU_MEMORY_RW_DEBUG -static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, - uint8_t *buf, int len, int is_write) +static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr, + uint8_t *buf, int len, bool is_write) { - return cpu_memory_rw_debug(env, addr, buf, len, is_write); + CPUClass *cc = CPU_GET_CLASS(cpu); + + if (cc->memory_rw_debug) { + return cc->memory_rw_debug(cpu, addr, buf, len, is_write); + } + return cpu_memory_rw_debug(cpu, addr, buf, len, is_write); } -#else -/* target_memory_rw_debug() defined in cpu.h */ -#endif enum { GDB_SIGNAL_0 = 0, @@ -287,9 +288,9 @@ enum RSState { RS_CHKSUM2, }; typedef struct GDBState { - CPUArchState *c_cpu; /* current CPU for step/continue ops */ - CPUArchState *g_cpu; /* current CPU for other ops */ - CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */ + CPUState *c_cpu; /* current CPU for step/continue ops */ + CPUState *g_cpu; /* current CPU for other ops */ + CPUState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ char line_buf[MAX_PACKET_LENGTH]; int line_buf_index; @@ -1839,7 +1840,7 @@ static const char *get_feature_xml(const char *p, const char **newp) /* Generate the XML description for this CPU. */ if (!target_xml[0]) { GDBRegisterState *r; - CPUArchState *env = first_cpu->env_ptr; + CPUState *cpu = first_cpu; snprintf(target_xml, sizeof(target_xml), "<?xml version=\"1.0\"?>" @@ -1848,7 +1849,7 @@ static const char *get_feature_xml(const char *p, const char **newp) "<xi:include href=\"%s\"/>", GDB_CORE_XML); - for (r = env->gdb_regs; r; r = r->next) { + for (r = cpu->gdb_regs; r; r = r->next) { pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\""); pstrcat(target_xml, sizeof(target_xml), r->xml); pstrcat(target_xml, sizeof(target_xml), "\"/>"); @@ -1866,14 +1867,15 @@ static const char *get_feature_xml(const char *p, const char **newp) } #endif -static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) +static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) { + CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < NUM_CORE_REGS) return cpu_gdb_read_register(env, mem_buf, reg); - for (r = env->gdb_regs; r; r = r->next) { + for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->get_reg(env, mem_buf, reg - r->base_reg); } @@ -1881,14 +1883,15 @@ static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) return 0; } -static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg) +static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) { + CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < NUM_CORE_REGS) return cpu_gdb_write_register(env, mem_buf, reg); - for (r = env->gdb_regs; r; r = r->next) { + for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->set_reg(env, mem_buf, reg - r->base_reg); } @@ -1903,15 +1906,15 @@ static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg) gdb reading a CPU register, and set_reg is gdb modifying a CPU register. */ -void gdb_register_coprocessor(CPUArchState * env, - gdb_reg_cb get_reg, gdb_reg_cb set_reg, - int num_regs, const char *xml, int g_pos) +void gdb_register_coprocessor(CPUState *cpu, + gdb_reg_cb get_reg, gdb_reg_cb set_reg, + int num_regs, const char *xml, int g_pos) { GDBRegisterState *s; GDBRegisterState **p; static int last_reg = NUM_CORE_REGS; - p = &env->gdb_regs; + p = &cpu->gdb_regs; while (*p) { /* Check for duplicates. */ if (strcmp((*p)->xml, xml) == 0) @@ -1954,8 +1957,9 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) CPUArchState *env; int err = 0; - if (kvm_enabled()) + if (kvm_enabled()) { return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); + } switch (type) { case GDB_BREAKPOINT_SW: @@ -1991,8 +1995,9 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) CPUArchState *env; int err = 0; - if (kvm_enabled()) + if (kvm_enabled()) { return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type); + } switch (type) { case GDB_BREAKPOINT_SW: @@ -2027,7 +2032,7 @@ static void gdb_breakpoint_remove_all(void) CPUArchState *env; if (kvm_enabled()) { - kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu)); + kvm_remove_all_breakpoints(gdbserver_state->c_cpu); return; } @@ -2042,49 +2047,22 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { - cpu_synchronize_state(ENV_GET_CPU(s->c_cpu)); -#if defined(TARGET_I386) - s->c_cpu->eip = pc; -#elif defined (TARGET_PPC) - s->c_cpu->nip = pc; -#elif defined (TARGET_SPARC) - s->c_cpu->pc = pc; - s->c_cpu->npc = pc + 4; -#elif defined (TARGET_ARM) - s->c_cpu->regs[15] = pc; -#elif defined (TARGET_SH4) - s->c_cpu->pc = pc; -#elif defined (TARGET_MIPS) - s->c_cpu->active_tc.PC = pc & ~(target_ulong)1; - if (pc & 1) { - s->c_cpu->hflags |= MIPS_HFLAG_M16; - } else { - s->c_cpu->hflags &= ~(MIPS_HFLAG_M16); + CPUState *cpu = s->c_cpu; + CPUClass *cc = CPU_GET_CLASS(cpu); + + cpu_synchronize_state(cpu); + if (cc->set_pc) { + cc->set_pc(cpu, pc); } -#elif defined (TARGET_MICROBLAZE) - s->c_cpu->sregs[SR_PC] = pc; -#elif defined(TARGET_OPENRISC) - s->c_cpu->pc = pc; -#elif defined (TARGET_CRIS) - s->c_cpu->pc = pc; -#elif defined (TARGET_ALPHA) - s->c_cpu->pc = pc; -#elif defined (TARGET_S390X) - s->c_cpu->psw.addr = pc; -#elif defined (TARGET_LM32) - s->c_cpu->pc = pc; -#elif defined(TARGET_XTENSA) - s->c_cpu->pc = pc; -#endif } -static CPUArchState *find_cpu(uint32_t thread_id) +static CPUState *find_cpu(uint32_t thread_id) { CPUState *cpu; for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { if (cpu_index(cpu) == thread_id) { - return cpu->env_ptr; + return cpu; } } @@ -2093,7 +2071,10 @@ static CPUArchState *find_cpu(uint32_t thread_id) static int gdb_handle_packet(GDBState *s, const char *line_buf) { +#ifdef TARGET_XTENSA CPUArchState *env; +#endif + CPUState *cpu; const char *p; uint32_t thread; int ch, reg_size, type, res; @@ -2111,7 +2092,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) case '?': /* TODO: Make this return the correct value for user-mode. */ snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP, - cpu_index(ENV_GET_CPU(s->c_cpu))); + cpu_index(s->c_cpu)); put_packet(s, buf); /* Remove all the breakpoints when this query is issued, * because gdb is doing and initial connect and the state @@ -2173,12 +2154,12 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } if (res) { if (res_thread != -1 && res_thread != 0) { - env = find_cpu(res_thread); - if (env == NULL) { + cpu = find_cpu(res_thread); + if (cpu == NULL) { put_packet(s, "E22"); break; } - s->c_cpu = env; + s->c_cpu = cpu; } if (res == 's') { cpu_single_step(s->c_cpu, sstep_flags); @@ -2239,8 +2220,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } break; case 'g': - cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); - env = s->g_cpu; + cpu_synchronize_state(s->g_cpu); +#ifdef TARGET_XTENSA + env = s->g_cpu->env_ptr; +#endif len = 0; for (addr = 0; addr < num_g_regs; addr++) { reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); @@ -2250,8 +2233,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, buf); break; case 'G': - cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); - env = s->g_cpu; + cpu_synchronize_state(s->g_cpu); +#ifdef TARGET_XTENSA + env = s->g_cpu->env_ptr; +#endif registers = mem_buf; len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); @@ -2267,7 +2252,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, NULL, 16); - if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) { + if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); @@ -2282,7 +2267,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ':') p++; hextomem(mem_buf, p, len); - if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) { + if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, + true) != 0) { put_packet(s, "E14"); } else { put_packet(s, "OK"); @@ -2341,18 +2327,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "OK"); break; } - env = find_cpu(thread); - if (env == NULL) { + cpu = find_cpu(thread); + if (cpu == NULL) { put_packet(s, "E22"); break; } switch (type) { case 'c': - s->c_cpu = env; + s->c_cpu = cpu; put_packet(s, "OK"); break; case 'g': - s->g_cpu = env; + s->g_cpu = cpu; put_packet(s, "OK"); break; default: @@ -2362,9 +2348,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'T': thread = strtoull(p, (char **)&p, 16); - env = find_cpu(thread); + cpu = find_cpu(thread); - if (env != NULL) { + if (cpu != NULL) { put_packet(s, "OK"); } else { put_packet(s, "E22"); @@ -2401,23 +2387,21 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "QC1"); break; } else if (strcmp(p,"fThreadInfo") == 0) { - s->query_cpu = first_cpu->env_ptr; + s->query_cpu = first_cpu; goto report_cpuinfo; } else if (strcmp(p,"sThreadInfo") == 0) { report_cpuinfo: if (s->query_cpu) { - snprintf(buf, sizeof(buf), "m%x", - cpu_index(ENV_GET_CPU(s->query_cpu))); + snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu)); put_packet(s, buf); - s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr; + s->query_cpu = s->query_cpu->next_cpu; } else put_packet(s, "l"); break; } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) { thread = strtoull(p+16, (char **)&p, 16); - env = find_cpu(thread); - if (env != NULL) { - CPUState *cpu = ENV_GET_CPU(env); + cpu = find_cpu(thread); + if (cpu != NULL) { cpu_synchronize_state(cpu); len = snprintf((char *)mem_buf, sizeof(mem_buf), "CPU#%d [%s]", cpu->cpu_index, @@ -2429,7 +2413,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } #ifdef CONFIG_USER_ONLY else if (strncmp(p, "Offsets", 7) == 0) { - TaskState *ts = s->c_cpu->opaque; + CPUArchState *env = s->c_cpu->env_ptr; + TaskState *ts = env->opaque; snprintf(buf, sizeof(buf), "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx @@ -2519,18 +2504,16 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) void gdb_set_stop_cpu(CPUState *cpu) { - CPUArchState *env = cpu->env_ptr; - - gdbserver_state->c_cpu = env; - gdbserver_state->g_cpu = env; + gdbserver_state->c_cpu = cpu; + gdbserver_state->g_cpu = cpu; } #ifndef CONFIG_USER_ONLY static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; - CPUArchState *env = s->c_cpu; - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = s->c_cpu->env_ptr; + CPUState *cpu = s->c_cpu; char buf[256]; const char *type; int ret; @@ -2598,7 +2581,7 @@ send_packet: put_packet(s, buf); /* disable single step if it was enabled */ - cpu_single_step(env, 0); + cpu_single_step(cpu, 0); } #endif @@ -2668,7 +2651,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) is still in the running state, which can cause packets to be dropped and state transition 'T' packets to be sent while the syscall is still being processed. */ - cpu_exit(ENV_GET_CPU(s->c_cpu)); + cpu_exit(s->c_cpu); #endif } @@ -2789,66 +2772,67 @@ gdb_queuesig (void) } int -gdb_handlesig (CPUArchState *env, int sig) +gdb_handlesig(CPUState *cpu, int sig) { - GDBState *s; - char buf[256]; - int n; + CPUArchState *env = cpu->env_ptr; + GDBState *s; + char buf[256]; + int n; - s = gdbserver_state; - if (gdbserver_fd < 0 || s->fd < 0) - return sig; + s = gdbserver_state; + if (gdbserver_fd < 0 || s->fd < 0) { + return sig; + } - /* disable single step if it was enabled */ - cpu_single_step(env, 0); - tb_flush(env); + /* disable single step if it was enabled */ + cpu_single_step(cpu, 0); + tb_flush(env); - if (sig != 0) - { - snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig)); - put_packet(s, buf); - } - /* put_packet() might have detected that the peer terminated the - connection. */ - if (s->fd < 0) - return sig; - - sig = 0; - s->state = RS_IDLE; - s->running_state = 0; - while (s->running_state == 0) { - n = read (s->fd, buf, 256); - if (n > 0) - { - int i; + if (sig != 0) { + snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig)); + put_packet(s, buf); + } + /* put_packet() might have detected that the peer terminated the + connection. */ + if (s->fd < 0) { + return sig; + } - for (i = 0; i < n; i++) - gdb_read_byte (s, buf[i]); - } - else if (n == 0 || errno != EAGAIN) - { - /* XXX: Connection closed. Should probably wait for another - connection before continuing. */ - return sig; + sig = 0; + s->state = RS_IDLE; + s->running_state = 0; + while (s->running_state == 0) { + n = read(s->fd, buf, 256); + if (n > 0) { + int i; + + for (i = 0; i < n; i++) { + gdb_read_byte(s, buf[i]); + } + } else if (n == 0 || errno != EAGAIN) { + /* XXX: Connection closed. Should probably wait for another + connection before continuing. */ + return sig; } - } - sig = s->signal; - s->signal = 0; - return sig; + } + sig = s->signal; + s->signal = 0; + return sig; } /* Tell the remote gdb that the process has exited due to SIG. */ void gdb_signalled(CPUArchState *env, int sig) { - GDBState *s; - char buf[4]; + GDBState *s; + char buf[4]; - s = gdbserver_state; - if (gdbserver_fd < 0 || s->fd < 0) - return; + s = gdbserver_state; + if (gdbserver_fd < 0 || s->fd < 0) { + return; + } - snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig)); - put_packet(s, buf); + snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig)); + put_packet(s, buf); } static void gdb_accept(void) @@ -2876,8 +2860,8 @@ static void gdb_accept(void) socket_set_nodelay(fd); s = g_malloc0(sizeof(GDBState)); - s->c_cpu = first_cpu->env_ptr; - s->g_cpu = first_cpu->env_ptr; + s->c_cpu = first_cpu; + s->g_cpu = first_cpu; s->fd = fd; gdb_has_xml = 0; @@ -3061,8 +3045,8 @@ int gdbserver_start(const char *device) mon_chr = s->mon_chr; memset(s, 0, sizeof(GDBState)); } - s->c_cpu = first_cpu->env_ptr; - s->g_cpu = first_cpu->env_ptr; + s->c_cpu = first_cpu; + s->g_cpu = first_cpu; s->chr = chr; s->state = chr ? RS_IDLE : RS_INACTIVE; s->mon_chr = mon_chr; diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 365b2197a1..a4506bcf42 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -146,6 +146,7 @@ static void update_guest_rom_state(VAPICROMState *s) static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env) { + CPUState *cs = CPU(x86_env_get_cpu(env)); hwaddr paddr; target_ulong addr; @@ -158,7 +159,7 @@ static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env) * virtual address space for the APIC mapping. */ for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) { - paddr = cpu_get_phys_page_debug(env, addr); + paddr = cpu_get_phys_page_debug(cs, addr); if (paddr != APIC_DEFAULT_ADDRESS) { continue; } @@ -187,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr) modrm_reg(opcode[1]) == instr->modrm_reg); } -static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, +static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong *pip, TPRAccess access) { + CPUState *cs = CPU(cpu); const TPRInstruction *instr; target_ulong ip = *pip; uint8_t opcode[2]; @@ -210,7 +212,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, * RSP, used by the patched instruction, is zero, so the guest gets a * double fault and dies. */ - if (env->regs[R_ESP] == 0) { + if (cpu->env.regs[R_ESP] == 0) { return -1; } @@ -225,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, if (instr->access != access) { continue; } - if (cpu_memory_rw_debug(env, ip - instr->length, opcode, + if (cpu_memory_rw_debug(cs, ip - instr->length, opcode, sizeof(opcode), 0) < 0) { return -1; } @@ -236,7 +238,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, } return -1; } else { - if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) { + if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) { return -1; } for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) { @@ -253,7 +255,7 @@ instruction_ok: * Grab the virtual TPR address from the instruction * and update the cached values. */ - if (cpu_memory_rw_debug(env, ip + instr->addr_offset, + if (cpu_memory_rw_debug(cs, ip + instr->addr_offset, (void *)&real_tpr_addr, sizeof(real_tpr_addr), 0) < 0) { return -1; @@ -271,6 +273,7 @@ instruction_ok: static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip) { + CPUState *cs = CPU(x86_env_get_cpu(env)); hwaddr paddr; uint32_t rom_state_vaddr; uint32_t pos, patch, offset; @@ -287,7 +290,7 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i /* find out virtual address of the ROM */ rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000); - paddr = cpu_get_phys_page_debug(env, rom_state_vaddr); + paddr = cpu_get_phys_page_debug(cs, rom_state_vaddr); if (paddr == -1) { return -1; } @@ -332,8 +335,9 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i * cannot be accessed or is considered invalid. This also ensures that we are * not patching the wrong guest. */ -static int get_kpcr_number(CPUX86State *env) +static int get_kpcr_number(X86CPU *cpu) { + CPUX86State *env = &cpu->env; struct kpcr { uint8_t fill1[0x1c]; uint32_t self; @@ -341,7 +345,7 @@ static int get_kpcr_number(CPUX86State *env) uint8_t number; } QEMU_PACKED kpcr; - if (cpu_memory_rw_debug(env, env->segs[R_FS].base, + if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base, (void *)&kpcr, sizeof(kpcr), 0) < 0 || kpcr.self != env->segs[R_FS].base) { return -1; @@ -349,9 +353,9 @@ static int get_kpcr_number(CPUX86State *env) return kpcr.number; } -static int vapic_enable(VAPICROMState *s, CPUX86State *env) +static int vapic_enable(VAPICROMState *s, X86CPU *cpu) { - int cpu_number = get_kpcr_number(env); + int cpu_number = get_kpcr_number(cpu); hwaddr vapic_paddr; static const uint8_t enabled = 1; @@ -362,26 +366,26 @@ static int vapic_enable(VAPICROMState *s, CPUX86State *env) (((hwaddr)cpu_number) << VAPIC_CPU_SHIFT); cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled), (void *)&enabled, sizeof(enabled), 1); - apic_enable_vapic(env->apic_state, vapic_paddr); + apic_enable_vapic(cpu->env.apic_state, vapic_paddr); s->state = VAPIC_ACTIVE; return 0; } -static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte) +static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte) { - cpu_memory_rw_debug(env, addr, &byte, 1, 1); + cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1); } -static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip, +static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip, uint32_t target) { uint32_t offset; offset = cpu_to_le32(target - ip - 5); - patch_byte(env, ip, 0xe8); /* call near */ - cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1); + patch_byte(cpu, ip, 0xe8); /* call near */ + cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1); } static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip) @@ -409,32 +413,32 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip) pause_all_vcpus(); - cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0); + cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0); switch (opcode[0]) { case 0x89: /* mov r32 to r/m32 */ - patch_byte(env, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */ - patch_call(s, env, ip + 1, handlers->set_tpr); + patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */ + patch_call(s, cpu, ip + 1, handlers->set_tpr); break; case 0x8b: /* mov r/m32 to r32 */ - patch_byte(env, ip, 0x90); - patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]); + patch_byte(cpu, ip, 0x90); + patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]); break; case 0xa1: /* mov abs to eax */ - patch_call(s, env, ip, handlers->get_tpr[0]); + patch_call(s, cpu, ip, handlers->get_tpr[0]); break; case 0xa3: /* mov eax to abs */ - patch_call(s, env, ip, handlers->set_tpr_eax); + patch_call(s, cpu, ip, handlers->set_tpr_eax); break; case 0xc7: /* mov imm32, r/m32 (c7/0) */ - patch_byte(env, ip, 0x68); /* push imm32 */ - cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0); - cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1); - patch_call(s, env, ip + 5, handlers->set_tpr); + patch_byte(cpu, ip, 0x68); /* push imm32 */ + cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0); + cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1); + patch_call(s, cpu, ip + 5, handlers->set_tpr); break; case 0xff: /* push r/m32 */ - patch_byte(env, ip, 0x50); /* push eax */ - patch_call(s, env, ip + 1, handlers->get_tpr_stack); + patch_byte(cpu, ip, 0x50); /* push eax */ + patch_call(s, cpu, ip + 1, handlers->get_tpr_stack); break; default: abort(); @@ -458,16 +462,16 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip, cpu_synchronize_state(cs); - if (evaluate_tpr_instruction(s, env, &ip, access) < 0) { + if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) { if (s->state == VAPIC_ACTIVE) { - vapic_enable(s, env); + vapic_enable(s, cpu); } return; } if (update_rom_mapping(s, env, ip) < 0) { return; } - if (vapic_enable(s, env) < 0) { + if (vapic_enable(s, cpu) < 0) { return; } patch_instruction(s, cpu, ip); @@ -667,8 +671,8 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data, * accurate. */ pause_all_vcpus(); - patch_byte(env, env->eip - 2, 0x66); - patch_byte(env, env->eip - 1, 0x90); + patch_byte(cpu, env->eip - 2, 0x66); + patch_byte(cpu, env->eip - 1, 0x90); resume_all_vcpus(); } @@ -681,7 +685,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data, if (find_real_tpr_addr(s, env) < 0) { break; } - vapic_enable(s, env); + vapic_enable(s, cpu); break; default: case 4: @@ -722,7 +726,7 @@ static void do_vapic_enable(void *data) VAPICROMState *s = data; X86CPU *cpu = X86_CPU(first_cpu); - vapic_enable(s, &cpu->env); + vapic_enable(s, cpu); } static int vapic_post_load(void *opaque, int version_id) diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c index 075daf1893..1138666ca5 100644 --- a/hw/xtensa/xtensa_lx60.c +++ b/hw/xtensa/xtensa_lx60.c @@ -144,9 +144,11 @@ static void lx60_net_init(MemoryRegion *address_space, memory_region_add_subregion(address_space, buffers, ram); } -static uint64_t translate_phys_addr(void *env, uint64_t addr) +static uint64_t translate_phys_addr(void *opaque, uint64_t addr) { - return cpu_get_phys_page_debug(env, addr); + XtensaCPU *cpu = opaque; + + return cpu_get_phys_page_debug(CPU(cpu), addr); } static void lx60_reset(void *opaque) @@ -252,7 +254,7 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args) } uint64_t elf_entry; uint64_t elf_lowaddr; - int success = load_elf(kernel_filename, translate_phys_addr, env, + int success = load_elf(kernel_filename, translate_phys_addr, cpu, &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0); if (success > 0) { env->pc = elf_entry; diff --git a/hw/xtensa/xtensa_sim.c b/hw/xtensa/xtensa_sim.c index a88707e161..ea91162b63 100644 --- a/hw/xtensa/xtensa_sim.c +++ b/hw/xtensa/xtensa_sim.c @@ -32,9 +32,11 @@ #include "exec/memory.h" #include "exec/address-spaces.h" -static uint64_t translate_phys_addr(void *env, uint64_t addr) +static uint64_t translate_phys_addr(void *opaque, uint64_t addr) { - return cpu_get_phys_page_debug(env, addr); + XtensaCPU *cpu = opaque; + + return cpu_get_phys_page_debug(CPU(cpu), addr); } static void sim_reset(void *opaque) @@ -88,10 +90,10 @@ static void xtensa_sim_init(QEMUMachineInitArgs *args) uint64_t elf_entry; uint64_t elf_lowaddr; #ifdef TARGET_WORDS_BIGENDIAN - int success = load_elf(kernel_filename, translate_phys_addr, env, + int success = load_elf(kernel_filename, translate_phys_addr, cpu, &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); #else - int success = load_elf(kernel_filename, translate_phys_addr, env, + int success = load_elf(kernel_filename, translate_phys_addr, cpu, &elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0); #endif if (success > 0) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 5084202217..f2800ec682 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -22,6 +22,7 @@ #include "qemu-common.h" #include "exec/cpu-common.h" #include "qemu/thread.h" +#include "qom/cpu.h" /* some important defines: * @@ -428,19 +429,8 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint); void cpu_watchpoint_remove_all(CPUArchState *env, int mask); -#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ -#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ -#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ - -void cpu_single_step(CPUArchState *env, int enabled); - #if !defined(CONFIG_USER_ONLY) -/* Return the physical page corresponding to a virtual one. Use it - only for debugging because no protection checks are done. Return -1 - if no page found. */ -hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr); - /* memory API */ extern ram_addr_t ram_size; @@ -494,7 +484,7 @@ void qemu_mutex_lock_ramlist(void); void qemu_mutex_unlock_ramlist(void); #endif /* !CONFIG_USER_ONLY */ -int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, +int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write); #endif /* CPU_ALL_H */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 39094b3f48..b5b93db842 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -170,13 +170,10 @@ typedef struct CPUWatchpoint { /* from this point: preserved by CPU reset */ \ /* ice debug support */ \ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \ - int singlestep_enabled; \ \ QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \ CPUWatchpoint *watchpoint_hit; \ \ - struct GDBRegisterState *gdb_regs; \ - \ /* Core interrupt code */ \ sigjmp_buf jmp_env; \ int exception_index; \ diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index ded4160e57..1bd00aea23 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -11,7 +11,7 @@ #define GDB_WATCHPOINT_ACCESS 4 #ifdef NEED_CPU_H -typedef void (*gdb_syscall_complete_cb)(CPUArchState *env, +typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, target_ulong ret, target_ulong err); void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...); @@ -20,13 +20,13 @@ void gdb_set_stop_cpu(CPUState *cpu); void gdb_exit(CPUArchState *, int); #ifdef CONFIG_USER_ONLY int gdb_queuesig (void); -int gdb_handlesig (CPUArchState *, int); +int gdb_handlesig(CPUState *, int); void gdb_signalled(CPUArchState *, int); void gdbserver_fork(CPUArchState *); #endif /* Get or set a register. Returns the size of the register. */ typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); -void gdb_register_coprocessor(CPUArchState *env, +void gdb_register_coprocessor(CPUState *cpu, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos); diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h index 93798b9614..8401f7d587 100644 --- a/include/exec/softmmu-semi.h +++ b/include/exec/softmmu-semi.h @@ -13,14 +13,14 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr) { uint32_t val; - cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0); + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0); return tswap32(val); } static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr) { uint8_t val; - cpu_memory_rw_debug(env, addr, &val, 1, 0); + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, 0); return val; } @@ -31,7 +31,7 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr) static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val) { val = tswap32(val); - cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1); + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1); } #define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; }) #define put_user_ual(arg, p) put_user_u32(arg, p) @@ -42,8 +42,9 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len, uint8_t *p; /* TODO: Make this something that isn't fixed size. */ p = malloc(len); - if (p && copy) - cpu_memory_rw_debug(env, addr, p, len, 0); + if (p && copy) { + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0); + } return p; } #define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy) @@ -58,7 +59,7 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr) return NULL; } do { - cpu_memory_rw_debug(env, addr, &c, 1, 0); + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0); addr++; *(p++) = c; } while (c); @@ -68,8 +69,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr) static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr, target_ulong len) { - if (len) - cpu_memory_rw_debug(env, addr, p, len, 1); + if (len) { + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1); + } free(p); } #define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index dfd81a1d2f..daf1835c1a 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -30,6 +30,18 @@ typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque); /** + * vaddr: + * Type wide enough to contain any #target_ulong virtual address. + */ +typedef uint64_t vaddr; +#define VADDR_PRId PRId64 +#define VADDR_PRIu PRIu64 +#define VADDR_PRIo PRIo64 +#define VADDR_PRIx PRIx64 +#define VADDR_PRIX PRIX64 +#define VADDR_MAX UINT64_MAX + +/** * SECTION:cpu * @section_id: QEMU-cpu * @title: CPU Class @@ -48,6 +60,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, bool is_write, bool is_exec, int opaque, unsigned size); +struct TranslationBlock; + /** * CPUClass: * @class_by_name: Callback to map -cpu command line model name to an @@ -56,11 +70,16 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, * @reset_dump_flags: #CPUDumpFlags to use for reset logging. * @do_interrupt: Callback for interrupt handling. * @do_unassigned_access: Callback for unassigned access handling. + * @memory_rw_debug: Callback for GDB memory access. * @dump_state: Callback for dumping state. * @dump_statistics: Callback for dumping statistics. * @get_arch_id: Callback for getting architecture-dependent CPU ID. * @get_paging_enabled: Callback for inquiring whether paging is enabled. * @get_memory_mapping: Callback for obtaining the memory mappings. + * @set_pc: Callback for setting the Program Counter register. + * @synchronize_from_tb: Callback for synchronizing state from a TCG + * #TranslationBlock. + * @get_phys_page_debug: Callback for obtaining a physical address. * @vmsd: State description for migration. * * Represents a CPU family or model. @@ -76,6 +95,8 @@ typedef struct CPUClass { int reset_dump_flags; void (*do_interrupt)(CPUState *cpu); CPUUnassignedAccess do_unassigned_access; + int (*memory_rw_debug)(CPUState *cpu, vaddr addr, + uint8_t *buf, int len, bool is_write); void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); void (*dump_statistics)(CPUState *cpu, FILE *f, @@ -84,6 +105,9 @@ typedef struct CPUClass { bool (*get_paging_enabled)(const CPUState *cpu); void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); + void (*set_pc)(CPUState *cpu, vaddr value); + void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); + hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, @@ -114,8 +138,10 @@ struct kvm_run; * @stopped: Indicates the CPU has been artificially stopped. * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this * CPU and return to its top level loop. + * @singlestep_enabled: Flags for single-stepping. * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. + * @gdb_regs: Additional GDB registers. * @next_cpu: Next CPU sharing TB cache. * @kvm_fd: vCPU file descriptor for KVM. * @@ -146,9 +172,11 @@ struct CPUState { volatile sig_atomic_t exit_request; volatile sig_atomic_t tcg_exit_req; uint32_t interrupt_request; + int singlestep_enabled; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; + struct GDBRegisterState *gdb_regs; CPUState *next_cpu; int kvm_fd; @@ -259,6 +287,25 @@ void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +#ifndef CONFIG_USER_ONLY +/** + * cpu_get_phys_page_debug: + * @cpu: The CPU to obtain the physical page address for. + * @addr: The virtual address. + * + * Obtains the physical page corresponding to a virtual one. + * Use it only for debugging because no protection checks are done. + * + * Returns: Corresponding physical page address or -1 if no page found. + */ +static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return cc->get_phys_page_debug(cpu, addr); +} +#endif + /** * cpu_reset: * @cpu: The CPU whose state is to be reset. @@ -277,59 +324,6 @@ void cpu_reset(CPUState *cpu); ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); /** - * cpu_class_set_vmsd: - * @cc: CPU class - * @value: Value to set. Unused for %CONFIG_USER_ONLY. - * - * Sets #VMStateDescription for @cc. - * - * The @value argument is intentionally discarded for the non-softmmu targets - * to avoid linker errors or excessive preprocessor usage. If this behavior - * is undesired, you should assign #CPUClass.vmsd directly instead. - */ -#ifndef CONFIG_USER_ONLY -static inline void cpu_class_set_vmsd(CPUClass *cc, - const struct VMStateDescription *value) -{ - cc->vmsd = value; -} -#else -#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL) -#endif - -#ifndef CONFIG_USER_ONLY -static inline void cpu_class_set_do_unassigned_access(CPUClass *cc, - CPUUnassignedAccess value) -{ - cc->do_unassigned_access = value; -} -#else -#define cpu_class_set_do_unassigned_access(cc, value) \ - ((cc)->do_unassigned_access = NULL) -#endif - -/** - * device_class_set_vmsd: - * @dc: Device class - * @value: Value to set. Unused for %CONFIG_USER_ONLY. - * - * Sets #VMStateDescription for @dc. - * - * The @value argument is intentionally discarded for the non-softmmu targets - * to avoid linker errors or excessive preprocessor usage. If this behavior - * is undesired, you should assign #DeviceClass.vmsd directly instead. - */ -#ifndef CONFIG_USER_ONLY -static inline void device_class_set_vmsd(DeviceClass *dc, - const struct VMStateDescription *value) -{ - dc->vmsd = value; -} -#else -#define device_class_set_vmsd(dc, value) ((dc)->vmsd = NULL) -#endif - -/** * qemu_cpu_has_work: * @cpu: The vCPU to check. * @@ -489,6 +483,19 @@ void cpu_resume(CPUState *cpu); */ void qemu_init_vcpu(CPUState *cpu); +#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ +#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ +#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ + +/** + * cpu_single_step: + * @cpu: CPU to the flags for. + * @enabled: Flags to enable. + * + * Enables or disables single-stepping for @cpu. + */ +void cpu_single_step(CPUState *cpu, int enabled); + #ifdef CONFIG_SOFTMMU extern const struct VMStateDescription vmstate_cpu_common; #else diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 1e08a85116..f8ac448e0b 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -169,9 +169,9 @@ void *kvm_arch_ram_alloc(ram_addr_t size); void kvm_setup_guest_memory(void *start, size_t size); void kvm_flush_coalesced_mmio_buffer(void); -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type); -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type); void kvm_remove_all_breakpoints(CPUState *cpu); int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap); @@ -1890,7 +1890,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) data.dbg.control = reinject_trap; - if (env->singlestep_enabled) { + if (cpu->singlestep_enabled) { data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; } kvm_arch_update_guest_debug(cpu, &data.dbg); @@ -1900,10 +1900,9 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return data.err; } -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { - CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp; int err; @@ -1946,10 +1945,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, return 0; } -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { - CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp; int err; @@ -2022,13 +2020,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return -EINVAL; } -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; } -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; diff --git a/kvm-stub.c b/kvm-stub.c index 370c8371d5..7b2233ae82 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return -ENOSYS; } -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; } -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; diff --git a/linux-user/cpu-uname.c b/linux-user/cpu-uname.c index 59cd6477d5..cc713e6553 100644 --- a/linux-user/cpu-uname.c +++ b/linux-user/cpu-uname.c @@ -55,12 +55,14 @@ const char *cpu_to_uname_machine(void *cpu_env) return "x86-64"; #elif defined(TARGET_I386) /* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */ - uint32_t cpuid_version = ((CPUX86State *)cpu_env)->cpuid_version; - int family = ((cpuid_version >> 8) & 0x0f) + ((cpuid_version >> 20) & 0xff); - if (family == 4) + CPUState *cpu = ENV_GET_CPU((CPUX86State *)cpu_env); + int family = object_property_get_int(OBJECT(cpu), "family", NULL); + if (family == 4) { return "i486"; - if (family == 5) + } + if (family == 5) { return "i586"; + } return "i686"; #else /* default is #define-d in each arch/ subdir */ diff --git a/linux-user/main.c b/linux-user/main.c index 99c3b3f5ef..f6a3aad9e5 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -312,6 +312,7 @@ static void set_idt(int n, unsigned int dpl) void cpu_loop(CPUX86State *env) { + CPUState *cs = CPU(x86_env_get_cpu(env)); int trapnr; abi_ulong pc; target_siginfo_t info; @@ -443,7 +444,7 @@ void cpu_loop(CPUX86State *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -875,7 +876,7 @@ void cpu_loop(CPUARMState *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -966,7 +967,7 @@ void cpu_loop(CPUUniCore32State *env) { int sig; - sig = gdb_handlesig(env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; @@ -1233,7 +1234,7 @@ void cpu_loop (CPUSPARCState *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -1764,7 +1765,7 @@ void cpu_loop(CPUPPCState *env) { int sig; - sig = gdb_handlesig(env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; @@ -2315,7 +2316,7 @@ done_syscall: { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -2475,7 +2476,7 @@ void cpu_loop(CPUOpenRISCState *env) break; } if (gdbsig) { - gdb_handlesig(env, gdbsig); + gdb_handlesig(cs, gdbsig); if (gdbsig != TARGET_SIGTRAP) { exit(1); } @@ -2518,7 +2519,7 @@ void cpu_loop(CPUSH4State *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -2586,7 +2587,7 @@ void cpu_loop(CPUCRISState *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -2686,7 +2687,7 @@ void cpu_loop(CPUMBState *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -2779,7 +2780,7 @@ void cpu_loop(CPUM68KState *env) { int sig; - sig = gdb_handlesig (env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -3006,7 +3007,7 @@ void cpu_loop(CPUAlphaState *env) } break; case EXCP_DEBUG: - info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP); + info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP); if (info.si_signo) { env->lock_addr = -1; info.si_errno = 0; @@ -3059,7 +3060,7 @@ void cpu_loop(CPUS390XState *env) break; case EXCP_DEBUG: - sig = gdb_handlesig(env, TARGET_SIGTRAP); + sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { n = TARGET_TRAP_BRKPT; goto do_signal_pc; @@ -3541,6 +3542,7 @@ int main(int argc, char **argv, char **envp) struct linux_binprm bprm; TaskState *ts; CPUArchState *env; + CPUState *cpu; int optind; char **target_environ, **wrk; char **target_argv; @@ -3637,11 +3639,12 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } + cpu = ENV_GET_CPU(env); #if defined(TARGET_SPARC) || defined(TARGET_PPC) - cpu_reset(ENV_GET_CPU(env)); + cpu_reset(cpu); #endif - thread_cpu = ENV_GET_CPU(env); + thread_cpu = cpu; if (getenv("QEMU_STRACE")) { do_strace = 1; @@ -4076,7 +4079,7 @@ int main(int argc, char **argv, char **envp) gdbstub_port); exit(1); } - gdb_handlesig(env, 0); + gdb_handlesig(cpu, 0); } cpu_loop(env); /* never exits */ diff --git a/linux-user/signal.c b/linux-user/signal.c index d0727becc2..a5e8906c4d 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -5386,6 +5386,7 @@ long do_rt_sigreturn(CPUArchState *env) void process_pending_signals(CPUArchState *cpu_env) { + CPUState *cpu = ENV_GET_CPU(cpu_env); int sig; abi_ulong handler; sigset_t set, old_set; @@ -5419,7 +5420,7 @@ void process_pending_signals(CPUArchState *cpu_env) if (!k->first) k->pending = 0; - sig = gdb_handlesig (cpu_env, sig); + sig = gdb_handlesig(cpu, sig); if (!sig) { sa = NULL; handler = TARGET_SIG_IGN; @@ -1164,7 +1164,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize, cpu_physical_memory_read(addr, buf, l); } else { env = mon_get_cpu(); - if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) { + if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) { monitor_printf(mon, " Cannot access memory\n"); break; } diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index 60125b19d5..b2eeba36f3 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -81,5 +81,6 @@ extern const struct VMStateDescription vmstate_alpha_cpu; void alpha_cpu_do_interrupt(CPUState *cpu); void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 26708055d9..c8c8c2c861 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -24,6 +24,13 @@ #include "migration/vmstate.h" +static void alpha_cpu_set_pc(CPUState *cs, vaddr value) +{ + AlphaCPU *cpu = ALPHA_CPU(cs); + + cpu->env.pc = value; +} + static void alpha_cpu_realizefn(DeviceState *dev, Error **errp) { AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev); @@ -263,8 +270,12 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = alpha_cpu_class_by_name; cc->do_interrupt = alpha_cpu_do_interrupt; cc->dump_state = alpha_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access); - device_class_set_vmsd(dc, &vmstate_alpha_cpu); + cc->set_pc = alpha_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = alpha_cpu_unassigned_access; + cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug; + dc->vmsd = &vmstate_alpha_cpu; +#endif } static const TypeInfo alpha_cpu_type_info = { diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 066f0324e2..c85dc6e575 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif /* !defined (__CPU_ALPHA_H__) */ diff --git a/target-alpha/helper.c b/target-alpha/helper.c index ff57dd6c18..fc61bb02f7 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -315,12 +315,13 @@ static int get_physical_address(CPUAlphaState *env, target_ulong addr, return ret; } -hwaddr cpu_get_phys_page_debug(CPUAlphaState *env, target_ulong addr) +hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + AlphaCPU *cpu = ALPHA_CPU(cs); target_ulong phys; int prot, fail; - fail = get_physical_address(env, addr, 0, 0, &phys, &prot); + fail = get_physical_address(&cpu->env, addr, 0, 0, &phys, &prot); return (fail >= 0 ? -1 : phys); } diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 5558b728dd..0efd5595e6 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -38,7 +38,6 @@ typedef struct DisasContext DisasContext; struct DisasContext { struct TranslationBlock *tb; - CPUAlphaState *env; uint64_t pc; int mem_idx; @@ -46,6 +45,11 @@ struct DisasContext { int tb_rm; /* Current flush-to-zero setting for this TB. */ int tb_ftz; + + /* implver value for this CPU. */ + int implver; + + bool singlestep_enabled; }; /* Return values from translate_one, indicating the state of the TB. @@ -380,7 +384,7 @@ static int use_goto_tb(DisasContext *ctx, uint64_t dest) /* Check for the dest on the same page as the start of the TB. We also want to suppress goto_tb in the case of single-steping and IO. */ return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0 - && !ctx->env->singlestep_enabled + && !ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)); } @@ -2248,8 +2252,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x6C: /* IMPLVER */ - if (rc != 31) - tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver); + if (rc != 31) { + tcg_gen_movi_i64(cpu_ir[rc], ctx->implver); + } break; default: goto invalid_opc; @@ -3383,6 +3388,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUAlphaState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; target_ulong pc_start; @@ -3398,9 +3404,10 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.tb = tb; - ctx.env = env; ctx.pc = pc_start; ctx.mem_idx = cpu_mmu_index(env); + ctx.implver = env->implver; + ctx.singlestep_enabled = cs->singlestep_enabled; /* ??? Every TB begins with unset rounding mode, to be initialized on the first fp insn of the TB. Alternately we could define a proper @@ -3457,7 +3464,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, || tcg_ctx.gen_opc_ptr >= gen_opc_end || num_insns >= max_insns || singlestep - || env->singlestep_enabled)) { + || ctx.singlestep_enabled)) { ret = EXIT_PC_STALE; } } while (ret == NO_EXIT); @@ -3474,7 +3481,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, tcg_gen_movi_i64(cpu_pc, ctx.pc); /* FALLTHRU */ case EXIT_PC_UPDATED: - if (env->singlestep_enabled) { + if (ctx.singlestep_enabled) { gen_excp_1(EXCP_DEBUG, 0); } else { tcg_gen_exit_tb(0); diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c index 5f01bca119..ee469c49c5 100644 --- a/target-arm/arm-semi.c +++ b/target-arm/arm-semi.c @@ -122,8 +122,10 @@ static target_ulong arm_semi_syscall_len; static target_ulong syscall_err; #endif -static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) +static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; #ifdef CONFIG_USER_ONLY TaskState *ts = env->opaque; #endif @@ -152,12 +154,14 @@ static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) } } -static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err) +static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; /* The size is always stored in big-endian order, extract the value. We assume the size always fit in 32 bits. */ uint32_t size; - cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); + cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); env->regs[0] = be32_to_cpu(size); #ifdef CONFIG_USER_ONLY ((TaskState *)env->opaque)->swi_errno = err; diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 48ba6054ec..02162c9aba 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -147,4 +147,6 @@ void arm_v7m_cpu_do_interrupt(CPUState *cpu); void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 9f1696f933..d3906a4829 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -25,6 +25,13 @@ #endif #include "sysemu/sysemu.h" +static void arm_cpu_set_pc(CPUState *cs, vaddr value) +{ + ARMCPU *cpu = ARM_CPU(cs); + + cpu->env.regs[15] = value; +} + static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) { /* Reset a single ARMCPRegInfo register */ @@ -816,7 +823,11 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = arm_cpu_class_by_name; cc->do_interrupt = arm_cpu_do_interrupt; cc->dump_state = arm_cpu_dump_state; - cpu_class_set_vmsd(cc, &vmstate_arm_cpu); + cc->set_pc = arm_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_arm_cpu; +#endif } static void cpu_register(const ARMCPUInfo *info) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c798b272a0..b2dc49413c 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -797,11 +797,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb) -{ - env->regs[15] = tb->pc; -} - /* Load an instruction and return it in the standard little-endian order */ static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr, bool do_swap) diff --git a/target-arm/helper.c b/target-arm/helper.c index aeae024165..b0c3ca1fbe 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1513,16 +1513,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model) void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) { + CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; if (arm_feature(env, ARM_FEATURE_NEON)) { - gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 51, "arm-neon.xml", 0); } else if (arm_feature(env, ARM_FEATURE_VFP3)) { - gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 35, "arm-vfp3.xml", 0); } else if (arm_feature(env, ARM_FEATURE_VFP)) { - gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 19, "arm-vfp.xml", 0); } } @@ -2762,17 +2763,19 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, return 1; } -hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr) +hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + ARMCPU *cpu = ARM_CPU(cs); hwaddr phys_addr; target_ulong page_size; int prot; int ret; - ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size); + ret = get_phys_addr(&cpu->env, addr, 0, 0, &phys_addr, &prot, &page_size); - if (ret != 0) + if (ret != 0) { return -1; + } return phys_addr; } diff --git a/target-arm/translate.c b/target-arm/translate.c index 7b50c8c308..6db4c50df4 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -9911,6 +9911,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; @@ -9930,7 +9931,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->condjmp = 0; dc->thumb = ARM_TBFLAG_THUMB(tb->flags); dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags); @@ -10080,7 +10081,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, * ensures prefetch aborts occur at the right place. */ num_insns ++; } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !cs->singlestep_enabled && !singlestep && dc->pc < next_page_start && num_insns < max_insns); @@ -10097,7 +10098,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, /* At this stage dc->condjmp will only be set when the skipped instruction was a conditional branch or trap, and the PC has already been written. */ - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (dc->condjmp) { gen_set_condexec(dc); diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index af7d14de4b..d7baf0746a 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -79,4 +79,6 @@ void crisv10_cpu_do_interrupt(CPUState *cpu); void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + #endif diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 2abb57fc23..ba095e75a5 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -26,6 +26,13 @@ #include "mmu.h" +static void cris_cpu_set_pc(CPUState *cs, vaddr value) +{ + CRISCPU *cpu = CRIS_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void cris_cpu_reset(CPUState *s) { @@ -247,6 +254,10 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = cris_cpu_class_by_name; cc->do_interrupt = cris_cpu_do_interrupt; cc->dump_state = cris_cpu_dump_state; + cc->set_pc = cris_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = cris_cpu_get_phys_page_debug; +#endif } static const TypeInfo cris_cpu_type_info = { diff --git a/target-cris/cpu.h b/target-cris/cpu.h index c12a8caea1..4b9fc4cb45 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} #endif diff --git a/target-cris/helper.c b/target-cris/helper.c index aba7537265..d274b388b8 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -255,16 +255,17 @@ void cris_cpu_do_interrupt(CPUState *cs) env->pregs[PR_ERP]); } -hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr) +hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + CRISCPU *cpu = CRIS_CPU(cs); uint32_t phy = addr; struct cris_mmu_result res; int miss; - miss = cris_mmu_translate(&res, env, addr, 0, 0, 1); + miss = cris_mmu_translate(&res, &cpu->env, addr, 0, 0, 1); /* If D TLB misses, try I TLB. */ if (miss) { - miss = cris_mmu_translate(&res, env, addr, 2, 0, 1); + miss = cris_mmu_translate(&res, &cpu->env, addr, 2, 0, 1); } if (!miss) { diff --git a/target-cris/translate.c b/target-cris/translate.c index 1de9743953..2a4beeb869 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3165,6 +3165,7 @@ static inline void gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUCRISState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; @@ -3197,7 +3198,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, dc->is_jmp = DISAS_NEXT; dc->ppc = pc_start; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->flags_uptodate = 1; dc->flagx_known = 1; dc->flags_x = tb->flags & X_FLAG; @@ -3337,7 +3338,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, /* If we are rexecuting a branch due to exceptions on delay slots dont break. */ - if (!(tb->pc & 1) && env->singlestep_enabled) { + if (!(tb->pc & 1) && cs->singlestep_enabled) { break; } } while (!dc->is_jmp && !dc->cpustate_changed @@ -3370,7 +3371,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, cris_evaluate_flags(dc); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(env_pc, npc); } diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 7e55e5fd2e..d928562c53 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -104,4 +104,6 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); + #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e3f75a81a7..cd350cb8e4 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2506,6 +2506,20 @@ static bool x86_cpu_get_paging_enabled(const CPUState *cs) return cpu->env.cr[0] & CR0_PG_MASK; } +static void x86_cpu_set_pc(CPUState *cs, vaddr value) +{ + X86CPU *cpu = X86_CPU(cs); + + cpu->env.eip = value; +} + +static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + X86CPU *cpu = X86_CPU(cs); + + cpu->env.eip = tb->pc - tb->cs_base; +} + static void x86_cpu_common_class_init(ObjectClass *oc, void *data) { X86CPUClass *xcc = X86_CPU_CLASS(oc); @@ -2522,16 +2536,19 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->do_interrupt = x86_cpu_do_interrupt; cc->dump_state = x86_cpu_dump_state; + cc->set_pc = x86_cpu_set_pc; + cc->synchronize_from_tb = x86_cpu_synchronize_from_tb; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifndef CONFIG_USER_ONLY cc->get_memory_mapping = x86_cpu_get_memory_mapping; + cc->get_phys_page_debug = x86_cpu_get_phys_page_debug; cc->write_elf64_note = x86_cpu_write_elf64_note; cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote; cc->write_elf32_note = x86_cpu_write_elf32_note; cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote; + cc->vmsd = &vmstate_x86_cpu; #endif - cpu_class_set_vmsd(cc, &vmstate_x86_cpu); } static const TypeInfo x86_cpu_type_info = { diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2d005b3ce9..cedefdc423 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1148,11 +1148,6 @@ static inline bool cpu_has_work(CPUState *cs) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb) -{ - env->eip = tb->pc - tb->cs_base; -} - static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc, target_ulong *cs_base, int *flags) { diff --git a/target-i386/helper.c b/target-i386/helper.c index d6f43d7a21..bf3e2ac73d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -363,7 +363,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "Code="); for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) { - if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) { + if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) { snprintf(codestr, sizeof(codestr), "%02x", code); } else { snprintf(codestr, sizeof(codestr), "??"); @@ -884,8 +884,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, return 1; } -hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr) +hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; target_ulong pde_addr, pte_addr; uint64_t pte; hwaddr paddr; @@ -1258,6 +1260,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, target_ulong *base, unsigned int *limit, unsigned int *flags) { + X86CPU *cpu = x86_env_get_cpu(env); + CPUState *cs = CPU(cpu); SegmentCache *dt; target_ulong ptr; uint32_t e1, e2; @@ -1270,8 +1274,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, index = selector & ~7; ptr = dt->base + index; if ((index + 7) > dt->limit - || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 - || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0) + || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 + || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0) return 0; *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 8315489989..3c9d10a762 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1594,6 +1594,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu) static int kvm_guest_debug_workarounds(X86CPU *cpu) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; int ret = 0; unsigned long reinject_trap = 0; @@ -1616,7 +1617,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu) * reinject them via SET_GUEST_DEBUG. */ if (reinject_trap || - (!kvm_has_robust_singlestep() && env->singlestep_enabled)) { + (!kvm_has_robust_singlestep() && cs->singlestep_enabled)) { ret = kvm_update_guest_debug(env, reinject_trap); } return ret; @@ -1931,25 +1932,23 @@ static int kvm_handle_tpr_access(X86CPU *cpu) return 1; } -int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp) +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - CPUX86State *env = &X86_CPU(cpu)->env; static const uint8_t int3 = 0xcc; - if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || - cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&int3, 1, 1)) { + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) { return -EINVAL; } return 0; } -int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp) +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - CPUX86State *env = &X86_CPU(cpu)->env; uint8_t int3; - if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc || - cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { + if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { return -EINVAL; } return 0; @@ -2042,13 +2041,14 @@ static CPUWatchpoint hw_watchpoint; static int kvm_handle_debug(X86CPU *cpu, struct kvm_debug_exit_arch *arch_info) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; int ret = 0; int n; if (arch_info->exception == 1) { if (arch_info->dr6 & (1 << 14)) { - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { ret = EXCP_DEBUG; } } else { diff --git a/target-i386/translate.c b/target-i386/translate.c index 6550c27798..065a9d320e 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8255,6 +8255,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; DisasContext dc1, *dc = &dc1; target_ulong pc_ptr; @@ -8281,7 +8282,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, dc->cpl = (flags >> HF_CPL_SHIFT) & 3; dc->iopl = (flags >> IOPL_SHIFT) & 3; dc->tf = (flags >> TF_SHIFT) & 1; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->cc_op = CC_OP_DYNAMIC; dc->cc_op_dirty = false; dc->cs_base = cs_base; @@ -8302,7 +8303,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, dc->code64 = (flags >> HF_CS64_SHIFT) & 1; #endif dc->flags = flags; - dc->jmp_opt = !(dc->tf || env->singlestep_enabled || + dc->jmp_opt = !(dc->tf || cs->singlestep_enabled || (flags & HF_INHIBIT_IRQ_MASK) #ifndef CONFIG_SOFTMMU || (flags & HF_SOFTMMU_MASK) diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h index e3bb619dc3..9e2732919d 100644 --- a/target-lm32/cpu-qom.h +++ b/target-lm32/cpu-qom.h @@ -78,5 +78,6 @@ extern const struct VMStateDescription vmstate_lm32_cpu; void lm32_cpu_do_interrupt(CPUState *cpu); void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 04327acc05..ce55e4807d 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -22,6 +22,13 @@ #include "qemu-common.h" +static void lm32_cpu_set_pc(CPUState *cs, vaddr value) +{ + LM32CPU *cpu = LM32_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void lm32_cpu_reset(CPUState *s) { @@ -79,7 +86,11 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = lm32_cpu_do_interrupt; cc->dump_state = lm32_cpu_dump_state; - cpu_class_set_vmsd(cc, &vmstate_lm32_cpu); + cc->set_pc = lm32_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_lm32_cpu; +#endif } static const TypeInfo lm32_cpu_type_info = { diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 856bdc745c..dbfe043551 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -232,9 +232,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPULM32State *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif diff --git a/target-lm32/helper.c b/target-lm32/helper.c index 615b44e5be..15bc61554d 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -37,10 +37,12 @@ int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, return 0; } -hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr) +hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + LM32CPU *cpu = LM32_CPU(cs); + addr &= TARGET_PAGE_MASK; - if (env->flags & LM32_FLAG_IGNORE_MSB) { + if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) { return addr & 0x7fffffff; } else { return addr; diff --git a/target-lm32/translate.c b/target-lm32/translate.c index ed12f50740..1247287050 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1015,6 +1015,7 @@ static inline void gen_intermediate_code_internal(LM32CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPULM32State *env = &cpu->env; struct DisasContext ctx, *dc = &ctx; uint16_t *gen_opc_end; @@ -1032,7 +1033,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->nr_nops = 0; if (pc_start & 3) { @@ -1077,7 +1078,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu, } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end - && !env->singlestep_enabled + && !cs->singlestep_enabled && !singlestep && (dc->pc < next_page_start) && num_insns < max_insns); @@ -1086,7 +1087,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu, gen_io_end(); } - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(cpu_pc, dc->pc); } diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h index 858bf30088..7115707e91 100644 --- a/target-m68k/cpu-qom.h +++ b/target-m68k/cpu-qom.h @@ -73,5 +73,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env) void m68k_cpu_do_interrupt(CPUState *cpu); void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 1b6ef664f5..988f476257 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -23,6 +23,13 @@ #include "migration/vmstate.h" +static void m68k_cpu_set_pc(CPUState *cs, vaddr value) +{ + M68kCPU *cpu = M68K_CPU(cs); + + cpu->env.pc = value; +} + static void m68k_set_feature(CPUM68KState *env, int feature) { env->features |= (1u << feature); @@ -182,6 +189,10 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->class_by_name = m68k_cpu_class_by_name; cc->do_interrupt = m68k_cpu_do_interrupt; cc->dump_state = m68k_cpu_dump_state; + cc->set_pc = m68k_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_m68k_cpu; } diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 9fdf89ef91..cfd6846347 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -260,9 +260,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 54fa419ace..00a7a08e83 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -121,10 +121,11 @@ M68kCPU *cpu_m68k_init(const char *cpu_model) void m68k_cpu_init_gdb(M68kCPU *cpu) { + CPUState *cs = CPU(cpu); CPUM68KState *env = &cpu->env; if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { - gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg, + gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg, 11, "cf-fp.xml", 18); } /* TODO: Add [E]MAC registers. */ @@ -290,7 +291,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, /* MMU */ /* TODO: This will need fixing once the MMU is implemented. */ -hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr) +hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { return addr; } diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c index 239fadbad5..94c4983813 100644 --- a/target-m68k/m68k-semi.c +++ b/target-m68k/m68k-semi.c @@ -161,8 +161,11 @@ static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, uint32_t err) static int m68k_semi_is_fseek; -static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) +static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + if (m68k_semi_is_fseek) { /* FIXME: We've already lost the high bits of the fseek return value. */ diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 2d73af50c3..d562eebef3 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -2974,6 +2974,7 @@ static inline void gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUM68KState *env = &cpu->env; DisasContext dc1, *dc = &dc1; uint16_t *gen_opc_end; @@ -2995,7 +2996,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; dc->cc_op = CC_OP_DYNAMIC; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->fpcr = env->fpcr; dc->user = (env->sr & SR_S) == 0; dc->is_mem = 0; @@ -3038,14 +3039,14 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, disas_m68k_insn(env, dc); num_insns++; } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !cs->singlestep_enabled && !singlestep && (pc_offset) < (TARGET_PAGE_SIZE - 32) && num_insns < max_insns); if (tb->cflags & CF_LAST_IO) gen_io_end(); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (!dc->is_jmp) { gen_flush_cc_op(dc); diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h index ec2b989a23..1318a36676 100644 --- a/target-microblaze/cpu-qom.h +++ b/target-microblaze/cpu-qom.h @@ -74,5 +74,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env) void mb_cpu_do_interrupt(CPUState *cs); void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index dce1c7ea67..9f10c8c778 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -26,6 +26,13 @@ #include "migration/vmstate.h" +static void mb_cpu_set_pc(CPUState *cs, vaddr value) +{ + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + + cpu->env.sregs[SR_PC] = value; +} + /* CPUClass::reset() */ static void mb_cpu_reset(CPUState *s) { @@ -133,7 +140,11 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = mb_cpu_do_interrupt; cc->dump_state = mb_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access); + cc->set_pc = mb_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = mb_cpu_unassigned_access; + cc->get_phys_page_debug = mb_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_mb_cpu; dc->props = mb_properties; } diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 6c35475fd6..7508cf5a06 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -365,9 +365,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUMBState *env, TranslationBlock *tb) -{ - env->sregs[SR_PC] = tb->pc; -} - #endif diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index c6c96d4488..4fa9ce9cb5 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -265,8 +265,10 @@ void mb_cpu_do_interrupt(CPUState *cs) } } -hwaddr cpu_get_phys_page_debug(CPUMBState * env, target_ulong addr) +hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUMBState *env = &cpu->env; target_ulong vaddr, paddr = 0; struct microblaze_mmu_lookup lu; unsigned int hit; diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index eba255b7c6..cd4357703f 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1741,6 +1741,7 @@ static inline void gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUMBState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; @@ -1766,7 +1767,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, dc->jmp = JMP_INDIRECT; } dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->cpustate_changed = 0; dc->abort_at_next_insn = 0; dc->nr_nops = 0; @@ -1859,8 +1860,9 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, break; } } - if (env->singlestep_enabled) + if (cs->singlestep_enabled) { break; + } } while (!dc->is_jmp && !dc->cpustate_changed && tcg_ctx.gen_opc_ptr < gen_opc_end && !singlestep @@ -1887,7 +1889,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, } t_sync_flags(dc); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG); if (dc->is_jmp != DISAS_JUMP) { diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index 654744a45b..7c8e616392 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -77,5 +77,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env) void mips_cpu_do_interrupt(CPUState *cpu); void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 60a3faf2f8..4834c86d02 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -22,6 +22,29 @@ #include "qemu-common.h" +static void mips_cpu_set_pc(CPUState *cs, vaddr value) +{ + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + + env->active_tc.PC = value & ~(target_ulong)1; + if (value & 1) { + env->hflags |= MIPS_HFLAG_M16; + } else { + env->hflags &= ~(MIPS_HFLAG_M16); + } +} + +static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + + env->active_tc.PC = tb->pc; + env->hflags &= ~MIPS_HFLAG_BMASK; + env->hflags |= tb->flags & MIPS_HFLAG_BMASK; +} + /* CPUClass::reset() */ static void mips_cpu_reset(CPUState *s) { @@ -75,7 +98,12 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->do_interrupt = mips_cpu_do_interrupt; cc->dump_state = mips_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access); + cc->set_pc = mips_cpu_set_pc; + cc->synchronize_from_tb = mips_cpu_synchronize_from_tb; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = mips_cpu_unassigned_access; + cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; +#endif } static const TypeInfo mips_cpu_type_info = { diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 7ffd2e36bd..a29c82faf1 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -732,13 +732,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb) -{ - env->active_tc.PC = tb->pc; - env->hflags &= ~MIPS_HFLAG_BMASK; - env->hflags |= tb->flags & MIPS_HFLAG_BMASK; -} - static inline void compute_hflags(CPUMIPSState *env) { env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | diff --git a/target-mips/helper.c b/target-mips/helper.c index 6983b92a11..6feef7bcd6 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -254,13 +254,16 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, } #if !defined(CONFIG_USER_ONLY) -hwaddr cpu_get_phys_page_debug(CPUMIPSState *env, target_ulong addr) +hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + MIPSCPU *cpu = MIPS_CPU(cs); hwaddr phys_addr; int prot; - if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) + if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, + ACCESS_INT) != 0) { return -1; + } return phys_addr; } #endif diff --git a/target-mips/translate.c b/target-mips/translate.c index 8246c200a1..877f8dfe88 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -15543,6 +15543,7 @@ static inline void gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUMIPSState *env = &cpu->env; DisasContext ctx; target_ulong pc_start; @@ -15561,7 +15562,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.pc = pc_start; ctx.saved_pc = -1; - ctx.singlestep_enabled = env->singlestep_enabled; + ctx.singlestep_enabled = cs->singlestep_enabled; ctx.insn_flags = env->insn_flags; ctx.tb = tb; ctx.bstate = BS_NONE; @@ -15637,8 +15638,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, This is what GDB expects and is consistent with what the hardware does (e.g. if a delay slot instruction faults, the reported PC is the PC of the branch). */ - if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) + if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) { break; + } if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; @@ -15653,9 +15655,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, if (singlestep) break; } - if (tb->cflags & CF_LAST_IO) + if (tb->cflags & CF_LAST_IO) { gen_io_end(); - if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) { + } + if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) { save_cpu_state(&ctx, ctx.bstate == BS_NONE); gen_helper_0e0i(raise_exception, EXCP_DEBUG); } else { diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 92ca5946bf..6550be5b35 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -22,6 +22,13 @@ #include "migration/vmstate.h" #include "machine.h" +static void moxie_cpu_set_pc(CPUState *cs, vaddr value) +{ + MoxieCPU *cpu = MOXIE_CPU(cs); + + cpu->env.pc = value; +} + static void moxie_cpu_reset(CPUState *s) { MoxieCPU *cpu = MOXIE_CPU(s); @@ -93,7 +100,11 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = moxie_cpu_do_interrupt; cc->dump_state = moxie_cpu_dump_state; - cpu_class_set_vmsd(cc, &vmstate_moxie_cpu); + cc->set_pc = moxie_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug; + cc->vmsd = &vmstate_moxie_cpu; +#endif } static void moxielite_initfn(Object *obj) diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h index 72d02c20c1..5ce14b5fd3 100644 --- a/target-moxie/cpu.h +++ b/target-moxie/cpu.h @@ -118,6 +118,7 @@ int cpu_moxie_exec(CPUMoxieState *s); void moxie_cpu_do_interrupt(CPUState *cs); void moxie_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); void moxie_translate_init(void); int cpu_moxie_signal_handler(int host_signum, void *pinfo, void *puc); @@ -143,11 +144,6 @@ static inline int cpu_mmu_index(CPUMoxieState *env) #include "exec/cpu-all.h" #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUMoxieState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { diff --git a/target-moxie/helper.c b/target-moxie/helper.c index ea0788fcea..b12e4ffcaf 100644 --- a/target-moxie/helper.c +++ b/target-moxie/helper.c @@ -118,11 +118,6 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, return 1; } -hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr) -{ - return addr; -} - #else /* !CONFIG_USER_ONLY */ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, @@ -162,12 +157,14 @@ void moxie_cpu_do_interrupt(CPUState *cs) } } -hwaddr cpu_get_phys_page_debug(CPUMoxieState *env, target_ulong addr) +hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + MoxieCPU *cpu = MOXIE_CPU(cs); uint32_t phy = addr; MoxieMMUResult res; int miss; - miss = moxie_mmu_translate(&res, env, addr, 0, 0); + + miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0); if (!miss) { phy = res.phy; } diff --git a/target-moxie/translate.c b/target-moxie/translate.c index 664d359438..8cc0bb7bfb 100644 --- a/target-moxie/translate.c +++ b/target-moxie/translate.c @@ -824,6 +824,7 @@ static inline void gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); DisasContext ctx; target_ulong pc_start; uint16_t *gen_opc_end; @@ -871,7 +872,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, ctx.pc += decode_opc(cpu, &ctx); num_insns++; - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { break; } @@ -880,7 +881,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, } } while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end); - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { tcg_gen_movi_tl(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); } else { diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 6d40f1b85e..3da5a7a8b1 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -20,6 +20,13 @@ #include "cpu.h" #include "qemu-common.h" +static void openrisc_cpu_set_pc(CPUState *cs, vaddr value) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void openrisc_cpu_reset(CPUState *s) { @@ -146,7 +153,11 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = openrisc_cpu_class_by_name; cc->do_interrupt = openrisc_cpu_do_interrupt; cc->dump_state = openrisc_cpu_dump_state; - device_class_set_vmsd(dc, &vmstate_openrisc_cpu); + cc->set_pc = openrisc_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug; + dc->vmsd = &vmstate_openrisc_cpu; +#endif } static void cpu_register(const OpenRISCCPUInfo *info) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 0aff8f20c7..3ddb7674c7 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -349,6 +349,7 @@ int cpu_openrisc_exec(CPUOpenRISCState *s); void openrisc_cpu_do_interrupt(CPUState *cpu); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); void openrisc_translate_init(void); int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address, @@ -428,9 +429,4 @@ static inline target_ulong cpu_get_pc(CPUOpenRISCState *env) return env->pc; } -static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif /* CPU_OPENRISC_H */ diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index d354e1f8b2..57f5616e9c 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -219,12 +219,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, #endif #ifndef CONFIG_USER_ONLY -hwaddr cpu_get_phys_page_debug(CPUOpenRISCState *env, - target_ulong addr) +hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); hwaddr phys_addr; int prot; - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) { return -1; diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index f222834fc3..a6050ba6d8 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -1662,6 +1662,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, TranslationBlock *tb, int search_pc) { + CPUState *cs = CPU(cpu); struct DisasContext ctx, *dc = &ctx; uint16_t *gen_opc_end; uint32_t pc_start; @@ -1681,7 +1682,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, dc->mem_idx = cpu_mmu_index(&cpu->env); dc->synced_flags = dc->tb_flags = tb->flags; dc->delayed_branch = !!(dc->tb_flags & D_FLAG); - dc->singlestep_enabled = cpu->env.singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("-----------------------------------------\n"); log_cpu_state(CPU(cpu), 0); @@ -1743,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, } } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end - && !cpu->env.singlestep_enabled + && !cs->singlestep_enabled && !singlestep && (dc->pc < next_page_start) && num_insns < max_insns); @@ -1755,7 +1756,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu, dc->is_jmp = DISAS_UPDATE; tcg_gen_movi_tl(cpu_pc, dc->pc); } - if (unlikely(cpu->env.singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(cpu_pc, dc->pc); } diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 7132599516..3341c5151d 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -105,5 +105,6 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 7a7b1bf35a..6f51e1f526 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2144,11 +2144,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb) -{ - env->nip = tb->pc; -} - void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env); #endif /* !defined (__CPU_PPC_H__) */ diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 77102c4b65..5dd4e05f78 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -1409,8 +1409,10 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, return ret; } -hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr) +hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; mmu_ctx_t ctx; switch (env->mmu_model) { diff --git a/target-ppc/translate.c b/target-ppc/translate.c index eb96272b0e..f07d70d866 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -9730,6 +9730,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; opc_handler_t **table, *handler; @@ -9770,8 +9771,9 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, ctx.singlestep_enabled = 0; if ((env->flags & POWERPC_FLAG_BE) && msr_be) ctx.singlestep_enabled |= CPU_BRANCH_STEP; - if (unlikely(env->singlestep_enabled)) + if (unlikely(cs->singlestep_enabled)) { ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP; + } #if defined (DO_SINGLE_STEP) && 0 /* Single step trace mode */ msr_se = 1; @@ -9873,7 +9875,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, ctx.exception != POWERPC_EXCP_BRANCH)) { gen_exception(ctxp, POWERPC_EXCP_TRACE); } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || - (env->singlestep_enabled) || + (cs->singlestep_enabled) || singlestep || num_insns >= max_insns)) { /* if we reach a page boundary or are single stepping, stop @@ -9887,7 +9889,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, if (ctx.exception == POWERPC_EXCP_NONE) { gen_goto_tb(&ctx, 0, ctx.nip); } else if (ctx.exception != POWERPC_EXCP_BRANCH) { - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { gen_debug_exception(ctxp); } /* Generate the return instruction */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 79bfcd8df9..0b0844f467 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7804,8 +7804,8 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu) static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) { + CPUState *cs = CPU(dev); PowerPCCPU *cpu = POWERPC_CPU(dev); - CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); Error *local_err = NULL; #if !defined(CONFIG_USER_ONLY) @@ -7849,15 +7849,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) init_ppc_proc(cpu); if (pcc->insns_flags & PPC_FLOAT) { - gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg, + gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, 33, "power-fpu.xml", 0); } if (pcc->insns_flags & PPC_ALTIVEC) { - gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg, + gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, 34, "power-altivec.xml", 0); } if (pcc->insns_flags & PPC_SPE) { - gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg, + gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, 34, "power-spe.xml", 0); } @@ -7865,6 +7865,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) #if defined(PPC_DUMP_CPU) { + CPUPPCState *env = &cpu->env; const char *mmu_model, *excp_model, *bus_model; switch (env->mmu_model) { case POWERPC_MMU_32B: @@ -8016,10 +8017,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) printf(" none\n"); printf(" Time-base/decrementer clock source: %s\n", env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock"); + dump_ppc_insns(env); + dump_ppc_sprs(env); + fflush(stdout); } - dump_ppc_insns(env); - dump_ppc_sprs(env); - fflush(stdout); #endif } @@ -8322,6 +8323,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) return cpu_list; } +static void ppc_cpu_set_pc(CPUState *cs, vaddr value) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + cpu->env.nip = value; +} + /* CPUClass::reset() */ static void ppc_cpu_reset(CPUState *s) { @@ -8449,6 +8457,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = ppc_cpu_do_interrupt; cc->dump_state = ppc_cpu_dump_state; cc->dump_statistics = ppc_cpu_dump_statistics; + cc->set_pc = ppc_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; +#endif } static const TypeInfo ppc_cpu_type_info = { diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h index 4c091e3ea0..a4fe8fb5fc 100644 --- a/target-s390x/cpu-qom.h +++ b/target-s390x/cpu-qom.h @@ -74,5 +74,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env) void s390_cpu_do_interrupt(CPUState *cpu); void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 1ef2fc0e86..cb89d1a46b 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -58,6 +58,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) } #endif +static void s390_cpu_set_pc(CPUState *cs, vaddr value) +{ + S390CPU *cpu = S390_CPU(cs); + + cpu->env.psw.addr = value; +} + /* CPUClass::reset() */ static void s390_cpu_reset(CPUState *s) { @@ -165,6 +172,10 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = s390_cpu_do_interrupt; cc->dump_state = s390_cpu_dump_state; + cc->set_pc = s390_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = s390_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_s390_cpu; } diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 646268858b..65bef8625f 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -1041,11 +1041,6 @@ static inline bool cpu_has_work(CPUState *cpu) (env->psw.mask & PSW_MASK_EXT); } -static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb) -{ - env->psw.addr = tb->pc; -} - /* fpu_helper.c */ uint32_t set_cc_nz_f32(float32 v); uint32_t set_cc_nz_f64(float64 v); diff --git a/target-s390x/helper.c b/target-s390x/helper.c index b425054be8..61abfd7d9e 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -417,9 +417,10 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr, return 0; } -hwaddr cpu_get_phys_page_debug(CPUS390XState *env, - target_ulong vaddr) +hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; target_ulong raddr; int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; int old_exc = env->exception_index; diff --git a/target-s390x/translate.c b/target-s390x/translate.c index cba7b87527..1fb76c5264 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -4740,6 +4740,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUS390XState *env = &cpu->env; DisasContext dc; target_ulong pc_start; @@ -4761,7 +4762,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu, dc.tb = tb; dc.pc = pc_start; dc.cc_op = CC_OP_DYNAMIC; - do_debug = dc.singlestep_enabled = env->singlestep_enabled; + do_debug = dc.singlestep_enabled = cs->singlestep_enabled; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; @@ -4818,7 +4819,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu, || tcg_ctx.gen_opc_ptr >= gen_opc_end || num_insns >= max_insns || singlestep - || env->singlestep_enabled)) { + || cs->singlestep_enabled)) { status = EXIT_PC_STALE; } } while (status == NO_EXIT); diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index c229a9a29b..7c9160bab8 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -86,5 +86,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env) void superh_cpu_do_interrupt(CPUState *cpu); void superh_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 03487eb32e..51a77576fb 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -24,6 +24,21 @@ #include "migration/vmstate.h" +static void superh_cpu_set_pc(CPUState *cs, vaddr value) +{ + SuperHCPU *cpu = SUPERH_CPU(cs); + + cpu->env.pc = value; +} + +static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + SuperHCPU *cpu = SUPERH_CPU(cs); + + cpu->env.pc = tb->pc; + cpu->env.flags = tb->flags; +} + /* CPUClass::reset() */ static void superh_cpu_reset(CPUState *s) { @@ -269,6 +284,11 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = superh_cpu_class_by_name; cc->do_interrupt = superh_cpu_do_interrupt; cc->dump_state = superh_cpu_dump_state; + cc->set_pc = superh_cpu_set_pc; + cc->synchronize_from_tb = superh_cpu_synchronize_from_tb; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = superh_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_sh_cpu; } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index c8df18bab1..276d2955c3 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -359,10 +359,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUSH4State *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->flags = tb->flags; -} - #endif /* _CPU_SH4_H */ diff --git a/target-sh4/helper.c b/target-sh4/helper.c index cb6a2d28bd..9ac28250e0 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -508,12 +508,13 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, return 0; } -hwaddr cpu_get_phys_page_debug(CPUSH4State * env, target_ulong addr) +hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + SuperHCPU *cpu = SUPERH_CPU(cs); target_ulong physical; int prot; - get_physical_address(env, &physical, &prot, addr, 0, 0); + get_physical_address(&cpu->env, &physical, &prot, addr, 0, 0); return physical; } diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 2fbe6685b0..59f3d47023 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -1849,6 +1849,7 @@ static inline void gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUSH4State *env = &cpu->env; DisasContext ctx; target_ulong pc_start; @@ -1868,7 +1869,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, so assume it is a dynamic branch. */ ctx.delayed_pc = -1; /* use delayed pc from env pointer */ ctx.tb = tb; - ctx.singlestep_enabled = env->singlestep_enabled; + ctx.singlestep_enabled = cs->singlestep_enabled; ctx.features = env->features; ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA); @@ -1914,8 +1915,9 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, ctx.pc += 2; if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; - if (env->singlestep_enabled) + if (cs->singlestep_enabled) { break; + } if (num_insns >= max_insns) break; if (singlestep) @@ -1923,7 +1925,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, } if (tb->cflags & CF_LAST_IO) gen_io_end(); - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); } else { diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h index 033a5b5219..39d975b5fc 100644 --- a/target-sparc/cpu-qom.h +++ b/target-sparc/cpu-qom.h @@ -78,5 +78,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env) void sparc_cpu_do_interrupt(CPUState *cpu); void sparc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 87c3a50c00..d1d03396ef 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -723,6 +723,22 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "\n"); } +static void sparc_cpu_set_pc(CPUState *cs, vaddr value) +{ + SPARCCPU *cpu = SPARC_CPU(cs); + + cpu->env.pc = value; + cpu->env.npc = value + 4; +} + +static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ + SPARCCPU *cpu = SPARC_CPU(cs); + + cpu->env.pc = tb->pc; + cpu->env.npc = tb->cs_base; +} + static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) { SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); @@ -766,7 +782,15 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = sparc_cpu_do_interrupt; cc->dump_state = sparc_cpu_dump_state; - cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access); +#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) + cc->memory_rw_debug = sparc_cpu_memory_rw_debug; +#endif + cc->set_pc = sparc_cpu_set_pc; + cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; +#ifndef CONFIG_USER_ONLY + cc->do_unassigned_access = sparc_cpu_unassigned_access; + cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; +#endif } static const TypeInfo sparc_cpu_type_info = { diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 41b014a0b3..41194ec06b 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -526,9 +526,8 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env); #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) -int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, - uint8_t *buf, int len, int is_write); -#define TARGET_CPU_MEMORY_RW_DEBUG +int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, + uint8_t *buf, int len, bool is_write); #endif @@ -759,10 +758,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUSPARCState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->npc = tb->cs_base; -} - #endif diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index 740cbe8f2c..ef12a0a8d0 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -310,6 +310,7 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev) void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) { + CPUState *cs = CPU(sparc_env_get_cpu(env)); target_ulong va, va1, va2; unsigned int n, m, o; hwaddr pde_ptr, pa; @@ -322,20 +323,20 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { pde = mmu_probe(env, va, 2); if (pde) { - pa = cpu_get_phys_page_debug(env, va); + pa = cpu_get_phys_page_debug(cs, va); (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n", va, pa, pde); for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { pde = mmu_probe(env, va1, 1); if (pde) { - pa = cpu_get_phys_page_debug(env, va1); + pa = cpu_get_phys_page_debug(cs, va1); (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde); for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { pde = mmu_probe(env, va2, 0); if (pde) { - pa = cpu_get_phys_page_debug(env, va2); + pa = cpu_get_phys_page_debug(cs, va2); (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n", @@ -352,9 +353,12 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) * reads (and only reads) in stack frames as if windows were flushed. We assume * that the sparc ABI is followed. */ -int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, - uint8_t *buf, int len, int is_write) +int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address, + uint8_t *buf, int len, bool is_write) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; + target_ulong addr = address; int i; int len1; int cwp = env->cwp; @@ -389,7 +393,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, /* Handle access before this window. */ if (addr < fp) { len1 = fp - addr; - if (cpu_memory_rw_debug(env, addr, buf, len1, is_write) != 0) { + if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) { return -1; } addr += len1; @@ -425,7 +429,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, } } } - return cpu_memory_rw_debug(env, addr, buf, len, is_write); + return cpu_memory_rw_debug(cs, addr, buf, len, is_write); } #else /* !TARGET_SPARC64 */ @@ -833,8 +837,10 @@ hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr, } #endif -hwaddr cpu_get_phys_page_debug(CPUSPARCState *env, target_ulong addr) +hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; hwaddr phys_addr; int mmu_idx = cpu_mmu_index(env); MemoryRegionSection section; diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 5e771e5da7..093e0e2c78 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -5223,6 +5223,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, TranslationBlock *tb, bool spc) { + CPUState *cs = CPU(cpu); CPUSPARCState *env = &cpu->env; target_ulong pc_start, last_pc; uint16_t *gen_opc_end; @@ -5244,7 +5245,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, dc->def = env->def; dc->fpu_enabled = tb_fpu_enabled(tb->flags); dc->address_mask_32bit = tb_am_enabled(tb->flags); - dc->singlestep = (env->singlestep_enabled || singlestep); + dc->singlestep = (cs->singlestep_enabled || singlestep); gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; num_insns = 0; diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h index 350d48034c..f727760d9e 100644 --- a/target-unicore32/cpu-qom.h +++ b/target-unicore32/cpu-qom.h @@ -63,5 +63,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env) void uc32_cpu_do_interrupt(CPUState *cpu); void uc32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 6572f0199b..46813e52ae 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -16,6 +16,13 @@ #include "qemu-common.h" #include "migration/vmstate.h" +static void uc32_cpu_set_pc(CPUState *cs, vaddr value) +{ + UniCore32CPU *cpu = UNICORE32_CPU(cs); + + cpu->env.regs[31] = value; +} + static inline void set_feature(CPUUniCore32State *env, int feature) { env->features |= feature; @@ -131,6 +138,10 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = uc32_cpu_class_by_name; cc->do_interrupt = uc32_cpu_do_interrupt; cc->dump_state = uc32_cpu_dump_state; + cc->set_pc = uc32_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_uc32_cpu; } diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index d4be5252f3..967511e3f6 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -146,11 +146,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env) #include "cpu-qom.h" #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock *tb) -{ - env->regs[31] = tb->pc; -} - static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc, target_ulong *cs_base, int *flags) { diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c index eadaeb11ab..1e13a85d05 100644 --- a/target-unicore32/softmmu.c +++ b/target-unicore32/softmmu.c @@ -261,9 +261,10 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address, return ret; } -hwaddr cpu_get_phys_page_debug(CPUUniCore32State *env, - target_ulong addr) +hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { - cpu_abort(env, "%s not supported yet\n", __func__); + UniCore32CPU *cpu = UNICORE32_CPU(cs); + + cpu_abort(&cpu->env, "%s not supported yet\n", __func__); return addr; } diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index d85185df36..68be1c64e0 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -1879,6 +1879,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUUniCore32State *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; @@ -1900,7 +1901,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->condjmp = 0; cpu_F0s = tcg_temp_new_i32(); cpu_F1s = tcg_temp_new_i32(); @@ -1971,7 +1972,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, * ensures prefetch aborts occur at the right place. */ num_insns++; } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && - !env->singlestep_enabled && + !cs->singlestep_enabled && !singlestep && dc->pc < next_page_start && num_insns < max_insns); @@ -1988,7 +1989,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, /* At this stage dc->condjmp will only be set when the skipped instruction was a conditional branch or trap, and the PC has already been written. */ - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (dc->condjmp) { if (dc->is_jmp == DISAS_SYSCALL) { diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index 31e7498181..b9896f2647 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -83,5 +83,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env) void xtensa_cpu_do_interrupt(CPUState *cpu); void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); +hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #endif diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 0488984d4a..d2bcfc69a2 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -33,6 +33,13 @@ #include "migration/vmstate.h" +static void xtensa_cpu_set_pc(CPUState *cs, vaddr value) +{ + XtensaCPU *cpu = XTENSA_CPU(cs); + + cpu->env.pc = value; +} + /* CPUClass::reset() */ static void xtensa_cpu_reset(CPUState *s) { @@ -100,6 +107,10 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = xtensa_cpu_do_interrupt; cc->dump_state = xtensa_cpu_dump_state; + cc->set_pc = xtensa_cpu_set_pc; +#ifndef CONFIG_USER_ONLY + cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug; +#endif dc->vmsd = &vmstate_xtensa_cpu; } diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 6c9fc35dcc..a8f02f6e4b 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -522,9 +522,4 @@ static inline int cpu_has_work(CPUState *cpu) return env->pending_irq_level; } -static inline void cpu_pc_from_tb(CPUXtensaState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - #endif diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 6f613c66a6..de6cc3b7c5 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -108,17 +108,18 @@ void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf) } } -hwaddr cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong addr) +hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { + XtensaCPU *cpu = XTENSA_CPU(cs); uint32_t paddr; uint32_t page_size; unsigned access; - if (xtensa_get_physical_addr(env, false, addr, 0, 0, + if (xtensa_get_physical_addr(&cpu->env, false, addr, 0, 0, &paddr, &page_size, &access) == 0) { return paddr; } - if (xtensa_get_physical_addr(env, false, addr, 2, 0, + if (xtensa_get_physical_addr(&cpu->env, false, addr, 2, 0, &paddr, &page_size, &access) == 0) { return paddr; } diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index e4cf828630..e692329157 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -2879,6 +2879,7 @@ static inline void gen_intermediate_code_internal(XtensaCPU *cpu, TranslationBlock *tb, bool search_pc) { + CPUState *cs = CPU(cpu); CPUXtensaState *env = &cpu->env; DisasContext dc; int insn_count = 0; @@ -2894,7 +2895,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, } dc.config = env->config; - dc.singlestep_enabled = env->singlestep_enabled; + dc.singlestep_enabled = cs->singlestep_enabled; dc.tb = tb; dc.pc = pc_start; dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK; @@ -2917,7 +2918,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, gen_tb_start(); - if (env->singlestep_enabled && env->exception_taken) { + if (cs->singlestep_enabled && env->exception_taken) { env->exception_taken = 0; tcg_gen_movi_i32(cpu_pc, dc.pc); gen_exception(&dc, EXCP_DEBUG); @@ -2970,7 +2971,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, if (dc.icount) { tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount); } - if (env->singlestep_enabled) { + if (cs->singlestep_enabled) { tcg_gen_movi_i32(cpu_pc, dc.pc); gen_exception(&dc, EXCP_DEBUG); break; diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c index 5fe0361c02..424253d1f3 100644 --- a/target-xtensa/xtensa-semi.c +++ b/target-xtensa/xtensa-semi.c @@ -152,6 +152,7 @@ static uint32_t errno_h2g(int host_errno) void HELPER(simcall)(CPUXtensaState *env) { + CPUState *cs = CPU(xtensa_env_get_cpu(env)); uint32_t *regs = env->regs; switch (regs[2]) { @@ -169,8 +170,7 @@ void HELPER(simcall)(CPUXtensaState *env) uint32_t len = regs[5]; while (len > 0) { - hwaddr paddr = - cpu_get_phys_page_debug(env, vaddr); + hwaddr paddr = cpu_get_phys_page_debug(cs, vaddr); uint32_t page_left = TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1)); uint32_t io_sz = page_left < len ? page_left : len; @@ -204,8 +204,8 @@ void HELPER(simcall)(CPUXtensaState *env) int i; for (i = 0; i < ARRAY_SIZE(name); ++i) { - rc = cpu_memory_rw_debug( - env, regs[3] + i, (uint8_t *)name + i, 1, 0); + rc = cpu_memory_rw_debug(cs, regs[3] + i, + (uint8_t *)name + i, 1, 0); if (rc != 0 || name[i] == 0) { break; } @@ -249,7 +249,7 @@ void HELPER(simcall)(CPUXtensaState *env) FD_SET(fd, &fdset); if (target_tv) { - cpu_memory_rw_debug(env, target_tv, + cpu_memory_rw_debug(cs, target_tv, (uint8_t *)target_tvv, sizeof(target_tvv), 0); tv.tv_sec = (int32_t)tswap32(target_tvv[0]); tv.tv_usec = (int32_t)tswap32(target_tvv[1]); @@ -284,8 +284,8 @@ void HELPER(simcall)(CPUXtensaState *env) }; argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text)); - cpu_memory_rw_debug( - env, regs[3], (uint8_t *)&argv, sizeof(argv), 1); + cpu_memory_rw_debug(cs, + regs[3], (uint8_t *)&argv, sizeof(argv), 1); } break; |