cpu-exec: Make debug_excp_handler a QOM CPU method

Make the debug_excp_handler target specific hook into a QOM
CPU method.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-09-12 14:06:48 +01:00
parent 08225676b2
commit 86025ee443
13 changed files with 27 additions and 28 deletions

View File

@ -295,16 +295,10 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env)
return tb; return tb;
} }
static CPUDebugExcpHandler *debug_excp_handler;
void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
{
debug_excp_handler = handler;
}
static void cpu_handle_debug_exception(CPUArchState *env) static void cpu_handle_debug_exception(CPUArchState *env)
{ {
CPUState *cpu = ENV_GET_CPU(env); CPUState *cpu = ENV_GET_CPU(env);
CPUClass *cc = CPU_GET_CLASS(cpu);
CPUWatchpoint *wp; CPUWatchpoint *wp;
if (!cpu->watchpoint_hit) { if (!cpu->watchpoint_hit) {
@ -312,9 +306,8 @@ static void cpu_handle_debug_exception(CPUArchState *env)
wp->flags &= ~BP_WATCHPOINT_HIT; wp->flags &= ~BP_WATCHPOINT_HIT;
} }
} }
if (debug_excp_handler) {
debug_excp_handler(env); cc->debug_excp_handler(cpu);
}
} }
/* main execution loop */ /* main execution loop */

View File

@ -356,10 +356,6 @@ static inline tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong
tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr); tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr);
#endif #endif
typedef void (CPUDebugExcpHandler)(CPUArchState *env);
void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
/* vl.c */ /* vl.c */
extern int singlestep; extern int singlestep;

View File

@ -95,6 +95,7 @@ struct TranslationBlock;
* @get_phys_page_debug: Callback for obtaining a physical address. * @get_phys_page_debug: Callback for obtaining a physical address.
* @gdb_read_register: Callback for letting GDB read a register. * @gdb_read_register: Callback for letting GDB read a register.
* @gdb_write_register: Callback for letting GDB write a register. * @gdb_write_register: Callback for letting GDB write a register.
* @debug_excp_handler: Callback for handling debug exceptions.
* @vmsd: State description for migration. * @vmsd: State description for migration.
* @gdb_num_core_regs: Number of core registers accessible to GDB. * @gdb_num_core_regs: Number of core registers accessible to GDB.
* @gdb_core_xml_file: File name for core registers GDB XML description. * @gdb_core_xml_file: File name for core registers GDB XML description.
@ -134,6 +135,7 @@ typedef struct CPUClass {
hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg); int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
void (*debug_excp_handler)(CPUState *cpu);
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
int cpuid, void *opaque); int cpuid, void *opaque);

View File

@ -202,6 +202,10 @@ static bool cpu_common_virtio_is_big_endian(CPUState *cpu)
return target_words_bigendian(); return target_words_bigendian();
} }
static void cpu_common_debug_excp_handler(CPUState *cpu)
{
}
void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags) int flags)
{ {
@ -340,6 +344,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->gdb_read_register = cpu_common_gdb_read_register; k->gdb_read_register = cpu_common_gdb_read_register;
k->gdb_write_register = cpu_common_gdb_write_register; k->gdb_write_register = cpu_common_gdb_write_register;
k->virtio_is_big_endian = cpu_common_virtio_is_big_endian; k->virtio_is_big_endian = cpu_common_virtio_is_big_endian;
k->debug_excp_handler = cpu_common_debug_excp_handler;
dc->realize = cpu_common_realizefn; dc->realize = cpu_common_realizefn;
/* /*
* Reason: CPUs still need special care by board code: wiring up * Reason: CPUs still need special care by board code: wiring up

View File

@ -2843,9 +2843,6 @@ static void x86_cpu_initfn(Object *obj)
if (tcg_enabled() && !inited) { if (tcg_enabled() && !inited) {
inited = 1; inited = 1;
optimize_flags_init(); optimize_flags_init();
#ifndef CONFIG_USER_ONLY
cpu_set_debug_excp_handler(breakpoint_handler);
#endif
} }
} }
@ -2942,6 +2939,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->vmsd = &vmstate_x86_cpu; cc->vmsd = &vmstate_x86_cpu;
#endif #endif
cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25; cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
#ifndef CONFIG_USER_ONLY
cc->debug_excp_handler = breakpoint_handler;
#endif
} }
static const TypeInfo x86_cpu_type_info = { static const TypeInfo x86_cpu_type_info = {

View File

@ -1121,7 +1121,7 @@ static inline int hw_breakpoint_len(unsigned long dr7, int index)
void hw_breakpoint_insert(CPUX86State *env, int index); void hw_breakpoint_insert(CPUX86State *env, int index);
void hw_breakpoint_remove(CPUX86State *env, int index); void hw_breakpoint_remove(CPUX86State *env, int index);
bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update); bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update);
void breakpoint_handler(CPUX86State *env); void breakpoint_handler(CPUState *cs);
/* will be suppressed */ /* will be suppressed */
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);

View File

@ -1011,9 +1011,10 @@ bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
return hit_enabled; return hit_enabled;
} }
void breakpoint_handler(CPUX86State *env) void breakpoint_handler(CPUState *cs)
{ {
CPUState *cs = CPU(x86_env_get_cpu(env)); X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
CPUBreakpoint *bp; CPUBreakpoint *bp;
if (cs->watchpoint_hit) { if (cs->watchpoint_hit) {

View File

@ -158,7 +158,6 @@ static void lm32_cpu_initfn(Object *obj)
if (tcg_enabled() && !tcg_initialized) { if (tcg_enabled() && !tcg_initialized) {
tcg_initialized = true; tcg_initialized = true;
lm32_translate_init(); lm32_translate_init();
cpu_set_debug_excp_handler(lm32_debug_excp_handler);
} }
} }
@ -273,6 +272,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->vmsd = &vmstate_lm32_cpu; cc->vmsd = &vmstate_lm32_cpu;
#endif #endif
cc->gdb_num_core_regs = 32 + 7; cc->gdb_num_core_regs = 32 + 7;
cc->debug_excp_handler = lm32_debug_excp_handler;
} }
static void lm32_register_cpu_type(const LM32CPUInfo *info) static void lm32_register_cpu_type(const LM32CPUInfo *info)

