}
cpu->cpu_index = cpu_index;
cpu->numa_node = 0;
- QTAILQ_INIT(&env->breakpoints);
+ QTAILQ_INIT(&cpu->breakpoints);
QTAILQ_INIT(&cpu->watchpoints);
#ifndef CONFIG_USER_ONLY
cpu->as = &address_space_memory;
CPUBreakpoint **breakpoint)
{
#if defined(TARGET_HAS_ICE)
+ CPUState *cpu = ENV_GET_CPU(env);
CPUBreakpoint *bp;
bp = g_malloc(sizeof(*bp));
/* 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_GET_CPU(env), pc);
+ breakpoint_invalidate(cpu, pc);
if (breakpoint) {
*breakpoint = bp;
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
{
#if defined(TARGET_HAS_ICE)
+ CPUState *cpu = ENV_GET_CPU(env);
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);
return 0;
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
{
#if defined(TARGET_HAS_ICE)
- QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
+ CPUState *cpu = ENV_GET_CPU(env);
- breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
+ QTAILQ_REMOVE(&cpu->breakpoints, breakpoint, entry);
+
+ breakpoint_invalidate(cpu, breakpoint->pc);
g_free(breakpoint);
#endif
void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
{
#if defined(TARGET_HAS_ICE)
+ CPUState *cpu = ENV_GET_CPU(env);
CPUBreakpoint *bp, *next;
- QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
+ QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) {
if (bp->flags & mask)
cpu_breakpoint_remove_by_ref(env, bp);
}
#endif
-typedef struct CPUBreakpoint {
- target_ulong pc;
- int flags; /* BP_* */
- QTAILQ_ENTRY(CPUBreakpoint) entry;
-} CPUBreakpoint;
-
#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
/* soft mmu support */ \
CPU_COMMON_TLB \
- \
- /* from this point: preserved by CPU reset */ \
- /* ice debug support */ \
- QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
#endif
} 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 gdb_num_g_regs;
QTAILQ_ENTRY(CPUState) node;
+ /* ice debug support */
+ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;
+
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;
CPUWatchpoint *watchpoint_hit;
/* Clone all break/watchpoints.
Note: Once we support ptrace with hw-debug register access, make sure
BP_CPU break/watchpoints are handled correctly on clone. */
- QTAILQ_INIT(&env->breakpoints);
+ QTAILQ_INIT(&cpu->breakpoints);
QTAILQ_INIT(&cpu->watchpoints);
#if defined(TARGET_HAS_ICE)
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL);
}
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
gen_tb_start();
do {
- 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) {
gen_excp(&ctx, EXCP_DEBUG, 0);
break;
acc->parent_reset(s);
- memset(env, 0, offsetof(CPUARMState, breakpoints));
+ memset(env, 0, offsetof(CPUARMState, features));
g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu);
env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
tcg_clear_temp_count();
do {
- 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
}
#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
ccc->parent_reset(s);
vr = env->pregs[PR_VR];
- memset(env, 0, offsetof(CPUCRISState, breakpoints));
+ memset(env, 0, offsetof(CPUCRISState, load_info));
env->pregs[PR_VR] = vr;
tlb_flush(env, 1);
CPU_COMMON
- /* Members after CPU_COMMON are preserved across resets. */
- void *load_info;
+ /* Members from load_info on are preserved across resets. */
+ void *load_info;
} CPUCRISState;
#include "cpu-qom.h"
static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
{
+ CPUState *cs = CPU(cris_env_get_cpu(env));
CPUBreakpoint *bp;
- 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) {
cris_evaluate_flags(dc);
tcg_gen_movi_tl(env_pc, dc->pc);
xcc->parent_reset(s);
- memset(env, 0, offsetof(CPUX86State, breakpoints));
+ memset(env, 0, offsetof(CPUX86State, pat));
tlb_flush(env, 1);
target_ulong exception_next_eip;
target_ulong dr[8]; /* debug registers */
union {
- CPUBreakpoint *cpu_breakpoint[4];
+ struct CPUBreakpoint *cpu_breakpoint[4];
struct CPUWatchpoint *cpu_watchpoint[4];
}; /* break/watchpoints for dr[0..3] */
uint32_t smbase;
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
uint64_t pat;
/* processor features (e.g. for CPUID insn) */
}
}
} 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, true);
}
break;
}
+ }
}
}
gen_tb_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);
lcc->parent_reset(s);
/* reset cpu state */
- memset(env, 0, offsetof(CPULM32State, breakpoints));
+ memset(env, 0, offsetof(CPULM32State, eba));
lm32_cpu_init_cfg_reg(cpu);
tlb_flush(env, 1);
uint32_t bp[4]; /* breakpoints */
uint32_t wp[4]; /* watchpoints */
- CPUBreakpoint * cpu_breakpoint[4];
+ struct CPUBreakpoint *cpu_breakpoint[4];
struct CPUWatchpoint *cpu_watchpoint[4];
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
uint32_t eba; /* exception base address */
uint32_t deba; /* debug exception base address */
}
}
} else {
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == env->pc) {
if (bp->flags & BP_CPU) {
raise_exception(env, EXCP_BREAKPOINT);
static void check_breakpoint(CPULM32State *env, DisasContext *dc)
{
+ CPUState *cs = CPU(lm32_env_get_cpu(env));
CPUBreakpoint *bp;
- 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) {
tcg_gen_movi_tl(cpu_pc, dc->pc);
t_gen_raise_exception(dc, EXCP_DEBUG);
mcc->parent_reset(s);
- memset(env, 0, offsetof(CPUM68KState, breakpoints));
+ memset(env, 0, offsetof(CPUM68KState, features));
#if !defined(CONFIG_USER_ONLY)
env->sr = 0x2700;
#endif
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
uint32_t features;
} CPUM68KState;
do {
pc_offset = dc->pc - pc_start;
gen_throws_exception = NULL;
- 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(dc, dc->pc, EXCP_DEBUG);
dc->is_jmp = DISAS_JUMP;
mcc->parent_reset(s);
- memset(env, 0, offsetof(CPUMBState, breakpoints));
+ memset(env, 0, sizeof(CPUMBState));
env->res_addr = RES_ADDR_NONE;
tlb_flush(env, 1);
static void check_breakpoint(CPUMBState *env, DisasContext *dc)
{
+ CPUState *cs = CPU(mb_env_get_cpu(env));
CPUBreakpoint *bp;
- 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) {
t_gen_raise_exception(dc, EXCP_DEBUG);
dc->is_jmp = DISAS_UPDATE;
mcc->parent_reset(s);
- memset(env, 0, offsetof(CPUMIPSState, breakpoints));
+ memset(env, 0, offsetof(CPUMIPSState, mvp));
tlb_flush(env, 1);
cpu_state_reset(env);
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
CPUMIPSMVPContext *mvp;
#if !defined(CONFIG_USER_ONLY)
CPUMIPSTLBContext *tlb;
LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
gen_tb_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;
mcc->parent_reset(s);
- memset(env, 0, offsetof(CPUMoxieState, breakpoints));
+ memset(env, 0, sizeof(CPUMoxieState));
env->pc = 0x1000;
tlb_flush(env, 1);
gen_tb_start();
do {
- 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 (ctx.pc == bp->pc) {
tcg_gen_movi_i32(cpu_pc, ctx.pc);
gen_helper_debug(cpu_env);
occ->parent_reset(s);
- memset(&cpu->env, 0, offsetof(CPUOpenRISCState, breakpoints));
+#ifndef CONFIG_USER_ONLY
+ memset(&cpu->env, 0, offsetof(CPUOpenRISCState, tlb));
+#else
+ memset(&cpu->env, 0, offsetof(CPUOpenRISCState, irq));
+#endif
tlb_flush(&cpu->env, 1);
/*tb_flush(&cpu->env); FIXME: Do we need it? */
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
#ifndef CONFIG_USER_ONLY
CPUOpenRISCTLBContext * tlb;
static void check_breakpoint(OpenRISCCPU *cpu, DisasContext *dc)
{
+ CPUState *cs = CPU(cpu);
CPUBreakpoint *bp;
- if (unlikely(!QTAILQ_EMPTY(&cpu->env.breakpoints))) {
- QTAILQ_FOREACH(bp, &cpu->env.breakpoints, entry) {
+ if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+ QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
if (bp->pc == dc->pc) {
tcg_gen_movi_tl(cpu_pc, dc->pc);
gen_exception(dc, EXCP_DEBUG);
/* Set env in case of segfault during code fetch */
while (ctx.exception == POWERPC_EXCP_NONE
&& tcg_ctx.gen_opc_ptr < gen_opc_end) {
- 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.nip) {
gen_debug_exception(ctxp);
break;
s390_cpu_reset(s);
/* initial reset does not touch regs,fregs and aregs */
- memset(&env->fpc, 0, offsetof(CPUS390XState, breakpoints) -
+ memset(&env->fpc, 0, offsetof(CPUS390XState, cpu_num) -
offsetof(CPUS390XState, fpc));
/* architectured initial values for CR 0 and 14 */
scc->parent_reset(s);
- memset(env, 0, offsetof(CPUS390XState, breakpoints));
+ memset(env, 0, offsetof(CPUS390XState, cpu_num));
/* architectured initial values for CR 0 and 14 */
env->cregs[0] = CR0_RESET;
}
status = NO_EXIT;
- 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) {
status = EXIT_PC_STALE;
do_debug = true;
scc->parent_reset(s);
- memset(env, 0, offsetof(CPUSH4State, breakpoints));
+ memset(env, 0, offsetof(CPUSH4State, id));
tlb_flush(env, 1);
env->pc = 0xA0000000;
CPU_COMMON
+ /* Fields from here on are preserved over CPU reset. */
int id; /* CPU model */
/* The features that we should emulate. See sh_features above. */
max_insns = CF_COUNT_MASK;
gen_tb_start();
while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end) {
- 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 (ctx.pc == bp->pc) {
/* We have hit a breakpoint - make sure PC is up-to-date */
tcg_gen_movi_i32(cpu_pc, ctx.pc);
scc->parent_reset(s);
- memset(env, 0, offsetof(CPUSPARCState, breakpoints));
+ memset(env, 0, offsetof(CPUSPARCState, version));
tlb_flush(env, 1);
env->cwp = 0;
#ifndef TARGET_SPARC64
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
target_ulong version;
uint32_t nwindows;
max_insns = CF_COUNT_MASK;
gen_tb_start();
do {
- 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) {
if (dc->pc != pc_start)
save_state(dc);
gen_tb_start();
do {
- 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_set_pc_im(dc->pc);
gen_exception(EXCP_DEBUG);
static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
{
+ CPUState *cs = CPU(xtensa_env_get_cpu(env));
CPUBreakpoint *bp;
- 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) {
tcg_gen_movi_i32(cpu_pc, dc->pc);
gen_exception(dc, EXCP_DEBUG);