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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iQIcBAABAgAGBQJR7dNJAAoJEPou0S0+fgE/R8IQAKByM7NGK9JCbMuuZgLzbtib
 J1t6cpdn6ghD/qTNUoC6TuCLB0XHlFenfHtLSC9uqMXZPX1i6UZIo2yRA69X2IEu
 NjUU6LdoduEYL0jBkZeBSvx1SgMVwiabR6kvQorpEzmJWXQdRav8aNCQuGEgvIcb
 sv8kA6Jwh0+S4HJm3gGMs/wBSSeVpP3SUB14RiZESIFQpOovP+i1Qs8qTtclYf4j
 P3qxwoUCJy0S9ayQ6bGJKTbVkY4oCgZHQzDJ09rRT3KM0SMto/cfmlks2zynbeak
 6RXa7iJ8UO4AyxcL37Va5QfVx+EKeu6TpMPxEEFqqgoxac9p4QPspvMmCv6XM4Ul
 TGldagWXHnyN9R5p/w6xMWoKizBE2AUPZh/N8CHI0zAvmaz0pfsiOotVEfs5lbi6
 B5At9lgikagLV43Usi090xOIa3sVL5N+lqxm8PB6UlWbdpFPSBU6Vgx9UBbQniAd
 eB0SP5BUaqM5pkoCHXprrOyCLs3rkEflS1/o1jd+LxH1czQXruns1bEKal/PW22m
 a4TmDQd4X0IvgcziJzo5TuwR4cqQWc5REr2M+EnyMsb0oT5bdCoDZc9oSz+uOW3I
 Qs5hMjs2mG1192heO6HF5YwFzv5RT2POXLtjM+eW72zN4uMrOiIsXU+neQUyWb20
 4+RywuU7mCFOX70UisL9
 =AkgR
 -----END PGP SIGNATURE-----

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()
  ...
This commit is contained in:
Anthony Liguori 2013-07-23 10:57:04 -05:00
commit 3988982c82
104 changed files with 783 additions and 550 deletions

19
HACKING
View file

@ -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 it would not be correct to store an actual guest physical address in a
ram_addr_t. ram_addr_t.
Use target_ulong (or abi_ulong) for CPU virtual addresses, however For CPU virtual addresses there are several possible types.
devices should not need to use target_ulong. 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 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 to use some system interface that requires a type like size_t, pid_t or

View file

@ -643,7 +643,7 @@ void cpu_loop(CPUSPARCState *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
#if 0 #if 0
if (sig) if (sig)
{ {
@ -738,6 +738,7 @@ int main(int argc, char **argv)
struct image_info info1, *info = &info1; struct image_info info1, *info = &info1;
TaskState ts1, *ts = &ts1; TaskState ts1, *ts = &ts1;
CPUArchState *env; CPUArchState *env;
CPUState *cpu;
int optind; int optind;
const char *r; const char *r;
int gdbstub_port = 0; int gdbstub_port = 0;
@ -912,10 +913,11 @@ int main(int argc, char **argv)
fprintf(stderr, "Unable to find CPU definition\n"); fprintf(stderr, "Unable to find CPU definition\n");
exit(1); exit(1);
} }
cpu = ENV_GET_CPU(env);
#if defined(TARGET_SPARC) || defined(TARGET_PPC) #if defined(TARGET_SPARC) || defined(TARGET_PPC)
cpu_reset(ENV_GET_CPU(env)); cpu_reset(cpu);
#endif #endif
thread_cpu = ENV_GET_CPU(env); thread_cpu = cpu;
if (getenv("QEMU_STRACE")) { if (getenv("QEMU_STRACE")) {
do_strace = 1; do_strace = 1;
@ -1134,7 +1136,7 @@ int main(int argc, char **argv)
if (gdbstub_port) { if (gdbstub_port) {
gdbserver_start (gdbstub_port); gdbserver_start (gdbstub_port);
gdb_handlesig(env, 0); gdb_handlesig(cpu, 0);
} }
cpu_loop(env); cpu_loop(env);
/* never exits */ /* never exits */

View file

@ -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 * counter hit zero); we must restore the guest PC to the address
* of the start of the TB. * of the start of the TB.
*/ */
CPUClass *cc = CPU_GET_CLASS(cpu);
TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); 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) { if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
/* We were asked to stop executing TBs (probably a pending /* We were asked to stop executing TBs (probably a pending
@ -291,7 +297,7 @@ int cpu_exec(CPUArchState *env)
for(;;) { for(;;) {
interrupt_request = cpu->interrupt_request; interrupt_request = cpu->interrupt_request;
if (unlikely(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. */ /* Mask out external interrupts for this step. */
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
} }

6
cpus.c
View file

