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:
		
							parent
							
								
									08225676b2
								
							
						
					
					
						commit
						86025ee443
					
				
							
								
								
									
										13
									
								
								cpu-exec.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								cpu-exec.c
									
									
									
									
									
								
							@ -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 */
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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 = {
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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) {
 | 
				
			||||||
 | 
				
			|||||||
@ -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)
 | 
				
			||||||
 | 
				
			|||||||
@ -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,
 | 
				
			||||||
 | 
				
			|||||||
@ -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) {
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user