View File

@ -211,7 +211,7 @@ void lm32_cpu_list(FILE *f, fprintf_function cpu_fprintf);
void lm32_translate_init(void); void lm32_translate_init(void);
void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value); void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value);
void QEMU_NORETURN raise_exception(CPULM32State *env, int index); void QEMU_NORETURN raise_exception(CPULM32State *env, int index);
void lm32_debug_excp_handler(CPULM32State *env); void lm32_debug_excp_handler(CPUState *cs);
void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address); void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address);
void lm32_breakpoint_remove(CPULM32State *env, int index); void lm32_breakpoint_remove(CPULM32State *env, int index);
void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address, void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,

View File

@ -125,9 +125,10 @@ static bool check_watchpoints(CPULM32State *env)
return false; return false;
} }
void lm32_debug_excp_handler(CPULM32State *env) void lm32_debug_excp_handler(CPUState *cs)
{ {
CPUState *cs = CPU(lm32_env_get_cpu(env)); LM32CPU *cpu = LM32_CPU(cs);
CPULM32State *env = &cpu->env;
CPUBreakpoint *bp; CPUBreakpoint *bp;
if (cs->watchpoint_hit) { if (cs->watchpoint_hit) {

View File

@ -119,7 +119,6 @@ static void xtensa_cpu_initfn(Object *obj)
if (tcg_enabled() && !tcg_inited) { if (tcg_enabled() && !tcg_inited) {
tcg_inited = true; tcg_inited = true;
xtensa_translate_init(); xtensa_translate_init();
cpu_set_debug_excp_handler(xtensa_breakpoint_handler);
} }
} }
@ -151,6 +150,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
cc->do_unaligned_access = xtensa_cpu_do_unaligned_access; cc->do_unaligned_access = xtensa_cpu_do_unaligned_access;
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug; cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
#endif #endif
cc->debug_excp_handler = xtensa_breakpoint_handler;
dc->vmsd = &vmstate_xtensa_cpu; dc->vmsd = &vmstate_xtensa_cpu;
} }

View File

@ -390,7 +390,7 @@ static inline CPUXtensaState *cpu_init(const char *cpu_model)
} }
void xtensa_translate_init(void); void xtensa_translate_init(void);
void xtensa_breakpoint_handler(CPUXtensaState *env); void xtensa_breakpoint_handler(CPUState *cs);
int cpu_xtensa_exec(CPUXtensaState *s); int cpu_xtensa_exec(CPUXtensaState *s);
void xtensa_register_core(XtensaConfigList *node); void xtensa_register_core(XtensaConfigList *node);
void check_interrupts(CPUXtensaState *s); void check_interrupts(CPUXtensaState *s);

View File

@ -79,9 +79,10 @@ static uint32_t check_hw_breakpoints(CPUXtensaState *env)
return 0; return 0;
} }
void xtensa_breakpoint_handler(CPUXtensaState *env) void xtensa_breakpoint_handler(CPUState *cs)
{ {
CPUState *cs = CPU(xtensa_env_get_cpu(env)); XtensaCPU *cpu = XTENSA_CPU(cs);
CPUXtensaState *env = &cpu->env;
if (cs->watchpoint_hit) { if (cs->watchpoint_hit) {
if (cs->watchpoint_hit->flags & BP_CPU) { if (cs->watchpoint_hit->flags & BP_CPU) {