@ -1186,7 +1186,7 @@ static void tcg_exec_all(void)
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
qemu_clock_enable(vm_clock, qemu_clock_enable(vm_clock,
(env->singlestep_enabled & SSTEP_NOTIMER) == 0); (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
if (cpu_can_run(cpu)) { if (cpu_can_run(cpu)) {
r = tcg_cpu_exec(env); r = tcg_cpu_exec(env);
@ -1285,7 +1285,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
{ {
FILE *f; FILE *f;
uint32_t l; uint32_t l;
CPUArchState *env;
CPUState *cpu; CPUState *cpu;
uint8_t buf[1024]; uint8_t buf[1024];
@ -1299,7 +1298,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
"a CPU number"); "a CPU number");
return; return;
} }
env = cpu->env_ptr;
f = fopen(filename, "wb"); f = fopen(filename, "wb");
if (!f) { if (!f) {
@ -1311,7 +1309,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
l = sizeof(buf); l = sizeof(buf);
if (l > size) if (l > size)
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) { if (fwrite(buf, 1, l, f) != l) {
error_set(errp, QERR_IO_ERROR); error_set(errp, QERR_IO_ERROR);
goto exit; goto exit;

View file

@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr,
{ {
CPUDebug *s = container_of(info, CPUDebug, info); 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; return 0;
} }
@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
if (monitor_disas_is_physical) { if (monitor_disas_is_physical) {
cpu_physical_memory_read(memaddr, myaddr, length); cpu_physical_memory_read(memaddr, myaddr, length);
} else { } 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; return 0;
} }

36
exec.c
View file

@ -415,14 +415,14 @@ void cpu_exec_init(CPUArchState *env)
#if defined(TARGET_HAS_ICE) #if defined(TARGET_HAS_ICE)
#if defined(CONFIG_USER_ONLY) #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); tb_invalidate_phys_page_range(pc, pc + 1, 0);
} }
#else #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)); (pc & ~TARGET_PAGE_MASK));
} }
#endif #endif
@ -525,15 +525,17 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
bp->flags = flags; bp->flags = flags;
/* keep all GDB-injected breakpoints in front */ /* keep all GDB-injected breakpoints in front */
if (flags & BP_GDB) if (flags & BP_GDB) {
QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry); QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
else } else {
QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry); QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
}
breakpoint_invalidate(env, pc); breakpoint_invalidate(ENV_GET_CPU(env), pc);
if (breakpoint) if (breakpoint) {
*breakpoint = bp; *breakpoint = bp;
}
return 0; return 0;
#else #else
return -ENOSYS; return -ENOSYS;
@ -564,7 +566,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
#if defined(TARGET_HAS_ICE) #if defined(TARGET_HAS_ICE)
QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry); QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
breakpoint_invalidate(env, breakpoint->pc); breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
g_free(breakpoint); g_free(breakpoint);
#endif #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 /* enable or disable single step mode. EXCP_DEBUG is returned by the
CPU loop after each instruction */ 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 defined(TARGET_HAS_ICE)
if (env->singlestep_enabled != enabled) { CPUArchState *env = cpu->env_ptr;
env->singlestep_enabled = enabled;
if (kvm_enabled()) if (cpu->singlestep_enabled != enabled) {
cpu->singlestep_enabled = enabled;
if (kvm_enabled()) {
kvm_update_guest_debug(env, 0); kvm_update_guest_debug(env, 0);
else { } else {
/* must flush all the translated code to avoid inconsistencies */ /* must flush all the translated code to avoid inconsistencies */
/* XXX: only flush what is necessary */ /* XXX: only flush what is necessary */
tb_flush(env); tb_flush(env);
@ -1831,7 +1835,7 @@ MemoryRegion *get_system_io(void)
/* physical memory access (slow version, mainly for debug) */ /* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY) #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) uint8_t *buf, int len, int is_write)
{ {
int l, flags; 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) */ /* 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) uint8_t *buf, int len, int is_write)
{ {
int l; int l;
@ -2611,7 +2615,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
while (len > 0) { while (len > 0) {
page = addr & TARGET_PAGE_MASK; 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 no physical page mapped, return an error */
if (phys_addr == -1) if (phys_addr == -1)
return -1; return -1;

266
gdbstub.c
View file

@ -42,15 +42,16 @@
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "qemu/bitops.h" #include "qemu/bitops.h"
#ifndef TARGET_CPU_MEMORY_RW_DEBUG static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, bool is_write)
uint8_t *buf, int len, int 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 { enum {
GDB_SIGNAL_0 = 0, GDB_SIGNAL_0 = 0,
@ -287,9 +288,9 @@ enum RSState {
RS_CHKSUM2, RS_CHKSUM2,
}; };
typedef struct GDBState { typedef struct GDBState {
CPUArchState *c_cpu; /* current CPU for step/continue ops */ CPUState *c_cpu; /* current CPU for step/continue ops */
CPUArchState *g_cpu; /* current CPU for other ops */ CPUState *g_cpu; /* current CPU for other ops */
CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */ CPUState *query_cpu; /* for q{f|s}ThreadInfo */
enum RSState state; /* parsing state */ enum RSState state; /* parsing state */
char line_buf[MAX_PACKET_LENGTH]; char line_buf[MAX_PACKET_LENGTH];
int line_buf_index; 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. */ /* Generate the XML description for this CPU. */
if (!target_xml[0]) { if (!target_xml[0]) {
GDBRegisterState *r; GDBRegisterState *r;
CPUArchState *env = first_cpu->env_ptr; CPUState *cpu = first_cpu;
snprintf(target_xml, sizeof(target_xml), snprintf(target_xml, sizeof(target_xml),
"<?xml version=\"1.0\"?>" "<?xml version=\"1.0\"?>"
@ -1848,7 +1849,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
"<xi:include href=\"%s\"/>", "<xi:include href=\"%s\"/>",
GDB_CORE_XML); 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), "<xi:include href=\"");
pstrcat(target_xml, sizeof(target_xml), r->xml); pstrcat(target_xml, sizeof(target_xml), r->xml);
pstrcat(target_xml, sizeof(target_xml), "\"/>"); pstrcat(target_xml, sizeof(target_xml), "\"/>");
@ -1866,14 +1867,15 @@ static const char *get_feature_xml(const char *p, const char **newp)
} }
#endif #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; GDBRegisterState *r;
if (reg < NUM_CORE_REGS) if (reg < NUM_CORE_REGS)
return cpu_gdb_read_register(env, mem_buf, reg); 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) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
return r->get_reg(env, mem_buf, reg - r->base_reg); 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; 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; GDBRegisterState *r;
if (reg < NUM_CORE_REGS) if (reg < NUM_CORE_REGS)
return cpu_gdb_write_register(env, mem_buf, reg); 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) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
return r->set_reg(env, mem_buf, reg - r->base_reg); 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. gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
*/ */
void gdb_register_coprocessor(CPUArchState * env, void gdb_register_coprocessor(CPUState *cpu,
gdb_reg_cb get_reg, gdb_reg_cb set_reg, gdb_reg_cb get_reg, gdb_reg_cb set_reg,
int num_regs, const char *xml, int g_pos) int num_regs, const char *xml, int g_pos)
{ {
GDBRegisterState *s; GDBRegisterState *s;
GDBRegisterState **p; GDBRegisterState **p;
static int last_reg = NUM_CORE_REGS; static int last_reg = NUM_CORE_REGS;
p = &env->gdb_regs; p = &cpu->gdb_regs;
while (*p) { while (*p) {
/* Check for duplicates. */ /* Check for duplicates. */
if (strcmp((*p)->xml, xml) == 0) 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; CPUArchState *env;
int err = 0; int err = 0;
if (kvm_enabled()) if (kvm_enabled()) {
return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
}
switch (type) { switch (type) {
case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_SW:
@ -1991,8 +1995,9 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
CPUArchState *env; CPUArchState *env;
int err = 0; int err = 0;
if (kvm_enabled()) if (kvm_enabled()) {
return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type); return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
}
switch (type) { switch (type) {
case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_SW:
@ -2027,7 +2032,7 @@ static void gdb_breakpoint_remove_all(void)
CPUArchState *env; CPUArchState *env;
if (kvm_enabled()) { if (kvm_enabled()) {
kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu)); kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
return; return;
} }
@ -2042,49 +2047,22 @@ static void gdb_breakpoint_remove_all(void)
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
{ {
cpu_synchronize_state(ENV_GET_CPU(s->c_cpu)); CPUState *cpu = s->c_cpu;
#if defined(TARGET_I386) CPUClass *cc = CPU_GET_CLASS(cpu);
s->c_cpu->eip = pc;
#elif defined (TARGET_PPC) cpu_synchronize_state(cpu);
s->c_cpu->nip = pc; if (cc->set_pc) {
#elif defined (TARGET_SPARC) cc->set_pc(cpu, pc);
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);
} }
#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; CPUState *cpu;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
if (cpu_index(cpu) == thread_id) { 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) static int gdb_handle_packet(GDBState *s, const char *line_buf)
{ {
#ifdef TARGET_XTENSA
CPUArchState *env; CPUArchState *env;
#endif
CPUState *cpu;
const char *p; const char *p;
uint32_t thread; uint32_t thread;
int ch, reg_size, type, res; int ch, reg_size, type, res;
@ -2111,7 +2092,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
case '?': case '?':
/* TODO: Make this return the correct value for user-mode. */ /* TODO: Make this return the correct value for user-mode. */
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP, 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); put_packet(s, buf);
/* Remove all the breakpoints when this query is issued, /* Remove all the breakpoints when this query is issued,
* because gdb is doing and initial connect and the state * 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) {
if (res_thread != -1 && res_thread != 0) { if (res_thread != -1 && res_thread != 0) {
env = find_cpu(res_thread); cpu = find_cpu(res_thread);
if (env == NULL) { if (cpu == NULL) {
put_packet(s, "E22"); put_packet(s, "E22");
break; break;
} }
s->c_cpu = env; s->c_cpu = cpu;
} }
if (res == 's') { if (res == 's') {
cpu_single_step(s->c_cpu, sstep_flags); cpu_single_step(s->c_cpu, sstep_flags);
@ -2239,8 +2220,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
} }
break; break;
case 'g': case 'g':
cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); cpu_synchronize_state(s->g_cpu);
env = s->g_cpu; #ifdef TARGET_XTENSA
env = s->g_cpu->env_ptr;
#endif
len = 0; len = 0;
for (addr = 0; addr < num_g_regs; addr++) { for (addr = 0; addr < num_g_regs; addr++) {
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, 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); put_packet(s, buf);
break; break;
case 'G': case 'G':
cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); cpu_synchronize_state(s->g_cpu);
env = s->g_cpu; #ifdef TARGET_XTENSA
env = s->g_cpu->env_ptr;
#endif
registers = mem_buf; registers = mem_buf;
len = strlen(p) / 2; len = strlen(p) / 2;
hextomem((uint8_t *)registers, p, len); hextomem((uint8_t *)registers, p, len);
@ -2267,7 +2252,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
if (*p == ',') if (*p == ',')
p++; p++;
len = strtoull(p, NULL, 16); 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"); put_packet (s, "E14");
} else { } else {
memtohex(buf, mem_buf, len); memtohex(buf, mem_buf, len);
@ -2282,7 +2267,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
if (*p == ':') if (*p == ':')
p++; p++;
hextomem(mem_buf, p, len); 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"); put_packet(s, "E14");
} else { } else {
put_packet(s, "OK"); put_packet(s, "OK");
@ -2341,18 +2327,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
put_packet(s, "OK"); put_packet(s, "OK");
break; break;
} }
env = find_cpu(thread); cpu = find_cpu(thread);
if (env == NULL) { if (cpu == NULL) {
put_packet(s, "E22"); put_packet(s, "E22");
break; break;
} }
switch (type) { switch (type) {
case 'c': case 'c':
s->c_cpu = env; s->c_cpu = cpu;
put_packet(s, "OK"); put_packet(s, "OK");
break; break;
case 'g': case 'g':
s->g_cpu = env; s->g_cpu = cpu;
put_packet(s, "OK"); put_packet(s, "OK");
break; break;
default: default:
@ -2362,9 +2348,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
break; break;
case 'T': case 'T':
thread = strtoull(p, (char **)&p, 16); thread = strtoull(p, (char **)&p, 16);
env = find_cpu(thread); cpu = find_cpu(thread);
if (env != NULL) { if (cpu != NULL) {
put_packet(s, "OK"); put_packet(s, "OK");
} else { } else {
put_packet(s, "E22"); put_packet(s, "E22");
@ -2401,23 +2387,21 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
put_packet(s, "QC1"); put_packet(s, "QC1");
break; break;
} else if (strcmp(p,"fThreadInfo") == 0) { } else if (strcmp(p,"fThreadInfo") == 0) {
s->query_cpu = first_cpu->env_ptr; s->query_cpu = first_cpu;
goto report_cpuinfo; goto report_cpuinfo;
} else if (strcmp(p,"sThreadInfo") == 0) { } else if (strcmp(p,"sThreadInfo") == 0) {
report_cpuinfo: report_cpuinfo:
if (s->query_cpu) { if (s->query_cpu) {
snprintf(buf, sizeof(buf), "m%x", snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
cpu_index(ENV_GET_CPU(s->query_cpu)));
put_packet(s, buf); 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 } else
put_packet(s, "l"); put_packet(s, "l");
break; break;
} else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) { } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
thread = strtoull(p+16, (char **)&p, 16); thread = strtoull(p+16, (char **)&p, 16);
env = find_cpu(thread); cpu = find_cpu(thread);
if (env != NULL) { if (cpu != NULL) {
CPUState *cpu = ENV_GET_CPU(env);
cpu_synchronize_state(cpu); cpu_synchronize_state(cpu);
len = snprintf((char *)mem_buf, sizeof(mem_buf), len = snprintf((char *)mem_buf, sizeof(mem_buf),
"CPU#%d [%s]", cpu->cpu_index, "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 #ifdef CONFIG_USER_ONLY
else if (strncmp(p, "Offsets", 7) == 0) { 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), snprintf(buf, sizeof(buf),
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx "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) void gdb_set_stop_cpu(CPUState *cpu)
{ {
CPUArchState *env = cpu->env_ptr; gdbserver_state->c_cpu = cpu;
gdbserver_state->g_cpu = cpu;
gdbserver_state->c_cpu = env;
gdbserver_state->g_cpu = env;
} }
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
static void gdb_vm_state_change(void *opaque, int running, RunState state) static void gdb_vm_state_change(void *opaque, int running, RunState state)
{ {
GDBState *s = gdbserver_state; GDBState *s = gdbserver_state;
CPUArchState *env = s->c_cpu; CPUArchState *env = s->c_cpu->env_ptr;
CPUState *cpu = ENV_GET_CPU(env); CPUState *cpu = s->c_cpu;
char buf[256]; char buf[256];
const char *type; const char *type;
int ret; int ret;
@ -2598,7 +2581,7 @@ send_packet:
put_packet(s, buf); put_packet(s, buf);
/* disable single step if it was enabled */ /* disable single step if it was enabled */
cpu_single_step(env, 0); cpu_single_step(cpu, 0);
} }
#endif #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 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 and state transition 'T' packets to be sent while the syscall is still
being processed. */ being processed. */
cpu_exit(ENV_GET_CPU(s->c_cpu)); cpu_exit(s->c_cpu);
#endif #endif
} }
@ -2789,66 +2772,67 @@ gdb_queuesig (void)
} }
int int
gdb_handlesig (CPUArchState *env, int sig) gdb_handlesig(CPUState *cpu, int sig)
{ {
GDBState *s; CPUArchState *env = cpu->env_ptr;
char buf[256]; GDBState *s;
int n; char buf[256];
int n;
s = gdbserver_state; s = gdbserver_state;
if (gdbserver_fd < 0 || s->fd < 0) if (gdbserver_fd < 0 || s->fd < 0) {
return sig; return sig;
/* disable single step if it was enabled */
cpu_single_step(env, 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; /* disable single step if it was enabled */
s->state = RS_IDLE; cpu_single_step(cpu, 0);
s->running_state = 0; tb_flush(env);
while (s->running_state == 0) {
n = read (s->fd, buf, 256);
if (n > 0)
{
int i;
for (i = 0; i < n; i++) if (sig != 0) {
gdb_read_byte (s, buf[i]); 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;
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;
} }
else if (n == 0 || errno != EAGAIN) }
{ sig = s->signal;
/* XXX: Connection closed. Should probably wait for another s->signal = 0;
connection before continuing. */ return sig;
return sig;
}
}
sig = s->signal;
s->signal = 0;
return sig;
} }
/* Tell the remote gdb that the process has exited due to SIG. */ /* Tell the remote gdb that the process has exited due to SIG. */
void gdb_signalled(CPUArchState *env, int sig) void gdb_signalled(CPUArchState *env, int sig)
{ {
GDBState *s; GDBState *s;
char buf[4]; char buf[4];
s = gdbserver_state; s = gdbserver_state;
if (gdbserver_fd < 0 || s->fd < 0) if (gdbserver_fd < 0 || s->fd < 0) {
return; return;
}
snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig)); snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
put_packet(s, buf); put_packet(s, buf);
} }
static void gdb_accept(void) static void gdb_accept(void)
@ -2876,8 +2860,8 @@ static void gdb_accept(void)
socket_set_nodelay(fd); socket_set_nodelay(fd);
s = g_malloc0(sizeof(GDBState)); s = g_malloc0(sizeof(GDBState));
s->c_cpu = first_cpu->env_ptr; s->c_cpu = first_cpu;
s->g_cpu = first_cpu->env_ptr; s->g_cpu = first_cpu;
s->fd = fd; s->fd = fd;
gdb_has_xml = 0; gdb_has_xml = 0;
@ -3061,8 +3045,8 @@ int gdbserver_start(const char *device)
mon_chr = s->mon_chr; mon_chr = s->mon_chr;
memset(s, 0, sizeof(GDBState)); memset(s, 0, sizeof(GDBState));
} }
s->c_cpu = first_cpu->env_ptr; s->c_cpu = first_cpu;
s->g_cpu = first_cpu->env_ptr; s->g_cpu = first_cpu;
s->chr = chr; s->chr = chr;
s->state = chr ? RS_IDLE : RS_INACTIVE; s->state = chr ? RS_IDLE : RS_INACTIVE;
s->mon_chr = mon_chr; s->mon_chr = mon_chr;

View file

@ -146,6 +146,7 @@ static void update_guest_rom_state(VAPICROMState *s)
static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env) static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
{ {
CPUState *cs = CPU(x86_env_get_cpu(env));
hwaddr paddr; hwaddr paddr;
target_ulong addr; target_ulong addr;
@ -158,7 +159,7 @@ static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
* virtual address space for the APIC mapping. * virtual address space for the APIC mapping.
*/ */
for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) { 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) { if (paddr != APIC_DEFAULT_ADDRESS) {
continue; continue;
} }
@ -187,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)
modrm_reg(opcode[1]) == instr->modrm_reg); 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) target_ulong *pip, TPRAccess access)
{ {
CPUState *cs = CPU(cpu);
const TPRInstruction *instr; const TPRInstruction *instr;
target_ulong ip = *pip; target_ulong ip = *pip;
uint8_t opcode[2]; 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 * RSP, used by the patched instruction, is zero, so the guest gets a
* double fault and dies. * double fault and dies.
*/ */
if (env->regs[R_ESP] == 0) { if (cpu->env.regs[R_ESP] == 0) {
return -1; return -1;
} }
@ -225,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
if (instr->access != access) { if (instr->access != access) {
continue; 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) { sizeof(opcode), 0) < 0) {
return -1; return -1;
} }
@ -236,7 +238,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
} }
return -1; return -1;
} else { } 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; return -1;
} }
for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) { for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
@ -253,7 +255,7 @@ instruction_ok:
* Grab the virtual TPR address from the instruction * Grab the virtual TPR address from the instruction
* and update the cached values. * 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, (void *)&real_tpr_addr,
sizeof(real_tpr_addr), 0) < 0) { sizeof(real_tpr_addr), 0) < 0) {
return -1; return -1;
@ -271,6 +273,7 @@ instruction_ok:
static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip) static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
{ {
CPUState *cs = CPU(x86_env_get_cpu(env));
hwaddr paddr; hwaddr paddr;
uint32_t rom_state_vaddr; uint32_t rom_state_vaddr;
uint32_t pos, patch, offset; 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 */ /* find out virtual address of the ROM */
rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000); 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) { if (paddr == -1) {
return -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 * cannot be accessed or is considered invalid. This also ensures that we are
* not patching the wrong guest. * 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 { struct kpcr {
uint8_t fill1[0x1c]; uint8_t fill1[0x1c];
uint32_t self; uint32_t self;
@ -341,7 +345,7 @@ static int get_kpcr_number(CPUX86State *env)
uint8_t number; uint8_t number;
} QEMU_PACKED kpcr; } 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 || (void *)&kpcr, sizeof(kpcr), 0) < 0 ||
kpcr.self != env->segs[R_FS].base) { kpcr.self != env->segs[R_FS].base) {
return -1; return -1;
@ -349,9 +353,9 @@ static int get_kpcr_number(CPUX86State *env)
return kpcr.number; 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; hwaddr vapic_paddr;
static const uint8_t enabled = 1; static const uint8_t enabled = 1;
@ -362,26 +366,26 @@ static int vapic_enable(VAPICROMState *s, CPUX86State *env)
(((hwaddr)cpu_number) << VAPIC_CPU_SHIFT); (((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled), cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
(void *)&enabled, sizeof(enabled), 1); (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; s->state = VAPIC_ACTIVE;
return 0; 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 target)
{ {
uint32_t offset; uint32_t offset;
offset = cpu_to_le32(target - ip - 5); offset = cpu_to_le32(target - ip - 5);
patch_byte(env, ip, 0xe8); /* call near */ patch_byte(cpu, ip, 0xe8); /* call near */
cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1); cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
} }
static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip) 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(); 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]) { switch (opcode[0]) {
case 0x89: /* mov r32 to r/m32 */ case 0x89: /* mov r32 to r/m32 */
patch_byte(env, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */ patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
patch_call(s, env, ip + 1, handlers->set_tpr); patch_call(s, cpu, ip + 1, handlers->set_tpr);
break; break;
case 0x8b: /* mov r/m32 to r32 */ case 0x8b: /* mov r/m32 to r32 */
patch_byte(env, ip, 0x90); patch_byte(cpu, ip, 0x90);
patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]); patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
break; break;
case 0xa1: /* mov abs to eax */ 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; break;
case 0xa3: /* mov eax to abs */ 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; break;
case 0xc7: /* mov imm32, r/m32 (c7/0) */ case 0xc7: /* mov imm32, r/m32 (c7/0) */
patch_byte(env, ip, 0x68); /* push imm32 */ patch_byte(cpu, ip, 0x68); /* push imm32 */
cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0); cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1); cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
patch_call(s, env, ip + 5, handlers->set_tpr); patch_call(s, cpu, ip + 5, handlers->set_tpr);
break; break;
case 0xff: /* push r/m32 */ case 0xff: /* push r/m32 */
patch_byte(env, ip, 0x50); /* push eax */ patch_byte(cpu, ip, 0x50); /* push eax */
patch_call(s, env, ip + 1, handlers->get_tpr_stack); patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
break; break;
default: default:
abort(); abort();
@ -458,16 +462,16 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
cpu_synchronize_state(cs); 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) { if (s->state == VAPIC_ACTIVE) {
vapic_enable(s, env); vapic_enable(s, cpu);
} }
return; return;
} }
if (update_rom_mapping(s, env, ip) < 0) { if (update_rom_mapping(s, env, ip) < 0) {
return; return;
} }
if (vapic_enable(s, env) < 0) { if (vapic_enable(s, cpu) < 0) {
return; return;
} }
patch_instruction(s, cpu, ip); patch_instruction(s, cpu, ip);
@ -667,8 +671,8 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
* accurate. * accurate.
*/ */
pause_all_vcpus(); pause_all_vcpus();
patch_byte(env, env->eip - 2, 0x66); patch_byte(cpu, env->eip - 2, 0x66);
patch_byte(env, env->eip - 1, 0x90); patch_byte(cpu, env->eip - 1, 0x90);
resume_all_vcpus(); 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) { if (find_real_tpr_addr(s, env) < 0) {
break; break;
} }
vapic_enable(s, env); vapic_enable(s, cpu);
break; break;
default: default:
case 4: case 4:
@ -722,7 +726,7 @@ static void do_vapic_enable(void *data)
VAPICROMState *s = data; VAPICROMState *s = data;
X86CPU *cpu = X86_CPU(first_cpu); 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) static int vapic_post_load(void *opaque, int version_id)

