Final moves from cpu-defs.h to qom/cpu.h
Change-Id: I70e68e9bd2f2510726b782b8b179afc8bfd5f065
diff --git a/cpu-exec.c b/cpu-exec.c
index 9cc8741..af9bdc9 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -180,12 +180,13 @@
debug_excp_handler = handler;
}
-static void cpu_handle_debug_exception(CPUOldState *env)
+static void cpu_handle_debug_exception(CPUArchState *env)
{
+ CPUState *cpu = ENV_GET_CPU(env);
CPUWatchpoint *wp;
- if (!env->watchpoint_hit) {
- QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ if (!cpu->watchpoint_hit) {
+ QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
wp->flags &= ~BP_WATCHPOINT_HIT;
}
}
@@ -647,17 +648,17 @@
tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
/* Restore PC. */
cpu_pc_from_tb(env, tb);
- insns_left = env->icount_decr.u32;
- if (env->icount_extra && insns_left >= 0) {
+ insns_left = cpu->icount_decr.u32;
+ if (cpu->icount_extra && insns_left >= 0) {
/* Refill decrementer and continue execution. */
- env->icount_extra += insns_left;
- if (env->icount_extra > 0xffff) {
+ cpu->icount_extra += insns_left;
+ if (cpu->icount_extra > 0xffff) {
insns_left = 0xffff;
} else {
- insns_left = env->icount_extra;
+ insns_left = cpu->icount_extra;
}
- env->icount_extra -= insns_left;
- env->icount_decr.u16.low = insns_left;
+ cpu->icount_extra -= insns_left;
+ cpu->icount_decr.u16.low = insns_left;
} else {
if (insns_left > 0) {
/* Execute remaining instructions. */
diff --git a/cpus.c b/cpus.c
index 8c5d617..589f40a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -306,7 +306,7 @@
if (!cpu_can_do_io(cpu)) {
fprintf(stderr, "Bad clock read\n");
}
- icount -= (env->icount_decr.u16.low + env->icount_extra);
+ icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
}
return qemu_icount_bias + (icount << icount_time_shift);
}
diff --git a/cputlb.c b/cputlb.c
index d7d5da2..600ea4a 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -208,6 +208,7 @@
hwaddr paddr, int prot,
int mmu_idx, target_ulong size)
{
+ CPUState *cpu = ENV_GET_CPU(env);
PhysPageDesc *p;
unsigned long pd;
unsigned int index;
@@ -265,7 +266,7 @@
code_address = address;
/* Make accesses to pages with watchpoints go via the
watchpoint trap routines. */
- QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
iotlb = io_mem_watch + paddr;
/* TODO: The memory case can be optimized by not trapping
diff --git a/exec.c b/exec.c
index 277f004..e95a925 100644
--- a/exec.c
+++ b/exec.c
@@ -47,9 +47,11 @@
#include "exec/hax.h"
#include "exec/ram_addr.h"
#include "qemu/timer.h"
+#include "qemu/error-report.h"
#if defined(CONFIG_USER_ONLY)
#include <qemu.h>
#endif
+
#include "translate-all.h"
//#define DEBUG_SUBPAGE
@@ -181,8 +183,8 @@
QTAILQ_INSERT_TAIL(&cpus, cpu, node);
cpu->numa_node = 0;
- QTAILQ_INIT(&env->breakpoints);
- QTAILQ_INIT(&env->watchpoints);
+ QTAILQ_INIT(&cpu->breakpoints);
+ QTAILQ_INIT(&cpu->watchpoints);
#if defined(CONFIG_USER_ONLY)
cpu_list_unlock();
#endif
@@ -205,49 +207,54 @@
}
#if defined(TARGET_HAS_ICE)
-static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+#if defined(CONFIG_USER_ONLY)
+static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{
- hwaddr addr;
- target_ulong pd;
- ram_addr_t ram_addr;
- PhysPageDesc *p;
+ tb_invalidate_phys_page_range(pc, pc + 1, 0);
+}
+#else
+static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
+{
+ CPUArchState *env = cpu->env_ptr;
- addr = cpu_get_phys_page_debug(env, pc);
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
+ hwaddr addr = cpu_get_phys_page_debug(env, pc);
+ PhysPageDesc *p = phys_page_find(addr >> TARGET_PAGE_BITS);
+ target_ulong pd;
if (!p) {
pd = IO_MEM_UNASSIGNED;
} else {
pd = p->phys_offset;
}
- ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
+ ram_addr_t ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
}
#endif
+#endif /* TARGET_HAS_ICE */
#if defined(CONFIG_USER_ONLY)
-void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
+void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
{
}
-int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
+int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
int flags, CPUWatchpoint **watchpoint)
{
return -ENOSYS;
}
#else
/* Add a watchpoint. */
-int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
+int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
int flags, CPUWatchpoint **watchpoint)
{
- target_ulong len_mask = ~(len - 1);
+ vaddr len_mask = ~(len - 1);
CPUWatchpoint *wp;
/* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
if ((len & (len - 1)) || (addr & ~len_mask) ||
len == 0 || len > TARGET_PAGE_SIZE) {
- fprintf(stderr, "qemu: tried to set invalid watchpoint at "
- TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
+ error_report("tried to set invalid watchpoint at %"
+ VADDR_PRIx ", len=%" VADDR_PRIu, addr, len);
return -EINVAL;
}
wp = g_malloc(sizeof(*wp));
@@ -257,12 +264,13 @@
wp->flags = flags;
/* keep all GDB-injected watchpoints in front */
- if (flags & BP_GDB)
- QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
- else
- QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
+ if (flags & BP_GDB) {
+ QTAILQ_INSERT_HEAD(&cpu->watchpoints, wp, entry);
+ } else {
+ QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
+ }
- tlb_flush_page(env, addr);
+ tlb_flush_page(cpu->env_ptr, addr);
if (watchpoint)
*watchpoint = wp;
@@ -270,16 +278,16 @@
}
/* Remove a specific watchpoint. */
-int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len,
+int cpu_watchpoint_remove(CPUState *cpu, vaddr addr, vaddr len,
int flags)
{
- target_ulong len_mask = ~(len - 1);
+ vaddr len_mask = ~(len - 1);
CPUWatchpoint *wp;
- QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
if (addr == wp->vaddr && len_mask == wp->len_mask
&& flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
- cpu_watchpoint_remove_by_ref(env, wp);
+ cpu_watchpoint_remove_by_ref(cpu, wp);
return 0;
}
}
@@ -287,29 +295,30 @@
}
/* Remove a specific watchpoint by reference. */
-void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
+void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint)
{
- QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
+ QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
- tlb_flush_page(env, watchpoint->vaddr);
+ tlb_flush_page(cpu->env_ptr, watchpoint->vaddr);
g_free(watchpoint);
}
/* Remove all matching watchpoints. */
-void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
+void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
{
CPUWatchpoint *wp, *next;
- QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
- if (wp->flags & mask)
- cpu_watchpoint_remove_by_ref(env, wp);
+ QTAILQ_FOREACH_SAFE(wp, &cpu->watchpoints, entry, next) {
+ if (wp->flags & mask) {
+ cpu_watchpoint_remove_by_ref(cpu, wp);
+ }
}
}
#endif
/* Add a breakpoint. */
-int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
+int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
CPUBreakpoint **breakpoint)
{
#if defined(TARGET_HAS_ICE)
@@ -322,12 +331,12 @@
/* keep all GDB-injected breakpoints in front */
if (flags & BP_GDB) {
- QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
+ QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry);
} else {
- QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
+ QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry);
}
- breakpoint_invalidate(env, pc);
+ breakpoint_invalidate(cpu, pc);
if (breakpoint) {
*breakpoint = bp;
@@ -339,14 +348,14 @@
}
/* Remove a specific breakpoint. */
-int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
+int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags)
{
#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
if (bp->pc == pc && bp->flags == flags) {
- cpu_breakpoint_remove_by_ref(env, bp);
+ cpu_breakpoint_remove_by_ref(cpu, bp);
return 0;
}
}
@@ -357,26 +366,27 @@
}
/* Remove a specific breakpoint by reference. */
-void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
+void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint)
{
#if defined(TARGET_HAS_ICE)
- QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
+ QTAILQ_REMOVE(&cpu->breakpoints, breakpoint, entry);
- breakpoint_invalidate(env, breakpoint->pc);
+ breakpoint_invalidate(cpu, breakpoint->pc);
g_free(breakpoint);
#endif
}
/* Remove all matching breakpoints. */
-void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
+void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
{
#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp, *next;
- QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
- if (bp->flags & mask)
- cpu_breakpoint_remove_by_ref(env, bp);
+ QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) {
+ if (bp->flags & mask) {
+ cpu_breakpoint_remove_by_ref(cpu, bp);
+ }
}
#endif
}
@@ -393,7 +403,8 @@
} else {
/* must flush all the translated code to avoid inconsistencies */
/* XXX: only flush what is necessary */
- tb_flush(cpu->env_ptr);
+ CPUArchState *env = cpu->env_ptr;
+ tb_flush(env);
}
}
#endif
@@ -1531,7 +1542,7 @@
CPUWatchpoint *wp;
int cpu_flags;
- if (env->watchpoint_hit) {
+ if (cpu->watchpoint_hit) {
/* We re-entered the check after replacing the TB. Now raise
* the debug interrupt so that is will trigger after the
* current instruction. */
@@ -1539,12 +1550,12 @@
return;
}
vaddr = (cpu->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
- QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+ QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
if ((vaddr == (wp->vaddr & len_mask) ||
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
wp->flags |= BP_WATCHPOINT_HIT;
- if (!env->watchpoint_hit) {
- env->watchpoint_hit = wp;
+ if (!cpu->watchpoint_hit) {
+ cpu->watchpoint_hit = wp;
tb_check_watchpoint(env);
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
cpu->exception_index = EXCP_DEBUG;
diff --git a/gdbstub.c b/gdbstub.c
index f44f547..58bdae1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1978,8 +1978,8 @@
return;
if (reason == EXCP_DEBUG) {
- if (env->watchpoint_hit) {
- switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
+ if (cpu->watchpoint_hit) {
+ switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
case BP_MEM_READ:
type = "r";
break;
@@ -1993,8 +1993,8 @@
snprintf(buf, sizeof(buf),
"T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
GDB_SIGNAL_TRAP, cpu_index(cpu), type,
- (target_ulong)env->watchpoint_hit->vaddr);
- env->watchpoint_hit = NULL;
+ (target_ulong)cpu->watchpoint_hit->vaddr);
+ cpu->watchpoint_hit = NULL;
goto send_packet;
}
tb_flush(env);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 473b19a..6192478 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -411,33 +411,6 @@
| CPU_INTERRUPT_TGT_EXT_3 \
| CPU_INTERRUPT_TGT_EXT_4)
-/* Breakpoint/watchpoint flags */
-#define BP_MEM_READ 0x01
-#define BP_MEM_WRITE 0x02
-#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
-#define BP_STOP_BEFORE_ACCESS 0x04
-#define BP_WATCHPOINT_HIT 0x08
-#define BP_GDB 0x10
-#define BP_CPU 0x20
-
-int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
- CPUBreakpoint **breakpoint);
-int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags);
-void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint);
-void cpu_breakpoint_remove_all(CPUArchState *env, int mask);
-int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
- int flags, CPUWatchpoint **watchpoint);
-int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
- target_ulong len, int flags);
-void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
-void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
-
-#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
-#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
-#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
-
-void cpu_single_step(CPUState *cpu, int enabled);
-
/* IO ports API */
#include "exec/ioport.h"
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index eb172b9..8f40558 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -30,7 +30,9 @@
#include "qemu-common.h"
#include "qemu/osdep.h"
#include "qemu/queue.h"
+#ifndef CONFIG_USER_ONLY
#include "exec/hwaddr.h"
+#endif
#ifndef TARGET_LONG_BITS
#error TARGET_LONG_BITS must be defined before including this header
@@ -117,55 +119,10 @@
#endif
-#ifdef HOST_WORDS_BIGENDIAN
-typedef struct icount_decr_u16 {
- uint16_t high;
- uint16_t low;
-} icount_decr_u16;
-#else
-typedef struct icount_decr_u16 {
- uint16_t low;
- uint16_t high;
-} icount_decr_u16;
-#endif
-
-struct kvm_run;
-struct KVMState;
-struct qemu_work_item;
-
-typedef struct CPUBreakpoint {
- target_ulong pc;
- int flags; /* BP_* */
- QTAILQ_ENTRY(CPUBreakpoint) entry;
-} CPUBreakpoint;
-
-typedef struct CPUWatchpoint {
- target_ulong vaddr;
- target_ulong len_mask;
- int flags; /* BP_* */
- QTAILQ_ENTRY(CPUWatchpoint) entry;
-} CPUWatchpoint;
#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
/* soft mmu support */ \
CPU_COMMON_TLB \
- \
- int64_t icount_extra; /* Instructions until next timer event. */ \
- /* Number of cycles left, with interrupt flag in high bit. \
- This allows a single read-compare-cbranch-write sequence to test \
- for both decrementer underflow and exceptions. */ \
- union { \
- uint32_t u32; \
- icount_decr_u16 u16; \
- } icount_decr; \
- \
- /* from this point: preserved by CPU reset */ \
- /* ice debug support */ \
- QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
- \
- QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
- CPUWatchpoint *watchpoint_hit; \
- \
#endif
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index b231d0f..9fc4fb1 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -17,13 +17,15 @@
icount_label = gen_new_label();
count = tcg_temp_local_new_i32();
- tcg_gen_ld_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u32));
+ tcg_gen_ld_i32(count, cpu_env,
+ -ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
/* This is a horrid hack to allow fixing up the value later. */
icount_arg = tcg_ctx.gen_opparam_ptr + 1;
tcg_gen_subi_i32(count, count, 0xdeadbeef);
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
- tcg_gen_st16_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u16.low));
+ tcg_gen_st16_i32(count, cpu_env,
+ -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
tcg_temp_free_i32(count);
}
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 3b4071a..b25d20f 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -58,6 +58,31 @@
struct TranslationBlock;
+#ifdef HOST_WORDS_BIGENDIAN
+typedef struct icount_decr_u16 {
+ uint16_t high;
+ uint16_t low;
+} icount_decr_u16;
+#else
+typedef struct icount_decr_u16 {
+ uint16_t low;
+ uint16_t high;
+} icount_decr_u16;
+#endif
+
+typedef struct CPUBreakpoint {
+ vaddr pc;
+ int flags; /* BP_* */
+ QTAILQ_ENTRY(CPUBreakpoint) entry;
+} CPUBreakpoint;
+
+typedef struct CPUWatchpoint {
+ vaddr vaddr;
+ vaddr len_mask;
+ int flags; /* BP_* */
+ QTAILQ_ENTRY(CPUWatchpoint) entry;
+} CPUWatchpoint;
+
struct KVMState;
struct kvm_run;
@@ -85,6 +110,7 @@
volatile sig_atomic_t exit_request;
uint32_t interrupt_request;
int singlestep_enabled;
+ int64_t icount_extra;
sigjmp_buf jmp_env;
void *env_ptr; /* CPUArchState */
@@ -95,6 +121,12 @@
const char *cpu_model_str;
+ /* ice debug support */
+ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;
+
+ QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;
+ CPUWatchpoint *watchpoint_hit;
+
void *opaque;
/* In order to avoid passing too many arguments to the MMIO helpers,
@@ -113,6 +145,10 @@
/* TODO Move common fields from CPUArchState here. */
int cpu_index; /* used by alpha TCG */
uint32_t halted; /* used by alpha, cris, ppc TCG */
+ union {
+ uint32_t u32;
+ icount_decr_u16 u16;
+ } icount_decr;
uint32_t can_do_io;
int32_t exception_index; /* used by m68k TCG */
@@ -280,6 +316,7 @@
*/
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 */
@@ -293,7 +330,28 @@
*/
void cpu_single_step(CPUState *cpu, int enabled);
+/* Breakpoint/watchpoint flags */
+#define BP_MEM_READ 0x01
+#define BP_MEM_WRITE 0x02
+#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
+#define BP_STOP_BEFORE_ACCESS 0x04
+#define BP_WATCHPOINT_HIT 0x08
+#define BP_GDB 0x10
+#define BP_CPU 0x20
+
+int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
+ CPUBreakpoint **breakpoint);
+int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags);
+void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint);
+void cpu_breakpoint_remove_all(CPUState *cpu, int mask);
+
+int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
+ int flags, CPUWatchpoint **watchpoint);
+int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
+ vaddr len, int flags);
+void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint);
+void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
-#endif // QEMU_CPU_H
+#endif
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 2da60ff..3b818b5 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -217,9 +217,6 @@
uint32_t teecr;
uint32_t teehbr;
- /* Internal CPU feature flags. */
- uint32_t features;
-
/* VFP coprocessor state. */
struct {
float64 regs[32];
@@ -272,6 +269,9 @@
/* These fields after the common ones so they are preserved on reset. */
+ /* Internal CPU feature flags. */
+ uint32_t features;
+
/* Coprocessor IO used by peripherals */
struct {
ARMReadCPFunc *cp_read;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index d522318..d3ec336 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -304,7 +304,7 @@
}
id = env->cp15.c0_cpuid;
- memset(env, 0, offsetof(CPUARMState, breakpoints));
+ memset(env, 0, offsetof(CPUARMState, features));
if (id)
cpu_reset_model_id(env, id);
/* DBGDIDR : we implement nothing, and just mirror the main ID
diff --git a/target-arm/translate.c b/target-arm/translate.c
index a878df5..935068e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9793,17 +9793,18 @@
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
basic block 'tb'. If search_pc is TRUE, also generate PC
information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUARMState *env,
+static inline void gen_intermediate_code_internal(ARMCPU *cpu,
TranslationBlock *tb,
- int search_pc)
+ bool search_pc)
{
- CPUState *cs = ENV_GET_CPU(env);
+ CPUState *cs = CPU(cpu);
+ CPUARMState *env = &cpu->env;
DisasContext dc1, *dc = &dc1;
CPUBreakpoint *bp;
uint16_t *gen_opc_end;
int j, lj;
target_ulong pc_start;
- uint32_t next_page_start;
+ target_ulong next_page_start;
int num_insns;
int max_insns;
@@ -9905,8 +9906,8 @@
}
#endif
- if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == dc->pc) {
gen_exception_insn(dc, 0, EXCP_DEBUG);
/* Advance PC so that clearing the breakpoint will
@@ -9968,7 +9969,7 @@
* ensures prefetch aborts occur at the right place. */
num_insns ++;
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
- !ENV_GET_CPU(env)->singlestep_enabled &&
+ !cs->singlestep_enabled &&
!singlestep &&
dc->pc < next_page_start &&
num_insns < max_insns);
@@ -9985,7 +9986,7 @@
/* At this stage dc->condjmp will only be set when the skipped
instruction was a conditional branch or trap, and the PC has
already been written. */
- if (unlikely(ENV_GET_CPU(env)->singlestep_enabled)) {
+ if (unlikely(cs->singlestep_enabled)) {
/* Make sure the pc is updated, and raise a debug exception. */
if (dc->condjmp) {
gen_set_condexec(dc);
@@ -10071,12 +10072,12 @@
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 0);
+ gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
}
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 1);
+ gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
}
static const char *cpu_mode_names[16] = {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4fa1729..cc2cd47 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -832,22 +832,23 @@
uint64_t tsc;
- uint64_t pat;
-
/* exception/interrupt handling */
int error_code;
int exception_is_int;
target_ulong exception_next_eip;
target_ulong dr[8]; /* debug registers */
union {
- CPUBreakpoint *cpu_breakpoint[4];
- CPUWatchpoint *cpu_watchpoint[4];
+ struct CPUBreakpoint *cpu_breakpoint[4];
+ struct CPUWatchpoint *cpu_watchpoint[4];
}; /* break/watchpoints for dr[0..3] */
uint32_t smbase;
int old_exception; /* exception in flight */
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
+ uint64_t pat;
+
/* processor features (e.g. for CPUID insn) */
uint32_t cpuid_level;
uint32_t cpuid_vendor1;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index f5f9e06..e2eb361 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -472,7 +472,7 @@
log_cpu_state(cpu, X86_DUMP_FPU | X86_DUMP_CCOP);
}
- memset(env, 0, offsetof(CPUX86State, breakpoints));
+ memset(env, 0, offsetof(CPUX86State, pat));
tlb_flush(env, 1);
@@ -530,8 +530,8 @@
memset(env->dr, 0, sizeof(env->dr));
env->dr[6] = DR6_FIXED_1;
env->dr[7] = DR7_FIXED_1;
- cpu_breakpoint_remove_all(env, BP_CPU);
- cpu_watchpoint_remove_all(env, BP_CPU);
+ cpu_breakpoint_remove_all(cpu, BP_CPU);
+ cpu_watchpoint_remove_all(cpu, BP_CPU);
}
void cpu_x86_close(CPUX86State *env)
@@ -1351,13 +1351,15 @@
void hw_breakpoint_insert(CPUX86State *env, int index)
{
+ CPUState *cs = CPU(x86_env_get_cpu(env));
int type, err = 0;
switch (hw_breakpoint_type(env->dr[7], index)) {
case 0:
- if (hw_breakpoint_enabled(env->dr[7], index))
- err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
+ if (hw_breakpoint_enabled(env->dr[7], index)) {
+ err = cpu_breakpoint_insert(cs, env->dr[index], BP_CPU,
&env->cpu_breakpoint[index]);
+ }
break;
case 1:
type = BP_CPU | BP_MEM_WRITE;
@@ -1368,27 +1370,32 @@
case 3:
type = BP_CPU | BP_MEM_ACCESS;
insert_wp:
- err = cpu_watchpoint_insert(env, env->dr[index],
+ err = cpu_watchpoint_insert(cs, env->dr[index],
hw_breakpoint_len(env->dr[7], index),
type, &env->cpu_watchpoint[index]);
break;
}
- if (err)
+
+ if (err) {
env->cpu_breakpoint[index] = NULL;
+ }
}
void hw_breakpoint_remove(CPUX86State *env, int index)
{
- if (!env->cpu_breakpoint[index])
+ CPUState *cs;
+ if (!env->cpu_breakpoint[index]) {
return;
+ }
+ cs = CPU(x86_env_get_cpu(env));
switch (hw_breakpoint_type(env->dr[7], index)) {
case 0:
if (hw_breakpoint_enabled(env->dr[7], index))
- cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
+ cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
break;
case 1:
case 3:
- cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
+ cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
break;
case 2:
/* No support for I/O watchpoints yet */
@@ -1420,18 +1427,20 @@
static void breakpoint_handler(CPUX86State *env)
{
+ CPUState *cs = CPU(x86_env_get_cpu(env));
CPUBreakpoint *bp;
- if (env->watchpoint_hit) {
- if (env->watchpoint_hit->flags & BP_CPU) {
- env->watchpoint_hit = NULL;
- if (check_hw_breakpoints(env, 0))
+ if (cs->watchpoint_hit) {
+ if (cs->watchpoint_hit->flags & BP_CPU) {
+ cs->watchpoint_hit = NULL;
+ if (check_hw_breakpoints(env, 0)) {
raise_exception(env, EXCP01_DB);
- else
+ } else {
cpu_resume_from_signal(env, NULL);
+ }
}
} else {
- QTAILQ_FOREACH(bp, &env->breakpoints, entry)
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == env->eip) {
if (bp->flags & BP_CPU) {
check_hw_breakpoints(env, 1);
@@ -1439,6 +1448,7 @@
}
break;
}
+ }
}
}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 3efc138..bf66a51 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -918,12 +918,13 @@
int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
{
+ CPUState *cs = current_cpu;
int handle = 0;
int n;
if (arch_info->exception == 1) {
if (arch_info->dr6 & (1 << 14)) {
- if (current_cpu->singlestep_enabled) {
+ if (cs->singlestep_enabled) {
handle = 1;
}
} else {
@@ -935,13 +936,13 @@
break;
case 0x1:
handle = 1;
- cpu_single_env->watchpoint_hit = &hw_watchpoint;
+ cs->watchpoint_hit = &hw_watchpoint;
hw_watchpoint.vaddr = hw_breakpoint[n].addr;
hw_watchpoint.flags = BP_MEM_WRITE;
break;
case 0x3:
handle = 1;
- cpu_single_env->watchpoint_hit = &hw_watchpoint;
+ cs->watchpoint_hit = &hw_watchpoint;
hw_watchpoint.vaddr = hw_breakpoint[n].addr;
hw_watchpoint.flags = BP_MEM_ACCESS;
break;
diff --git a/target-i386/machine.c b/target-i386/machine.c
index d4f0a40..d743237 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -145,6 +145,7 @@
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
CPUX86State *env = opaque;
+ CPUState *cs = ENV_GET_CPU(env);
int i, guess_mmx;
uint32_t hflags;
uint16_t fptag, fpregs_format;
@@ -220,8 +221,8 @@
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->dr[i]);
- cpu_breakpoint_remove_all(env, BP_CPU);
- cpu_watchpoint_remove_all(env, BP_CPU);
+ cpu_breakpoint_remove_all(cs, BP_CPU);
+ cpu_watchpoint_remove_all(cs, BP_CPU);
for (i = 0; i < 4; i++)
hw_breakpoint_insert(env, i);
diff --git a/target-i386/translate.c b/target-i386/translate.c
index f125877..2d91461 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7761,13 +7761,15 @@
"cc_dst");
}
-/* generate intermediate code in tcg_ctx.gen_opc_buf and gen_opparam_buf for
+/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
basic block 'tb'. If search_pc is TRUE, also generate PC
information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUX86State *env,
+static inline void gen_intermediate_code_internal(X86CPU *cpu,
TranslationBlock *tb,
- int search_pc)
+ bool search_pc)
{
+ CPUState *cs = CPU(cpu);
+ CPUX86State *env = &cpu->env;
DisasContext dc1, *dc = &dc1;
target_ulong pc_ptr;
uint16_t *gen_opc_end;
@@ -7793,7 +7795,7 @@
dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
dc->iopl = (flags >> IOPL_SHIFT) & 3;
dc->tf = (flags >> TF_SHIFT) & 1;
- dc->singlestep_enabled = ENV_GET_CPU(env)->singlestep_enabled;
+ dc->singlestep_enabled = cs->singlestep_enabled;
dc->cc_op = CC_OP_DYNAMIC;
dc->cc_op_dirty = false;
dc->cs_base = cs_base;
@@ -7816,7 +7818,7 @@
dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
#endif
dc->flags = flags;
- dc->jmp_opt = !(dc->tf || ENV_GET_CPU(env)->singlestep_enabled ||
+ dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
(flags & HF_INHIBIT_IRQ_MASK)
#ifndef CONFIG_SOFTMMU
|| (flags & HF_SOFTMMU_MASK)
@@ -7855,8 +7857,8 @@
gen_icount_start();
for(;;) {
- if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == pc_ptr &&
!((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
gen_debug(dc, pc_ptr - dc->cs_base);
@@ -7882,8 +7884,7 @@
pc_ptr = disas_insn(env, dc, pc_ptr);
num_insns++;
#ifdef CONFIG_HAX
- if (hax_enabled() && hax_stop_translate(ENV_GET_CPU(env)))
- {
+ if (hax_enabled() && hax_stop_translate(cs)) {
gen_jmp_im(pc_ptr - dc->cs_base);
gen_eob(dc);
break;
@@ -7954,12 +7955,12 @@
void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 0);
+ gen_intermediate_code_internal(x86_env_get_cpu(env), tb, false);
}
void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 1);
+ gen_intermediate_code_internal(x86_env_get_cpu(env), tb, true);
}
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 339f100..ccb71f6 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -471,6 +471,7 @@
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
CPUMIPSMVPContext *mvp;
#if !defined(CONFIG_USER_ONLY)
CPUMIPSTLBContext *tlb;
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 1b6cef1..c3f0400 100755
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -8334,9 +8334,11 @@
}
static inline void
-gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
- int search_pc)
+gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
+ bool search_pc)
{
+ CPUState *cs = CPU(cpu);
+ CPUMIPSState *env = &cpu->env;
DisasContext ctx;
target_ulong pc_start;
uint16_t *gen_opc_end;
@@ -8352,7 +8354,7 @@
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.pc = pc_start;
ctx.saved_pc = -1;
- ctx.singlestep_enabled = ENV_GET_CPU(env)->singlestep_enabled;
+ ctx.singlestep_enabled = cs->singlestep_enabled;
ctx.tb = tb;
ctx.bstate = BS_NONE;
/* Restore delay slot state from the tb context. */
@@ -8375,8 +8377,8 @@
LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
gen_icount_start();
while (ctx.bstate == BS_NONE) {
- if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == ctx.pc) {
save_cpu_state(&ctx, 1);
ctx.bstate = BS_BRANCH;
@@ -8412,8 +8414,9 @@
This is what GDB expects and is consistent with what the
hardware does (e.g. if a delay slot instruction faults, the
reported PC is the PC of the branch). */
- if (ENV_GET_CPU(env)->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
+ if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
break;
+ }
/* Do not split a branch instruction and its delay slot into two
TB's when a page boundary is crossed. This causes TB's to be
@@ -8421,8 +8424,9 @@
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
break;
- if (tcg_ctx.gen_opc_ptr >= gen_opc_end)
+ if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
break;
+ }
if (num_insns >= max_insns)
break;
@@ -8430,9 +8434,10 @@
if (singlestep)
break;
}
- if (tb->cflags & CF_LAST_IO)
+ if (tb->cflags & CF_LAST_IO) {
gen_io_end();
- if (ENV_GET_CPU(env)->singlestep_enabled && ctx.bstate != BS_BRANCH) {
+ }
+ if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
save_cpu_state(&ctx, ctx.bstate == BS_NONE);
gen_helper_1i(raise_exception, cpu_env, EXCP_DEBUG);
} else {
@@ -8479,12 +8484,12 @@
void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 0);
+ gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
}
void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 1);
+ gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
}
static void fpu_dump_state(CPUMIPSState *env, FILE *f,
@@ -8672,7 +8677,7 @@
log_cpu_state(cpu, 0);
}
- memset(env, 0, offsetof(CPUMIPSState, breakpoints));
+ memset(env, 0, offsetof(CPUMIPSState, mvp));
tlb_flush(env, 1);
/* Reset registers to their default values */
diff --git a/translate-all.c b/translate-all.c
index b552105..179675f 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -215,7 +215,7 @@
if (use_icount) {
/* Reset the cycle counter to the start of the block. */
- env->icount_decr.u16.low += tb->icount;
+ cpu->icount_decr.u16.low += tb->icount;
/* Clear the IO flag. */
cpu->can_do_io = 0;
}
@@ -240,7 +240,7 @@
while (s->gen_opc_instr_start[j] == 0) {
j--;
}
- env->icount_decr.u16.low -= s->gen_opc_icount[j];
+ cpu->icount_decr.u16.low -= s->gen_opc_icount[j];
restore_state_to_opc(env, tb, j);
@@ -1443,13 +1443,13 @@
}
if (use_icount) {
- env->icount_decr.u16.high = 0xffff;
+ cpu->icount_decr.u16.high = 0xffff;
if (!cpu_can_do_io(cpu)
&& (mask & ~old_mask) != 0) {
cpu_abort(cpu, "Raised interrupt while not in I/O function");
}
} else {
- // cpu->tcg_exit_req = 1;
+ cpu->tcg_exit_req = 1;
cpu_unlink_tb(env);
}
}
@@ -1514,11 +1514,11 @@
cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
(void *)retaddr);
}
- n = env->icount_decr.u16.low + tb->icount;
+ n = cpu->icount_decr.u16.low + tb->icount;
cpu_restore_state_from_tb(tb, env, retaddr);
/* Calculate how many instructions had been executed before the fault
occurred. */
- n = n - env->icount_decr.u16.low;
+ n = n - cpu->icount_decr.u16.low;
/* Generate a new TB ending on the I/O insn. */
n++;
/* On MIPS and SH, delay slot instructions can only be restarted if
@@ -1528,14 +1528,14 @@
#if defined(TARGET_MIPS)
if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
env->active_tc.PC -= 4;
- env->icount_decr.u16.low++;
+ cpu->icount_decr.u16.low++;
env->hflags &= ~MIPS_HFLAG_BMASK;
}
#elif defined(TARGET_SH4)
if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
&& n > 1) {
env->pc -= 2;
- env->icount_decr.u16.low++;
+ cpu->icount_decr.u16.low++;
env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
}
#endif