View file

@ -144,9 +144,11 @@ static void lx60_net_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, buffers, ram); 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) 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_entry;
uint64_t elf_lowaddr; 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); &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
if (success > 0) { if (success > 0) {
env->pc = elf_entry; env->pc = elf_entry;

View file

@ -32,9 +32,11 @@
#include "exec/memory.h" #include "exec/memory.h"
#include "exec/address-spaces.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) static void sim_reset(void *opaque)
@ -88,10 +90,10 @@ static void xtensa_sim_init(QEMUMachineInitArgs *args)
uint64_t elf_entry; uint64_t elf_entry;
uint64_t elf_lowaddr; uint64_t elf_lowaddr;
#ifdef TARGET_WORDS_BIGENDIAN #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); &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
#else #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); &elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0);
#endif #endif
if (success > 0) { if (success > 0) {

View file

@ -22,6 +22,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "exec/cpu-common.h" #include "exec/cpu-common.h"
#include "qemu/thread.h" #include "qemu/thread.h"
#include "qom/cpu.h"
/* some important defines: /* 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_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
void cpu_watchpoint_remove_all(CPUArchState *env, int mask); 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) #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 */ /* memory API */
extern ram_addr_t ram_size; extern ram_addr_t ram_size;
@ -494,7 +484,7 @@ void qemu_mutex_lock_ramlist(void);
void qemu_mutex_unlock_ramlist(void); void qemu_mutex_unlock_ramlist(void);
#endif /* !CONFIG_USER_ONLY */ #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); uint8_t *buf, int len, int is_write);
#endif /* CPU_ALL_H */ #endif /* CPU_ALL_H */

View file

@ -170,13 +170,10 @@ typedef struct CPUWatchpoint {
/* from this point: preserved by CPU reset */ \ /* from this point: preserved by CPU reset */ \
/* ice debug support */ \ /* ice debug support */ \
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
int singlestep_enabled; \
\ \
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \ QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
CPUWatchpoint *watchpoint_hit; \ CPUWatchpoint *watchpoint_hit; \
\ \
struct GDBRegisterState *gdb_regs; \
\
/* Core interrupt code */ \ /* Core interrupt code */ \
sigjmp_buf jmp_env; \ sigjmp_buf jmp_env; \
int exception_index; \ int exception_index; \

View file

@ -11,7 +11,7 @@
#define GDB_WATCHPOINT_ACCESS 4 #define GDB_WATCHPOINT_ACCESS 4
#ifdef NEED_CPU_H #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); target_ulong ret, target_ulong err);
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...); 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); void gdb_exit(CPUArchState *, int);
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
int gdb_queuesig (void); int gdb_queuesig (void);
int gdb_handlesig (CPUArchState *, int); int gdb_handlesig(CPUState *, int);
void gdb_signalled(CPUArchState *, int); void gdb_signalled(CPUArchState *, int);
void gdbserver_fork(CPUArchState *); void gdbserver_fork(CPUArchState *);
#endif #endif
/* Get or set a register. Returns the size of the register. */ /* Get or set a register. Returns the size of the register. */
typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); 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, gdb_reg_cb get_reg, gdb_reg_cb set_reg,
int num_regs, const char *xml, int g_pos); int num_regs, const char *xml, int g_pos);

View file

@ -13,14 +13,14 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
{ {
uint32_t val; 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); return tswap32(val);
} }
static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr) static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
{ {
uint8_t val; 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; 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) static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
{ {
val = tswap32(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_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
#define put_user_ual(arg, p) put_user_u32(arg, p) #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; uint8_t *p;
/* TODO: Make this something that isn't fixed size. */ /* TODO: Make this something that isn't fixed size. */
p = malloc(len); p = malloc(len);
if (p && copy) if (p && copy) {
cpu_memory_rw_debug(env, addr, p, len, 0); cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0);
}
return p; return p;
} }
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy) #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; return NULL;
} }
do { do {
cpu_memory_rw_debug(env, addr, &c, 1, 0); cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0);
addr++; addr++;
*(p++) = c; *(p++) = c;
} while (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, static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
target_ulong len) target_ulong len)
{ {
if (len) if (len) {
cpu_memory_rw_debug(env, addr, p, len, 1); cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1);
}
free(p); free(p);
} }
#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len) #define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)

View file

@ -29,6 +29,18 @@
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque); 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:cpu
* @section_id: QEMU-cpu * @section_id: QEMU-cpu
@ -48,6 +60,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
bool is_write, bool is_exec, int opaque, bool is_write, bool is_exec, int opaque,
unsigned size); unsigned size);
struct TranslationBlock;
/** /**
* CPUClass: * CPUClass:
* @class_by_name: Callback to map -cpu command line model name to an * @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. * @reset_dump_flags: #CPUDumpFlags to use for reset logging.
* @do_interrupt: Callback for interrupt handling. * @do_interrupt: Callback for interrupt handling.
* @do_unassigned_access: Callback for unassigned access handling. * @do_unassigned_access: Callback for unassigned access handling.
* @memory_rw_debug: Callback for GDB memory access.
* @dump_state: Callback for dumping state. * @dump_state: Callback for dumping state.
* @dump_statistics: Callback for dumping statistics. * @dump_statistics: Callback for dumping statistics.
* @get_arch_id: Callback for getting architecture-dependent CPU ID. * @get_arch_id: Callback for getting architecture-dependent CPU ID.
* @get_paging_enabled: Callback for inquiring whether paging is enabled. * @get_paging_enabled: Callback for inquiring whether paging is enabled.
* @get_memory_mapping: Callback for obtaining the memory mappings. * @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. * @vmsd: State description for migration.
* *
* Represents a CPU family or model. * Represents a CPU family or model.
@ -76,6 +95,8 @@ typedef struct CPUClass {
int reset_dump_flags; int reset_dump_flags;
void (*do_interrupt)(CPUState *cpu); void (*do_interrupt)(CPUState *cpu);
CPUUnassignedAccess do_unassigned_access; 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, void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
void (*dump_statistics)(CPUState *cpu, FILE *f, void (*dump_statistics)(CPUState *cpu, FILE *f,
@ -84,6 +105,9 @@ typedef struct CPUClass {
bool (*get_paging_enabled)(const CPUState *cpu); bool (*get_paging_enabled)(const CPUState *cpu);
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
Error **errp); 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; const struct VMStateDescription *vmsd;
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
@ -114,8 +138,10 @@ struct kvm_run;
* @stopped: Indicates the CPU has been artificially stopped. * @stopped: Indicates the CPU has been artificially stopped.
* @tcg_exit_req: Set to force TCG to stop executing linked TBs for this * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
* CPU and return to its top level loop. * CPU and return to its top level loop.
* @singlestep_enabled: Flags for single-stepping.
* @env_ptr: Pointer to subclass-specific CPUArchState field. * @env_ptr: Pointer to subclass-specific CPUArchState field.
* @current_tb: Currently executing TB. * @current_tb: Currently executing TB.
* @gdb_regs: Additional GDB registers.
* @next_cpu: Next CPU sharing TB cache. * @next_cpu: Next CPU sharing TB cache.
* @kvm_fd: vCPU file descriptor for KVM. * @kvm_fd: vCPU file descriptor for KVM.
* *
@ -146,9 +172,11 @@ struct CPUState {
volatile sig_atomic_t exit_request; volatile sig_atomic_t exit_request;
volatile sig_atomic_t tcg_exit_req; volatile sig_atomic_t tcg_exit_req;
uint32_t interrupt_request; uint32_t interrupt_request;
int singlestep_enabled;
void *env_ptr; /* CPUArchState */ void *env_ptr; /* CPUArchState */
struct TranslationBlock *current_tb; struct TranslationBlock *current_tb;
struct GDBRegisterState *gdb_regs;
CPUState *next_cpu; CPUState *next_cpu;
int kvm_fd; 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, void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); 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_reset:
* @cpu: The CPU whose state is to be reset. * @cpu: The CPU whose state is to be reset.
@ -276,59 +323,6 @@ void cpu_reset(CPUState *cpu);
*/ */
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); 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: * qemu_cpu_has_work:
* @cpu: The vCPU to check. * @cpu: The vCPU to check.
@ -489,6 +483,19 @@ void cpu_resume(CPUState *cpu);
*/ */
void qemu_init_vcpu(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 #ifdef CONFIG_SOFTMMU
extern const struct VMStateDescription vmstate_cpu_common; extern const struct VMStateDescription vmstate_cpu_common;
#else #else

View file

@ -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_setup_guest_memory(void *start, size_t size);
void kvm_flush_coalesced_mmio_buffer(void); 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); 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); target_ulong len, int type);
void kvm_remove_all_breakpoints(CPUState *cpu); void kvm_remove_all_breakpoints(CPUState *cpu);
int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap); int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);

View file

@ -1890,7 +1890,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
data.dbg.control = reinject_trap; data.dbg.control = reinject_trap;
if (env->singlestep_enabled) { if (cpu->singlestep_enabled) {
data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
} }
kvm_arch_update_guest_debug(cpu, &data.dbg); 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; 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) target_ulong len, int type)
{ {
CPUState *cpu = ENV_GET_CPU(env);
struct kvm_sw_breakpoint *bp; struct kvm_sw_breakpoint *bp;
int err; int err;
@ -1946,10 +1945,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
return 0; 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) target_ulong len, int type)
{ {
CPUState *cpu = ENV_GET_CPU(env);
struct kvm_sw_breakpoint *bp; struct kvm_sw_breakpoint *bp;
int err; int err;
@ -2022,13 +2020,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
return -EINVAL; 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) target_ulong len, int type)
{ {
return -EINVAL; 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) target_ulong len, int type)
{ {
return -EINVAL; return -EINVAL;

View file

@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
return -ENOSYS; 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) target_ulong len, int type)
{ {
return -EINVAL; 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) target_ulong len, int type)
{ {
return -EINVAL; return -EINVAL;

View file

@ -55,12 +55,14 @@ const char *cpu_to_uname_machine(void *cpu_env)
return "x86-64"; return "x86-64";
#elif defined(TARGET_I386) #elif defined(TARGET_I386)
/* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */ /* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */
uint32_t cpuid_version = ((CPUX86State *)cpu_env)->cpuid_version; CPUState *cpu = ENV_GET_CPU((CPUX86State *)cpu_env);
int family = ((cpuid_version >> 8) & 0x0f) + ((cpuid_version >> 20) & 0xff); int family = object_property_get_int(OBJECT(cpu), "family", NULL);
if (family == 4) if (family == 4) {
return "i486"; return "i486";
if (family == 5) }
if (family == 5) {
return "i586"; return "i586";
}
return "i686"; return "i686";
#else #else
/* default is #define-d in each arch/ subdir */ /* default is #define-d in each arch/ subdir */

View file

@ -312,6 +312,7 @@ static void set_idt(int n, unsigned int dpl)
void cpu_loop(CPUX86State *env) void cpu_loop(CPUX86State *env)
{ {
CPUState *cs = CPU(x86_env_get_cpu(env));
int trapnr; int trapnr;
abi_ulong pc; abi_ulong pc;
target_siginfo_t info; target_siginfo_t info;
@ -443,7 +444,7 @@ void cpu_loop(CPUX86State *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -875,7 +876,7 @@ void cpu_loop(CPUARMState *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -966,7 +967,7 @@ void cpu_loop(CPUUniCore32State *env)
{ {
int sig; int sig;
sig = gdb_handlesig(env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) { if (sig) {
info.si_signo = sig; info.si_signo = sig;
info.si_errno = 0; info.si_errno = 0;
@ -1233,7 +1234,7 @@ void cpu_loop (CPUSPARCState *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -1764,7 +1765,7 @@ void cpu_loop(CPUPPCState *env)
{ {
int sig; int sig;
sig = gdb_handlesig(env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) { if (sig) {
info.si_signo = sig; info.si_signo = sig;
info.si_errno = 0; info.si_errno = 0;
@ -2315,7 +2316,7 @@ done_syscall:
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -2475,7 +2476,7 @@ void cpu_loop(CPUOpenRISCState *env)
break; break;
} }
if (gdbsig) { if (gdbsig) {
gdb_handlesig(env, gdbsig); gdb_handlesig(cs, gdbsig);
if (gdbsig != TARGET_SIGTRAP) { if (gdbsig != TARGET_SIGTRAP) {
exit(1); exit(1);
} }
@ -2518,7 +2519,7 @@ void cpu_loop(CPUSH4State *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -2586,7 +2587,7 @@ void cpu_loop(CPUCRISState *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -2686,7 +2687,7 @@ void cpu_loop(CPUMBState *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -2779,7 +2780,7 @@ void cpu_loop(CPUM68KState *env)
{ {
int sig; int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) if (sig)
{ {
info.si_signo = sig; info.si_signo = sig;
@ -3006,7 +3007,7 @@ void cpu_loop(CPUAlphaState *env)
} }
break; break;
case EXCP_DEBUG: case EXCP_DEBUG:
info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP); info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
if (info.si_signo) { if (info.si_signo) {
env->lock_addr = -1; env->lock_addr = -1;
info.si_errno = 0; info.si_errno = 0;
@ -3059,7 +3060,7 @@ void cpu_loop(CPUS390XState *env)
break; break;
case EXCP_DEBUG: case EXCP_DEBUG:
sig = gdb_handlesig(env, TARGET_SIGTRAP); sig = gdb_handlesig(cs, TARGET_SIGTRAP);
if (sig) { if (sig) {
n = TARGET_TRAP_BRKPT; n = TARGET_TRAP_BRKPT;
goto do_signal_pc; goto do_signal_pc;
@ -3541,6 +3542,7 @@ int main(int argc, char **argv, char **envp)
struct linux_binprm bprm; struct linux_binprm bprm;
TaskState *ts; TaskState *ts;
CPUArchState *env; CPUArchState *env;
CPUState *cpu;
int optind; int optind;
char **target_environ, **wrk; char **target_environ, **wrk;
char **target_argv; char **target_argv;
@ -3637,11 +3639,12 @@ int main(int argc, char **argv, char **envp)
fprintf(stderr, "Unable to find CPU definition\n"); fprintf(stderr, "Unable to find CPU definition\n");
exit(1); exit(1);
} }
cpu = ENV_GET_CPU(env);
#if defined(TARGET_SPARC) || defined(TARGET_PPC) #if defined(TARGET_SPARC) || defined(TARGET_PPC)
cpu_reset(ENV_GET_CPU(env)); cpu_reset(cpu);
#endif #endif
thread_cpu = ENV_GET_CPU(env); thread_cpu = cpu;
if (getenv("QEMU_STRACE")) { if (getenv("QEMU_STRACE")) {
do_strace = 1; do_strace = 1;
@ -4076,7 +4079,7 @@ int main(int argc, char **argv, char **envp)
gdbstub_port); gdbstub_port);
exit(1); exit(1);
} }
gdb_handlesig(env, 0); gdb_handlesig(cpu, 0);
} }
cpu_loop(env); cpu_loop(env);
/* never exits */ /* never exits */

View file

@ -5386,6 +5386,7 @@ long do_rt_sigreturn(CPUArchState *env)
void process_pending_signals(CPUArchState *cpu_env) void process_pending_signals(CPUArchState *cpu_env)
{ {
CPUState *cpu = ENV_GET_CPU(cpu_env);
int sig; int sig;
abi_ulong handler; abi_ulong handler;
sigset_t set, old_set; sigset_t set, old_set;
@ -5419,7 +5420,7 @@ void process_pending_signals(CPUArchState *cpu_env)
if (!k->first) if (!k->first)
k->pending = 0; k->pending = 0;
sig = gdb_handlesig (cpu_env, sig); sig = gdb_handlesig(cpu, sig);
if (!sig) { if (!sig) {
sa = NULL; sa = NULL;
handler = TARGET_SIG_IGN; handler = TARGET_SIG_IGN;

View file

@ -1164,7 +1164,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
cpu_physical_memory_read(addr, buf, l); cpu_physical_memory_read(addr, buf, l);
} else { } else {
env = mon_get_cpu(); 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"); monitor_printf(mon, " Cannot access memory\n");
break; break;
} }

View file

@ -81,5 +81,6 @@ extern const struct VMStateDescription vmstate_alpha_cpu;
void alpha_cpu_do_interrupt(CPUState *cpu); void alpha_cpu_do_interrupt(CPUState *cpu);
void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -24,6 +24,13 @@
#include "migration/vmstate.h" #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) static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
{ {
AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev); 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->class_by_name = alpha_cpu_class_by_name;
cc->do_interrupt = alpha_cpu_do_interrupt; cc->do_interrupt = alpha_cpu_do_interrupt;
cc->dump_state = alpha_cpu_dump_state; cc->dump_state = alpha_cpu_dump_state;
cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access); cc->set_pc = alpha_cpu_set_pc;
device_class_set_vmsd(dc, &vmstate_alpha_cpu); #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 = { static const TypeInfo alpha_cpu_type_info = {

View file

@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #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__) */ #endif /* !defined (__CPU_ALPHA_H__) */

View file

@ -315,12 +315,13 @@ static int get_physical_address(CPUAlphaState *env, target_ulong addr,
return ret; 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; target_ulong phys;
int prot, fail; 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); return (fail >= 0 ? -1 : phys);
} }

View file

@ -38,7 +38,6 @@
typedef struct DisasContext DisasContext; typedef struct DisasContext DisasContext;
struct DisasContext { struct DisasContext {
struct TranslationBlock *tb; struct TranslationBlock *tb;
CPUAlphaState *env;
uint64_t pc; uint64_t pc;
int mem_idx; int mem_idx;
@ -46,6 +45,11 @@ struct DisasContext {
int tb_rm; int tb_rm;
/* Current flush-to-zero setting for this TB. */ /* Current flush-to-zero setting for this TB. */
int tb_ftz; int tb_ftz;
/* implver value for this CPU. */
int implver;
bool singlestep_enabled;
}; };
/* Return values from translate_one, indicating the state of the TB. /* 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 /* 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. */ also want to suppress goto_tb in the case of single-steping and IO. */
return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0 return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
&& !ctx->env->singlestep_enabled && !ctx->singlestep_enabled
&& !(ctx->tb->cflags & CF_LAST_IO)); && !(ctx->tb->cflags & CF_LAST_IO));
} }
@ -2248,8 +2252,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
break; break;
case 0x6C: case 0x6C:
/* IMPLVER */ /* IMPLVER */
if (rc != 31) if (rc != 31) {
tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver); tcg_gen_movi_i64(cpu_ir[rc], ctx->implver);
}
break; break;
default: default:
goto invalid_opc; goto invalid_opc;
@ -3383,6 +3388,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUAlphaState *env = &cpu->env; CPUAlphaState *env = &cpu->env;
DisasContext ctx, *ctxp = &ctx; DisasContext ctx, *ctxp = &ctx;
target_ulong pc_start; 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; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.tb = tb; ctx.tb = tb;
ctx.env = env;
ctx.pc = pc_start; ctx.pc = pc_start;
ctx.mem_idx = cpu_mmu_index(env); 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 /* ??? Every TB begins with unset rounding mode, to be initialized on
the first fp insn of the TB. Alternately we could define a proper 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 || tcg_ctx.gen_opc_ptr >= gen_opc_end
|| num_insns >= max_insns || num_insns >= max_insns
|| singlestep || singlestep
|| env->singlestep_enabled)) { || ctx.singlestep_enabled)) {
ret = EXIT_PC_STALE; ret = EXIT_PC_STALE;
} }
} while (ret == NO_EXIT); } 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); tcg_gen_movi_i64(cpu_pc, ctx.pc);
/* FALLTHRU */ /* FALLTHRU */
case EXIT_PC_UPDATED: case EXIT_PC_UPDATED:
if (env->singlestep_enabled) { if (ctx.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG, 0); gen_excp_1(EXCP_DEBUG, 0);
} else { } else {
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);

View file

@ -122,8 +122,10 @@ static target_ulong arm_semi_syscall_len;
static target_ulong syscall_err; static target_ulong syscall_err;
#endif #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 #ifdef CONFIG_USER_ONLY
TaskState *ts = env->opaque; TaskState *ts = env->opaque;
#endif #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 size is always stored in big-endian order, extract
the value. We assume the size always fit in 32 bits. */ the value. We assume the size always fit in 32 bits. */
uint32_t size; 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); env->regs[0] = be32_to_cpu(size);
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
((TaskState *)env->opaque)->swi_errno = err; ((TaskState *)env->opaque)->swi_errno = err;

View file

@ -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, void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -25,6 +25,13 @@
#endif #endif
#include "sysemu/sysemu.h" #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) static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
{ {
/* Reset a single ARMCPRegInfo register */ /* 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->class_by_name = arm_cpu_class_by_name;
cc->do_interrupt = arm_cpu_do_interrupt; cc->do_interrupt = arm_cpu_do_interrupt;
cc->dump_state = arm_cpu_dump_state; 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) static void cpu_register(const ARMCPUInfo *info)

View file

@ -797,11 +797,6 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #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 */ /* Load an instruction and return it in the standard little-endian order */
static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr, static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
bool do_swap) bool do_swap)

View file

@ -1513,16 +1513,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
{ {
CPUState *cs = CPU(cpu);
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
if (arm_feature(env, ARM_FEATURE_NEON)) { 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); 51, "arm-neon.xml", 0);
} else if (arm_feature(env, ARM_FEATURE_VFP3)) { } 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); 35, "arm-vfp3.xml", 0);
} else if (arm_feature(env, ARM_FEATURE_VFP)) { } 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); 19, "arm-vfp.xml", 0);
} }
} }
@ -2762,17 +2763,19 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
return 1; 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; hwaddr phys_addr;
target_ulong page_size; target_ulong page_size;
int prot; int prot;
int ret; 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 -1;
}
return phys_addr; return phys_addr;
} }

View file

@ -9911,6 +9911,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUARMState *env = &cpu->env; CPUARMState *env = &cpu->env;
DisasContext dc1, *dc = &dc1; DisasContext dc1, *dc = &dc1;
CPUBreakpoint *bp; CPUBreakpoint *bp;
@ -9930,7 +9931,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
dc->is_jmp = DISAS_NEXT; dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start; dc->pc = pc_start;
dc->singlestep_enabled = env->singlestep_enabled; dc->singlestep_enabled = cs->singlestep_enabled;
dc->condjmp = 0; dc->condjmp = 0;
dc->thumb = ARM_TBFLAG_THUMB(tb->flags); dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(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. */ * ensures prefetch aborts occur at the right place. */
num_insns ++; num_insns ++;
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled && !cs->singlestep_enabled &&
!singlestep && !singlestep &&
dc->pc < next_page_start && dc->pc < next_page_start &&
num_insns < max_insns); 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 /* At this stage dc->condjmp will only be set when the skipped
instruction was a conditional branch or trap, and the PC has instruction was a conditional branch or trap, and the PC has
already been written. */ already been written. */
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
/* Make sure the pc is updated, and raise a debug exception. */ /* Make sure the pc is updated, and raise a debug exception. */
if (dc->condjmp) { if (dc->condjmp) {
gen_set_condexec(dc); gen_set_condexec(dc);

View file

@ -79,4 +79,6 @@ void crisv10_cpu_do_interrupt(CPUState *cpu);
void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -26,6 +26,13 @@
#include "mmu.h" #include "mmu.h"
static void cris_cpu_set_pc(CPUState *cs, vaddr value)
{
CRISCPU *cpu = CRIS_CPU(cs);
cpu->env.pc = value;
}
/* CPUClass::reset() */ /* CPUClass::reset() */
static void cris_cpu_reset(CPUState *s) 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->class_by_name = cris_cpu_class_by_name;
cc->do_interrupt = cris_cpu_do_interrupt; cc->do_interrupt = cris_cpu_do_interrupt;
cc->dump_state = cris_cpu_dump_state; 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 = { static const TypeInfo cris_cpu_type_info = {

View file

@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #include "exec/exec-all.h"
static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
}
#endif #endif

View file

@ -255,16 +255,17 @@ void cris_cpu_do_interrupt(CPUState *cs)
env->pregs[PR_ERP]); 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; uint32_t phy = addr;
struct cris_mmu_result res; struct cris_mmu_result res;
int miss; 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 D TLB misses, try I TLB. */
if (miss) { 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) { if (!miss) {

View file

@ -3165,6 +3165,7 @@ static inline void
gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUCRISState *env = &cpu->env; CPUCRISState *env = &cpu->env;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
uint32_t pc_start; uint32_t pc_start;
@ -3197,7 +3198,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
dc->is_jmp = DISAS_NEXT; dc->is_jmp = DISAS_NEXT;
dc->ppc = pc_start; dc->ppc = pc_start;
dc->pc = pc_start; dc->pc = pc_start;
dc->singlestep_enabled = env->singlestep_enabled; dc->singlestep_enabled = cs->singlestep_enabled;
dc->flags_uptodate = 1; dc->flags_uptodate = 1;
dc->flagx_known = 1; dc->flagx_known = 1;
dc->flags_x = tb->flags & X_FLAG; 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 /* If we are rexecuting a branch due to exceptions on
delay slots dont break. */ delay slots dont break. */
if (!(tb->pc & 1) && env->singlestep_enabled) { if (!(tb->pc & 1) && cs->singlestep_enabled) {
break; break;
} }
} while (!dc->is_jmp && !dc->cpustate_changed } while (!dc->is_jmp && !dc->cpustate_changed
@ -3370,7 +3371,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
cris_evaluate_flags(dc); cris_evaluate_flags(dc);
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
if (dc->is_jmp == DISAS_NEXT) { if (dc->is_jmp == DISAS_NEXT) {
tcg_gen_movi_tl(env_pc, npc); tcg_gen_movi_tl(env_pc, npc);
} }

View file

@ -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, void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -2506,6 +2506,20 @@ static bool x86_cpu_get_paging_enabled(const CPUState *cs)
return cpu->env.cr[0] & CR0_PG_MASK; 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) static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
{ {
X86CPUClass *xcc = X86_CPU_CLASS(oc); 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->do_interrupt = x86_cpu_do_interrupt;
cc->dump_state = x86_cpu_dump_state; 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_arch_id = x86_cpu_get_arch_id;
cc->get_paging_enabled = x86_cpu_get_paging_enabled; cc->get_paging_enabled = x86_cpu_get_paging_enabled;
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
cc->get_memory_mapping = x86_cpu_get_memory_mapping; 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_note = x86_cpu_write_elf64_note;
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote; cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
cc->write_elf32_note = x86_cpu_write_elf32_note; cc->write_elf32_note = x86_cpu_write_elf32_note;
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote; cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
cc->vmsd = &vmstate_x86_cpu;
#endif #endif
cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
} }
static const TypeInfo x86_cpu_type_info = { static const TypeInfo x86_cpu_type_info = {

View file

@ -1148,11 +1148,6 @@ static inline bool cpu_has_work(CPUState *cs)
#include "exec/exec-all.h" #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, static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
target_ulong *cs_base, int *flags) target_ulong *cs_base, int *flags)
{ {

View file

@ -363,7 +363,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "Code="); cpu_fprintf(f, "Code=");
for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) { 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); snprintf(codestr, sizeof(codestr), "%02x", code);
} else { } else {
snprintf(codestr, sizeof(codestr), "??"); snprintf(codestr, sizeof(codestr), "??");
@ -884,8 +884,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
return 1; 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; target_ulong pde_addr, pte_addr;
uint64_t pte; uint64_t pte;
hwaddr paddr; hwaddr paddr;
@ -1258,6 +1260,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
target_ulong *base, unsigned int *limit, target_ulong *base, unsigned int *limit,
unsigned int *flags) unsigned int *flags)
{ {
X86CPU *cpu = x86_env_get_cpu(env);
CPUState *cs = CPU(cpu);
SegmentCache *dt; SegmentCache *dt;
target_ulong ptr; target_ulong ptr;
uint32_t e1, e2; uint32_t e1, e2;
@ -1270,8 +1274,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
index = selector & ~7; index = selector & ~7;
ptr = dt->base + index; ptr = dt->base + index;
if ((index + 7) > dt->limit if ((index + 7) > dt->limit
|| cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 || cpu_memory_rw_debug(cs, 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+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
return 0; return 0;
*base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));

View file

@ -1594,6 +1594,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu)
static int kvm_guest_debug_workarounds(X86CPU *cpu) static int kvm_guest_debug_workarounds(X86CPU *cpu)
{ {
CPUState *cs = CPU(cpu);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
int ret = 0; int ret = 0;
unsigned long reinject_trap = 0; unsigned long reinject_trap = 0;
@ -1616,7 +1617,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu)
* reinject them via SET_GUEST_DEBUG. * reinject them via SET_GUEST_DEBUG.
*/ */
if (reinject_trap || 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); ret = kvm_update_guest_debug(env, reinject_trap);
} }
return ret; return ret;
@ -1931,25 +1932,23 @@ static int kvm_handle_tpr_access(X86CPU *cpu)
return 1; 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; static const uint8_t int3 = 0xcc;
if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&int3, 1, 1)) { cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) {
return -EINVAL; return -EINVAL;
} }
return 0; 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; uint8_t int3;
if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc || if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
@ -2042,13 +2041,14 @@ static CPUWatchpoint hw_watchpoint;
static int kvm_handle_debug(X86CPU *cpu, static int kvm_handle_debug(X86CPU *cpu,
struct kvm_debug_exit_arch *arch_info) struct kvm_debug_exit_arch *arch_info)
{ {
CPUState *cs = CPU(cpu);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
int ret = 0; int ret = 0;
int n; int n;
if (arch_info->exception == 1) { if (arch_info->exception == 1) {
if (arch_info->dr6 & (1 << 14)) { if (arch_info->dr6 & (1 << 14)) {
if (env->singlestep_enabled) { if (cs->singlestep_enabled) {
ret = EXCP_DEBUG; ret = EXCP_DEBUG;
} }
} else { } else {

View file

@ -8255,6 +8255,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
DisasContext dc1, *dc = &dc1; DisasContext dc1, *dc = &dc1;
target_ulong pc_ptr; 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->cpl = (flags >> HF_CPL_SHIFT) & 3;
dc->iopl = (flags >> IOPL_SHIFT) & 3; dc->iopl = (flags >> IOPL_SHIFT) & 3;
dc->tf = (flags >> TF_SHIFT) & 1; 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 = CC_OP_DYNAMIC;
dc->cc_op_dirty = false; dc->cc_op_dirty = false;
dc->cs_base = cs_base; 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; dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
#endif #endif
dc->flags = flags; dc->flags = flags;
dc->jmp_opt = !(dc->tf || env->singlestep_enabled || dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
(flags & HF_INHIBIT_IRQ_MASK) (flags & HF_INHIBIT_IRQ_MASK)
#ifndef CONFIG_SOFTMMU #ifndef CONFIG_SOFTMMU
|| (flags & HF_SOFTMMU_MASK) || (flags & HF_SOFTMMU_MASK)

View file

@ -78,5 +78,6 @@ extern const struct VMStateDescription vmstate_lm32_cpu;
void lm32_cpu_do_interrupt(CPUState *cpu); void lm32_cpu_do_interrupt(CPUState *cpu);
void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -22,6 +22,13 @@
#include "qemu-common.h" #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() */ /* CPUClass::reset() */
static void lm32_cpu_reset(CPUState *s) 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->do_interrupt = lm32_cpu_do_interrupt;
cc->dump_state = lm32_cpu_dump_state; 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 = { static const TypeInfo lm32_cpu_type_info = {

View file

@ -232,9 +232,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #include "exec/exec-all.h"
static inline void cpu_pc_from_tb(CPULM32State *env, TranslationBlock *tb)
{
env->pc = tb->pc;
}
#endif #endif

View file

@ -37,10 +37,12 @@ int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
return 0; 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; addr &= TARGET_PAGE_MASK;
if (env->flags & LM32_FLAG_IGNORE_MSB) { if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) {
return addr & 0x7fffffff; return addr & 0x7fffffff;
} else { } else {
return addr; return addr;

View file

@ -1015,6 +1015,7 @@ static inline
void gen_intermediate_code_internal(LM32CPU *cpu, void gen_intermediate_code_internal(LM32CPU *cpu,
TranslationBlock *tb, bool search_pc) TranslationBlock *tb, bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPULM32State *env = &cpu->env; CPULM32State *env = &cpu->env;
struct DisasContext ctx, *dc = &ctx; struct DisasContext ctx, *dc = &ctx;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
@ -1032,7 +1033,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
dc->is_jmp = DISAS_NEXT; dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start; dc->pc = pc_start;
dc->singlestep_enabled = env->singlestep_enabled; dc->singlestep_enabled = cs->singlestep_enabled;
dc->nr_nops = 0; dc->nr_nops = 0;
if (pc_start & 3) { if (pc_start & 3) {
@ -1077,7 +1078,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
} while (!dc->is_jmp } while (!dc->is_jmp
&& tcg_ctx.gen_opc_ptr < gen_opc_end && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !env->singlestep_enabled && !cs->singlestep_enabled
&& !singlestep && !singlestep
&& (dc->pc < next_page_start) && (dc->pc < next_page_start)
&& num_insns < max_insns); && num_insns < max_insns);
@ -1086,7 +1087,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
gen_io_end(); gen_io_end();
} }
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
if (dc->is_jmp == DISAS_NEXT) { if (dc->is_jmp == DISAS_NEXT) {
tcg_gen_movi_tl(cpu_pc, dc->pc); tcg_gen_movi_tl(cpu_pc, dc->pc);
} }

View file

@ -73,5 +73,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
void m68k_cpu_do_interrupt(CPUState *cpu); void m68k_cpu_do_interrupt(CPUState *cpu);
void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -23,6 +23,13 @@
#include "migration/vmstate.h" #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) static void m68k_set_feature(CPUM68KState *env, int feature)
{ {
env->features |= (1u << 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->class_by_name = m68k_cpu_class_by_name;
cc->do_interrupt = m68k_cpu_do_interrupt; cc->do_interrupt = m68k_cpu_do_interrupt;
cc->dump_state = m68k_cpu_dump_state; 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; dc->vmsd = &vmstate_m68k_cpu;
} }

View file

@ -260,9 +260,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #include "exec/exec-all.h"
static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
}
#endif #endif

View file

@ -121,10 +121,11 @@ M68kCPU *cpu_m68k_init(const char *cpu_model)
void m68k_cpu_init_gdb(M68kCPU *cpu) void m68k_cpu_init_gdb(M68kCPU *cpu)
{ {
CPUState *cs = CPU(cpu);
CPUM68KState *env = &cpu->env; CPUM68KState *env = &cpu->env;
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { 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); 11, "cf-fp.xml", 18);
} }
/* TODO: Add [E]MAC registers. */ /* TODO: Add [E]MAC registers. */
@ -290,7 +291,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
/* MMU */ /* MMU */
/* TODO: This will need fixing once the MMU is implemented. */ /* 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; return addr;
} }

View file

@ -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 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) { if (m68k_semi_is_fseek) {
/* FIXME: We've already lost the high bits of the fseek /* FIXME: We've already lost the high bits of the fseek
return value. */ return value. */

View file

@ -2974,6 +2974,7 @@ static inline void
gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUM68KState *env = &cpu->env; CPUM68KState *env = &cpu->env;
DisasContext dc1, *dc = &dc1; DisasContext dc1, *dc = &dc1;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
@ -2995,7 +2996,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
dc->is_jmp = DISAS_NEXT; dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start; dc->pc = pc_start;
dc->cc_op = CC_OP_DYNAMIC; dc->cc_op = CC_OP_DYNAMIC;
dc->singlestep_enabled = env->singlestep_enabled; dc->singlestep_enabled = cs->singlestep_enabled;
dc->fpcr = env->fpcr; dc->fpcr = env->fpcr;
dc->user = (env->sr & SR_S) == 0; dc->user = (env->sr & SR_S) == 0;
dc->is_mem = 0; dc->is_mem = 0;
@ -3038,14 +3039,14 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
disas_m68k_insn(env, dc); disas_m68k_insn(env, dc);
num_insns++; num_insns++;
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled && !cs->singlestep_enabled &&
!singlestep && !singlestep &&
(pc_offset) < (TARGET_PAGE_SIZE - 32) && (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
num_insns < max_insns); num_insns < max_insns);
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO)
gen_io_end(); gen_io_end();
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
/* Make sure the pc is updated, and raise a debug exception. */ /* Make sure the pc is updated, and raise a debug exception. */
if (!dc->is_jmp) { if (!dc->is_jmp) {
gen_flush_cc_op(dc); gen_flush_cc_op(dc);

View file

@ -74,5 +74,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
void mb_cpu_do_interrupt(CPUState *cs); void mb_cpu_do_interrupt(CPUState *cs);
void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -26,6 +26,13 @@
#include "migration/vmstate.h" #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() */ /* CPUClass::reset() */
static void mb_cpu_reset(CPUState *s) 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->do_interrupt = mb_cpu_do_interrupt;
cc->dump_state = mb_cpu_dump_state; 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->vmsd = &vmstate_mb_cpu;
dc->props = mb_properties; dc->props = mb_properties;
} }

View file

@ -365,9 +365,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #include "exec/exec-all.h"
static inline void cpu_pc_from_tb(CPUMBState *env, TranslationBlock *tb)
{
env->sregs[SR_PC] = tb->pc;
}
#endif #endif

View file

@ -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; target_ulong vaddr, paddr = 0;
struct microblaze_mmu_lookup lu; struct microblaze_mmu_lookup lu;
unsigned int hit; unsigned int hit;

View file

@ -1741,6 +1741,7 @@ static inline void
gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUMBState *env = &cpu->env; CPUMBState *env = &cpu->env;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
uint32_t pc_start; uint32_t pc_start;
@ -1766,7 +1767,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
dc->jmp = JMP_INDIRECT; dc->jmp = JMP_INDIRECT;
} }
dc->pc = pc_start; dc->pc = pc_start;
dc->singlestep_enabled = env->singlestep_enabled; dc->singlestep_enabled = cs->singlestep_enabled;
dc->cpustate_changed = 0; dc->cpustate_changed = 0;
dc->abort_at_next_insn = 0; dc->abort_at_next_insn = 0;
dc->nr_nops = 0; dc->nr_nops = 0;
@ -1859,8 +1860,9 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
break; break;
} }
} }
if (env->singlestep_enabled) if (cs->singlestep_enabled) {
break; break;
}
} while (!dc->is_jmp && !dc->cpustate_changed } while (!dc->is_jmp && !dc->cpustate_changed
&& tcg_ctx.gen_opc_ptr < gen_opc_end && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !singlestep && !singlestep
@ -1887,7 +1889,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
} }
t_sync_flags(dc); t_sync_flags(dc);
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG); TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
if (dc->is_jmp != DISAS_JUMP) { if (dc->is_jmp != DISAS_JUMP) {

View file

@ -77,5 +77,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
void mips_cpu_do_interrupt(CPUState *cpu); void mips_cpu_do_interrupt(CPUState *cpu);
void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -22,6 +22,29 @@
#include "qemu-common.h" #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() */ /* CPUClass::reset() */
static void mips_cpu_reset(CPUState *s) 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->do_interrupt = mips_cpu_do_interrupt;
cc->dump_state = mips_cpu_dump_state; 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 = { static const TypeInfo mips_cpu_type_info = {

View file

@ -732,13 +732,6 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #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) static inline void compute_hflags(CPUMIPSState *env)
{ {
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |

View file

@ -254,13 +254,16 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
} }
#if !defined(CONFIG_USER_ONLY) #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; hwaddr phys_addr;
int prot; 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 -1;
}
return phys_addr; return phys_addr;
} }
#endif #endif

View file

@ -15543,6 +15543,7 @@ static inline void
gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUMIPSState *env = &cpu->env; CPUMIPSState *env = &cpu->env;
DisasContext ctx; DisasContext ctx;
target_ulong pc_start; 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; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.pc = pc_start; ctx.pc = pc_start;
ctx.saved_pc = -1; ctx.saved_pc = -1;
ctx.singlestep_enabled = env->singlestep_enabled; ctx.singlestep_enabled = cs->singlestep_enabled;
ctx.insn_flags = env->insn_flags; ctx.insn_flags = env->insn_flags;
ctx.tb = tb; ctx.tb = tb;
ctx.bstate = BS_NONE; 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 This is what GDB expects and is consistent with what the
hardware does (e.g. if a delay slot instruction faults, the hardware does (e.g. if a delay slot instruction faults, the
reported PC is the PC of the branch). */ 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; break;
}
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
break; break;
@ -15653,9 +15655,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
if (singlestep) if (singlestep)
break; break;
} }
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO) {
gen_io_end(); 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); save_cpu_state(&ctx, ctx.bstate == BS_NONE);
gen_helper_0e0i(raise_exception, EXCP_DEBUG); gen_helper_0e0i(raise_exception, EXCP_DEBUG);
} else { } else {

View file

@ -22,6 +22,13 @@
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "machine.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) static void moxie_cpu_reset(CPUState *s)
{ {
MoxieCPU *cpu = MOXIE_CPU(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->do_interrupt = moxie_cpu_do_interrupt;
cc->dump_state = moxie_cpu_dump_state; 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) static void moxielite_initfn(Object *obj)

View file

@ -118,6 +118,7 @@ int cpu_moxie_exec(CPUMoxieState *s);
void moxie_cpu_do_interrupt(CPUState *cs); void moxie_cpu_do_interrupt(CPUState *cs);
void moxie_cpu_dump_state(CPUState *cpu, FILE *f, void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void moxie_translate_init(void); void moxie_translate_init(void);
int cpu_moxie_signal_handler(int host_signum, void *pinfo, int cpu_moxie_signal_handler(int host_signum, void *pinfo,
void *puc); void *puc);
@ -143,11 +144,6 @@ static inline int cpu_mmu_index(CPUMoxieState *env)
#include "exec/cpu-all.h" #include "exec/cpu-all.h"
#include "exec/exec-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, static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
target_ulong *cs_base, int *flags) target_ulong *cs_base, int *flags)
{ {

View file

@ -118,11 +118,6 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
return 1; return 1;
} }
hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
{
return addr;
}
#else /* !CONFIG_USER_ONLY */ #else /* !CONFIG_USER_ONLY */
int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address, 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; uint32_t phy = addr;
MoxieMMUResult res; MoxieMMUResult res;
int miss; int miss;
miss = moxie_mmu_translate(&res, env, addr, 0, 0);
miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
if (!miss) { if (!miss) {
phy = res.phy; phy = res.phy;
} }

View file

@ -824,6 +824,7 @@ static inline void
gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb, gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
DisasContext ctx; DisasContext ctx;
target_ulong pc_start; target_ulong pc_start;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
@ -871,7 +872,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
ctx.pc += decode_opc(cpu, &ctx); ctx.pc += decode_opc(cpu, &ctx);
num_insns++; num_insns++;
if (env->singlestep_enabled) { if (cs->singlestep_enabled) {
break; 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); } 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); tcg_gen_movi_tl(cpu_pc, ctx.pc);
gen_helper_debug(cpu_env); gen_helper_debug(cpu_env);
} else { } else {

View file

@ -20,6 +20,13 @@
#include "cpu.h" #include "cpu.h"
#include "qemu-common.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() */ /* CPUClass::reset() */
static void openrisc_cpu_reset(CPUState *s) 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->class_by_name = openrisc_cpu_class_by_name;
cc->do_interrupt = openrisc_cpu_do_interrupt; cc->do_interrupt = openrisc_cpu_do_interrupt;
cc->dump_state = openrisc_cpu_dump_state; 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) static void cpu_register(const OpenRISCCPUInfo *info)

View file

@ -349,6 +349,7 @@ int cpu_openrisc_exec(CPUOpenRISCState *s);
void openrisc_cpu_do_interrupt(CPUState *cpu); void openrisc_cpu_do_interrupt(CPUState *cpu);
void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void openrisc_translate_init(void); void openrisc_translate_init(void);
int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
target_ulong address, target_ulong address,
@ -428,9 +429,4 @@ static inline target_ulong cpu_get_pc(CPUOpenRISCState *env)
return env->pc; return env->pc;
} }
static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
}
#endif /* CPU_OPENRISC_H */ #endif /* CPU_OPENRISC_H */

View file

@ -219,12 +219,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
#endif #endif
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
hwaddr cpu_get_phys_page_debug(CPUOpenRISCState *env, hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
target_ulong addr)
{ {
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
hwaddr phys_addr; hwaddr phys_addr;
int prot; int prot;
OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) { if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
return -1; return -1;

View file

@ -1662,6 +1662,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
int search_pc) int search_pc)
{ {
CPUState *cs = CPU(cpu);
struct DisasContext ctx, *dc = &ctx; struct DisasContext ctx, *dc = &ctx;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
uint32_t pc_start; 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->mem_idx = cpu_mmu_index(&cpu->env);
dc->synced_flags = dc->tb_flags = tb->flags; dc->synced_flags = dc->tb_flags = tb->flags;
dc->delayed_branch = !!(dc->tb_flags & D_FLAG); 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)) { if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("-----------------------------------------\n"); qemu_log("-----------------------------------------\n");
log_cpu_state(CPU(cpu), 0); log_cpu_state(CPU(cpu), 0);
@ -1743,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
} }
} while (!dc->is_jmp } while (!dc->is_jmp
&& tcg_ctx.gen_opc_ptr < gen_opc_end && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !cpu->env.singlestep_enabled && !cs->singlestep_enabled
&& !singlestep && !singlestep
&& (dc->pc < next_page_start) && (dc->pc < next_page_start)
&& num_insns < max_insns); && num_insns < max_insns);
@ -1755,7 +1756,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
dc->is_jmp = DISAS_UPDATE; dc->is_jmp = DISAS_UPDATE;
tcg_gen_movi_tl(cpu_pc, dc->pc); 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) { if (dc->is_jmp == DISAS_NEXT) {
tcg_gen_movi_tl(cpu_pc, dc->pc); tcg_gen_movi_tl(cpu_pc, dc->pc);
} }

View file

@ -105,5 +105,6 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f, void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -2144,11 +2144,6 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #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); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
#endif /* !defined (__CPU_PPC_H__) */ #endif /* !defined (__CPU_PPC_H__) */

View file

@ -1409,8 +1409,10 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
return ret; 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; mmu_ctx_t ctx;
switch (env->mmu_model) { switch (env->mmu_model) {

View file

@ -9730,6 +9730,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env; CPUPPCState *env = &cpu->env;
DisasContext ctx, *ctxp = &ctx; DisasContext ctx, *ctxp = &ctx;
opc_handler_t **table, *handler; opc_handler_t **table, *handler;
@ -9770,8 +9771,9 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
ctx.singlestep_enabled = 0; ctx.singlestep_enabled = 0;
if ((env->flags & POWERPC_FLAG_BE) && msr_be) if ((env->flags & POWERPC_FLAG_BE) && msr_be)
ctx.singlestep_enabled |= CPU_BRANCH_STEP; ctx.singlestep_enabled |= CPU_BRANCH_STEP;
if (unlikely(env->singlestep_enabled)) if (unlikely(cs->singlestep_enabled)) {
ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP; ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
}
#if defined (DO_SINGLE_STEP) && 0 #if defined (DO_SINGLE_STEP) && 0
/* Single step trace mode */ /* Single step trace mode */
msr_se = 1; msr_se = 1;
@ -9873,7 +9875,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
ctx.exception != POWERPC_EXCP_BRANCH)) { ctx.exception != POWERPC_EXCP_BRANCH)) {
gen_exception(ctxp, POWERPC_EXCP_TRACE); gen_exception(ctxp, POWERPC_EXCP_TRACE);
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) || } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
(env->singlestep_enabled) || (cs->singlestep_enabled) ||
singlestep || singlestep ||
num_insns >= max_insns)) { num_insns >= max_insns)) {
/* if we reach a page boundary or are single stepping, stop /* 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) { if (ctx.exception == POWERPC_EXCP_NONE) {
gen_goto_tb(&ctx, 0, ctx.nip); gen_goto_tb(&ctx, 0, ctx.nip);
} else if (ctx.exception != POWERPC_EXCP_BRANCH) { } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
gen_debug_exception(ctxp); gen_debug_exception(ctxp);
} }
/* Generate the return instruction */ /* Generate the return instruction */

View file

@ -7804,8 +7804,8 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu)
static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev);
PowerPCCPU *cpu = POWERPC_CPU(dev); PowerPCCPU *cpu = POWERPC_CPU(dev);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
Error *local_err = NULL; Error *local_err = NULL;
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
@ -7849,15 +7849,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
init_ppc_proc(cpu); init_ppc_proc(cpu);
if (pcc->insns_flags & PPC_FLOAT) { 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); 33, "power-fpu.xml", 0);
} }
if (pcc->insns_flags & PPC_ALTIVEC) { 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); 34, "power-altivec.xml", 0);
} }
if (pcc->insns_flags & PPC_SPE) { 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); 34, "power-spe.xml", 0);
} }
@ -7865,6 +7865,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
#if defined(PPC_DUMP_CPU) #if defined(PPC_DUMP_CPU)
{ {
CPUPPCState *env = &cpu->env;
const char *mmu_model, *excp_model, *bus_model; const char *mmu_model, *excp_model, *bus_model;
switch (env->mmu_model) { switch (env->mmu_model) {
case POWERPC_MMU_32B: case POWERPC_MMU_32B:
@ -8016,10 +8017,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
printf(" none\n"); printf(" none\n");
printf(" Time-base/decrementer clock source: %s\n", printf(" Time-base/decrementer clock source: %s\n",
env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock"); 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 #endif
} }
@ -8322,6 +8323,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
return cpu_list; return cpu_list;
} }
static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
cpu->env.nip = value;
}
/* CPUClass::reset() */ /* CPUClass::reset() */
static void ppc_cpu_reset(CPUState *s) 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->do_interrupt = ppc_cpu_do_interrupt;
cc->dump_state = ppc_cpu_dump_state; cc->dump_state = ppc_cpu_dump_state;
cc->dump_statistics = ppc_cpu_dump_statistics; 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 = { static const TypeInfo ppc_cpu_type_info = {

View file

@ -74,5 +74,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
void s390_cpu_do_interrupt(CPUState *cpu); void s390_cpu_do_interrupt(CPUState *cpu);
void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -58,6 +58,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
} }
#endif #endif
static void s390_cpu_set_pc(CPUState *cs, vaddr value)
{
S390CPU *cpu = S390_CPU(cs);
cpu->env.psw.addr = value;
}
/* CPUClass::reset() */ /* CPUClass::reset() */
static void s390_cpu_reset(CPUState *s) 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->do_interrupt = s390_cpu_do_interrupt;
cc->dump_state = s390_cpu_dump_state; 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; dc->vmsd = &vmstate_s390_cpu;
} }

View file

@ -1041,11 +1041,6 @@ static inline bool cpu_has_work(CPUState *cpu)
(env->psw.mask & PSW_MASK_EXT); (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 */ /* fpu_helper.c */
uint32_t set_cc_nz_f32(float32 v); uint32_t set_cc_nz_f32(float32 v);
uint32_t set_cc_nz_f64(float64 v); uint32_t set_cc_nz_f64(float64 v);

View file

@ -417,9 +417,10 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
return 0; return 0;
} }
hwaddr cpu_get_phys_page_debug(CPUS390XState *env, hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
target_ulong vaddr)
{ {
S390CPU *cpu = S390_CPU(cs);
CPUS390XState *env = &cpu->env;
target_ulong raddr; target_ulong raddr;
int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
int old_exc = env->exception_index; int old_exc = env->exception_index;

View file

@ -4740,6 +4740,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUS390XState *env = &cpu->env; CPUS390XState *env = &cpu->env;
DisasContext dc; DisasContext dc;
target_ulong pc_start; target_ulong pc_start;
@ -4761,7 +4762,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
dc.tb = tb; dc.tb = tb;
dc.pc = pc_start; dc.pc = pc_start;
dc.cc_op = CC_OP_DYNAMIC; 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; 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 || tcg_ctx.gen_opc_ptr >= gen_opc_end
|| num_insns >= max_insns || num_insns >= max_insns
|| singlestep || singlestep
|| env->singlestep_enabled)) { || cs->singlestep_enabled)) {
status = EXIT_PC_STALE; status = EXIT_PC_STALE;
} }
} while (status == NO_EXIT); } while (status == NO_EXIT);

View file

@ -86,5 +86,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
void superh_cpu_do_interrupt(CPUState *cpu); void superh_cpu_do_interrupt(CPUState *cpu);
void superh_cpu_dump_state(CPUState *cpu, FILE *f, void superh_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -24,6 +24,21 @@
#include "migration/vmstate.h" #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() */ /* CPUClass::reset() */
static void superh_cpu_reset(CPUState *s) 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->class_by_name = superh_cpu_class_by_name;
cc->do_interrupt = superh_cpu_do_interrupt; cc->do_interrupt = superh_cpu_do_interrupt;
cc->dump_state = superh_cpu_dump_state; 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; dc->vmsd = &vmstate_sh_cpu;
} }

View file

@ -359,10 +359,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #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 */ #endif /* _CPU_SH4_H */

View file

@ -508,12 +508,13 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
return 0; 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; target_ulong physical;
int prot; int prot;
get_physical_address(env, &physical, &prot, addr, 0, 0); get_physical_address(&cpu->env, &physical, &prot, addr, 0, 0);
return physical; return physical;
} }

View file

@ -1849,6 +1849,7 @@ static inline void
gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
bool search_pc) bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUSH4State *env = &cpu->env; CPUSH4State *env = &cpu->env;
DisasContext ctx; DisasContext ctx;
target_ulong pc_start; target_ulong pc_start;
@ -1868,7 +1869,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
so assume it is a dynamic branch. */ so assume it is a dynamic branch. */
ctx.delayed_pc = -1; /* use delayed pc from env pointer */ ctx.delayed_pc = -1; /* use delayed pc from env pointer */
ctx.tb = tb; ctx.tb = tb;
ctx.singlestep_enabled = env->singlestep_enabled; ctx.singlestep_enabled = cs->singlestep_enabled;
ctx.features = env->features; ctx.features = env->features;
ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA); ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
@ -1914,8 +1915,9 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
ctx.pc += 2; ctx.pc += 2;
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
break; break;
if (env->singlestep_enabled) if (cs->singlestep_enabled) {
break; break;
}
if (num_insns >= max_insns) if (num_insns >= max_insns)
break; break;
if (singlestep) if (singlestep)
@ -1923,7 +1925,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
} }
if (tb->cflags & CF_LAST_IO) if (tb->cflags & CF_LAST_IO)
gen_io_end(); gen_io_end();
if (env->singlestep_enabled) { if (cs->singlestep_enabled) {
tcg_gen_movi_i32(cpu_pc, ctx.pc); tcg_gen_movi_i32(cpu_pc, ctx.pc);
gen_helper_debug(cpu_env); gen_helper_debug(cpu_env);
} else { } else {

View file

@ -78,5 +78,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
void sparc_cpu_do_interrupt(CPUState *cpu); void sparc_cpu_do_interrupt(CPUState *cpu);
void sparc_cpu_dump_state(CPUState *cpu, FILE *f, void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -723,6 +723,22 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "\n"); 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) static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
{ {
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); 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->do_interrupt = sparc_cpu_do_interrupt;
cc->dump_state = sparc_cpu_dump_state; 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 = { static const TypeInfo sparc_cpu_type_info = {

View file

@ -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); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
uint8_t *buf, int len, int is_write); uint8_t *buf, int len, bool is_write);
#define TARGET_CPU_MEMORY_RW_DEBUG
#endif #endif
@ -759,10 +758,4 @@ static inline bool cpu_has_work(CPUState *cpu)
#include "exec/exec-all.h" #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 #endif

View file

@ -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) void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
{ {
CPUState *cs = CPU(sparc_env_get_cpu(env));
target_ulong va, va1, va2; target_ulong va, va1, va2;
unsigned int n, m, o; unsigned int n, m, o;
hwaddr pde_ptr, pa; 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) { for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
pde = mmu_probe(env, va, 2); pde = mmu_probe(env, va, 2);
if (pde) { 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 (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
" PDE: " TARGET_FMT_lx "\n", va, pa, pde); " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
pde = mmu_probe(env, va1, 1); pde = mmu_probe(env, va1, 1);
if (pde) { 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: " (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n", TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
va1, pa, pde); va1, pa, pde);
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
pde = mmu_probe(env, va2, 0); pde = mmu_probe(env, va2, 0);
if (pde) { 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: " (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
TARGET_FMT_plx " PTE: " TARGET_FMT_plx " PTE: "
TARGET_FMT_lx "\n", 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 * reads (and only reads) in stack frames as if windows were flushed. We assume
* that the sparc ABI is followed. * that the sparc ABI is followed.
*/ */
int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address,
uint8_t *buf, int len, int is_write) uint8_t *buf, int len, bool is_write)
{ {
SPARCCPU *cpu = SPARC_CPU(cs);
CPUSPARCState *env = &cpu->env;
target_ulong addr = address;
int i; int i;
int len1; int len1;
int cwp = env->cwp; int cwp = env->cwp;
@ -389,7 +393,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
/* Handle access before this window. */ /* Handle access before this window. */
if (addr < fp) { if (addr < fp) {
len1 = fp - addr; 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; return -1;
} }
addr += len1; 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 */ #else /* !TARGET_SPARC64 */
@ -833,8 +837,10 @@ hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
} }
#endif #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; hwaddr phys_addr;
int mmu_idx = cpu_mmu_index(env); int mmu_idx = cpu_mmu_index(env);
MemoryRegionSection section; MemoryRegionSection section;

View file

@ -5223,6 +5223,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
TranslationBlock *tb, TranslationBlock *tb,
bool spc) bool spc)
{ {
CPUState *cs = CPU(cpu);
CPUSPARCState *env = &cpu->env; CPUSPARCState *env = &cpu->env;
target_ulong pc_start, last_pc; target_ulong pc_start, last_pc;
uint16_t *gen_opc_end; uint16_t *gen_opc_end;
@ -5244,7 +5245,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
dc->def = env->def; dc->def = env->def;
dc->fpu_enabled = tb_fpu_enabled(tb->flags); dc->fpu_enabled = tb_fpu_enabled(tb->flags);
dc->address_mask_32bit = tb_am_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; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
num_insns = 0; num_insns = 0;

View file

@ -63,5 +63,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
void uc32_cpu_do_interrupt(CPUState *cpu); void uc32_cpu_do_interrupt(CPUState *cpu);
void uc32_cpu_dump_state(CPUState *cpu, FILE *f, void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -16,6 +16,13 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "migration/vmstate.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) static inline void set_feature(CPUUniCore32State *env, int feature)
{ {
env->features |= 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->class_by_name = uc32_cpu_class_by_name;
cc->do_interrupt = uc32_cpu_do_interrupt; cc->do_interrupt = uc32_cpu_do_interrupt;
cc->dump_state = uc32_cpu_dump_state; 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; dc->vmsd = &vmstate_uc32_cpu;
} }

View file

@ -146,11 +146,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env)
#include "cpu-qom.h" #include "cpu-qom.h"
#include "exec/exec-all.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, static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
target_ulong *cs_base, int *flags) target_ulong *cs_base, int *flags)
{ {

View file

@ -261,9 +261,10 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
return ret; return ret;
} }
hwaddr cpu_get_phys_page_debug(CPUUniCore32State *env, hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
target_ulong 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; return addr;
} }

View file

@ -1879,6 +1879,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
TranslationBlock *tb, bool search_pc) TranslationBlock *tb, bool search_pc)
{ {
CPUState *cs = CPU(cpu);
CPUUniCore32State *env = &cpu->env; CPUUniCore32State *env = &cpu->env;
DisasContext dc1, *dc = &dc1; DisasContext dc1, *dc = &dc1;
CPUBreakpoint *bp; CPUBreakpoint *bp;
@ -1900,7 +1901,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
dc->is_jmp = DISAS_NEXT; dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start; dc->pc = pc_start;
dc->singlestep_enabled = env->singlestep_enabled; dc->singlestep_enabled = cs->singlestep_enabled;
dc->condjmp = 0; dc->condjmp = 0;
cpu_F0s = tcg_temp_new_i32(); cpu_F0s = tcg_temp_new_i32();
cpu_F1s = 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. */ * ensures prefetch aborts occur at the right place. */
num_insns++; num_insns++;
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled && !cs->singlestep_enabled &&
!singlestep && !singlestep &&
dc->pc < next_page_start && dc->pc < next_page_start &&
num_insns < max_insns); 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 /* At this stage dc->condjmp will only be set when the skipped
instruction was a conditional branch or trap, and the PC has instruction was a conditional branch or trap, and the PC has
already been written. */ already been written. */
if (unlikely(env->singlestep_enabled)) { if (unlikely(cs->singlestep_enabled)) {
/* Make sure the pc is updated, and raise a debug exception. */ /* Make sure the pc is updated, and raise a debug exception. */
if (dc->condjmp) { if (dc->condjmp) {
if (dc->is_jmp == DISAS_SYSCALL) { if (dc->is_jmp == DISAS_SYSCALL) {

View file

@ -83,5 +83,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
void xtensa_cpu_do_interrupt(CPUState *cpu); void xtensa_cpu_do_interrupt(CPUState *cpu);
void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
#endif #endif

View file

@ -33,6 +33,13 @@
#include "migration/vmstate.h" #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() */ /* CPUClass::reset() */
static void xtensa_cpu_reset(CPUState *s) 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->do_interrupt = xtensa_cpu_do_interrupt;
cc->dump_state = xtensa_cpu_dump_state; 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; dc->vmsd = &vmstate_xtensa_cpu;
} }

Some files were not shown because too many files have changed in this diff Show more