From 0ac46af39ee84461782b6f096ba1a165c7b0e503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 26 Jul 2013 16:42:25 +0200 Subject: [PATCH 01/25] linux-user: Avoid redundant ENV_GET_CPU() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a mismerge in 874ec3c5b3821bb964f9f37b2f930f2a9ce51652. Acked-by: Riku Voipio Signed-off-by: Andreas Färber --- linux-user/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/main.c b/linux-user/main.c index 5dc09471e4..5309117034 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3637,7 +3637,7 @@ int main(int argc, char **argv, char **envp) exit(1); } cpu = ENV_GET_CPU(env); - cpu_reset(ENV_GET_CPU(env)); + cpu_reset(cpu); thread_cpu = cpu; From 38e478eccfb1ace415914a331c8e1b16ae64b57f Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 25 Jul 2013 20:50:21 +0200 Subject: [PATCH 02/25] kvm: Change prototype of kvm_update_guest_debug() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passing a CPUState pointer instead of a CPUArchState pointer eliminates the last target dependent data type in sysemu/kvm.h. It also simplifies the code. Signed-off-by: Stefan Weil Acked-by: Paolo Bonzini Signed-off-by: Andreas Färber --- exec.c | 5 ++--- include/sysemu/kvm.h | 2 +- kvm-all.c | 17 +++++------------ kvm-stub.c | 2 +- target-i386/kvm.c | 2 +- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/exec.c b/exec.c index 3ba9525bd3..c4f2894ea1 100644 --- a/exec.c +++ b/exec.c @@ -590,15 +590,14 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask) void cpu_single_step(CPUState *cpu, int enabled) { #if defined(TARGET_HAS_ICE) - CPUArchState *env = cpu->env_ptr; - if (cpu->singlestep_enabled != enabled) { cpu->singlestep_enabled = enabled; if (kvm_enabled()) { - kvm_update_guest_debug(env, 0); + kvm_update_guest_debug(cpu, 0); } else { /* must flush all the translated code to avoid inconsistencies */ /* XXX: only flush what is necessary */ + CPUArchState *env = cpu->env_ptr; tb_flush(env); } } diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index f8ac448e0b..de74411f41 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -174,7 +174,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type); void kvm_remove_all_breakpoints(CPUState *cpu); -int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap); +int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap); #ifndef _WIN32 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset); #endif diff --git a/kvm-all.c b/kvm-all.c index 4fb4ccbeca..716860f617 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1883,9 +1883,8 @@ static void kvm_invoke_set_guest_debug(void *data) &dbg_data->dbg); } -int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) +int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap) { - CPUState *cpu = ENV_GET_CPU(env); struct kvm_set_guest_debug_data data; data.dbg.control = reinject_trap; @@ -1935,9 +1934,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, } for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { - CPUArchState *env = cpu->env_ptr; - - err = kvm_update_guest_debug(env, 0); + err = kvm_update_guest_debug(cpu, 0); if (err) { return err; } @@ -1977,9 +1974,7 @@ int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, } for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { - CPUArchState *env = cpu->env_ptr; - - err = kvm_update_guest_debug(env, 0); + err = kvm_update_guest_debug(cpu, 0); if (err) { return err; } @@ -2007,15 +2002,13 @@ void kvm_remove_all_breakpoints(CPUState *cpu) kvm_arch_remove_all_hw_breakpoints(); for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { - CPUArchState *env = cpu->env_ptr; - - kvm_update_guest_debug(env, 0); + kvm_update_guest_debug(cpu, 0); } } #else /* !KVM_CAP_SET_GUEST_DEBUG */ -int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) +int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap) { return -EINVAL; } diff --git a/kvm-stub.c b/kvm-stub.c index 7b2233ae82..771360b3ca 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -78,7 +78,7 @@ void kvm_setup_guest_memory(void *start, size_t size) { } -int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) +int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap) { return -ENOSYS; } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 3c9d10a762..376fc70ae3 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1618,7 +1618,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu) */ if (reinject_trap || (!kvm_has_robust_singlestep() && cs->singlestep_enabled)) { - ret = kvm_update_guest_debug(env, reinject_trap); + ret = kvm_update_guest_debug(cs, reinject_trap); } return ret; } From 9282b73a4078f10b5d1c96707aeed213eedbc8e1 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Fri, 26 Jul 2013 17:48:06 +0200 Subject: [PATCH 03/25] target-s390x: Fix CPUState rework fallout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit f17ec444c3d39f76bcd8b71c2c05d5754bfe333e exec: Change cpu_memory_rw_debug() argument to CPUState missed to update s390x KVM code, breaking the build. Let's fix it up. Signed-off-by: Christian Borntraeger Signed-off-by: Andreas Färber --- target-s390x/kvm.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 60e94f8ee8..85f01125de 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -345,12 +345,10 @@ void *kvm_arch_ram_alloc(ram_addr_t size) int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - S390CPU *cpu = S390_CPU(cs); - CPUS390XState *env = &cpu->env; static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01}; - if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || - cpu_memory_rw_debug(env, bp->pc, (uint8_t *)diag_501, 4, 1)) { + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)diag_501, 4, 1)) { return -EINVAL; } return 0; @@ -358,16 +356,14 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - S390CPU *cpu = S390_CPU(cs); - CPUS390XState *env = &cpu->env; uint8_t t[4]; static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01}; - if (cpu_memory_rw_debug(env, bp->pc, t, 4, 0)) { + if (cpu_memory_rw_debug(cs, bp->pc, t, 4, 0)) { return -EINVAL; } else if (memcmp(t, diag_501, 4)) { return -EINVAL; - } else if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { + } else if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { return -EINVAL; } From 67cce5617ee968946fc6402f02743fffaa4a1a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 01:47:51 +0200 Subject: [PATCH 04/25] target-xtensa: Introduce XtensaCPU subclasses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register a CPU type per core registered. Save the XtensaConfig in XtensaCPUClass and copy it from there to CPUXtensaState, to avoid touching every env->config access for now. Prepares for storing per-class GDB register count. Acked-by: Max Filippov Signed-off-by: Andreas Färber --- target-xtensa/cpu-qom.h | 3 +++ target-xtensa/cpu.c | 24 +++++++++++++++++++++++- target-xtensa/helper.c | 32 +++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index b9896f2647..1b9479eb9c 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -45,6 +45,7 @@ * XtensaCPUClass: * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. + * @config: The CPU core configuration. * * An Xtensa CPU model. */ @@ -55,6 +56,8 @@ typedef struct XtensaCPUClass { DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); + + const XtensaConfig *config; } XtensaCPUClass; /** diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index d2bcfc69a2..5a39971d2c 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -64,6 +64,25 @@ static void xtensa_cpu_reset(CPUState *s) reset_mmu(env); } +static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + char *typename; + + if (cpu_model == NULL) { + return NULL; + } + + typename = g_strdup_printf("%s-" TYPE_XTENSA_CPU, cpu_model); + oc = object_class_by_name(typename); + g_free(typename); + if (oc == NULL || !object_class_dynamic_cast(oc, TYPE_XTENSA_CPU) || + object_class_is_abstract(oc)) { + return NULL; + } + return oc; +} + static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp) { XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev); @@ -75,10 +94,12 @@ static void xtensa_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); XtensaCPU *cpu = XTENSA_CPU(obj); + XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(obj); CPUXtensaState *env = &cpu->env; static bool tcg_inited; cs->env_ptr = env; + env->config = xcc->config; cpu_exec_init(env); if (tcg_enabled() && !tcg_inited) { @@ -105,6 +126,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) xcc->parent_reset = cc->reset; cc->reset = xtensa_cpu_reset; + cc->class_by_name = xtensa_cpu_class_by_name; cc->do_interrupt = xtensa_cpu_do_interrupt; cc->dump_state = xtensa_cpu_dump_state; cc->set_pc = xtensa_cpu_set_pc; @@ -119,7 +141,7 @@ static const TypeInfo xtensa_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(XtensaCPU), .instance_init = xtensa_cpu_initfn, - .abstract = false, + .abstract = true, .class_size = sizeof(XtensaCPUClass), .class_init = xtensa_cpu_class_init, }; diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index de6cc3b7c5..e3098798af 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -35,10 +35,27 @@ static struct XtensaConfigList *xtensa_cores; +static void xtensa_core_class_init(ObjectClass *oc, void *data) +{ + XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc); + const XtensaConfig *config = data; + + xcc->config = config; +} + void xtensa_register_core(XtensaConfigList *node) { + TypeInfo type = { + .parent = TYPE_XTENSA_CPU, + .class_init = xtensa_core_class_init, + .class_data = (void *)node->config, + }; + node->next = xtensa_cores; xtensa_cores = node; + type.name = g_strdup_printf("%s-" TYPE_XTENSA_CPU, node->config->name); + type_register(&type); + g_free((gpointer)type.name); } static uint32_t check_hw_breakpoints(CPUXtensaState *env) @@ -72,24 +89,17 @@ void xtensa_breakpoint_handler(CPUXtensaState *env) XtensaCPU *cpu_xtensa_init(const char *cpu_model) { + ObjectClass *oc; XtensaCPU *cpu; CPUXtensaState *env; - const XtensaConfig *config = NULL; - XtensaConfigList *core = xtensa_cores; - for (; core; core = core->next) - if (strcmp(core->config->name, cpu_model) == 0) { - config = core->config; - break; - } - - if (config == NULL) { + oc = cpu_class_by_name(TYPE_XTENSA_CPU, cpu_model); + if (oc == NULL) { return NULL; } - cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU)); + cpu = XTENSA_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; - env->config = config; xtensa_irq_init(env); From 47d74ef57a0fe66fa2fdcce46b4daec4f60a1fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 11:17:26 +0200 Subject: [PATCH 05/25] gdbstub: Fix cpu_gdb_{read,write}_register() Coding Style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add braces, replace tabs, remove trailing whitespace, drop space before parenthesis and place break etc. below case statements. Signed-off-by: Andreas Färber --- gdbstub.c | 444 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 291 insertions(+), 153 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 35ca7c2c1e..cd25c066ec 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -571,26 +571,42 @@ static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) } else { GET_REG32(env->eip); } - case IDX_FLAGS_REG: GET_REG32(env->eflags); + case IDX_FLAGS_REG: + GET_REG32(env->eflags); - case IDX_SEG_REGS: GET_REG32(env->segs[R_CS].selector); - case IDX_SEG_REGS + 1: GET_REG32(env->segs[R_SS].selector); - case IDX_SEG_REGS + 2: GET_REG32(env->segs[R_DS].selector); - case IDX_SEG_REGS + 3: GET_REG32(env->segs[R_ES].selector); - case IDX_SEG_REGS + 4: GET_REG32(env->segs[R_FS].selector); - case IDX_SEG_REGS + 5: GET_REG32(env->segs[R_GS].selector); + case IDX_SEG_REGS: + GET_REG32(env->segs[R_CS].selector); + case IDX_SEG_REGS + 1: + GET_REG32(env->segs[R_SS].selector); + case IDX_SEG_REGS + 2: + GET_REG32(env->segs[R_DS].selector); + case IDX_SEG_REGS + 3: + GET_REG32(env->segs[R_ES].selector); + case IDX_SEG_REGS + 4: + GET_REG32(env->segs[R_FS].selector); + case IDX_SEG_REGS + 5: + GET_REG32(env->segs[R_GS].selector); - case IDX_FP_REGS + 8: GET_REG32(env->fpuc); - case IDX_FP_REGS + 9: GET_REG32((env->fpus & ~0x3800) | - (env->fpstt & 0x7) << 11); - case IDX_FP_REGS + 10: GET_REG32(0); /* ftag */ - case IDX_FP_REGS + 11: GET_REG32(0); /* fiseg */ - case IDX_FP_REGS + 12: GET_REG32(0); /* fioff */ - case IDX_FP_REGS + 13: GET_REG32(0); /* foseg */ - case IDX_FP_REGS + 14: GET_REG32(0); /* fooff */ - case IDX_FP_REGS + 15: GET_REG32(0); /* fop */ + case IDX_FP_REGS + 8: + GET_REG32(env->fpuc); + case IDX_FP_REGS + 9: + GET_REG32((env->fpus & ~0x3800) | + (env->fpstt & 0x7) << 11); + case IDX_FP_REGS + 10: + GET_REG32(0); /* ftag */ + case IDX_FP_REGS + 11: + GET_REG32(0); /* fiseg */ + case IDX_FP_REGS + 12: + GET_REG32(0); /* fioff */ + case IDX_FP_REGS + 13: + GET_REG32(0); /* foseg */ + case IDX_FP_REGS + 14: + GET_REG32(0); /* fooff */ + case IDX_FP_REGS + 15: + GET_REG32(0); /* fop */ - case IDX_MXCSR_REG: GET_REG32(env->mxcsr); + case IDX_MXCSR_REG: + GET_REG32(env->mxcsr); } } return 0; @@ -612,8 +628,10 @@ static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf) limit = 0xffff; flags = 0; } else { - if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, &flags)) + if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, + &flags)) { return 4; + } } cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags); #endif @@ -664,12 +682,18 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) env->eflags = ldl_p(mem_buf); return 4; - case IDX_SEG_REGS: return cpu_x86_gdb_load_seg(env, R_CS, mem_buf); - case IDX_SEG_REGS + 1: return cpu_x86_gdb_load_seg(env, R_SS, mem_buf); - case IDX_SEG_REGS + 2: return cpu_x86_gdb_load_seg(env, R_DS, mem_buf); - case IDX_SEG_REGS + 3: return cpu_x86_gdb_load_seg(env, R_ES, mem_buf); - case IDX_SEG_REGS + 4: return cpu_x86_gdb_load_seg(env, R_FS, mem_buf); - case IDX_SEG_REGS + 5: return cpu_x86_gdb_load_seg(env, R_GS, mem_buf); + case IDX_SEG_REGS: + return cpu_x86_gdb_load_seg(env, R_CS, mem_buf); + case IDX_SEG_REGS + 1: + return cpu_x86_gdb_load_seg(env, R_SS, mem_buf); + case IDX_SEG_REGS + 2: + return cpu_x86_gdb_load_seg(env, R_DS, mem_buf); + case IDX_SEG_REGS + 3: + return cpu_x86_gdb_load_seg(env, R_ES, mem_buf); + case IDX_SEG_REGS + 4: + return cpu_x86_gdb_load_seg(env, R_FS, mem_buf); + case IDX_SEG_REGS + 5: + return cpu_x86_gdb_load_seg(env, R_GS, mem_buf); case IDX_FP_REGS + 8: env->fpuc = ldl_p(mem_buf); @@ -679,12 +703,18 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) env->fpstt = (tmp >> 11) & 7; env->fpus = tmp & ~0x3800; return 4; - case IDX_FP_REGS + 10: /* ftag */ return 4; - case IDX_FP_REGS + 11: /* fiseg */ return 4; - case IDX_FP_REGS + 12: /* fioff */ return 4; - case IDX_FP_REGS + 13: /* foseg */ return 4; - case IDX_FP_REGS + 14: /* fooff */ return 4; - case IDX_FP_REGS + 15: /* fop */ return 4; + case IDX_FP_REGS + 10: /* ftag */ + return 4; + case IDX_FP_REGS + 11: /* fiseg */ + return 4; + case IDX_FP_REGS + 12: /* fioff */ + return 4; + case IDX_FP_REGS + 13: /* foseg */ + return 4; + case IDX_FP_REGS + 14: /* fooff */ + return 4; + case IDX_FP_REGS + 15: /* fop */ + return 4; case IDX_MXCSR_REG: env->mxcsr = ldl_p(mem_buf); @@ -716,29 +746,37 @@ static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) GET_REGL(env->gpr[n]); } else if (n < 64) { /* fprs */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } stfq_p(mem_buf, env->fpr[n-32]); return 8; } else { switch (n) { - case 64: GET_REGL(env->nip); - case 65: GET_REGL(env->msr); + case 64: + GET_REGL(env->nip); + case 65: + GET_REGL(env->msr); case 66: { uint32_t cr = 0; int i; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { cr |= env->crf[i] << (32 - ((i + 1) * 4)); + } GET_REG32(cr); } - case 67: GET_REGL(env->lr); - case 68: GET_REGL(env->ctr); - case 69: GET_REGL(env->xer); + case 67: + GET_REGL(env->lr); + case 68: + GET_REGL(env->ctr); + case 69: + GET_REGL(env->xer); case 70: { - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } GET_REG32(env->fpscr); } } @@ -754,8 +792,9 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) return sizeof(target_ulong); } else if (n < 64) { /* fprs */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } env->fpr[n-32] = ldfq_p(mem_buf); return 8; } else { @@ -770,8 +809,9 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) { uint32_t cr = ldl_p(mem_buf); int i; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; + } return 4; } case 67: @@ -785,8 +825,9 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) return sizeof(target_ulong); case 70: /* fpscr */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); return sizeof(target_ulong); } @@ -829,15 +870,24 @@ static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) } /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { - case 64: GET_REGA(env->y); - case 65: GET_REGA(cpu_get_psr(env)); - case 66: GET_REGA(env->wim); - case 67: GET_REGA(env->tbr); - case 68: GET_REGA(env->pc); - case 69: GET_REGA(env->npc); - case 70: GET_REGA(env->fsr); - case 71: GET_REGA(0); /* csr */ - default: GET_REGA(0); + case 64: + GET_REGA(env->y); + case 65: + GET_REGA(cpu_get_psr(env)); + case 66: + GET_REGA(env->wim); + case 67: + GET_REGA(env->tbr); + case 68: + GET_REGA(env->pc); + case 69: + GET_REGA(env->npc); + case 70: + GET_REGA(env->fsr); + case 71: + GET_REGA(0); /* csr */ + default: + GET_REGA(0); } #else if (n < 64) { @@ -853,15 +903,21 @@ static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) GET_REG64(env->fpr[(n - 32) / 2].ll); } switch (n) { - case 80: GET_REGL(env->pc); - case 81: GET_REGL(env->npc); - case 82: GET_REGL((cpu_get_ccr(env) << 32) | - ((env->asi & 0xff) << 24) | - ((env->pstate & 0xfff) << 8) | - cpu_get_cwp64(env)); - case 83: GET_REGL(env->fsr); - case 84: GET_REGL(env->fprs); - case 85: GET_REGL(env->y); + case 80: + GET_REGL(env->pc); + case 81: + GET_REGL(env->npc); + case 82: + GET_REGL((cpu_get_ccr(env) << 32) | + ((env->asi & 0xff) << 24) | + ((env->pstate & 0xfff) << 8) | + cpu_get_cwp64(env)); + case 83: + GET_REGL(env->fsr); + case 84: + GET_REGL(env->fprs); + case 85: + GET_REGL(env->y); } #endif return 0; @@ -898,14 +954,29 @@ static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) } else { /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { - case 64: env->y = tmp; break; - case 65: cpu_put_psr(env, tmp); break; - case 66: env->wim = tmp; break; - case 67: env->tbr = tmp; break; - case 68: env->pc = tmp; break; - case 69: env->npc = tmp; break; - case 70: env->fsr = tmp; break; - default: return 0; + case 64: + env->y = tmp; + break; + case 65: + cpu_put_psr(env, tmp); + break; + case 66: + env->wim = tmp; + break; + case 67: + env->tbr = tmp; + break; + case 68: + env->pc = tmp; + break; + case 69: + env->npc = tmp; + break; + case 70: + env->fsr = tmp; + break; + default: + return 0; } } return 4; @@ -924,18 +995,29 @@ static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) env->fpr[(n - 32) / 2].ll = tmp; } else { switch (n) { - case 80: env->pc = tmp; break; - case 81: env->npc = tmp; break; + case 80: + env->pc = tmp; + break; + case 81: + env->npc = tmp; + break; case 82: cpu_put_ccr(env, tmp >> 32); - env->asi = (tmp >> 24) & 0xff; - env->pstate = (tmp >> 8) & 0xfff; + env->asi = (tmp >> 24) & 0xff; + env->pstate = (tmp >> 8) & 0xfff; cpu_put_cwp64(env, tmp & 0xff); - break; - case 83: env->fsr = tmp; break; - case 84: env->fprs = tmp; break; - case 85: env->y = tmp; break; - default: return 0; + break; + case 83: + env->fsr = tmp; + break; + case 84: + env->fprs = tmp; + break; + case 85: + env->y = tmp; + break; + default: + return 0; } } return 8; @@ -959,16 +1041,18 @@ static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) } if (n < 24) { /* FPA registers. */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } memset(mem_buf, 0, 12); return 12; } switch (n) { case 24: /* FPA status register. */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } GET_REG32(0); case 25: /* CPSR */ @@ -986,8 +1070,9 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) /* Mask out low bit of PC to workaround gdb bugs. This will probably cause problems if we ever implement the Jazelle DBX extensions. */ - if (n == 15) + if (n == 15) { tmp &= ~1; + } if (n < 16) { /* Core integer register. */ @@ -996,19 +1081,21 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) } if (n < 24) { /* 16-23 */ /* FPA registers (ignored). */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } return 12; } switch (n) { case 24: /* FPA status register (ignored). */ - if (gdb_has_xml) + if (gdb_has_xml) { return 0; + } return 4; case 25: /* CPSR */ - cpsr_write (env, tmp, 0xffffffff); + cpsr_write(env, tmp, 0xffffffff); return 4; } /* Unknown register. */ @@ -1030,9 +1117,11 @@ static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) /* A0-A7 */ GET_REG32(env->aregs[n - 8]); } else { - switch (n) { - case 16: GET_REG32(env->sr); - case 17: GET_REG32(env->pc); + switch (n) { + case 16: + GET_REG32(env->sr); + case 17: + GET_REG32(env->pc); } } /* FP registers not included here because they vary between @@ -1054,9 +1143,14 @@ static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) env->aregs[n - 8] = tmp; } else { switch (n) { - case 16: env->sr = tmp; break; - case 17: env->pc = tmp; break; - default: return 0; + case 16: + env->sr = tmp; + break; + case 17: + env->pc = tmp; + break; + default: + return 0; } } return 4; @@ -1072,44 +1166,55 @@ static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) } if (env->CP0_Config1 & (1 << CP0C1_FP)) { if (n >= 38 && n < 70) { - if (env->CP0_Status & (1 << CP0St_FR)) - GET_REGL(env->active_fpu.fpr[n - 38].d); - else - GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); + if (env->CP0_Status & (1 << CP0St_FR)) { + GET_REGL(env->active_fpu.fpr[n - 38].d); + } else { + GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); + } } switch (n) { - case 70: GET_REGL((int32_t)env->active_fpu.fcr31); - case 71: GET_REGL((int32_t)env->active_fpu.fcr0); + case 70: + GET_REGL((int32_t)env->active_fpu.fcr31); + case 71: + GET_REGL((int32_t)env->active_fpu.fcr0); } } switch (n) { - case 32: GET_REGL((int32_t)env->CP0_Status); - case 33: GET_REGL(env->active_tc.LO[0]); - case 34: GET_REGL(env->active_tc.HI[0]); - case 35: GET_REGL(env->CP0_BadVAddr); - case 36: GET_REGL((int32_t)env->CP0_Cause); - case 37: GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16)); - case 72: GET_REGL(0); /* fp */ - case 89: GET_REGL((int32_t)env->CP0_PRid); + case 32: + GET_REGL((int32_t)env->CP0_Status); + case 33: + GET_REGL(env->active_tc.LO[0]); + case 34: + GET_REGL(env->active_tc.HI[0]); + case 35: + GET_REGL(env->CP0_BadVAddr); + case 36: + GET_REGL((int32_t)env->CP0_Cause); + case 37: + GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16)); + case 72: + GET_REGL(0); /* fp */ + case 89: + GET_REGL((int32_t)env->CP0_PRid); } if (n >= 73 && n <= 88) { - /* 16 embedded regs. */ - GET_REGL(0); + /* 16 embedded regs. */ + GET_REGL(0); } return 0; } /* convert MIPS rounding mode in FCR31 to IEEE library */ -static unsigned int ieee_rm[] = - { +static unsigned int ieee_rm[] = { float_round_nearest_even, float_round_to_zero, float_round_up, float_round_down - }; +}; #define RESTORE_ROUNDING_MODE \ - set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status) + set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \ + &env->active_fpu.fp_status) static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) { @@ -1124,10 +1229,11 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 73) { if (n < 70) { - if (env->CP0_Status & (1 << CP0St_FR)) - env->active_fpu.fpr[n - 38].d = tmp; - else - env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; + if (env->CP0_Status & (1 << CP0St_FR)) { + env->active_fpu.fpr[n - 38].d = tmp; + } else { + env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; + } } switch (n) { case 70: @@ -1135,16 +1241,28 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) /* set rounding mode */ RESTORE_ROUNDING_MODE; break; - case 71: env->active_fpu.fcr0 = tmp; break; + case 71: + env->active_fpu.fcr0 = tmp; + break; } return sizeof(target_ulong); } switch (n) { - case 32: env->CP0_Status = tmp; break; - case 33: env->active_tc.LO[0] = tmp; break; - case 34: env->active_tc.HI[0] = tmp; break; - case 35: env->CP0_BadVAddr = tmp; break; - case 36: env->CP0_Cause = tmp; break; + case 32: + env->CP0_Status = tmp; + break; + case 33: + env->active_tc.LO[0] = tmp; + break; + case 34: + env->active_tc.HI[0] = tmp; + break; + case 35: + env->CP0_BadVAddr = tmp; + break; + case 36: + env->CP0_Cause = tmp; + break; case 37: env->active_tc.PC = tmp & ~(target_ulong)1; if (tmp & 1) { @@ -1153,12 +1271,14 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) env->hflags &= ~(MIPS_HFLAG_M16); } break; - case 72: /* fp, ignored */ break; - default: - if (n > 89) - return 0; - /* Other registers are readonly. Ignore writes. */ - break; + case 72: /* fp, ignored */ + break; + default: + if (n > 89) { + return 0; + } + /* Other registers are readonly. Ignore writes. */ + break; } return sizeof(target_ulong); @@ -1340,7 +1460,8 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) case 51 ... 58: env->gregs[n - (51 - 16)] = ldl_p(mem_buf); break; - default: return 0; + default: + return 0; } return 4; @@ -1352,9 +1473,9 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) { if (n < 32) { - GET_REG32(env->regs[n]); + GET_REG32(env->regs[n]); } else { - GET_REG32(env->sregs[n - 32]); + GET_REG32(env->sregs[n - 32]); } return 0; } @@ -1363,15 +1484,16 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) { uint32_t tmp; - if (n > NUM_CORE_REGS) - return 0; + if (n > NUM_CORE_REGS) { + return 0; + } tmp = ldl_p(mem_buf); if (n < 32) { - env->regs[n] = tmp; + env->regs[n] = tmp; } else { - env->sregs[n - 32] = tmp; + env->sregs[n - 32] = tmp; } return 4; } @@ -1416,27 +1538,34 @@ static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) { uint8_t srs; - if (env->pregs[PR_VR] < 32) + if (env->pregs[PR_VR] < 32) { return read_register_crisv10(env, mem_buf, n); + } srs = env->pregs[PR_SRS]; if (n < 16) { - GET_REG32(env->regs[n]); + GET_REG32(env->regs[n]); } if (n >= 21 && n < 32) { - GET_REG32(env->pregs[n - 16]); + GET_REG32(env->pregs[n - 16]); } if (n >= 33 && n < 49) { - GET_REG32(env->sregs[srs][n - 33]); + GET_REG32(env->sregs[srs][n - 33]); } switch (n) { - case 16: GET_REG8(env->pregs[0]); - case 17: GET_REG8(env->pregs[1]); - case 18: GET_REG32(env->pregs[2]); - case 19: GET_REG8(srs); - case 20: GET_REG16(env->pregs[4]); - case 32: GET_REG32(env->pc); + case 16: + GET_REG8(env->pregs[0]); + case 17: + GET_REG8(env->pregs[1]); + case 18: + GET_REG32(env->pregs[2]); + case 19: + GET_REG8(srs); + case 20: + GET_REG16(env->pregs[4]); + case 32: + GET_REG32(env->pc); } return 0; @@ -1446,27 +1575,36 @@ static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) { uint32_t tmp; - if (n > 49) - return 0; + if (n > 49) { + return 0; + } tmp = ldl_p(mem_buf); if (n < 16) { - env->regs[n] = tmp; + env->regs[n] = tmp; } if (n >= 21 && n < 32) { - env->pregs[n - 16] = tmp; + env->pregs[n - 16] = tmp; } /* FIXME: Should support function regs be writable? */ switch (n) { - case 16: return 1; - case 17: return 1; - case 18: env->pregs[PR_PID] = tmp; break; - case 19: return 1; - case 20: return 2; - case 32: env->pc = tmp; break; + case 16: + return 1; + case 17: + return 1; + case 18: + env->pregs[PR_PID] = tmp; + break; + case 19: + return 1; + case 20: + return 2; + case 32: + env->pc = tmp; + break; } return 4; @@ -1731,7 +1869,7 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) default: qemu_log("%s from reg %d of unsupported type %d\n", - __func__, n, reg->type); + __func__, n, reg->type); return 0; } } @@ -1775,7 +1913,7 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) default: qemu_log("%s to reg %d of unsupported type %d\n", - __func__, n, reg->type); + __func__, n, reg->type); return 0; } From 19a77215f1ba966c4d37dadec45f38be789b8529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 11:52:52 +0200 Subject: [PATCH 06/25] gdbstub: Drop dead code in cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET_REG*() macros include a return statement, thus no need for break. Acked-by: Michael Walle (for lm32) Signed-off-by: Andreas Färber --- gdbstub.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index cd25c066ec..9ede3de7ae 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1295,15 +1295,12 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) switch (n) { case 32: /* PPC */ GET_REG32(env->ppc); - break; case 33: /* NPC */ GET_REG32(env->npc); - break; case 34: /* SR */ GET_REG32(env->sr); - break; default: break; @@ -1516,14 +1513,11 @@ read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) switch (n) { case 16: GET_REG8(env->pregs[n - 16]); - break; case 17: GET_REG8(env->pregs[n - 16]); - break; case 20: case 21: GET_REG16(env->pregs[n - 16]); - break; default: if (n >= 23) { GET_REG32(env->pregs[n - 16]); @@ -1693,22 +1687,16 @@ static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); val = deposit64(env->psw.mask, 44, 2, cc_op); GET_REGL(val); - break; case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); - break; case S390_R0_REGNUM ... S390_R15_REGNUM: GET_REGL(env->regs[n-S390_R0_REGNUM]); - break; case S390_A0_REGNUM ... S390_A15_REGNUM: GET_REG32(env->aregs[n-S390_A0_REGNUM]); - break; case S390_FPC_REGNUM: GET_REG32(env->fpc); - break; case S390_F0_REGNUM ... S390_F15_REGNUM: GET_REG64(env->fregs[n-S390_F0_REGNUM].ll); - break; } return 0; @@ -1762,26 +1750,19 @@ static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) switch (n) { case 32: GET_REG32(env->pc); - break; /* FIXME: put in right exception ID */ case 33: GET_REG32(0); - break; case 34: GET_REG32(env->eba); - break; case 35: GET_REG32(env->deba); - break; case 36: GET_REG32(env->ie); - break; case 37: GET_REG32(lm32_pic_get_im(env->pic_state)); - break; case 38: GET_REG32(lm32_pic_get_ip(env->pic_state)); - break; } } return 0; @@ -1844,28 +1825,22 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) switch (reg->type) { case 9: /*pc*/ GET_REG32(env->pc); - break; case 1: /*ar*/ xtensa_sync_phys_from_window(env); GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); - break; case 2: /*SR*/ GET_REG32(env->sregs[reg->targno & 0xff]); - break; case 3: /*UR*/ GET_REG32(env->uregs[reg->targno & 0xff]); - break; case 4: /*f*/ GET_REG32(float32_val(env->fregs[reg->targno & 0x0f])); - break; case 8: /*a*/ GET_REG32(env->regs[reg->targno & 0x0f]); - break; default: qemu_log("%s from reg %d of unsupported type %d\n", From a0e372f0c49ac01faeaeb73a6e8f50e8ac615f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 28 Jun 2013 23:18:47 +0200 Subject: [PATCH 07/25] cpu: Introduce CPUState::gdb_num_regs and CPUClass::gdb_num_core_regs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPUState::gdb_num_regs replaces num_g_regs. CPUClass::gdb_num_core_regs replaces NUM_CORE_REGS. Allows building gdb_register_coprocessor() for xtensa, too. As a side effect this should fix coprocessor register numbering for SMP. Acked-by: Michael Walle (for lm32) Acked-by: Max Filippov (for xtensa) Signed-off-by: Andreas Färber --- gdbstub.c | 83 +++++++++---------------------------- include/qom/cpu.h | 7 +++- qom/cpu.c | 9 ++++ target-alpha/cpu.c | 1 + target-arm/cpu.c | 1 + target-cris/cpu.c | 2 + target-i386/cpu.c | 1 + target-lm32/cpu.c | 1 + target-m68k/cpu.c | 1 + target-microblaze/cpu.c | 1 + target-mips/cpu.c | 2 + target-openrisc/cpu.c | 1 + target-ppc/translate_init.c | 2 + target-s390x/cpu.c | 1 + target-sh4/cpu.c | 1 + target-sparc/cpu.c | 6 +++ target-xtensa/cpu.c | 3 ++ target-xtensa/helper.c | 8 ++++ 18 files changed, 66 insertions(+), 65 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 9ede3de7ae..4879055c60 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -530,8 +530,6 @@ static const int gpr_map[16] = { #endif static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25) - #define IDX_IP_REG CPU_NB_REGS #define IDX_FLAGS_REG (IDX_IP_REG + 1) #define IDX_SEG_REGS (IDX_FLAGS_REG + 1) @@ -732,7 +730,6 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) historical mishap the FP registers appear in between core integer regs and PC, MSR, CR, and so forth. We hack round this by giving the FP regs zero size when talking to a newer gdb. */ -#define NUM_CORE_REGS 71 #if defined (TARGET_PPC64) #define GDB_CORE_XML "power64-core.xml" #else @@ -837,12 +834,6 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) #elif defined (TARGET_SPARC) -#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) -#define NUM_CORE_REGS 86 -#else -#define NUM_CORE_REGS 72 -#endif - #ifdef TARGET_ABI32 #define GET_REGA(val) GET_REG32(val) #else @@ -1030,7 +1021,6 @@ static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) the FPA registers appear in between core integer regs and the CPSR. We hack round this by giving the FPA regs zero size when talking to a newer gdb. */ -#define NUM_CORE_REGS 26 #define GDB_CORE_XML "arm-core.xml" static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) @@ -1104,8 +1094,6 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) #elif defined (TARGET_M68K) -#define NUM_CORE_REGS 18 - #define GDB_CORE_XML "cf-core.xml" static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) @@ -1157,8 +1145,6 @@ static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_MIPS) -#define NUM_CORE_REGS 73 - static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -1285,8 +1271,6 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) } #elif defined(TARGET_OPENRISC) -#define NUM_CORE_REGS (32 + 3) - static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -1312,9 +1296,11 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) static int cpu_gdb_write_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) { + OpenRISCCPU *cpu = openrisc_env_get_cpu(env); + CPUClass *cc = CPU_GET_CLASS(cpu); uint32_t tmp; - if (n > NUM_CORE_REGS) { + if (n > cc->gdb_num_core_regs) { return 0; } @@ -1347,8 +1333,6 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env, /* Hint: Use "set architecture sh4" in GDB to see fpu registers */ /* FIXME: We should use XML for this. */ -#define NUM_CORE_REGS 59 - static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) { switch (n) { @@ -1465,8 +1449,6 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_MICROBLAZE) -#define NUM_CORE_REGS (32 + 5) - static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -1479,9 +1461,11 @@ static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) { + MicroBlazeCPU *cpu = mb_env_get_cpu(env); + CPUClass *cc = CPU_GET_CLASS(cpu); uint32_t tmp; - if (n > NUM_CORE_REGS) { + if (n > cc->gdb_num_core_regs) { return 0; } @@ -1496,8 +1480,6 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_CRIS) -#define NUM_CORE_REGS 49 - static int read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) { @@ -1605,8 +1587,6 @@ static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_ALPHA) -#define NUM_CORE_REGS 67 - static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) { uint64_t val; @@ -1675,8 +1655,6 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_S390X) -#define NUM_CORE_REGS S390_NUM_REGS - static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) { uint64_t val; @@ -1740,7 +1718,6 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n) #elif defined (TARGET_LM32) #include "hw/lm32/lm32_pic.h" -#define NUM_CORE_REGS (32 + 7) static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) { @@ -1770,9 +1747,11 @@ static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) { + LM32CPU *cpu = lm32_env_get_cpu(env); + CPUClass *cc = CPU_GET_CLASS(cpu); uint32_t tmp; - if (n > NUM_CORE_REGS) { + if (n > cc->gdb_num_core_regs) { return 0; } @@ -1806,14 +1785,6 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) } #elif defined(TARGET_XTENSA) -/* Use num_core_regs to see only non-privileged registers in an unmodified gdb. - * Use num_regs to see all registers. gdb modification is required for that: - * reset bit 0 in the 'flags' field of the registers definitions in the - * gdb/xtensa-config.c inside gdb source tree or inside gdb overlay. - */ -#define NUM_CORE_REGS (env->config->gdb_regmap.num_regs) -#define num_g_regs NUM_CORE_REGS - static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) { const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; @@ -1896,8 +1867,6 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) } #else -#define NUM_CORE_REGS 0 - static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n) { return 0; @@ -1910,10 +1879,6 @@ static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n) #endif -#if !defined(TARGET_XTENSA) -static int num_g_regs = NUM_CORE_REGS; -#endif - #ifdef GDB_CORE_XML /* Encode data using the encoding for 'x' packets. */ static int memtox(char *buf, const char *mem, int len) @@ -1982,11 +1947,13 @@ static const char *get_feature_xml(const char *p, const char **newp) static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) { + CPUClass *cc = CPU_GET_CLASS(cpu); CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; - if (reg < NUM_CORE_REGS) + if (reg < cc->gdb_num_core_regs) { return cpu_gdb_read_register(env, mem_buf, reg); + } for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { @@ -1998,11 +1965,13 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) { + CPUClass *cc = CPU_GET_CLASS(cpu); CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; - if (reg < NUM_CORE_REGS) + if (reg < cc->gdb_num_core_regs) { return cpu_gdb_write_register(env, mem_buf, reg); + } for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { @@ -2012,7 +1981,6 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) return 0; } -#if !defined(TARGET_XTENSA) /* Register a supplemental set of CPU registers. If g_pos is nonzero it specifies the first register number and these registers are included in a standard "g" packet. Direction is relative to gdb, i.e. get_reg is @@ -2025,7 +1993,6 @@ void gdb_register_coprocessor(CPUState *cpu, { GDBRegisterState *s; GDBRegisterState **p; - static int last_reg = NUM_CORE_REGS; p = &cpu->gdb_regs; while (*p) { @@ -2036,25 +2003,22 @@ void gdb_register_coprocessor(CPUState *cpu, } s = g_new0(GDBRegisterState, 1); - s->base_reg = last_reg; + s->base_reg = cpu->gdb_num_regs; s->num_regs = num_regs; s->get_reg = get_reg; s->set_reg = set_reg; s->xml = xml; /* Add to end of list. */ - last_reg += num_regs; + cpu->gdb_num_regs += num_regs; *p = s; if (g_pos) { if (g_pos != s->base_reg) { fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n" "Expected %d got %d\n", xml, g_pos, s->base_reg); - } else { - num_g_regs = last_reg; } } } -#endif #ifndef CONFIG_USER_ONLY static const int xlat_gdb_type[] = { @@ -2184,9 +2148,6 @@ static CPUState *find_cpu(uint32_t thread_id) static int gdb_handle_packet(GDBState *s, const char *line_buf) { -#ifdef TARGET_XTENSA - CPUArchState *env; -#endif CPUState *cpu; const char *p; uint32_t thread; @@ -2334,11 +2295,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'g': cpu_synchronize_state(s->g_cpu); -#ifdef TARGET_XTENSA - env = s->g_cpu->env_ptr; -#endif len = 0; - for (addr = 0; addr < num_g_regs; addr++) { + for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) { reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); len += reg_size; } @@ -2347,13 +2305,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'G': cpu_synchronize_state(s->g_cpu); -#ifdef TARGET_XTENSA - env = s->g_cpu->env_ptr; -#endif registers = mem_buf; len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); - for (addr = 0; addr < num_g_regs && len > 0; addr++) { + for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) { reg_size = gdb_write_register(s->g_cpu, registers, addr); len -= reg_size; registers += reg_size; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index daf1835c1a..195fe593ea 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -81,6 +81,7 @@ struct TranslationBlock; * #TranslationBlock. * @get_phys_page_debug: Callback for obtaining a physical address. * @vmsd: State description for migration. + * @gdb_num_core_regs: Number of core registers accessible to GDB. * * Represents a CPU family or model. */ @@ -109,7 +110,6 @@ typedef struct CPUClass { void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); - const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, int cpuid, void *opaque); int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, @@ -118,6 +118,9 @@ typedef struct CPUClass { int cpuid, void *opaque); int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, void *opaque); + + const struct VMStateDescription *vmsd; + int gdb_num_core_regs; } CPUClass; struct KVMState; @@ -142,6 +145,7 @@ struct kvm_run; * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. * @gdb_regs: Additional GDB registers. + * @gdb_num_regs: Number of total registers accessible to GDB. * @next_cpu: Next CPU sharing TB cache. * @kvm_fd: vCPU file descriptor for KVM. * @@ -177,6 +181,7 @@ struct CPUState { void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; struct GDBRegisterState *gdb_regs; + int gdb_num_regs; CPUState *next_cpu; int kvm_fd; diff --git a/qom/cpu.c b/qom/cpu.c index 5c45ab5333..2839ddf650 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -226,6 +226,14 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) } } +static void cpu_common_initfn(Object *obj) +{ + CPUState *cpu = CPU(obj); + CPUClass *cc = CPU_GET_CLASS(obj); + + cpu->gdb_num_regs = cc->gdb_num_core_regs; +} + static int64_t cpu_common_get_arch_id(CPUState *cpu) { return cpu->cpu_index; @@ -253,6 +261,7 @@ static const TypeInfo cpu_type_info = { .name = TYPE_CPU, .parent = TYPE_DEVICE, .instance_size = sizeof(CPUState), + .instance_init = cpu_common_initfn, .abstract = true, .class_size = sizeof(CPUClass), .class_init = cpu_class_init, diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index c8c8c2c861..cc0f69a84a 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -276,6 +276,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug; dc->vmsd = &vmstate_alpha_cpu; #endif + cc->gdb_num_core_regs = 67; } static const TypeInfo alpha_cpu_type_info = { diff --git a/target-arm/cpu.c b/target-arm/cpu.c index d3906a4829..f39c19f162 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -828,6 +828,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; cc->vmsd = &vmstate_arm_cpu; #endif + cc->gdb_num_core_regs = 26; } static void cpu_register(const ARMCPUInfo *info) diff --git a/target-cris/cpu.c b/target-cris/cpu.c index ba095e75a5..31eeddf822 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -258,6 +258,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = cris_cpu_get_phys_page_debug; #endif + + cc->gdb_num_core_regs = 49; } static const TypeInfo cris_cpu_type_info = { diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cd350cb8e4..df9832e151 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2549,6 +2549,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote; cc->vmsd = &vmstate_x86_cpu; #endif + cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25; } static const TypeInfo x86_cpu_type_info = { diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index ce55e4807d..aa52696cda 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -91,6 +91,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug; cc->vmsd = &vmstate_lm32_cpu; #endif + cc->gdb_num_core_regs = 32 + 7; } static const TypeInfo lm32_cpu_type_info = { diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 988f476257..93200d9964 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -194,6 +194,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_m68k_cpu; + cc->gdb_num_core_regs = 18; } static void register_cpu_type(const M68kCPUInfo *info) diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 9f10c8c778..758b0cb07d 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -147,6 +147,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) #endif dc->vmsd = &vmstate_mb_cpu; dc->props = mb_properties; + cc->gdb_num_core_regs = 32 + 5; } static const TypeInfo mb_cpu_type_info = { diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 4834c86d02..e667fb7b7c 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -104,6 +104,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->do_unassigned_access = mips_cpu_unassigned_access; cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; #endif + + cc->gdb_num_core_regs = 73; } static const TypeInfo mips_cpu_type_info = { diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 7718820ecc..9b042e14b0 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -159,6 +159,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug; dc->vmsd = &vmstate_openrisc_cpu; #endif + cc->gdb_num_core_regs = 32 + 3; } static void cpu_register(const OpenRISCCPUInfo *info) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 0b0844f467..91161939c0 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8461,6 +8461,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; #endif + + cc->gdb_num_core_regs = 71; } static const TypeInfo ppc_cpu_type_info = { diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index cb89d1a46b..8f99d7c86c 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -177,6 +177,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->get_phys_page_debug = s390_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_s390_cpu; + cc->gdb_num_core_regs = S390_NUM_REGS; } static const TypeInfo s390_cpu_type_info = { diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 51a77576fb..35f0535436 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -290,6 +290,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->get_phys_page_debug = superh_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_sh_cpu; + cc->gdb_num_core_regs = 59; } static const TypeInfo superh_cpu_type_info = { diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index d1d03396ef..388a632d18 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -791,6 +791,12 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->do_unassigned_access = sparc_cpu_unassigned_access; cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; #endif + +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) + cc->gdb_num_core_regs = 86; +#else + cc->gdb_num_core_regs = 72; +#endif } static const TypeInfo sparc_cpu_type_info = { diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 5a39971d2c..560fa0c058 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -85,8 +85,11 @@ static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model) static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp) { + CPUState *cs = CPU(dev); XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev); + cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs; + xcc->parent_realize(dev, errp); } diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index e3098798af..a0f9993b2d 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -37,10 +37,18 @@ static struct XtensaConfigList *xtensa_cores; static void xtensa_core_class_init(ObjectClass *oc, void *data) { + CPUClass *cc = CPU_CLASS(oc); XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc); const XtensaConfig *config = data; xcc->config = config; + + /* Use num_core_regs to see only non-privileged registers in an unmodified + * gdb. Use num_regs to see all registers. gdb modification is required + * for that: reset bit 0 in the 'flags' field of the registers definitions + * in the gdb/xtensa-config.c inside gdb source tree or inside gdb overlay. + */ + cc->gdb_num_core_regs = config->gdb_regmap.num_regs; } void xtensa_register_core(XtensaConfigList *node) From f20f9df06e6f724d2ccdaf5f9a6dae45c061db75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:07:54 +0200 Subject: [PATCH 08/25] target-i386: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 203 +------------------------------------- target-i386/gdbstub.c | 222 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 202 deletions(-) create mode 100644 target-i386/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 4879055c60..5a2320420c 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -520,208 +520,7 @@ static int put_packet(GDBState *s, const char *buf) #if defined(TARGET_I386) -#ifdef TARGET_X86_64 -static const int gpr_map[16] = { - R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP, - 8, 9, 10, 11, 12, 13, 14, 15 -}; -#else -#define gpr_map gpr_map32 -#endif -static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - -#define IDX_IP_REG CPU_NB_REGS -#define IDX_FLAGS_REG (IDX_IP_REG + 1) -#define IDX_SEG_REGS (IDX_FLAGS_REG + 1) -#define IDX_FP_REGS (IDX_SEG_REGS + 6) -#define IDX_XMM_REGS (IDX_FP_REGS + 16) -#define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) - -static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) -{ - if (n < CPU_NB_REGS) { - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - GET_REG64(env->regs[gpr_map[n]]); - } else if (n < CPU_NB_REGS32) { - GET_REG32(env->regs[gpr_map32[n]]); - } - } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { -#ifdef USE_X86LDOUBLE - /* FIXME: byteswap float values - after fixing fpregs layout. */ - memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10); -#else - memset(mem_buf, 0, 10); -#endif - return 10; - } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { - n -= IDX_XMM_REGS; - if (n < CPU_NB_REGS32 || - (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { - stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0)); - stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1)); - return 16; - } - } else { - switch (n) { - case IDX_IP_REG: - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - GET_REG64(env->eip); - } else { - GET_REG32(env->eip); - } - case IDX_FLAGS_REG: - GET_REG32(env->eflags); - - case IDX_SEG_REGS: - GET_REG32(env->segs[R_CS].selector); - case IDX_SEG_REGS + 1: - GET_REG32(env->segs[R_SS].selector); - case IDX_SEG_REGS + 2: - GET_REG32(env->segs[R_DS].selector); - case IDX_SEG_REGS + 3: - GET_REG32(env->segs[R_ES].selector); - case IDX_SEG_REGS + 4: - GET_REG32(env->segs[R_FS].selector); - case IDX_SEG_REGS + 5: - GET_REG32(env->segs[R_GS].selector); - - case IDX_FP_REGS + 8: - GET_REG32(env->fpuc); - case IDX_FP_REGS + 9: - GET_REG32((env->fpus & ~0x3800) | - (env->fpstt & 0x7) << 11); - case IDX_FP_REGS + 10: - GET_REG32(0); /* ftag */ - case IDX_FP_REGS + 11: - GET_REG32(0); /* fiseg */ - case IDX_FP_REGS + 12: - GET_REG32(0); /* fioff */ - case IDX_FP_REGS + 13: - GET_REG32(0); /* foseg */ - case IDX_FP_REGS + 14: - GET_REG32(0); /* fooff */ - case IDX_FP_REGS + 15: - GET_REG32(0); /* fop */ - - case IDX_MXCSR_REG: - GET_REG32(env->mxcsr); - } - } - return 0; -} - -static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf) -{ - uint16_t selector = ldl_p(mem_buf); - - if (selector != env->segs[sreg].selector) { -#if defined(CONFIG_USER_ONLY) - cpu_x86_load_seg(env, sreg, selector); -#else - unsigned int limit, flags; - target_ulong base; - - if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { - base = selector << 4; - limit = 0xffff; - flags = 0; - } else { - if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, - &flags)) { - return 4; - } - } - cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags); -#endif - } - return 4; -} - -static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) -{ - uint32_t tmp; - - if (n < CPU_NB_REGS) { - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - env->regs[gpr_map[n]] = ldtul_p(mem_buf); - return sizeof(target_ulong); - } else if (n < CPU_NB_REGS32) { - n = gpr_map32[n]; - env->regs[n] &= ~0xffffffffUL; - env->regs[n] |= (uint32_t)ldl_p(mem_buf); - return 4; - } - } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { -#ifdef USE_X86LDOUBLE - /* FIXME: byteswap float values - after fixing fpregs layout. */ - memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10); -#endif - return 10; - } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { - n -= IDX_XMM_REGS; - if (n < CPU_NB_REGS32 || - (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { - env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf); - env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8); - return 16; - } - } else { - switch (n) { - case IDX_IP_REG: - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - env->eip = ldq_p(mem_buf); - return 8; - } else { - env->eip &= ~0xffffffffUL; - env->eip |= (uint32_t)ldl_p(mem_buf); - return 4; - } - case IDX_FLAGS_REG: - env->eflags = ldl_p(mem_buf); - return 4; - - case IDX_SEG_REGS: - return cpu_x86_gdb_load_seg(env, R_CS, mem_buf); - case IDX_SEG_REGS + 1: - return cpu_x86_gdb_load_seg(env, R_SS, mem_buf); - case IDX_SEG_REGS + 2: - return cpu_x86_gdb_load_seg(env, R_DS, mem_buf); - case IDX_SEG_REGS + 3: - return cpu_x86_gdb_load_seg(env, R_ES, mem_buf); - case IDX_SEG_REGS + 4: - return cpu_x86_gdb_load_seg(env, R_FS, mem_buf); - case IDX_SEG_REGS + 5: - return cpu_x86_gdb_load_seg(env, R_GS, mem_buf); - - case IDX_FP_REGS + 8: - env->fpuc = ldl_p(mem_buf); - return 4; - case IDX_FP_REGS + 9: - tmp = ldl_p(mem_buf); - env->fpstt = (tmp >> 11) & 7; - env->fpus = tmp & ~0x3800; - return 4; - case IDX_FP_REGS + 10: /* ftag */ - return 4; - case IDX_FP_REGS + 11: /* fiseg */ - return 4; - case IDX_FP_REGS + 12: /* fioff */ - return 4; - case IDX_FP_REGS + 13: /* foseg */ - return 4; - case IDX_FP_REGS + 14: /* fooff */ - return 4; - case IDX_FP_REGS + 15: /* fop */ - return 4; - - case IDX_MXCSR_REG: - env->mxcsr = ldl_p(mem_buf); - return 4; - } - } - /* Unrecognised register. */ - return 0; -} +#include "target-i386/gdbstub.c" #elif defined (TARGET_PPC) diff --git a/target-i386/gdbstub.c b/target-i386/gdbstub.c new file mode 100644 index 0000000000..974d8ad9a3 --- /dev/null +++ b/target-i386/gdbstub.c @@ -0,0 +1,222 @@ +/* + * x86 gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifdef TARGET_X86_64 +static const int gpr_map[16] = { + R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP, + 8, 9, 10, 11, 12, 13, 14, 15 +}; +#else +#define gpr_map gpr_map32 +#endif +static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +#define IDX_IP_REG CPU_NB_REGS +#define IDX_FLAGS_REG (IDX_IP_REG + 1) +#define IDX_SEG_REGS (IDX_FLAGS_REG + 1) +#define IDX_FP_REGS (IDX_SEG_REGS + 6) +#define IDX_XMM_REGS (IDX_FP_REGS + 16) +#define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) + +static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) +{ + if (n < CPU_NB_REGS) { + if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { + GET_REG64(env->regs[gpr_map[n]]); + } else if (n < CPU_NB_REGS32) { + GET_REG32(env->regs[gpr_map32[n]]); + } + } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { +#ifdef USE_X86LDOUBLE + /* FIXME: byteswap float values - after fixing fpregs layout. */ + memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10); +#else + memset(mem_buf, 0, 10); +#endif + return 10; + } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { + n -= IDX_XMM_REGS; + if (n < CPU_NB_REGS32 || + (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { + stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0)); + stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1)); + return 16; + } + } else { + switch (n) { + case IDX_IP_REG: + if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { + GET_REG64(env->eip); + } else { + GET_REG32(env->eip); + } + case IDX_FLAGS_REG: + GET_REG32(env->eflags); + + case IDX_SEG_REGS: + GET_REG32(env->segs[R_CS].selector); + case IDX_SEG_REGS + 1: + GET_REG32(env->segs[R_SS].selector); + case IDX_SEG_REGS + 2: + GET_REG32(env->segs[R_DS].selector); + case IDX_SEG_REGS + 3: + GET_REG32(env->segs[R_ES].selector); + case IDX_SEG_REGS + 4: + GET_REG32(env->segs[R_FS].selector); + case IDX_SEG_REGS + 5: + GET_REG32(env->segs[R_GS].selector); + + case IDX_FP_REGS + 8: + GET_REG32(env->fpuc); + case IDX_FP_REGS + 9: + GET_REG32((env->fpus & ~0x3800) | + (env->fpstt & 0x7) << 11); + case IDX_FP_REGS + 10: + GET_REG32(0); /* ftag */ + case IDX_FP_REGS + 11: + GET_REG32(0); /* fiseg */ + case IDX_FP_REGS + 12: + GET_REG32(0); /* fioff */ + case IDX_FP_REGS + 13: + GET_REG32(0); /* foseg */ + case IDX_FP_REGS + 14: + GET_REG32(0); /* fooff */ + case IDX_FP_REGS + 15: + GET_REG32(0); /* fop */ + + case IDX_MXCSR_REG: + GET_REG32(env->mxcsr); + } + } + return 0; +} + +static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf) +{ + uint16_t selector = ldl_p(mem_buf); + + if (selector != env->segs[sreg].selector) { +#if defined(CONFIG_USER_ONLY) + cpu_x86_load_seg(env, sreg, selector); +#else + unsigned int limit, flags; + target_ulong base; + + if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { + base = selector << 4; + limit = 0xffff; + flags = 0; + } else { + if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, + &flags)) { + return 4; + } + } + cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags); +#endif + } + return 4; +} + +static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + if (n < CPU_NB_REGS) { + if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { + env->regs[gpr_map[n]] = ldtul_p(mem_buf); + return sizeof(target_ulong); + } else if (n < CPU_NB_REGS32) { + n = gpr_map32[n]; + env->regs[n] &= ~0xffffffffUL; + env->regs[n] |= (uint32_t)ldl_p(mem_buf); + return 4; + } + } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { +#ifdef USE_X86LDOUBLE + /* FIXME: byteswap float values - after fixing fpregs layout. */ + memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10); +#endif + return 10; + } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { + n -= IDX_XMM_REGS; + if (n < CPU_NB_REGS32 || + (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { + env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf); + env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8); + return 16; + } + } else { + switch (n) { + case IDX_IP_REG: + if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { + env->eip = ldq_p(mem_buf); + return 8; + } else { + env->eip &= ~0xffffffffUL; + env->eip |= (uint32_t)ldl_p(mem_buf); + return 4; + } + case IDX_FLAGS_REG: + env->eflags = ldl_p(mem_buf); + return 4; + + case IDX_SEG_REGS: + return cpu_x86_gdb_load_seg(env, R_CS, mem_buf); + case IDX_SEG_REGS + 1: + return cpu_x86_gdb_load_seg(env, R_SS, mem_buf); + case IDX_SEG_REGS + 2: + return cpu_x86_gdb_load_seg(env, R_DS, mem_buf); + case IDX_SEG_REGS + 3: + return cpu_x86_gdb_load_seg(env, R_ES, mem_buf); + case IDX_SEG_REGS + 4: + return cpu_x86_gdb_load_seg(env, R_FS, mem_buf); + case IDX_SEG_REGS + 5: + return cpu_x86_gdb_load_seg(env, R_GS, mem_buf); + + case IDX_FP_REGS + 8: + env->fpuc = ldl_p(mem_buf); + return 4; + case IDX_FP_REGS + 9: + tmp = ldl_p(mem_buf); + env->fpstt = (tmp >> 11) & 7; + env->fpus = tmp & ~0x3800; + return 4; + case IDX_FP_REGS + 10: /* ftag */ + return 4; + case IDX_FP_REGS + 11: /* fiseg */ + return 4; + case IDX_FP_REGS + 12: /* fioff */ + return 4; + case IDX_FP_REGS + 13: /* foseg */ + return 4; + case IDX_FP_REGS + 14: /* fooff */ + return 4; + case IDX_FP_REGS + 15: /* fop */ + return 4; + + case IDX_MXCSR_REG: + env->mxcsr = ldl_p(mem_buf); + return 4; + } + } + /* Unrecognised register. */ + return 0; +} From 0980bfabbc2e93d42c6b5ade578b371c36f6f23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:26:33 +0200 Subject: [PATCH 09/25] target-ppc: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 101 +---------------------------------- target-ppc/gdbstub.c | 122 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 100 deletions(-) create mode 100644 target-ppc/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 5a2320420c..c858b7f2b6 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -524,112 +524,13 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_PPC) -/* Old gdb always expects FP registers. Newer (xml-aware) gdb only - expects whatever the target description contains. Due to a - historical mishap the FP registers appear in between core integer - regs and PC, MSR, CR, and so forth. We hack round this by giving the - FP regs zero size when talking to a newer gdb. */ #if defined (TARGET_PPC64) #define GDB_CORE_XML "power64-core.xml" #else #define GDB_CORE_XML "power-core.xml" #endif -static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - /* gprs */ - GET_REGL(env->gpr[n]); - } else if (n < 64) { - /* fprs */ - if (gdb_has_xml) { - return 0; - } - stfq_p(mem_buf, env->fpr[n-32]); - return 8; - } else { - switch (n) { - case 64: - GET_REGL(env->nip); - case 65: - GET_REGL(env->msr); - case 66: - { - uint32_t cr = 0; - int i; - for (i = 0; i < 8; i++) { - cr |= env->crf[i] << (32 - ((i + 1) * 4)); - } - GET_REG32(cr); - } - case 67: - GET_REGL(env->lr); - case 68: - GET_REGL(env->ctr); - case 69: - GET_REGL(env->xer); - case 70: - { - if (gdb_has_xml) { - return 0; - } - GET_REG32(env->fpscr); - } - } - } - return 0; -} - -static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - /* gprs */ - env->gpr[n] = ldtul_p(mem_buf); - return sizeof(target_ulong); - } else if (n < 64) { - /* fprs */ - if (gdb_has_xml) { - return 0; - } - env->fpr[n-32] = ldfq_p(mem_buf); - return 8; - } else { - switch (n) { - case 64: - env->nip = ldtul_p(mem_buf); - return sizeof(target_ulong); - case 65: - ppc_store_msr(env, ldtul_p(mem_buf)); - return sizeof(target_ulong); - case 66: - { - uint32_t cr = ldl_p(mem_buf); - int i; - for (i = 0; i < 8; i++) { - env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; - } - return 4; - } - case 67: - env->lr = ldtul_p(mem_buf); - return sizeof(target_ulong); - case 68: - env->ctr = ldtul_p(mem_buf); - return sizeof(target_ulong); - case 69: - env->xer = ldtul_p(mem_buf); - return sizeof(target_ulong); - case 70: - /* fpscr */ - if (gdb_has_xml) { - return 0; - } - store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); - return sizeof(target_ulong); - } - } - return 0; -} +#include "target-ppc/gdbstub.c" #elif defined (TARGET_SPARC) diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c new file mode 100644 index 0000000000..b834e60f54 --- /dev/null +++ b/target-ppc/gdbstub.c @@ -0,0 +1,122 @@ +/* + * PowerPC gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* Old gdb always expects FP registers. Newer (xml-aware) gdb only + * expects whatever the target description contains. Due to a + * historical mishap the FP registers appear in between core integer + * regs and PC, MSR, CR, and so forth. We hack round this by giving the + * FP regs zero size when talking to a newer gdb. + */ + +static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + /* gprs */ + GET_REGL(env->gpr[n]); + } else if (n < 64) { + /* fprs */ + if (gdb_has_xml) { + return 0; + } + stfq_p(mem_buf, env->fpr[n-32]); + return 8; + } else { + switch (n) { + case 64: + GET_REGL(env->nip); + case 65: + GET_REGL(env->msr); + case 66: + { + uint32_t cr = 0; + int i; + for (i = 0; i < 8; i++) { + cr |= env->crf[i] << (32 - ((i + 1) * 4)); + } + GET_REG32(cr); + } + case 67: + GET_REGL(env->lr); + case 68: + GET_REGL(env->ctr); + case 69: + GET_REGL(env->xer); + case 70: + { + if (gdb_has_xml) { + return 0; + } + GET_REG32(env->fpscr); + } + } + } + return 0; +} + +static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + /* gprs */ + env->gpr[n] = ldtul_p(mem_buf); + return sizeof(target_ulong); + } else if (n < 64) { + /* fprs */ + if (gdb_has_xml) { + return 0; + } + env->fpr[n-32] = ldfq_p(mem_buf); + return 8; + } else { + switch (n) { + case 64: + env->nip = ldtul_p(mem_buf); + return sizeof(target_ulong); + case 65: + ppc_store_msr(env, ldtul_p(mem_buf)); + return sizeof(target_ulong); + case 66: + { + uint32_t cr = ldl_p(mem_buf); + int i; + for (i = 0; i < 8; i++) { + env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; + } + return 4; + } + case 67: + env->lr = ldtul_p(mem_buf); + return sizeof(target_ulong); + case 68: + env->ctr = ldtul_p(mem_buf); + return sizeof(target_ulong); + case 69: + env->xer = ldtul_p(mem_buf); + return sizeof(target_ulong); + case 70: + /* fpscr */ + if (gdb_has_xml) { + return 0; + } + store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); + return sizeof(target_ulong); + } + } + return 0; +} From d19c87f44d8d7bac48d4b35863ae825f872ed54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:29:26 +0200 Subject: [PATCH 10/25] target-sparc: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 180 +------------------------------------ target-sparc/gdbstub.c | 200 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 179 deletions(-) create mode 100644 target-sparc/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index c858b7f2b6..bf98eb079b 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -534,186 +534,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_SPARC) -#ifdef TARGET_ABI32 -#define GET_REGA(val) GET_REG32(val) -#else -#define GET_REGA(val) GET_REGL(val) -#endif +#include "target-sparc/gdbstub.c" -static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) -{ - if (n < 8) { - /* g0..g7 */ - GET_REGA(env->gregs[n]); - } - if (n < 32) { - /* register window */ - GET_REGA(env->regwptr[n - 8]); - } -#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) - if (n < 64) { - /* fprs */ - if (n & 1) { - GET_REG32(env->fpr[(n - 32) / 2].l.lower); - } else { - GET_REG32(env->fpr[(n - 32) / 2].l.upper); - } - } - /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ - switch (n) { - case 64: - GET_REGA(env->y); - case 65: - GET_REGA(cpu_get_psr(env)); - case 66: - GET_REGA(env->wim); - case 67: - GET_REGA(env->tbr); - case 68: - GET_REGA(env->pc); - case 69: - GET_REGA(env->npc); - case 70: - GET_REGA(env->fsr); - case 71: - GET_REGA(0); /* csr */ - default: - GET_REGA(0); - } -#else - if (n < 64) { - /* f0-f31 */ - if (n & 1) { - GET_REG32(env->fpr[(n - 32) / 2].l.lower); - } else { - GET_REG32(env->fpr[(n - 32) / 2].l.upper); - } - } - if (n < 80) { - /* f32-f62 (double width, even numbers only) */ - GET_REG64(env->fpr[(n - 32) / 2].ll); - } - switch (n) { - case 80: - GET_REGL(env->pc); - case 81: - GET_REGL(env->npc); - case 82: - GET_REGL((cpu_get_ccr(env) << 32) | - ((env->asi & 0xff) << 24) | - ((env->pstate & 0xfff) << 8) | - cpu_get_cwp64(env)); - case 83: - GET_REGL(env->fsr); - case 84: - GET_REGL(env->fprs); - case 85: - GET_REGL(env->y); - } -#endif - return 0; -} - -static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) -{ -#if defined(TARGET_ABI32) - abi_ulong tmp; - - tmp = ldl_p(mem_buf); -#else - target_ulong tmp; - - tmp = ldtul_p(mem_buf); -#endif - - if (n < 8) { - /* g0..g7 */ - env->gregs[n] = tmp; - } else if (n < 32) { - /* register window */ - env->regwptr[n - 8] = tmp; - } -#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) - else if (n < 64) { - /* fprs */ - /* f0-f31 */ - if (n & 1) { - env->fpr[(n - 32) / 2].l.lower = tmp; - } else { - env->fpr[(n - 32) / 2].l.upper = tmp; - } - } else { - /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ - switch (n) { - case 64: - env->y = tmp; - break; - case 65: - cpu_put_psr(env, tmp); - break; - case 66: - env->wim = tmp; - break; - case 67: - env->tbr = tmp; - break; - case 68: - env->pc = tmp; - break; - case 69: - env->npc = tmp; - break; - case 70: - env->fsr = tmp; - break; - default: - return 0; - } - } - return 4; -#else - else if (n < 64) { - /* f0-f31 */ - tmp = ldl_p(mem_buf); - if (n & 1) { - env->fpr[(n - 32) / 2].l.lower = tmp; - } else { - env->fpr[(n - 32) / 2].l.upper = tmp; - } - return 4; - } else if (n < 80) { - /* f32-f62 (double width, even numbers only) */ - env->fpr[(n - 32) / 2].ll = tmp; - } else { - switch (n) { - case 80: - env->pc = tmp; - break; - case 81: - env->npc = tmp; - break; - case 82: - cpu_put_ccr(env, tmp >> 32); - env->asi = (tmp >> 24) & 0xff; - env->pstate = (tmp >> 8) & 0xfff; - cpu_put_cwp64(env, tmp & 0xff); - break; - case 83: - env->fsr = tmp; - break; - case 84: - env->fprs = tmp; - break; - case 85: - env->y = tmp; - break; - default: - return 0; - } - } - return 8; -#endif -} #elif defined (TARGET_ARM) /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c new file mode 100644 index 0000000000..914f586ab3 --- /dev/null +++ b/target-sparc/gdbstub.c @@ -0,0 +1,200 @@ +/* + * SPARC gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifdef TARGET_ABI32 +#define GET_REGA(val) GET_REG32(val) +#else +#define GET_REGA(val) GET_REGL(val) +#endif + +static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) +{ + if (n < 8) { + /* g0..g7 */ + GET_REGA(env->gregs[n]); + } + if (n < 32) { + /* register window */ + GET_REGA(env->regwptr[n - 8]); + } +#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) + if (n < 64) { + /* fprs */ + if (n & 1) { + GET_REG32(env->fpr[(n - 32) / 2].l.lower); + } else { + GET_REG32(env->fpr[(n - 32) / 2].l.upper); + } + } + /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ + switch (n) { + case 64: + GET_REGA(env->y); + case 65: + GET_REGA(cpu_get_psr(env)); + case 66: + GET_REGA(env->wim); + case 67: + GET_REGA(env->tbr); + case 68: + GET_REGA(env->pc); + case 69: + GET_REGA(env->npc); + case 70: + GET_REGA(env->fsr); + case 71: + GET_REGA(0); /* csr */ + default: + GET_REGA(0); + } +#else + if (n < 64) { + /* f0-f31 */ + if (n & 1) { + GET_REG32(env->fpr[(n - 32) / 2].l.lower); + } else { + GET_REG32(env->fpr[(n - 32) / 2].l.upper); + } + } + if (n < 80) { + /* f32-f62 (double width, even numbers only) */ + GET_REG64(env->fpr[(n - 32) / 2].ll); + } + switch (n) { + case 80: + GET_REGL(env->pc); + case 81: + GET_REGL(env->npc); + case 82: + GET_REGL((cpu_get_ccr(env) << 32) | + ((env->asi & 0xff) << 24) | + ((env->pstate & 0xfff) << 8) | + cpu_get_cwp64(env)); + case 83: + GET_REGL(env->fsr); + case 84: + GET_REGL(env->fprs); + case 85: + GET_REGL(env->y); + } +#endif + return 0; +} + +static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) +{ +#if defined(TARGET_ABI32) + abi_ulong tmp; + + tmp = ldl_p(mem_buf); +#else + target_ulong tmp; + + tmp = ldtul_p(mem_buf); +#endif + + if (n < 8) { + /* g0..g7 */ + env->gregs[n] = tmp; + } else if (n < 32) { + /* register window */ + env->regwptr[n - 8] = tmp; + } +#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) + else if (n < 64) { + /* fprs */ + /* f0-f31 */ + if (n & 1) { + env->fpr[(n - 32) / 2].l.lower = tmp; + } else { + env->fpr[(n - 32) / 2].l.upper = tmp; + } + } else { + /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ + switch (n) { + case 64: + env->y = tmp; + break; + case 65: + cpu_put_psr(env, tmp); + break; + case 66: + env->wim = tmp; + break; + case 67: + env->tbr = tmp; + break; + case 68: + env->pc = tmp; + break; + case 69: + env->npc = tmp; + break; + case 70: + env->fsr = tmp; + break; + default: + return 0; + } + } + return 4; +#else + else if (n < 64) { + /* f0-f31 */ + tmp = ldl_p(mem_buf); + if (n & 1) { + env->fpr[(n - 32) / 2].l.lower = tmp; + } else { + env->fpr[(n - 32) / 2].l.upper = tmp; + } + return 4; + } else if (n < 80) { + /* f32-f62 (double width, even numbers only) */ + env->fpr[(n - 32) / 2].ll = tmp; + } else { + switch (n) { + case 80: + env->pc = tmp; + break; + case 81: + env->npc = tmp; + break; + case 82: + cpu_put_ccr(env, tmp >> 32); + env->asi = (tmp >> 24) & 0xff; + env->pstate = (tmp >> 8) & 0xfff; + cpu_put_cwp64(env, tmp & 0xff); + break; + case 83: + env->fsr = tmp; + break; + case 84: + env->fprs = tmp; + break; + case 85: + env->y = tmp; + break; + default: + return 0; + } + } + return 8; +#endif +} From 58850dad68f3458cf430395db2e016f1d03ad7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:32:15 +0200 Subject: [PATCH 11/25] target-arm: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 74 +--------------------------------- target-arm/gdbstub.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 73 deletions(-) create mode 100644 target-arm/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index bf98eb079b..73e64117d7 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -538,81 +538,9 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_ARM) -/* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect - whatever the target description contains. Due to a historical mishap - the FPA registers appear in between core integer regs and the CPSR. - We hack round this by giving the FPA regs zero size when talking to a - newer gdb. */ #define GDB_CORE_XML "arm-core.xml" -static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) -{ - if (n < 16) { - /* Core integer register. */ - GET_REG32(env->regs[n]); - } - if (n < 24) { - /* FPA registers. */ - if (gdb_has_xml) { - return 0; - } - memset(mem_buf, 0, 12); - return 12; - } - switch (n) { - case 24: - /* FPA status register. */ - if (gdb_has_xml) { - return 0; - } - GET_REG32(0); - case 25: - /* CPSR */ - GET_REG32(cpsr_read(env)); - } - /* Unknown register. */ - return 0; -} - -static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) -{ - uint32_t tmp; - - tmp = ldl_p(mem_buf); - - /* Mask out low bit of PC to workaround gdb bugs. This will probably - cause problems if we ever implement the Jazelle DBX extensions. */ - if (n == 15) { - tmp &= ~1; - } - - if (n < 16) { - /* Core integer register. */ - env->regs[n] = tmp; - return 4; - } - if (n < 24) { /* 16-23 */ - /* FPA registers (ignored). */ - if (gdb_has_xml) { - return 0; - } - return 12; - } - switch (n) { - case 24: - /* FPA status register (ignored). */ - if (gdb_has_xml) { - return 0; - } - return 4; - case 25: - /* CPSR */ - cpsr_write(env, tmp, 0xffffffff); - return 4; - } - /* Unknown register. */ - return 0; -} +#include "target-arm/gdbstub.c" #elif defined (TARGET_M68K) diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c new file mode 100644 index 0000000000..74903a372e --- /dev/null +++ b/target-arm/gdbstub.c @@ -0,0 +1,94 @@ +/* + * ARM gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect + whatever the target description contains. Due to a historical mishap + the FPA registers appear in between core integer regs and the CPSR. + We hack round this by giving the FPA regs zero size when talking to a + newer gdb. */ + +static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) +{ + if (n < 16) { + /* Core integer register. */ + GET_REG32(env->regs[n]); + } + if (n < 24) { + /* FPA registers. */ + if (gdb_has_xml) { + return 0; + } + memset(mem_buf, 0, 12); + return 12; + } + switch (n) { + case 24: + /* FPA status register. */ + if (gdb_has_xml) { + return 0; + } + GET_REG32(0); + case 25: + /* CPSR */ + GET_REG32(cpsr_read(env)); + } + /* Unknown register. */ + return 0; +} + +static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + tmp = ldl_p(mem_buf); + + /* Mask out low bit of PC to workaround gdb bugs. This will probably + cause problems if we ever implement the Jazelle DBX extensions. */ + if (n == 15) { + tmp &= ~1; + } + + if (n < 16) { + /* Core integer register. */ + env->regs[n] = tmp; + return 4; + } + if (n < 24) { /* 16-23 */ + /* FPA registers (ignored). */ + if (gdb_has_xml) { + return 0; + } + return 12; + } + switch (n) { + case 24: + /* FPA status register (ignored). */ + if (gdb_has_xml) { + return 0; + } + return 4; + case 25: + /* CPSR */ + cpsr_write(env, tmp, 0xffffffff); + return 4; + } + /* Unknown register. */ + return 0; +} From c88de14ca45257feb82e23f3ff07e861010bd5ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:33:56 +0200 Subject: [PATCH 12/25] target-m68k: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 47 +----------------------------- target-m68k/gdbstub.c | 67 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 target-m68k/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 73e64117d7..3ed2bfe181 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -546,53 +546,8 @@ static int put_packet(GDBState *s, const char *buf) #define GDB_CORE_XML "cf-core.xml" -static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) -{ - if (n < 8) { - /* D0-D7 */ - GET_REG32(env->dregs[n]); - } else if (n < 16) { - /* A0-A7 */ - GET_REG32(env->aregs[n - 8]); - } else { - switch (n) { - case 16: - GET_REG32(env->sr); - case 17: - GET_REG32(env->pc); - } - } - /* FP registers not included here because they vary between - ColdFire and m68k. Use XML bits for these. */ - return 0; -} +#include "target-m68k/gdbstub.c" -static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) -{ - uint32_t tmp; - - tmp = ldl_p(mem_buf); - - if (n < 8) { - /* D0-D7 */ - env->dregs[n] = tmp; - } else if (n < 16) { - /* A0-A7 */ - env->aregs[n - 8] = tmp; - } else { - switch (n) { - case 16: - env->sr = tmp; - break; - case 17: - env->pc = tmp; - break; - default: - return 0; - } - } - return 4; -} #elif defined (TARGET_MIPS) static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) diff --git a/target-m68k/gdbstub.c b/target-m68k/gdbstub.c new file mode 100644 index 0000000000..2eb4b980c4 --- /dev/null +++ b/target-m68k/gdbstub.c @@ -0,0 +1,67 @@ +/* + * m68k gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) +{ + if (n < 8) { + /* D0-D7 */ + GET_REG32(env->dregs[n]); + } else if (n < 16) { + /* A0-A7 */ + GET_REG32(env->aregs[n - 8]); + } else { + switch (n) { + case 16: + GET_REG32(env->sr); + case 17: + GET_REG32(env->pc); + } + } + /* FP registers not included here because they vary between + ColdFire and m68k. Use XML bits for these. */ + return 0; +} + +static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + tmp = ldl_p(mem_buf); + + if (n < 8) { + /* D0-D7 */ + env->dregs[n] = tmp; + } else if (n < 16) { + /* A0-A7 */ + env->aregs[n - 8] = tmp; + } else { + switch (n) { + case 16: + env->sr = tmp; + break; + case 17: + env->pc = tmp; + break; + default: + return 0; + } + } + return 4; +} From 814ac26c2d3820b85f05b696735d4e1e6d7d05aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:38:42 +0200 Subject: [PATCH 13/25] target-mips: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 124 +----------------------------------- target-mips/gdbstub.c | 144 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 123 deletions(-) create mode 100644 target-mips/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 3ed2bfe181..7ee0870065 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -550,130 +550,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_MIPS) -static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - GET_REGL(env->active_tc.gpr[n]); - } - if (env->CP0_Config1 & (1 << CP0C1_FP)) { - if (n >= 38 && n < 70) { - if (env->CP0_Status & (1 << CP0St_FR)) { - GET_REGL(env->active_fpu.fpr[n - 38].d); - } else { - GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); - } - } - switch (n) { - case 70: - GET_REGL((int32_t)env->active_fpu.fcr31); - case 71: - GET_REGL((int32_t)env->active_fpu.fcr0); - } - } - switch (n) { - case 32: - GET_REGL((int32_t)env->CP0_Status); - case 33: - GET_REGL(env->active_tc.LO[0]); - case 34: - GET_REGL(env->active_tc.HI[0]); - case 35: - GET_REGL(env->CP0_BadVAddr); - case 36: - GET_REGL((int32_t)env->CP0_Cause); - case 37: - GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16)); - case 72: - GET_REGL(0); /* fp */ - case 89: - GET_REGL((int32_t)env->CP0_PRid); - } - if (n >= 73 && n <= 88) { - /* 16 embedded regs. */ - GET_REGL(0); - } +#include "target-mips/gdbstub.c" - return 0; -} - -/* convert MIPS rounding mode in FCR31 to IEEE library */ -static unsigned int ieee_rm[] = { - float_round_nearest_even, - float_round_to_zero, - float_round_up, - float_round_down -}; -#define RESTORE_ROUNDING_MODE \ - set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \ - &env->active_fpu.fp_status) - -static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) -{ - target_ulong tmp; - - tmp = ldtul_p(mem_buf); - - if (n < 32) { - env->active_tc.gpr[n] = tmp; - return sizeof(target_ulong); - } - if (env->CP0_Config1 & (1 << CP0C1_FP) - && n >= 38 && n < 73) { - if (n < 70) { - if (env->CP0_Status & (1 << CP0St_FR)) { - env->active_fpu.fpr[n - 38].d = tmp; - } else { - env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; - } - } - switch (n) { - case 70: - env->active_fpu.fcr31 = tmp & 0xFF83FFFF; - /* set rounding mode */ - RESTORE_ROUNDING_MODE; - break; - case 71: - env->active_fpu.fcr0 = tmp; - break; - } - return sizeof(target_ulong); - } - switch (n) { - case 32: - env->CP0_Status = tmp; - break; - case 33: - env->active_tc.LO[0] = tmp; - break; - case 34: - env->active_tc.HI[0] = tmp; - break; - case 35: - env->CP0_BadVAddr = tmp; - break; - case 36: - env->CP0_Cause = tmp; - break; - case 37: - env->active_tc.PC = tmp & ~(target_ulong)1; - if (tmp & 1) { - env->hflags |= MIPS_HFLAG_M16; - } else { - env->hflags &= ~(MIPS_HFLAG_M16); - } - break; - case 72: /* fp, ignored */ - break; - default: - if (n > 89) { - return 0; - } - /* Other registers are readonly. Ignore writes. */ - break; - } - - return sizeof(target_ulong); -} #elif defined(TARGET_OPENRISC) static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c new file mode 100644 index 0000000000..15dc281ea5 --- /dev/null +++ b/target-mips/gdbstub.c @@ -0,0 +1,144 @@ +/* + * MIPS gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + GET_REGL(env->active_tc.gpr[n]); + } + if (env->CP0_Config1 & (1 << CP0C1_FP)) { + if (n >= 38 && n < 70) { + if (env->CP0_Status & (1 << CP0St_FR)) { + GET_REGL(env->active_fpu.fpr[n - 38].d); + } else { + GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); + } + } + switch (n) { + case 70: + GET_REGL((int32_t)env->active_fpu.fcr31); + case 71: + GET_REGL((int32_t)env->active_fpu.fcr0); + } + } + switch (n) { + case 32: + GET_REGL((int32_t)env->CP0_Status); + case 33: + GET_REGL(env->active_tc.LO[0]); + case 34: + GET_REGL(env->active_tc.HI[0]); + case 35: + GET_REGL(env->CP0_BadVAddr); + case 36: + GET_REGL((int32_t)env->CP0_Cause); + case 37: + GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16)); + case 72: + GET_REGL(0); /* fp */ + case 89: + GET_REGL((int32_t)env->CP0_PRid); + } + if (n >= 73 && n <= 88) { + /* 16 embedded regs. */ + GET_REGL(0); + } + + return 0; +} + +/* convert MIPS rounding mode in FCR31 to IEEE library */ +static unsigned int ieee_rm[] = { + float_round_nearest_even, + float_round_to_zero, + float_round_up, + float_round_down +}; +#define RESTORE_ROUNDING_MODE \ + set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \ + &env->active_fpu.fp_status) + +static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) +{ + target_ulong tmp; + + tmp = ldtul_p(mem_buf); + + if (n < 32) { + env->active_tc.gpr[n] = tmp; + return sizeof(target_ulong); + } + if (env->CP0_Config1 & (1 << CP0C1_FP) + && n >= 38 && n < 73) { + if (n < 70) { + if (env->CP0_Status & (1 << CP0St_FR)) { + env->active_fpu.fpr[n - 38].d = tmp; + } else { + env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; + } + } + switch (n) { + case 70: + env->active_fpu.fcr31 = tmp & 0xFF83FFFF; + /* set rounding mode */ + RESTORE_ROUNDING_MODE; + break; + case 71: + env->active_fpu.fcr0 = tmp; + break; + } + return sizeof(target_ulong); + } + switch (n) { + case 32: + env->CP0_Status = tmp; + break; + case 33: + env->active_tc.LO[0] = tmp; + break; + case 34: + env->active_tc.HI[0] = tmp; + break; + case 35: + env->CP0_BadVAddr = tmp; + break; + case 36: + env->CP0_Cause = tmp; + break; + case 37: + env->active_tc.PC = tmp & ~(target_ulong)1; + if (tmp & 1) { + env->hflags |= MIPS_HFLAG_M16; + } else { + env->hflags &= ~(MIPS_HFLAG_M16); + } + break; + case 72: /* fp, ignored */ + break; + default: + if (n > 89) { + return 0; + } + /* Other registers are readonly. Ignore writes. */ + break; + } + + return sizeof(target_ulong); +} From 30028739eb6b2e95b94b957f3b4f8f258da3aa88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:40:38 +0200 Subject: [PATCH 14/25] target-openrisc: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Jia Liu Signed-off-by: Andreas Färber --- gdbstub.c | 57 +---------------------------- target-openrisc/gdbstub.c | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 56 deletions(-) create mode 100644 target-openrisc/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 7ee0870065..7bcdd3f064 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -554,63 +554,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined(TARGET_OPENRISC) -static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - GET_REG32(env->gpr[n]); - } else { - switch (n) { - case 32: /* PPC */ - GET_REG32(env->ppc); +#include "target-openrisc/gdbstub.c" - case 33: /* NPC */ - GET_REG32(env->npc); - - case 34: /* SR */ - GET_REG32(env->sr); - - default: - break; - } - } - return 0; -} - -static int cpu_gdb_write_register(CPUOpenRISCState *env, - uint8_t *mem_buf, int n) -{ - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); - uint32_t tmp; - - if (n > cc->gdb_num_core_regs) { - return 0; - } - - tmp = ldl_p(mem_buf); - - if (n < 32) { - env->gpr[n] = tmp; - } else { - switch (n) { - case 32: /* PPC */ - env->ppc = tmp; - break; - - case 33: /* NPC */ - env->npc = tmp; - break; - - case 34: /* SR */ - env->sr = tmp; - break; - - default: - break; - } - } - return 4; -} #elif defined (TARGET_SH4) /* Hint: Use "set architecture sh4" in GDB to see fpu registers */ diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c new file mode 100644 index 0000000000..fba096aa1c --- /dev/null +++ b/target-openrisc/gdbstub.c @@ -0,0 +1,77 @@ +/* + * OpenRISC gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + GET_REG32(env->gpr[n]); + } else { + switch (n) { + case 32: /* PPC */ + GET_REG32(env->ppc); + + case 33: /* NPC */ + GET_REG32(env->npc); + + case 34: /* SR */ + GET_REG32(env->sr); + + default: + break; + } + } + return 0; +} + +static int cpu_gdb_write_register(CPUOpenRISCState *env, + uint8_t *mem_buf, int n) +{ + OpenRISCCPU *cpu = openrisc_env_get_cpu(env); + CPUClass *cc = CPU_GET_CLASS(cpu); + uint32_t tmp; + + if (n > cc->gdb_num_core_regs) { + return 0; + } + + tmp = ldl_p(mem_buf); + + if (n < 32) { + env->gpr[n] = tmp; + } else { + switch (n) { + case 32: /* PPC */ + env->ppc = tmp; + break; + + case 33: /* NPC */ + env->npc = tmp; + break; + + case 34: /* SR */ + env->sr = tmp; + break; + + default: + break; + } + } + return 4; +} From 2f93773241f99457a0957a43b2490be6f594cfa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:42:52 +0200 Subject: [PATCH 15/25] target-sh4: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 117 +----------------------------------- target-sh4/gdbstub.c | 137 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 116 deletions(-) create mode 100644 target-sh4/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 7bcdd3f064..61b1bc7e81 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -558,123 +558,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_SH4) -/* Hint: Use "set architecture sh4" in GDB to see fpu registers */ -/* FIXME: We should use XML for this. */ +#include "target-sh4/gdbstub.c" -static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) -{ - switch (n) { - case 0 ... 7: - if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { - GET_REGL(env->gregs[n + 16]); - } else { - GET_REGL(env->gregs[n]); - } - case 8 ... 15: - GET_REGL(env->gregs[n]); - case 16: - GET_REGL(env->pc); - case 17: - GET_REGL(env->pr); - case 18: - GET_REGL(env->gbr); - case 19: - GET_REGL(env->vbr); - case 20: - GET_REGL(env->mach); - case 21: - GET_REGL(env->macl); - case 22: - GET_REGL(env->sr); - case 23: - GET_REGL(env->fpul); - case 24: - GET_REGL(env->fpscr); - case 25 ... 40: - if (env->fpscr & FPSCR_FR) { - stfl_p(mem_buf, env->fregs[n - 9]); - } else { - stfl_p(mem_buf, env->fregs[n - 25]); - } - return 4; - case 41: - GET_REGL(env->ssr); - case 42: - GET_REGL(env->spc); - case 43 ... 50: - GET_REGL(env->gregs[n - 43]); - case 51 ... 58: - GET_REGL(env->gregs[n - (51 - 16)]); - } - - return 0; -} - -static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) -{ - switch (n) { - case 0 ... 7: - if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { - env->gregs[n + 16] = ldl_p(mem_buf); - } else { - env->gregs[n] = ldl_p(mem_buf); - } - break; - case 8 ... 15: - env->gregs[n] = ldl_p(mem_buf); - break; - case 16: - env->pc = ldl_p(mem_buf); - break; - case 17: - env->pr = ldl_p(mem_buf); - break; - case 18: - env->gbr = ldl_p(mem_buf); - break; - case 19: - env->vbr = ldl_p(mem_buf); - break; - case 20: - env->mach = ldl_p(mem_buf); - break; - case 21: - env->macl = ldl_p(mem_buf); - break; - case 22: - env->sr = ldl_p(mem_buf); - break; - case 23: - env->fpul = ldl_p(mem_buf); - break; - case 24: - env->fpscr = ldl_p(mem_buf); - break; - case 25 ... 40: - if (env->fpscr & FPSCR_FR) { - env->fregs[n - 9] = ldfl_p(mem_buf); - } else { - env->fregs[n - 25] = ldfl_p(mem_buf); - } - break; - case 41: - env->ssr = ldl_p(mem_buf); - break; - case 42: - env->spc = ldl_p(mem_buf); - break; - case 43 ... 50: - env->gregs[n - 43] = ldl_p(mem_buf); - break; - case 51 ... 58: - env->gregs[n - (51 - 16)] = ldl_p(mem_buf); - break; - default: - return 0; - } - - return 4; -} #elif defined (TARGET_MICROBLAZE) static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c new file mode 100644 index 0000000000..38bc630f3a --- /dev/null +++ b/target-sh4/gdbstub.c @@ -0,0 +1,137 @@ +/* + * SuperH gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* Hint: Use "set architecture sh4" in GDB to see fpu registers */ +/* FIXME: We should use XML for this. */ + +static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) +{ + switch (n) { + case 0 ... 7: + if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { + GET_REGL(env->gregs[n + 16]); + } else { + GET_REGL(env->gregs[n]); + } + case 8 ... 15: + GET_REGL(env->gregs[n]); + case 16: + GET_REGL(env->pc); + case 17: + GET_REGL(env->pr); + case 18: + GET_REGL(env->gbr); + case 19: + GET_REGL(env->vbr); + case 20: + GET_REGL(env->mach); + case 21: + GET_REGL(env->macl); + case 22: + GET_REGL(env->sr); + case 23: + GET_REGL(env->fpul); + case 24: + GET_REGL(env->fpscr); + case 25 ... 40: + if (env->fpscr & FPSCR_FR) { + stfl_p(mem_buf, env->fregs[n - 9]); + } else { + stfl_p(mem_buf, env->fregs[n - 25]); + } + return 4; + case 41: + GET_REGL(env->ssr); + case 42: + GET_REGL(env->spc); + case 43 ... 50: + GET_REGL(env->gregs[n - 43]); + case 51 ... 58: + GET_REGL(env->gregs[n - (51 - 16)]); + } + + return 0; +} + +static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) +{ + switch (n) { + case 0 ... 7: + if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { + env->gregs[n + 16] = ldl_p(mem_buf); + } else { + env->gregs[n] = ldl_p(mem_buf); + } + break; + case 8 ... 15: + env->gregs[n] = ldl_p(mem_buf); + break; + case 16: + env->pc = ldl_p(mem_buf); + break; + case 17: + env->pr = ldl_p(mem_buf); + break; + case 18: + env->gbr = ldl_p(mem_buf); + break; + case 19: + env->vbr = ldl_p(mem_buf); + break; + case 20: + env->mach = ldl_p(mem_buf); + break; + case 21: + env->macl = ldl_p(mem_buf); + break; + case 22: + env->sr = ldl_p(mem_buf); + break; + case 23: + env->fpul = ldl_p(mem_buf); + break; + case 24: + env->fpscr = ldl_p(mem_buf); + break; + case 25 ... 40: + if (env->fpscr & FPSCR_FR) { + env->fregs[n - 9] = ldfl_p(mem_buf); + } else { + env->fregs[n - 25] = ldfl_p(mem_buf); + } + break; + case 41: + env->ssr = ldl_p(mem_buf); + break; + case 42: + env->spc = ldl_p(mem_buf); + break; + case 43 ... 50: + env->gregs[n - 43] = ldl_p(mem_buf); + break; + case 51 ... 58: + env->gregs[n - (51 - 16)] = ldl_p(mem_buf); + break; + default: + return 0; + } + + return 4; +} From eabfc2398f3e4e553843c15b1e3a3af2a52a7fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:45:47 +0200 Subject: [PATCH 16/25] target-microblaze: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 29 +--------------------- target-microblaze/gdbstub.c | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 target-microblaze/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 61b1bc7e81..ab030b5dcb 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -562,35 +562,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_MICROBLAZE) -static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - GET_REG32(env->regs[n]); - } else { - GET_REG32(env->sregs[n - 32]); - } - return 0; -} +#include "target-microblaze/gdbstub.c" -static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) -{ - MicroBlazeCPU *cpu = mb_env_get_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); - uint32_t tmp; - - if (n > cc->gdb_num_core_regs) { - return 0; - } - - tmp = ldl_p(mem_buf); - - if (n < 32) { - env->regs[n] = tmp; - } else { - env->sregs[n - 32] = tmp; - } - return 4; -} #elif defined (TARGET_CRIS) static int diff --git a/target-microblaze/gdbstub.c b/target-microblaze/gdbstub.c new file mode 100644 index 0000000000..96c4bc085a --- /dev/null +++ b/target-microblaze/gdbstub.c @@ -0,0 +1,49 @@ +/* + * MicroBlaze gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + GET_REG32(env->regs[n]); + } else { + GET_REG32(env->sregs[n - 32]); + } + return 0; +} + +static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) +{ + MicroBlazeCPU *cpu = mb_env_get_cpu(env); + CPUClass *cc = CPU_GET_CLASS(cpu); + uint32_t tmp; + + if (n > cc->gdb_num_core_regs) { + return 0; + } + + tmp = ldl_p(mem_buf); + + if (n < 32) { + env->regs[n] = tmp; + } else { + env->sregs[n - 32] = tmp; + } + return 4; +} From 213c19d69fb9c7537afb8539bbdf12dba90ba0ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:50:22 +0200 Subject: [PATCH 17/25] target-cris: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 105 +---------------------------------- target-cris/gdbstub.c | 125 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 104 deletions(-) create mode 100644 target-cris/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index ab030b5dcb..9ffb41f6dd 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -566,111 +566,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_CRIS) -static int -read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) -{ - if (n < 15) { - GET_REG32(env->regs[n]); - } +#include "target-cris/gdbstub.c" - if (n == 15) { - GET_REG32(env->pc); - } - - if (n < 32) { - switch (n) { - case 16: - GET_REG8(env->pregs[n - 16]); - case 17: - GET_REG8(env->pregs[n - 16]); - case 20: - case 21: - GET_REG16(env->pregs[n - 16]); - default: - if (n >= 23) { - GET_REG32(env->pregs[n - 16]); - } - break; - } - } - return 0; -} - -static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) -{ - uint8_t srs; - - if (env->pregs[PR_VR] < 32) { - return read_register_crisv10(env, mem_buf, n); - } - - srs = env->pregs[PR_SRS]; - if (n < 16) { - GET_REG32(env->regs[n]); - } - - if (n >= 21 && n < 32) { - GET_REG32(env->pregs[n - 16]); - } - if (n >= 33 && n < 49) { - GET_REG32(env->sregs[srs][n - 33]); - } - switch (n) { - case 16: - GET_REG8(env->pregs[0]); - case 17: - GET_REG8(env->pregs[1]); - case 18: - GET_REG32(env->pregs[2]); - case 19: - GET_REG8(srs); - case 20: - GET_REG16(env->pregs[4]); - case 32: - GET_REG32(env->pc); - } - - return 0; -} - -static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) -{ - uint32_t tmp; - - if (n > 49) { - return 0; - } - - tmp = ldl_p(mem_buf); - - if (n < 16) { - env->regs[n] = tmp; - } - - if (n >= 21 && n < 32) { - env->pregs[n - 16] = tmp; - } - - /* FIXME: Should support function regs be writable? */ - switch (n) { - case 16: - return 1; - case 17: - return 1; - case 18: - env->pregs[PR_PID] = tmp; - break; - case 19: - return 1; - case 20: - return 2; - case 32: - env->pc = tmp; - break; - } - - return 4; -} #elif defined (TARGET_ALPHA) static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) diff --git a/target-cris/gdbstub.c b/target-cris/gdbstub.c new file mode 100644 index 0000000000..b48224a14f --- /dev/null +++ b/target-cris/gdbstub.c @@ -0,0 +1,125 @@ +/* + * CRIS gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int +read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) +{ + if (n < 15) { + GET_REG32(env->regs[n]); + } + + if (n == 15) { + GET_REG32(env->pc); + } + + if (n < 32) { + switch (n) { + case 16: + GET_REG8(env->pregs[n - 16]); + case 17: + GET_REG8(env->pregs[n - 16]); + case 20: + case 21: + GET_REG16(env->pregs[n - 16]); + default: + if (n >= 23) { + GET_REG32(env->pregs[n - 16]); + } + break; + } + } + return 0; +} + +static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) +{ + uint8_t srs; + + if (env->pregs[PR_VR] < 32) { + return read_register_crisv10(env, mem_buf, n); + } + + srs = env->pregs[PR_SRS]; + if (n < 16) { + GET_REG32(env->regs[n]); + } + + if (n >= 21 && n < 32) { + GET_REG32(env->pregs[n - 16]); + } + if (n >= 33 && n < 49) { + GET_REG32(env->sregs[srs][n - 33]); + } + switch (n) { + case 16: + GET_REG8(env->pregs[0]); + case 17: + GET_REG8(env->pregs[1]); + case 18: + GET_REG32(env->pregs[2]); + case 19: + GET_REG8(srs); + case 20: + GET_REG16(env->pregs[4]); + case 32: + GET_REG32(env->pc); + } + + return 0; +} + +static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + if (n > 49) { + return 0; + } + + tmp = ldl_p(mem_buf); + + if (n < 16) { + env->regs[n] = tmp; + } + + if (n >= 21 && n < 32) { + env->pregs[n - 16] = tmp; + } + + /* FIXME: Should support function regs be writable? */ + switch (n) { + case 16: + return 1; + case 17: + return 1; + case 18: + env->pregs[PR_PID] = tmp; + break; + case 19: + return 1; + case 20: + return 2; + case 32: + env->pc = tmp; + break; + } + + return 4; +} From c3ce8eb3c50272d81bfea30ae9a9bd959fd68a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:52:32 +0200 Subject: [PATCH 18/25] target-alpha: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 66 +------------------------------- target-alpha/gdbstub.c | 86 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 65 deletions(-) create mode 100644 target-alpha/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 9ffb41f6dd..51e64bb4cb 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -570,72 +570,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_ALPHA) -static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) -{ - uint64_t val; - CPU_DoubleU d; +#include "target-alpha/gdbstub.c" - switch (n) { - case 0 ... 30: - val = env->ir[n]; - break; - case 32 ... 62: - d.d = env->fir[n - 32]; - val = d.ll; - break; - case 63: - val = cpu_alpha_load_fpcr(env); - break; - case 64: - val = env->pc; - break; - case 66: - val = env->unique; - break; - case 31: - case 65: - /* 31 really is the zero register; 65 is unassigned in the - gdb protocol, but is still required to occupy 8 bytes. */ - val = 0; - break; - default: - return 0; - } - GET_REGL(val); -} - -static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) -{ - target_ulong tmp = ldtul_p(mem_buf); - CPU_DoubleU d; - - switch (n) { - case 0 ... 30: - env->ir[n] = tmp; - break; - case 32 ... 62: - d.ll = tmp; - env->fir[n - 32] = d.d; - break; - case 63: - cpu_alpha_store_fpcr(env, tmp); - break; - case 64: - env->pc = tmp; - break; - case 66: - env->unique = tmp; - break; - case 31: - case 65: - /* 31 really is the zero register; 65 is unassigned in the - gdb protocol, but is still required to occupy 8 bytes. */ - break; - default: - return 0; - } - return 8; -} #elif defined (TARGET_S390X) static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) diff --git a/target-alpha/gdbstub.c b/target-alpha/gdbstub.c new file mode 100644 index 0000000000..b23afe4587 --- /dev/null +++ b/target-alpha/gdbstub.c @@ -0,0 +1,86 @@ +/* + * Alpha gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) +{ + uint64_t val; + CPU_DoubleU d; + + switch (n) { + case 0 ... 30: + val = env->ir[n]; + break; + case 32 ... 62: + d.d = env->fir[n - 32]; + val = d.ll; + break; + case 63: + val = cpu_alpha_load_fpcr(env); + break; + case 64: + val = env->pc; + break; + case 66: + val = env->unique; + break; + case 31: + case 65: + /* 31 really is the zero register; 65 is unassigned in the + gdb protocol, but is still required to occupy 8 bytes. */ + val = 0; + break; + default: + return 0; + } + GET_REGL(val); +} + +static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) +{ + target_ulong tmp = ldtul_p(mem_buf); + CPU_DoubleU d; + + switch (n) { + case 0 ... 30: + env->ir[n] = tmp; + break; + case 32 ... 62: + d.ll = tmp; + env->fir[n - 32] = d.d; + break; + case 63: + cpu_alpha_store_fpcr(env, tmp); + break; + case 64: + env->pc = tmp; + break; + case 66: + env->unique = tmp; + break; + case 31: + case 65: + /* 31 really is the zero register; 65 is unassigned in the + gdb protocol, but is still required to occupy 8 bytes. */ + break; + default: + return 0; + } + return 8; +} From cfae5c905a29128372e1f8ec4a29d70e1361d07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:54:12 +0200 Subject: [PATCH 19/25] target-s390x: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- gdbstub.c | 60 +------------------------------ target-s390x/gdbstub.c | 80 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 59 deletions(-) create mode 100644 target-s390x/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 51e64bb4cb..58502f3991 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -574,66 +574,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_S390X) -static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) -{ - uint64_t val; - int cc_op; +#include "target-s390x/gdbstub.c" - switch (n) { - case S390_PSWM_REGNUM: - cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); - val = deposit64(env->psw.mask, 44, 2, cc_op); - GET_REGL(val); - case S390_PSWA_REGNUM: - GET_REGL(env->psw.addr); - case S390_R0_REGNUM ... S390_R15_REGNUM: - GET_REGL(env->regs[n-S390_R0_REGNUM]); - case S390_A0_REGNUM ... S390_A15_REGNUM: - GET_REG32(env->aregs[n-S390_A0_REGNUM]); - case S390_FPC_REGNUM: - GET_REG32(env->fpc); - case S390_F0_REGNUM ... S390_F15_REGNUM: - GET_REG64(env->fregs[n-S390_F0_REGNUM].ll); - } - - return 0; -} - -static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n) -{ - target_ulong tmpl; - uint32_t tmp32; - int r = 8; - tmpl = ldtul_p(mem_buf); - tmp32 = ldl_p(mem_buf); - - switch (n) { - case S390_PSWM_REGNUM: - env->psw.mask = tmpl; - env->cc_op = extract64(tmpl, 44, 2); - break; - case S390_PSWA_REGNUM: - env->psw.addr = tmpl; - break; - case S390_R0_REGNUM ... S390_R15_REGNUM: - env->regs[n-S390_R0_REGNUM] = tmpl; - break; - case S390_A0_REGNUM ... S390_A15_REGNUM: - env->aregs[n-S390_A0_REGNUM] = tmp32; - r = 4; - break; - case S390_FPC_REGNUM: - env->fpc = tmp32; - r = 4; - break; - case S390_F0_REGNUM ... S390_F15_REGNUM: - env->fregs[n-S390_F0_REGNUM].ll = tmpl; - break; - default: - return 0; - } - return r; -} #elif defined (TARGET_LM32) #include "hw/lm32/lm32_pic.h" diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c new file mode 100644 index 0000000000..c966143a9d --- /dev/null +++ b/target-s390x/gdbstub.c @@ -0,0 +1,80 @@ +/* + * s390x gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) +{ + uint64_t val; + int cc_op; + + switch (n) { + case S390_PSWM_REGNUM: + cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); + val = deposit64(env->psw.mask, 44, 2, cc_op); + GET_REGL(val); + case S390_PSWA_REGNUM: + GET_REGL(env->psw.addr); + case S390_R0_REGNUM ... S390_R15_REGNUM: + GET_REGL(env->regs[n-S390_R0_REGNUM]); + case S390_A0_REGNUM ... S390_A15_REGNUM: + GET_REG32(env->aregs[n-S390_A0_REGNUM]); + case S390_FPC_REGNUM: + GET_REG32(env->fpc); + case S390_F0_REGNUM ... S390_F15_REGNUM: + GET_REG64(env->fregs[n-S390_F0_REGNUM].ll); + } + + return 0; +} + +static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n) +{ + target_ulong tmpl; + uint32_t tmp32; + int r = 8; + tmpl = ldtul_p(mem_buf); + tmp32 = ldl_p(mem_buf); + + switch (n) { + case S390_PSWM_REGNUM: + env->psw.mask = tmpl; + env->cc_op = extract64(tmpl, 44, 2); + break; + case S390_PSWA_REGNUM: + env->psw.addr = tmpl; + break; + case S390_R0_REGNUM ... S390_R15_REGNUM: + env->regs[n-S390_R0_REGNUM] = tmpl; + break; + case S390_A0_REGNUM ... S390_A15_REGNUM: + env->aregs[n-S390_A0_REGNUM] = tmp32; + r = 4; + break; + case S390_FPC_REGNUM: + env->fpc = tmp32; + r = 4; + break; + case S390_F0_REGNUM ... S390_F15_REGNUM: + env->fregs[n-S390_F0_REGNUM].ll = tmpl; + break; + default: + return 0; + } + return r; +} From d0ff8d056d3aab93b4a7b7910f938652c2febc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:55:44 +0200 Subject: [PATCH 20/25] target-lm32: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acked-by: Michael Walle Signed-off-by: Andreas Färber --- gdbstub.c | 66 +-------------------------------- target-lm32/gdbstub.c | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 65 deletions(-) create mode 100644 target-lm32/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 58502f3991..8a2f80c7d1 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -578,72 +578,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined (TARGET_LM32) -#include "hw/lm32/lm32_pic.h" +#include "target-lm32/gdbstub.c" -static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - GET_REG32(env->regs[n]); - } else { - switch (n) { - case 32: - GET_REG32(env->pc); - /* FIXME: put in right exception ID */ - case 33: - GET_REG32(0); - case 34: - GET_REG32(env->eba); - case 35: - GET_REG32(env->deba); - case 36: - GET_REG32(env->ie); - case 37: - GET_REG32(lm32_pic_get_im(env->pic_state)); - case 38: - GET_REG32(lm32_pic_get_ip(env->pic_state)); - } - } - return 0; -} - -static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) -{ - LM32CPU *cpu = lm32_env_get_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); - uint32_t tmp; - - if (n > cc->gdb_num_core_regs) { - return 0; - } - - tmp = ldl_p(mem_buf); - - if (n < 32) { - env->regs[n] = tmp; - } else { - switch (n) { - case 32: - env->pc = tmp; - break; - case 34: - env->eba = tmp; - break; - case 35: - env->deba = tmp; - break; - case 36: - env->ie = tmp; - break; - case 37: - lm32_pic_set_im(env->pic_state, tmp); - break; - case 38: - lm32_pic_set_ip(env->pic_state, tmp); - break; - } - } - return 4; -} #elif defined(TARGET_XTENSA) static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) diff --git a/target-lm32/gdbstub.c b/target-lm32/gdbstub.c new file mode 100644 index 0000000000..732a633b7a --- /dev/null +++ b/target-lm32/gdbstub.c @@ -0,0 +1,85 @@ +/* + * LM32 gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#include "hw/lm32/lm32_pic.h" + +static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + GET_REG32(env->regs[n]); + } else { + switch (n) { + case 32: + GET_REG32(env->pc); + /* FIXME: put in right exception ID */ + case 33: + GET_REG32(0); + case 34: + GET_REG32(env->eba); + case 35: + GET_REG32(env->deba); + case 36: + GET_REG32(env->ie); + case 37: + GET_REG32(lm32_pic_get_im(env->pic_state)); + case 38: + GET_REG32(lm32_pic_get_ip(env->pic_state)); + } + } + return 0; +} + +static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) +{ + LM32CPU *cpu = lm32_env_get_cpu(env); + CPUClass *cc = CPU_GET_CLASS(cpu); + uint32_t tmp; + + if (n > cc->gdb_num_core_regs) { + return 0; + } + + tmp = ldl_p(mem_buf); + + if (n < 32) { + env->regs[n] = tmp; + } else { + switch (n) { + case 32: + env->pc = tmp; + break; + case 34: + env->eba = tmp; + break; + case 35: + env->deba = tmp; + break; + case 36: + env->ie = tmp; + break; + case 37: + lm32_pic_set_im(env->pic_state, tmp); + break; + case 38: + lm32_pic_set_ip(env->pic_state, tmp); + break; + } + } + return 4; +} From 25d8ac0e31c3c68dfdd6da7c33b87870b4a3b623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 12:57:38 +0200 Subject: [PATCH 21/25] target-xtensa: Move cpu_gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acked-by: Max Filippov Signed-off-by: Andreas Färber --- gdbstub.c | 80 +------------------------------- target-xtensa/gdbstub.c | 100 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 79 deletions(-) create mode 100644 target-xtensa/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index 8a2f80c7d1..75271954d5 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -582,86 +582,8 @@ static int put_packet(GDBState *s, const char *buf) #elif defined(TARGET_XTENSA) -static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) -{ - const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; +#include "target-xtensa/gdbstub.c" - if (n < 0 || n >= env->config->gdb_regmap.num_regs) { - return 0; - } - - switch (reg->type) { - case 9: /*pc*/ - GET_REG32(env->pc); - - case 1: /*ar*/ - xtensa_sync_phys_from_window(env); - GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); - - case 2: /*SR*/ - GET_REG32(env->sregs[reg->targno & 0xff]); - - case 3: /*UR*/ - GET_REG32(env->uregs[reg->targno & 0xff]); - - case 4: /*f*/ - GET_REG32(float32_val(env->fregs[reg->targno & 0x0f])); - - case 8: /*a*/ - GET_REG32(env->regs[reg->targno & 0x0f]); - - default: - qemu_log("%s from reg %d of unsupported type %d\n", - __func__, n, reg->type); - return 0; - } -} - -static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) -{ - uint32_t tmp; - const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; - - if (n < 0 || n >= env->config->gdb_regmap.num_regs) { - return 0; - } - - tmp = ldl_p(mem_buf); - - switch (reg->type) { - case 9: /*pc*/ - env->pc = tmp; - break; - - case 1: /*ar*/ - env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp; - xtensa_sync_window_from_phys(env); - break; - - case 2: /*SR*/ - env->sregs[reg->targno & 0xff] = tmp; - break; - - case 3: /*UR*/ - env->uregs[reg->targno & 0xff] = tmp; - break; - - case 4: /*f*/ - env->fregs[reg->targno & 0x0f] = make_float32(tmp); - break; - - case 8: /*a*/ - env->regs[reg->targno & 0x0f] = tmp; - break; - - default: - qemu_log("%s to reg %d of unsupported type %d\n", - __func__, n, reg->type); - return 0; - } - - return 4; -} #else static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n) diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c new file mode 100644 index 0000000000..0880b7cd87 --- /dev/null +++ b/target-xtensa/gdbstub.c @@ -0,0 +1,100 @@ +/* + * Xtensa gdb server stub + * + * Copyright (c) 2003-2005 Fabrice Bellard + * Copyright (c) 2013 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) +{ + const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; + + if (n < 0 || n >= env->config->gdb_regmap.num_regs) { + return 0; + } + + switch (reg->type) { + case 9: /*pc*/ + GET_REG32(env->pc); + + case 1: /*ar*/ + xtensa_sync_phys_from_window(env); + GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); + + case 2: /*SR*/ + GET_REG32(env->sregs[reg->targno & 0xff]); + + case 3: /*UR*/ + GET_REG32(env->uregs[reg->targno & 0xff]); + + case 4: /*f*/ + GET_REG32(float32_val(env->fregs[reg->targno & 0x0f])); + + case 8: /*a*/ + GET_REG32(env->regs[reg->targno & 0x0f]); + + default: + qemu_log("%s from reg %d of unsupported type %d\n", + __func__, n, reg->type); + return 0; + } +} + +static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; + + if (n < 0 || n >= env->config->gdb_regmap.num_regs) { + return 0; + } + + tmp = ldl_p(mem_buf); + + switch (reg->type) { + case 9: /*pc*/ + env->pc = tmp; + break; + + case 1: /*ar*/ + env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp; + xtensa_sync_window_from_phys(env); + break; + + case 2: /*SR*/ + env->sregs[reg->targno & 0xff] = tmp; + break; + + case 3: /*UR*/ + env->uregs[reg->targno & 0xff] = tmp; + break; + + case 4: /*f*/ + env->fregs[reg->targno & 0x0f] = make_float32(tmp); + break; + + case 8: /*a*/ + env->regs[reg->targno & 0x0f] = tmp; + break; + + default: + qemu_log("%s to reg %d of unsupported type %d\n", + __func__, n, reg->type); + return 0; + } + + return 4; +} From 986a2998932e978e63fc3b7ead1fef81f7aad52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 13:05:05 +0200 Subject: [PATCH 22/25] gdbstub: Replace GET_REG*() macros with gdb_get_reg*() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids polluting the global namespace with a non-prefixed macro and makes it obvious in the call sites that we return. Semi-automatic conversion using, e.g., sed -i 's/GET_REGL(/return gdb_get_regl(mem_buf, /g' target-*/gdbstub.c followed by manual tweaking for sparc's GET_REGA() and Coding Style. Acked-by: Michael Walle (for lm32) Acked-by: Max Filippov (for xtensa) Signed-off-by: Andreas Färber --- gdbstub.c | 29 -------------------- include/exec/gdbstub.h | 37 +++++++++++++++++++++++++ target-alpha/gdbstub.c | 2 +- target-arm/gdbstub.c | 6 ++--- target-cris/gdbstub.c | 30 ++++++++++----------- target-i386/gdbstub.c | 42 ++++++++++++++--------------- target-lm32/gdbstub.c | 16 +++++------ target-m68k/gdbstub.c | 8 +++--- target-microblaze/gdbstub.c | 4 +-- target-mips/gdbstub.c | 31 +++++++++++---------- target-openrisc/gdbstub.c | 8 +++--- target-ppc/gdbstub.c | 16 +++++------ target-s390x/gdbstub.c | 12 ++++----- target-sh4/gdbstub.c | 32 +++++++++++----------- target-sparc/gdbstub.c | 54 ++++++++++++++++++------------------- target-xtensa/gdbstub.c | 14 +++++----- 16 files changed, 177 insertions(+), 164 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 75271954d5..eb506309d4 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -489,35 +489,6 @@ static int put_packet(GDBState *s, const char *buf) return put_packet_binary(s, buf, strlen(buf)); } -/* The GDB remote protocol transfers values in target byte order. This means - we can use the raw memory access routines to access the value buffer. - Conveniently, these also handle the case where the buffer is mis-aligned. - */ -#define GET_REG8(val) do { \ - stb_p(mem_buf, val); \ - return 1; \ - } while(0) -#define GET_REG16(val) do { \ - stw_p(mem_buf, val); \ - return 2; \ - } while(0) -#define GET_REG32(val) do { \ - stl_p(mem_buf, val); \ - return 4; \ - } while(0) -#define GET_REG64(val) do { \ - stq_p(mem_buf, val); \ - return 8; \ - } while(0) - -#if TARGET_LONG_BITS == 64 -#define GET_REGL(val) GET_REG64(val) -#define ldtul_p(addr) ldq_p(addr) -#else -#define GET_REGL(val) GET_REG32(val) -#define ldtul_p(addr) ldl_p(addr) -#endif - #if defined(TARGET_I386) #include "target-i386/gdbstub.c" diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 7ea1ad7f9c..a5bd341d55 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -39,6 +39,43 @@ static inline int cpu_index(CPUState *cpu) #endif } +/* The GDB remote protocol transfers values in target byte order. This means + * we can use the raw memory access routines to access the value buffer. + * Conveniently, these also handle the case where the buffer is mis-aligned. + */ + +static inline int gdb_get_reg8(uint8_t *mem_buf, uint8_t val) +{ + stb_p(mem_buf, val); + return 1; +} + +static inline int gdb_get_reg16(uint8_t *mem_buf, uint16_t val) +{ + stw_p(mem_buf, val); + return 2; +} + +static inline int gdb_get_reg32(uint8_t *mem_buf, uint32_t val) +{ + stl_p(mem_buf, val); + return 4; +} + +static inline int gdb_get_reg64(uint8_t *mem_buf, uint64_t val) +{ + stq_p(mem_buf, val); + return 8; +} + +#if TARGET_LONG_BITS == 64 +#define gdb_get_regl(buf, val) gdb_get_reg64(buf, val) +#define ldtul_p(addr) ldq_p(addr) +#else +#define gdb_get_regl(buf, val) gdb_get_reg32(buf, val) +#define ldtul_p(addr) ldl_p(addr) +#endif + #endif #ifdef CONFIG_USER_ONLY diff --git a/target-alpha/gdbstub.c b/target-alpha/gdbstub.c index b23afe4587..1c18698aa6 100644 --- a/target-alpha/gdbstub.c +++ b/target-alpha/gdbstub.c @@ -49,7 +49,7 @@ static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) default: return 0; } - GET_REGL(val); + return gdb_get_regl(mem_buf, val); } static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c index 74903a372e..e1c7df4149 100644 --- a/target-arm/gdbstub.c +++ b/target-arm/gdbstub.c @@ -28,7 +28,7 @@ static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) { if (n < 16) { /* Core integer register. */ - GET_REG32(env->regs[n]); + return gdb_get_reg32(mem_buf, env->regs[n]); } if (n < 24) { /* FPA registers. */ @@ -44,10 +44,10 @@ static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) if (gdb_has_xml) { return 0; } - GET_REG32(0); + return gdb_get_reg32(mem_buf, 0); case 25: /* CPSR */ - GET_REG32(cpsr_read(env)); + return gdb_get_reg32(mem_buf, cpsr_read(env)); } /* Unknown register. */ return 0; diff --git a/target-cris/gdbstub.c b/target-cris/gdbstub.c index b48224a14f..ed23966c91 100644 --- a/target-cris/gdbstub.c +++ b/target-cris/gdbstub.c @@ -22,25 +22,25 @@ static int read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) { if (n < 15) { - GET_REG32(env->regs[n]); + return gdb_get_reg32(mem_buf, env->regs[n]); } if (n == 15) { - GET_REG32(env->pc); + return gdb_get_reg32(mem_buf, env->pc); } if (n < 32) { switch (n) { case 16: - GET_REG8(env->pregs[n - 16]); + return gdb_get_reg8(mem_buf, env->pregs[n - 16]); case 17: - GET_REG8(env->pregs[n - 16]); + return gdb_get_reg8(mem_buf, env->pregs[n - 16]); case 20: case 21: - GET_REG16(env->pregs[n - 16]); + return gdb_get_reg16(mem_buf, env->pregs[n - 16]); default: if (n >= 23) { - GET_REG32(env->pregs[n - 16]); + return gdb_get_reg32(mem_buf, env->pregs[n - 16]); } break; } @@ -58,28 +58,28 @@ static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) srs = env->pregs[PR_SRS]; if (n < 16) { - GET_REG32(env->regs[n]); + return gdb_get_reg32(mem_buf, env->regs[n]); } if (n >= 21 && n < 32) { - GET_REG32(env->pregs[n - 16]); + return gdb_get_reg32(mem_buf, env->pregs[n - 16]); } if (n >= 33 && n < 49) { - GET_REG32(env->sregs[srs][n - 33]); + return gdb_get_reg32(mem_buf, env->sregs[srs][n - 33]); } switch (n) { case 16: - GET_REG8(env->pregs[0]); + return gdb_get_reg8(mem_buf, env->pregs[0]); case 17: - GET_REG8(env->pregs[1]); + return gdb_get_reg8(mem_buf, env->pregs[1]); case 18: - GET_REG32(env->pregs[2]); + return gdb_get_reg32(mem_buf, env->pregs[2]); case 19: - GET_REG8(srs); + return gdb_get_reg8(mem_buf, srs); case 20: - GET_REG16(env->pregs[4]); + return gdb_get_reg16(mem_buf, env->pregs[4]); case 32: - GET_REG32(env->pc); + return gdb_get_reg32(mem_buf, env->pc); } return 0; diff --git a/target-i386/gdbstub.c b/target-i386/gdbstub.c index 974d8ad9a3..0a4d97d24c 100644 --- a/target-i386/gdbstub.c +++ b/target-i386/gdbstub.c @@ -39,9 +39,9 @@ static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) { if (n < CPU_NB_REGS) { if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - GET_REG64(env->regs[gpr_map[n]]); + return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]); } else if (n < CPU_NB_REGS32) { - GET_REG32(env->regs[gpr_map32[n]]); + return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]); } } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { #ifdef USE_X86LDOUBLE @@ -63,46 +63,46 @@ static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) switch (n) { case IDX_IP_REG: if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - GET_REG64(env->eip); + return gdb_get_reg64(mem_buf, env->eip); } else { - GET_REG32(env->eip); + return gdb_get_reg32(mem_buf, env->eip); } case IDX_FLAGS_REG: - GET_REG32(env->eflags); + return gdb_get_reg32(mem_buf, env->eflags); case IDX_SEG_REGS: - GET_REG32(env->segs[R_CS].selector); + return gdb_get_reg32(mem_buf, env->segs[R_CS].selector); case IDX_SEG_REGS + 1: - GET_REG32(env->segs[R_SS].selector); + return gdb_get_reg32(mem_buf, env->segs[R_SS].selector); case IDX_SEG_REGS + 2: - GET_REG32(env->segs[R_DS].selector); + return gdb_get_reg32(mem_buf, env->segs[R_DS].selector); case IDX_SEG_REGS + 3: - GET_REG32(env->segs[R_ES].selector); + return gdb_get_reg32(mem_buf, env->segs[R_ES].selector); case IDX_SEG_REGS + 4: - GET_REG32(env->segs[R_FS].selector); + return gdb_get_reg32(mem_buf, env->segs[R_FS].selector); case IDX_SEG_REGS + 5: - GET_REG32(env->segs[R_GS].selector); + return gdb_get_reg32(mem_buf, env->segs[R_GS].selector); case IDX_FP_REGS + 8: - GET_REG32(env->fpuc); + return gdb_get_reg32(mem_buf, env->fpuc); case IDX_FP_REGS + 9: - GET_REG32((env->fpus & ~0x3800) | - (env->fpstt & 0x7) << 11); + return gdb_get_reg32(mem_buf, (env->fpus & ~0x3800) | + (env->fpstt & 0x7) << 11); case IDX_FP_REGS + 10: - GET_REG32(0); /* ftag */ + return gdb_get_reg32(mem_buf, 0); /* ftag */ case IDX_FP_REGS + 11: - GET_REG32(0); /* fiseg */ + return gdb_get_reg32(mem_buf, 0); /* fiseg */ case IDX_FP_REGS + 12: - GET_REG32(0); /* fioff */ + return gdb_get_reg32(mem_buf, 0); /* fioff */ case IDX_FP_REGS + 13: - GET_REG32(0); /* foseg */ + return gdb_get_reg32(mem_buf, 0); /* foseg */ case IDX_FP_REGS + 14: - GET_REG32(0); /* fooff */ + return gdb_get_reg32(mem_buf, 0); /* fooff */ case IDX_FP_REGS + 15: - GET_REG32(0); /* fop */ + return gdb_get_reg32(mem_buf, 0); /* fop */ case IDX_MXCSR_REG: - GET_REG32(env->mxcsr); + return gdb_get_reg32(mem_buf, env->mxcsr); } } return 0; diff --git a/target-lm32/gdbstub.c b/target-lm32/gdbstub.c index 732a633b7a..17f08f5d94 100644 --- a/target-lm32/gdbstub.c +++ b/target-lm32/gdbstub.c @@ -22,24 +22,24 @@ static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) { if (n < 32) { - GET_REG32(env->regs[n]); + return gdb_get_reg32(mem_buf, env->regs[n]); } else { switch (n) { case 32: - GET_REG32(env->pc); + return gdb_get_reg32(mem_buf, env->pc); /* FIXME: put in right exception ID */ case 33: - GET_REG32(0); + return gdb_get_reg32(mem_buf, 0); case 34: - GET_REG32(env->eba); + return gdb_get_reg32(mem_buf, env->eba); case 35: - GET_REG32(env->deba); + return gdb_get_reg32(mem_buf, env->deba); case 36: - GET_REG32(env->ie); + return gdb_get_reg32(mem_buf, env->ie); case 37: - GET_REG32(lm32_pic_get_im(env->pic_state)); + return gdb_get_reg32(mem_buf, lm32_pic_get_im(env->pic_state)); case 38: - GET_REG32(lm32_pic_get_ip(env->pic_state)); + return gdb_get_reg32(mem_buf, lm32_pic_get_ip(env->pic_state)); } } return 0; diff --git a/target-m68k/gdbstub.c b/target-m68k/gdbstub.c index 2eb4b980c4..9fa9fa6a1f 100644 --- a/target-m68k/gdbstub.c +++ b/target-m68k/gdbstub.c @@ -22,16 +22,16 @@ static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) { if (n < 8) { /* D0-D7 */ - GET_REG32(env->dregs[n]); + return gdb_get_reg32(mem_buf, env->dregs[n]); } else if (n < 16) { /* A0-A7 */ - GET_REG32(env->aregs[n - 8]); + return gdb_get_reg32(mem_buf, env->aregs[n - 8]); } else { switch (n) { case 16: - GET_REG32(env->sr); + return gdb_get_reg32(mem_buf, env->sr); case 17: - GET_REG32(env->pc); + return gdb_get_reg32(mem_buf, env->pc); } } /* FP registers not included here because they vary between diff --git a/target-microblaze/gdbstub.c b/target-microblaze/gdbstub.c index 96c4bc085a..678de21b5f 100644 --- a/target-microblaze/gdbstub.c +++ b/target-microblaze/gdbstub.c @@ -21,9 +21,9 @@ static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) { if (n < 32) { - GET_REG32(env->regs[n]); + return gdb_get_reg32(mem_buf, env->regs[n]); } else { - GET_REG32(env->sregs[n - 32]); + return gdb_get_reg32(mem_buf, env->sregs[n - 32]); } return 0; } diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c index 15dc281ea5..db826d8516 100644 --- a/target-mips/gdbstub.c +++ b/target-mips/gdbstub.c @@ -21,44 +21,47 @@ static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) { if (n < 32) { - GET_REGL(env->active_tc.gpr[n]); + return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); } if (env->CP0_Config1 & (1 << CP0C1_FP)) { if (n >= 38 && n < 70) { if (env->CP0_Status & (1 << CP0St_FR)) { - GET_REGL(env->active_fpu.fpr[n - 38].d); + return gdb_get_regl(mem_buf, + env->active_fpu.fpr[n - 38].d); } else { - GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); + return gdb_get_regl(mem_buf, + env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]); } } switch (n) { case 70: - GET_REGL((int32_t)env->active_fpu.fcr31); + return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31); case 71: - GET_REGL((int32_t)env->active_fpu.fcr0); + return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0); } } switch (n) { case 32: - GET_REGL((int32_t)env->CP0_Status); + return gdb_get_regl(mem_buf, (int32_t)env->CP0_Status); case 33: - GET_REGL(env->active_tc.LO[0]); + return gdb_get_regl(mem_buf, env->active_tc.LO[0]); case 34: - GET_REGL(env->active_tc.HI[0]); + return gdb_get_regl(mem_buf, env->active_tc.HI[0]); case 35: - GET_REGL(env->CP0_BadVAddr); + return gdb_get_regl(mem_buf, env->CP0_BadVAddr); case 36: - GET_REGL((int32_t)env->CP0_Cause); + return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause); case 37: - GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16)); + return gdb_get_regl(mem_buf, env->active_tc.PC | + !!(env->hflags & MIPS_HFLAG_M16)); case 72: - GET_REGL(0); /* fp */ + return gdb_get_regl(mem_buf, 0); /* fp */ case 89: - GET_REGL((int32_t)env->CP0_PRid); + return gdb_get_regl(mem_buf, (int32_t)env->CP0_PRid); } if (n >= 73 && n <= 88) { /* 16 embedded regs. */ - GET_REGL(0); + return gdb_get_regl(mem_buf, 0); } return 0; diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c index fba096aa1c..bdb8d2c73f 100644 --- a/target-openrisc/gdbstub.c +++ b/target-openrisc/gdbstub.c @@ -21,17 +21,17 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) { if (n < 32) { - GET_REG32(env->gpr[n]); + return gdb_get_reg32(mem_buf, env->gpr[n]); } else { switch (n) { case 32: /* PPC */ - GET_REG32(env->ppc); + return gdb_get_reg32(mem_buf, env->ppc); case 33: /* NPC */ - GET_REG32(env->npc); + return gdb_get_reg32(mem_buf, env->npc); case 34: /* SR */ - GET_REG32(env->sr); + return gdb_get_reg32(mem_buf, env->sr); default: break; diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c index b834e60f54..40a9d7b6d4 100644 --- a/target-ppc/gdbstub.c +++ b/target-ppc/gdbstub.c @@ -29,7 +29,7 @@ static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { /* gprs */ - GET_REGL(env->gpr[n]); + return gdb_get_regl(mem_buf, env->gpr[n]); } else if (n < 64) { /* fprs */ if (gdb_has_xml) { @@ -40,9 +40,9 @@ static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) } else { switch (n) { case 64: - GET_REGL(env->nip); + return gdb_get_regl(mem_buf, env->nip); case 65: - GET_REGL(env->msr); + return gdb_get_regl(mem_buf, env->msr); case 66: { uint32_t cr = 0; @@ -50,20 +50,20 @@ static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) for (i = 0; i < 8; i++) { cr |= env->crf[i] << (32 - ((i + 1) * 4)); } - GET_REG32(cr); + return gdb_get_reg32(mem_buf, cr); } case 67: - GET_REGL(env->lr); + return gdb_get_regl(mem_buf, env->lr); case 68: - GET_REGL(env->ctr); + return gdb_get_regl(mem_buf, env->ctr); case 69: - GET_REGL(env->xer); + return gdb_get_regl(mem_buf, env->xer); case 70: { if (gdb_has_xml) { return 0; } - GET_REG32(env->fpscr); + return gdb_get_reg32(mem_buf, env->fpscr); } } } diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c index c966143a9d..ee3e984a32 100644 --- a/target-s390x/gdbstub.c +++ b/target-s390x/gdbstub.c @@ -27,17 +27,17 @@ static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) case S390_PSWM_REGNUM: cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); val = deposit64(env->psw.mask, 44, 2, cc_op); - GET_REGL(val); + return gdb_get_regl(mem_buf, val); case S390_PSWA_REGNUM: - GET_REGL(env->psw.addr); + return gdb_get_regl(mem_buf, env->psw.addr); case S390_R0_REGNUM ... S390_R15_REGNUM: - GET_REGL(env->regs[n-S390_R0_REGNUM]); + return gdb_get_regl(mem_buf, env->regs[n-S390_R0_REGNUM]); case S390_A0_REGNUM ... S390_A15_REGNUM: - GET_REG32(env->aregs[n-S390_A0_REGNUM]); + return gdb_get_reg32(mem_buf, env->aregs[n-S390_A0_REGNUM]); case S390_FPC_REGNUM: - GET_REG32(env->fpc); + return gdb_get_reg32(mem_buf, env->fpc); case S390_F0_REGNUM ... S390_F15_REGNUM: - GET_REG64(env->fregs[n-S390_F0_REGNUM].ll); + return gdb_get_reg64(mem_buf, env->fregs[n-S390_F0_REGNUM].ll); } return 0; diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c index 38bc630f3a..fb85718fc0 100644 --- a/target-sh4/gdbstub.c +++ b/target-sh4/gdbstub.c @@ -26,30 +26,30 @@ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) switch (n) { case 0 ... 7: if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { - GET_REGL(env->gregs[n + 16]); + return gdb_get_regl(mem_buf, env->gregs[n + 16]); } else { - GET_REGL(env->gregs[n]); + return gdb_get_regl(mem_buf, env->gregs[n]); } case 8 ... 15: - GET_REGL(env->gregs[n]); + return gdb_get_regl(mem_buf, env->gregs[n]); case 16: - GET_REGL(env->pc); + return gdb_get_regl(mem_buf, env->pc); case 17: - GET_REGL(env->pr); + return gdb_get_regl(mem_buf, env->pr); case 18: - GET_REGL(env->gbr); + return gdb_get_regl(mem_buf, env->gbr); case 19: - GET_REGL(env->vbr); + return gdb_get_regl(mem_buf, env->vbr); case 20: - GET_REGL(env->mach); + return gdb_get_regl(mem_buf, env->mach); case 21: - GET_REGL(env->macl); + return gdb_get_regl(mem_buf, env->macl); case 22: - GET_REGL(env->sr); + return gdb_get_regl(mem_buf, env->sr); case 23: - GET_REGL(env->fpul); + return gdb_get_regl(mem_buf, env->fpul); case 24: - GET_REGL(env->fpscr); + return gdb_get_regl(mem_buf, env->fpscr); case 25 ... 40: if (env->fpscr & FPSCR_FR) { stfl_p(mem_buf, env->fregs[n - 9]); @@ -58,13 +58,13 @@ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) } return 4; case 41: - GET_REGL(env->ssr); + return gdb_get_regl(mem_buf, env->ssr); case 42: - GET_REGL(env->spc); + return gdb_get_regl(mem_buf, env->spc); case 43 ... 50: - GET_REGL(env->gregs[n - 43]); + return gdb_get_regl(mem_buf, env->gregs[n - 43]); case 51 ... 58: - GET_REGL(env->gregs[n - (51 - 16)]); + return gdb_get_regl(mem_buf, env->gregs[n - (51 - 16)]); } return 0; diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c index 914f586ab3..460c0b7197 100644 --- a/target-sparc/gdbstub.c +++ b/target-sparc/gdbstub.c @@ -19,80 +19,80 @@ */ #ifdef TARGET_ABI32 -#define GET_REGA(val) GET_REG32(val) +#define gdb_get_rega(buf, val) gdb_get_reg32(buf, val) #else -#define GET_REGA(val) GET_REGL(val) +#define gdb_get_rega(buf, val) gdb_get_regl(buf, val) #endif static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) { if (n < 8) { /* g0..g7 */ - GET_REGA(env->gregs[n]); + return gdb_get_rega(mem_buf, env->gregs[n]); } if (n < 32) { /* register window */ - GET_REGA(env->regwptr[n - 8]); + return gdb_get_rega(mem_buf, env->regwptr[n - 8]); } #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) if (n < 64) { /* fprs */ if (n & 1) { - GET_REG32(env->fpr[(n - 32) / 2].l.lower); + return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); } else { - GET_REG32(env->fpr[(n - 32) / 2].l.upper); + return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); } } /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { case 64: - GET_REGA(env->y); + return gdb_get_rega(mem_buf, env->y); case 65: - GET_REGA(cpu_get_psr(env)); + return gdb_get_rega(mem_buf, cpu_get_psr(env)); case 66: - GET_REGA(env->wim); + return gdb_get_rega(mem_buf, env->wim); case 67: - GET_REGA(env->tbr); + return gdb_get_rega(mem_buf, env->tbr); case 68: - GET_REGA(env->pc); + return gdb_get_rega(mem_buf, env->pc); case 69: - GET_REGA(env->npc); + return gdb_get_rega(mem_buf, env->npc); case 70: - GET_REGA(env->fsr); + return gdb_get_rega(mem_buf, env->fsr); case 71: - GET_REGA(0); /* csr */ + return gdb_get_rega(mem_buf, 0); /* csr */ default: - GET_REGA(0); + return gdb_get_rega(mem_buf, 0); } #else if (n < 64) { /* f0-f31 */ if (n & 1) { - GET_REG32(env->fpr[(n - 32) / 2].l.lower); + return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); } else { - GET_REG32(env->fpr[(n - 32) / 2].l.upper); + return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); } } if (n < 80) { /* f32-f62 (double width, even numbers only) */ - GET_REG64(env->fpr[(n - 32) / 2].ll); + return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll); } switch (n) { case 80: - GET_REGL(env->pc); + return gdb_get_regl(mem_buf, env->pc); case 81: - GET_REGL(env->npc); + return gdb_get_regl(mem_buf, env->npc); case 82: - GET_REGL((cpu_get_ccr(env) << 32) | - ((env->asi & 0xff) << 24) | - ((env->pstate & 0xfff) << 8) | - cpu_get_cwp64(env)); + return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) | + ((env->asi & 0xff) << 24) | + ((env->pstate & 0xfff) << 8) | + cpu_get_cwp64(env)); case 83: - GET_REGL(env->fsr); + return gdb_get_regl(mem_buf, env->fsr); case 84: - GET_REGL(env->fprs); + return gdb_get_regl(mem_buf, env->fprs); case 85: - GET_REGL(env->y); + return gdb_get_regl(mem_buf, env->y); } #endif return 0; diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c index 0880b7cd87..c963563f1f 100644 --- a/target-xtensa/gdbstub.c +++ b/target-xtensa/gdbstub.c @@ -28,23 +28,25 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) switch (reg->type) { case 9: /*pc*/ - GET_REG32(env->pc); + return gdb_get_reg32(mem_buf, env->pc); case 1: /*ar*/ xtensa_sync_phys_from_window(env); - GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); + return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff) + % env->config->nareg]); case 2: /*SR*/ - GET_REG32(env->sregs[reg->targno & 0xff]); + return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]); case 3: /*UR*/ - GET_REG32(env->uregs[reg->targno & 0xff]); + return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]); case 4: /*f*/ - GET_REG32(float32_val(env->fregs[reg->targno & 0x0f])); + return gdb_get_reg32(mem_buf, float32_val(env->fregs[reg->targno + & 0x0f])); case 8: /*a*/ - GET_REG32(env->regs[reg->targno & 0x0f]); + return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]); default: qemu_log("%s from reg %d of unsupported type %d\n", From 5b50e790f9e9403d11b4164193b76530ee85a2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 29 Jun 2013 04:18:45 +0200 Subject: [PATCH 23/25] cpu: Introduce CPUClass::gdb_{read,write}_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completes migration of target-specific code to new target-*/gdbstub.c. Acked-by: Michael Walle (for lm32) Acked-by: Max Filippov (for xtensa) Signed-off-by: Andreas Färber --- gdbstub.c | 80 +++------------------------------ include/exec/gdbstub.h | 8 ++++ include/qom/cpu.h | 4 ++ qom/cpu.c | 13 ++++++ target-alpha/Makefile.objs | 1 + target-alpha/cpu-qom.h | 2 + target-alpha/cpu.c | 2 + target-alpha/gdbstub.c | 11 ++++- target-arm/Makefile.objs | 1 + target-arm/cpu-qom.h | 3 ++ target-arm/cpu.c | 2 + target-arm/gdbstub.c | 12 ++++- target-cris/Makefile.objs | 1 + target-cris/cpu-qom.h | 3 ++ target-cris/cpu.c | 2 + target-cris/gdbstub.c | 11 ++++- target-i386/Makefile.objs | 1 + target-i386/cpu-qom.h | 3 ++ target-i386/cpu.c | 2 + target-i386/gdbstub.c | 27 +++++++---- target-lm32/Makefile.objs | 1 + target-lm32/cpu-qom.h | 2 + target-lm32/cpu.c | 2 + target-lm32/gdbstub.c | 15 +++++-- target-m68k/Makefile.objs | 1 + target-m68k/cpu-qom.h | 2 + target-m68k/cpu.c | 2 + target-m68k/gdbstub.c | 12 ++++- target-microblaze/Makefile.objs | 1 + target-microblaze/cpu-qom.h | 2 + target-microblaze/cpu.c | 2 + target-microblaze/gdbstub.c | 15 +++++-- target-mips/Makefile.objs | 1 + target-mips/cpu-qom.h | 2 + target-mips/cpu.c | 2 + target-mips/gdbstub.c | 12 ++++- target-openrisc/Makefile.objs | 1 + target-openrisc/cpu.c | 2 + target-openrisc/cpu.h | 2 + target-openrisc/gdbstub.c | 16 ++++--- target-ppc/Makefile.objs | 1 + target-ppc/cpu-qom.h | 2 + target-ppc/gdbstub.c | 13 +++++- target-ppc/translate_init.c | 2 + target-s390x/Makefile.objs | 1 + target-s390x/cpu-qom.h | 2 + target-s390x/cpu.c | 2 + target-s390x/gdbstub.c | 12 ++++- target-sh4/Makefile.objs | 1 + target-sh4/cpu-qom.h | 2 + target-sh4/cpu.c | 2 + target-sh4/gdbstub.c | 13 +++++- target-sparc/Makefile.objs | 1 + target-sparc/cpu-qom.h | 2 + target-sparc/cpu.c | 2 + target-sparc/gdbstub.c | 12 ++++- target-xtensa/Makefile.objs | 1 + target-xtensa/cpu-qom.h | 2 + target-xtensa/cpu.c | 2 + target-xtensa/gdbstub.c | 11 ++++- 60 files changed, 255 insertions(+), 115 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index eb506309d4..d8a5a0e698 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -40,7 +40,6 @@ #include "cpu.h" #include "qemu/sockets.h" #include "sysemu/kvm.h" -#include "qemu/bitops.h" static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, bool is_write) @@ -316,10 +315,7 @@ static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER; static GDBState *gdbserver_state; -/* This is an ugly hack to cope with both new and old gdb. - If gdb sends qXfer:features:read then assume we're talking to a newish - gdb that understands target descriptions. */ -static int gdb_has_xml; +bool gdb_has_xml; #ifdef CONFIG_USER_ONLY /* XXX: This is not thread safe. Do we care? */ @@ -489,11 +485,7 @@ static int put_packet(GDBState *s, const char *buf) return put_packet_binary(s, buf, strlen(buf)); } -#if defined(TARGET_I386) - -#include "target-i386/gdbstub.c" - -#elif defined (TARGET_PPC) +#if defined(TARGET_PPC) #if defined (TARGET_PPC64) #define GDB_CORE_XML "power64-core.xml" @@ -501,72 +493,14 @@ static int put_packet(GDBState *s, const char *buf) #define GDB_CORE_XML "power-core.xml" #endif -#include "target-ppc/gdbstub.c" - -#elif defined (TARGET_SPARC) - -#include "target-sparc/gdbstub.c" - #elif defined (TARGET_ARM) #define GDB_CORE_XML "arm-core.xml" -#include "target-arm/gdbstub.c" - #elif defined (TARGET_M68K) #define GDB_CORE_XML "cf-core.xml" -#include "target-m68k/gdbstub.c" - -#elif defined (TARGET_MIPS) - -#include "target-mips/gdbstub.c" - -#elif defined(TARGET_OPENRISC) - -#include "target-openrisc/gdbstub.c" - -#elif defined (TARGET_SH4) - -#include "target-sh4/gdbstub.c" - -#elif defined (TARGET_MICROBLAZE) - -#include "target-microblaze/gdbstub.c" - -#elif defined (TARGET_CRIS) - -#include "target-cris/gdbstub.c" - -#elif defined (TARGET_ALPHA) - -#include "target-alpha/gdbstub.c" - -#elif defined (TARGET_S390X) - -#include "target-s390x/gdbstub.c" - -#elif defined (TARGET_LM32) - -#include "target-lm32/gdbstub.c" - -#elif defined(TARGET_XTENSA) - -#include "target-xtensa/gdbstub.c" - -#else - -static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n) -{ - return 0; -} - -static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n) -{ - return 0; -} - #endif #ifdef GDB_CORE_XML @@ -642,7 +576,7 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) GDBRegisterState *r; if (reg < cc->gdb_num_core_regs) { - return cpu_gdb_read_register(env, mem_buf, reg); + return cc->gdb_read_register(cpu, mem_buf, reg); } for (r = cpu->gdb_regs; r; r = r->next) { @@ -660,7 +594,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) GDBRegisterState *r; if (reg < cc->gdb_num_core_regs) { - return cpu_gdb_write_register(env, mem_buf, reg); + return cc->gdb_write_register(cpu, mem_buf, reg); } for (r = cpu->gdb_regs; r; r = r->next) { @@ -1212,7 +1146,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) const char *xml; target_ulong total_len; - gdb_has_xml = 1; + gdb_has_xml = true; p += 19; xml = get_feature_xml(p, &p); if (!xml) { @@ -1621,7 +1555,7 @@ static void gdb_accept(void) s->c_cpu = first_cpu; s->g_cpu = first_cpu; s->fd = fd; - gdb_has_xml = 0; + gdb_has_xml = false; gdbserver_state = s; @@ -1707,7 +1641,7 @@ static void gdb_chr_event(void *opaque, int event) switch (event) { case CHR_EVENT_OPENED: vm_stop(RUN_STATE_PAUSED); - gdb_has_xml = 0; + gdb_has_xml = false; break; default: break; diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index a5bd341d55..a608a26c30 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -84,6 +84,14 @@ int gdbserver_start(int); int gdbserver_start(const char *port); #endif +/** + * gdb_has_xml: + * This is an ugly hack to cope with both new and old gdb. + * If gdb sends qXfer:features:read then assume we're talking to a newish + * gdb that understands target descriptions. + */ +extern bool gdb_has_xml; + /* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */ extern const char *const xml_builtin[][2]; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 195fe593ea..c001474b6c 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -80,6 +80,8 @@ struct TranslationBlock; * @synchronize_from_tb: Callback for synchronizing state from a TCG * #TranslationBlock. * @get_phys_page_debug: Callback for obtaining a physical address. + * @gdb_read_register: Callback for letting GDB read a register. + * @gdb_write_register: Callback for letting GDB write a register. * @vmsd: State description for migration. * @gdb_num_core_regs: Number of core registers accessible to GDB. * @@ -109,6 +111,8 @@ typedef struct CPUClass { 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); + int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg); + int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, int cpuid, void *opaque); diff --git a/qom/cpu.c b/qom/cpu.c index 2839ddf650..dbc9fb6489 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -157,6 +157,17 @@ static int cpu_common_write_elf64_note(WriteCoreDumpFunction f, } +static int cpu_common_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg) +{ + return 0; +} + +static int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg) +{ + return 0; +} + + void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags) { @@ -253,6 +264,8 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->write_elf32_note = cpu_common_write_elf32_note; k->write_elf64_qemunote = cpu_common_write_elf64_qemunote; k->write_elf64_note = cpu_common_write_elf64_note; + k->gdb_read_register = cpu_common_gdb_read_register; + k->gdb_write_register = cpu_common_gdb_write_register; dc->realize = cpu_common_realizefn; dc->no_user = 1; } diff --git a/target-alpha/Makefile.objs b/target-alpha/Makefile.objs index 590304cc61..b96c5da98d 100644 --- a/target-alpha/Makefile.objs +++ b/target-alpha/Makefile.objs @@ -1,3 +1,4 @@ obj-$(CONFIG_SOFTMMU) += machine.o obj-y += translate.o helper.o cpu.o obj-y += int_helper.o fpu_helper.o sys_helper.o mem_helper.o +obj-y += gdbstub.o diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index b2eeba36f3..2ebc9bcacb 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -82,5 +82,7 @@ void alpha_cpu_do_interrupt(CPUState *cpu); void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index cc0f69a84a..64c70bc1e9 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -271,6 +271,8 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = alpha_cpu_do_interrupt; cc->dump_state = alpha_cpu_dump_state; cc->set_pc = alpha_cpu_set_pc; + cc->gdb_read_register = alpha_cpu_gdb_read_register; + cc->gdb_write_register = alpha_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->do_unassigned_access = alpha_cpu_unassigned_access; cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug; diff --git a/target-alpha/gdbstub.c b/target-alpha/gdbstub.c index 1c18698aa6..980f140e72 100644 --- a/target-alpha/gdbstub.c +++ b/target-alpha/gdbstub.c @@ -17,9 +17,14 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" -static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) +int alpha_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; uint64_t val; CPU_DoubleU d; @@ -52,8 +57,10 @@ static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) return gdb_get_regl(mem_buf, val); } -static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) +int alpha_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; target_ulong tmp = ldtul_p(mem_buf); CPU_DoubleU d; diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs index 4a6e52e528..2d9f77fa9b 100644 --- a/target-arm/Makefile.objs +++ b/target-arm/Makefile.objs @@ -4,3 +4,4 @@ obj-$(CONFIG_KVM) += kvm.o obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-y += translate.o op_helper.o helper.o cpu.o obj-y += neon_helper.o iwmmxt_helper.o +obj-y += gdbstub.o diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 02162c9aba..cf3658714e 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -149,4 +149,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); + #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index f39c19f162..a493cc2239 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -824,6 +824,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = arm_cpu_do_interrupt; cc->dump_state = arm_cpu_dump_state; cc->set_pc = arm_cpu_set_pc; + cc->gdb_read_register = arm_cpu_gdb_read_register; + cc->gdb_write_register = arm_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = arm_cpu_get_phys_page_debug; cc->vmsd = &vmstate_arm_cpu; diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c index e1c7df4149..1c3439654f 100644 --- a/target-arm/gdbstub.c +++ b/target-arm/gdbstub.c @@ -17,6 +17,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect whatever the target description contains. Due to a historical mishap @@ -24,8 +27,11 @@ We hack round this by giving the FPA regs zero size when talking to a newer gdb. */ -static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) +int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + if (n < 16) { /* Core integer register. */ return gdb_get_reg32(mem_buf, env->regs[n]); @@ -53,8 +59,10 @@ static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) +int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; uint32_t tmp; tmp = ldl_p(mem_buf); diff --git a/target-cris/Makefile.objs b/target-cris/Makefile.objs index afb87bcc80..7779227fc4 100644 --- a/target-cris/Makefile.objs +++ b/target-cris/Makefile.objs @@ -1,2 +1,3 @@ obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += mmu.o machine.o diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index d7baf0746a..3e92ea011d 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -81,4 +81,7 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); + #endif diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 31eeddf822..8fcc95d994 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -255,6 +255,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = cris_cpu_do_interrupt; cc->dump_state = cris_cpu_dump_state; cc->set_pc = cris_cpu_set_pc; + cc->gdb_read_register = cris_cpu_gdb_read_register; + cc->gdb_write_register = cris_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = cris_cpu_get_phys_page_debug; #endif diff --git a/target-cris/gdbstub.c b/target-cris/gdbstub.c index ed23966c91..958a370e06 100644 --- a/target-cris/gdbstub.c +++ b/target-cris/gdbstub.c @@ -17,6 +17,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" static int read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) @@ -48,8 +51,10 @@ read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) +int cris_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; uint8_t srs; if (env->pregs[PR_VR] < 32) { @@ -85,8 +90,10 @@ static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) +int cris_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; uint32_t tmp; if (n > 49) { diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index c1d4f059da..3b629d4d39 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -1,6 +1,7 @@ obj-y += translate.o helper.o cpu.o obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o +obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_NO_KVM) += kvm-stub.o diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index d928562c53..60d2b5d772 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -106,4 +106,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); + #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index df9832e151..2b59b7d7ef 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2538,6 +2538,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->dump_state = x86_cpu_dump_state; cc->set_pc = x86_cpu_set_pc; cc->synchronize_from_tb = x86_cpu_synchronize_from_tb; + cc->gdb_read_register = x86_cpu_gdb_read_register; + cc->gdb_write_register = x86_cpu_gdb_write_register; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifndef CONFIG_USER_ONLY diff --git a/target-i386/gdbstub.c b/target-i386/gdbstub.c index 0a4d97d24c..15bebeff89 100644 --- a/target-i386/gdbstub.c +++ b/target-i386/gdbstub.c @@ -17,6 +17,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" #ifdef TARGET_X86_64 static const int gpr_map[16] = { @@ -35,8 +38,11 @@ static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; #define IDX_XMM_REGS (IDX_FP_REGS + 16) #define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) -static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) +int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + if (n < CPU_NB_REGS) { if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]); @@ -108,8 +114,9 @@ static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf) +static int x86_cpu_gdb_load_seg(X86CPU *cpu, int sreg, uint8_t *mem_buf) { + CPUX86State *env = &cpu->env; uint16_t selector = ldl_p(mem_buf); if (selector != env->segs[sreg].selector) { @@ -135,8 +142,10 @@ static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf) return 4; } -static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) +int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; uint32_t tmp; if (n < CPU_NB_REGS) { @@ -179,17 +188,17 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) return 4; case IDX_SEG_REGS: - return cpu_x86_gdb_load_seg(env, R_CS, mem_buf); + return x86_cpu_gdb_load_seg(cpu, R_CS, mem_buf); case IDX_SEG_REGS + 1: - return cpu_x86_gdb_load_seg(env, R_SS, mem_buf); + return x86_cpu_gdb_load_seg(cpu, R_SS, mem_buf); case IDX_SEG_REGS + 2: - return cpu_x86_gdb_load_seg(env, R_DS, mem_buf); + return x86_cpu_gdb_load_seg(cpu, R_DS, mem_buf); case IDX_SEG_REGS + 3: - return cpu_x86_gdb_load_seg(env, R_ES, mem_buf); + return x86_cpu_gdb_load_seg(cpu, R_ES, mem_buf); case IDX_SEG_REGS + 4: - return cpu_x86_gdb_load_seg(env, R_FS, mem_buf); + return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf); case IDX_SEG_REGS + 5: - return cpu_x86_gdb_load_seg(env, R_GS, mem_buf); + return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf); case IDX_FP_REGS + 8: env->fpuc = ldl_p(mem_buf); diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs index ca20f21443..40236876c8 100644 --- a/target-lm32/Makefile.objs +++ b/target-lm32/Makefile.objs @@ -1,2 +1,3 @@ obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += machine.o diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h index 9e2732919d..723f6049c3 100644 --- a/target-lm32/cpu-qom.h +++ b/target-lm32/cpu-qom.h @@ -79,5 +79,7 @@ void lm32_cpu_do_interrupt(CPUState *cpu); void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int lm32_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index aa52696cda..962d553de0 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -87,6 +87,8 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = lm32_cpu_do_interrupt; cc->dump_state = lm32_cpu_dump_state; cc->set_pc = lm32_cpu_set_pc; + cc->gdb_read_register = lm32_cpu_gdb_read_register; + cc->gdb_write_register = lm32_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug; cc->vmsd = &vmstate_lm32_cpu; diff --git a/target-lm32/gdbstub.c b/target-lm32/gdbstub.c index 17f08f5d94..4979a98d74 100644 --- a/target-lm32/gdbstub.c +++ b/target-lm32/gdbstub.c @@ -17,10 +17,16 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" #include "hw/lm32/lm32_pic.h" -static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) +int lm32_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + LM32CPU *cpu = LM32_CPU(cs); + CPULM32State *env = &cpu->env; + if (n < 32) { return gdb_get_reg32(mem_buf, env->regs[n]); } else { @@ -45,10 +51,11 @@ static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) +int lm32_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { - LM32CPU *cpu = lm32_env_get_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); + LM32CPU *cpu = LM32_CPU(cs); + CPUClass *cc = CPU_GET_CLASS(cs); + CPULM32State *env = &cpu->env; uint32_t tmp; if (n > cc->gdb_num_core_regs) { diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs index 2e2b85044d..02cf616a78 100644 --- a/target-m68k/Makefile.objs +++ b/target-m68k/Makefile.objs @@ -1,2 +1,3 @@ obj-y += m68k-semi.o obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += gdbstub.o diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h index 7115707e91..7f388eda68 100644 --- a/target-m68k/cpu-qom.h +++ b/target-m68k/cpu-qom.h @@ -74,5 +74,7 @@ void m68k_cpu_do_interrupt(CPUState *cpu); void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 93200d9964..01a70f194d 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -190,6 +190,8 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->do_interrupt = m68k_cpu_do_interrupt; cc->dump_state = m68k_cpu_dump_state; cc->set_pc = m68k_cpu_set_pc; + cc->gdb_read_register = m68k_cpu_gdb_read_register; + cc->gdb_write_register = m68k_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug; #endif diff --git a/target-m68k/gdbstub.c b/target-m68k/gdbstub.c index 9fa9fa6a1f..ae8179c016 100644 --- a/target-m68k/gdbstub.c +++ b/target-m68k/gdbstub.c @@ -17,9 +17,15 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" -static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) +int m68k_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + if (n < 8) { /* D0-D7 */ return gdb_get_reg32(mem_buf, env->dregs[n]); @@ -39,8 +45,10 @@ static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) +int m68k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; uint32_t tmp; tmp = ldl_p(mem_buf); diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs index 985330eac5..f3d7b44c89 100644 --- a/target-microblaze/Makefile.objs +++ b/target-microblaze/Makefile.objs @@ -1,2 +1,3 @@ obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += mmu.o diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h index 1318a36676..35a12b42a5 100644 --- a/target-microblaze/cpu-qom.h +++ b/target-microblaze/cpu-qom.h @@ -75,5 +75,7 @@ void mb_cpu_do_interrupt(CPUState *cs); void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int mb_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 758b0cb07d..c75d1bd642 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -141,6 +141,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = mb_cpu_do_interrupt; cc->dump_state = mb_cpu_dump_state; cc->set_pc = mb_cpu_set_pc; + cc->gdb_read_register = mb_cpu_gdb_read_register; + cc->gdb_write_register = mb_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->do_unassigned_access = mb_cpu_unassigned_access; cc->get_phys_page_debug = mb_cpu_get_phys_page_debug; diff --git a/target-microblaze/gdbstub.c b/target-microblaze/gdbstub.c index 678de21b5f..a70e2ee3cb 100644 --- a/target-microblaze/gdbstub.c +++ b/target-microblaze/gdbstub.c @@ -17,9 +17,15 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" -static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) +int mb_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUMBState *env = &cpu->env; + if (n < 32) { return gdb_get_reg32(mem_buf, env->regs[n]); } else { @@ -28,10 +34,11 @@ static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) +int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { - MicroBlazeCPU *cpu = mb_env_get_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUClass *cc = CPU_GET_CLASS(cs); + CPUMBState *env = &cpu->env; uint32_t tmp; if (n > cc->gdb_num_core_regs) { diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs index 119c816518..0277d56e82 100644 --- a/target-mips/Makefile.objs +++ b/target-mips/Makefile.objs @@ -1,2 +1,3 @@ obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o +obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += machine.o diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index 7c8e616392..8877f813f7 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -78,5 +78,7 @@ void mips_cpu_do_interrupt(CPUState *cpu); void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int mips_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-mips/cpu.c b/target-mips/cpu.c index e667fb7b7c..f81f9e9409 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -100,6 +100,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->dump_state = mips_cpu_dump_state; cc->set_pc = mips_cpu_set_pc; cc->synchronize_from_tb = mips_cpu_synchronize_from_tb; + cc->gdb_read_register = mips_cpu_gdb_read_register; + cc->gdb_write_register = mips_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->do_unassigned_access = mips_cpu_unassigned_access; cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c index db826d8516..5b72d58a44 100644 --- a/target-mips/gdbstub.c +++ b/target-mips/gdbstub.c @@ -17,9 +17,15 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" -static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) +int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + if (n < 32) { return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); } @@ -78,8 +84,10 @@ static unsigned int ieee_rm[] = { set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \ &env->active_fpu.fp_status) -static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) +int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; target_ulong tmp; tmp = ldtul_p(mem_buf); diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs index 44dc5399df..397d01650e 100644 --- a/target-openrisc/Makefile.objs +++ b/target-openrisc/Makefile.objs @@ -2,3 +2,4 @@ obj-$(CONFIG_SOFTMMU) += machine.o obj-y += cpu.o exception.o interrupt.o mmu.o translate.o obj-y += exception_helper.o fpu_helper.o int_helper.o \ interrupt_helper.o mmu_helper.o sys_helper.o +obj-y += gdbstub.o diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 9b042e14b0..aa269fb7a6 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -155,6 +155,8 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = openrisc_cpu_do_interrupt; cc->dump_state = openrisc_cpu_dump_state; cc->set_pc = openrisc_cpu_set_pc; + cc->gdb_read_register = openrisc_cpu_gdb_read_register; + cc->gdb_write_register = openrisc_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug; dc->vmsd = &vmstate_openrisc_cpu; diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 3ddb7674c7..8fd0bc0bf0 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -350,6 +350,8 @@ void openrisc_cpu_do_interrupt(CPUState *cpu); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void openrisc_translate_init(void); int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address, diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c index bdb8d2c73f..18bcc46167 100644 --- a/target-openrisc/gdbstub.c +++ b/target-openrisc/gdbstub.c @@ -17,9 +17,15 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" -static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) +int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); + CPUOpenRISCState *env = &cpu->env; + if (n < 32) { return gdb_get_reg32(mem_buf, env->gpr[n]); } else { @@ -40,11 +46,11 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUOpenRISCState *env, - uint8_t *mem_buf, int n) +int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); - CPUClass *cc = CPU_GET_CLASS(cpu); + OpenRISCCPU *cpu = OPENRISC_CPU(cs); + CPUClass *cc = CPU_GET_CLASS(cs); + CPUOpenRISCState *env = &cpu->env; uint32_t tmp; if (n > cc->gdb_num_core_regs) { diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs index 6e78cb3624..f72e3993f7 100644 --- a/target-ppc/Makefile.objs +++ b/target-ppc/Makefile.objs @@ -13,3 +13,4 @@ obj-y += timebase_helper.o obj-y += misc_helper.o obj-y += mem_helper.o obj-$(CONFIG_USER_ONLY) += user_only_helper.o +obj-y += gdbstub.o diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 3341c5151d..fc0d737880 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -106,5 +106,7 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c index 40a9d7b6d4..1c910902ea 100644 --- a/target-ppc/gdbstub.c +++ b/target-ppc/gdbstub.c @@ -17,6 +17,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" /* Old gdb always expects FP registers. Newer (xml-aware) gdb only * expects whatever the target description contains. Due to a @@ -25,8 +28,11 @@ * FP regs zero size when talking to a newer gdb. */ -static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) +int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + if (n < 32) { /* gprs */ return gdb_get_regl(mem_buf, env->gpr[n]); @@ -70,8 +76,11 @@ static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) +int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + if (n < 32) { /* gprs */ env->gpr[n] = ldtul_p(mem_buf); diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 91161939c0..370d243b52 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8458,6 +8458,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->dump_state = ppc_cpu_dump_state; cc->dump_statistics = ppc_cpu_dump_statistics; cc->set_pc = ppc_cpu_set_pc; + cc->gdb_read_register = ppc_cpu_gdb_read_register; + cc->gdb_write_register = ppc_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; #endif diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs index 4e634173a4..ab938e7ad8 100644 --- a/target-s390x/Makefile.objs +++ b/target-s390x/Makefile.objs @@ -1,4 +1,5 @@ obj-y += translate.o helper.o cpu.o interrupt.o obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o +obj-y += gdbstub.o obj-$(CONFIG_SOFTMMU) += ioinst.o obj-$(CONFIG_KVM) += kvm.o diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h index a4fe8fb5fc..0d63b1cf20 100644 --- a/target-s390x/cpu-qom.h +++ b/target-s390x/cpu-qom.h @@ -75,5 +75,7 @@ void s390_cpu_do_interrupt(CPUState *cpu); void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 8f99d7c86c..1d16da3787 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -173,6 +173,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = s390_cpu_do_interrupt; cc->dump_state = s390_cpu_dump_state; cc->set_pc = s390_cpu_set_pc; + cc->gdb_read_register = s390_cpu_gdb_read_register; + cc->gdb_write_register = s390_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = s390_cpu_get_phys_page_debug; #endif diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c index ee3e984a32..a129742e2f 100644 --- a/target-s390x/gdbstub.c +++ b/target-s390x/gdbstub.c @@ -17,9 +17,15 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" +#include "qemu/bitops.h" -static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) +int s390_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; uint64_t val; int cc_op; @@ -43,8 +49,10 @@ static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n) +int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; target_ulong tmpl; uint32_t tmp32; int r = 8; diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs index cb448a840f..a285358adf 100644 --- a/target-sh4/Makefile.objs +++ b/target-sh4/Makefile.objs @@ -1 +1,2 @@ obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += gdbstub.o diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index 7c9160bab8..c04e78631b 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -87,5 +87,7 @@ void superh_cpu_do_interrupt(CPUState *cpu); void superh_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int superh_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 35f0535436..bda3c5112c 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -286,6 +286,8 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->dump_state = superh_cpu_dump_state; cc->set_pc = superh_cpu_set_pc; cc->synchronize_from_tb = superh_cpu_synchronize_from_tb; + cc->gdb_read_register = superh_cpu_gdb_read_register; + cc->gdb_write_register = superh_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = superh_cpu_get_phys_page_debug; #endif diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c index fb85718fc0..df4fa2af76 100644 --- a/target-sh4/gdbstub.c +++ b/target-sh4/gdbstub.c @@ -17,12 +17,18 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" /* Hint: Use "set architecture sh4" in GDB to see fpu registers */ /* FIXME: We should use XML for this. */ -static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) +int superh_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + SuperHCPU *cpu = SUPERH_CPU(cs); + CPUSH4State *env = &cpu->env; + switch (n) { case 0 ... 7: if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { @@ -70,8 +76,11 @@ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) +int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + SuperHCPU *cpu = SUPERH_CPU(cs); + CPUSH4State *env = &cpu->env; + switch (n) { case 0 ... 7: if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs index 9fc42ea9b0..1cd81cccc3 100644 --- a/target-sparc/Makefile.objs +++ b/target-sparc/Makefile.objs @@ -4,3 +4,4 @@ obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o obj-$(TARGET_SPARC) += int32_helper.o obj-$(TARGET_SPARC64) += int64_helper.o obj-$(TARGET_SPARC64) += vis_helper.o +obj-y += gdbstub.o diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h index 39d975b5fc..8e3e0de277 100644 --- a/target-sparc/cpu-qom.h +++ b/target-sparc/cpu-qom.h @@ -79,5 +79,7 @@ void sparc_cpu_do_interrupt(CPUState *cpu); void sparc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 388a632d18..c7b4a90663 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -787,6 +787,8 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) #endif cc->set_pc = sparc_cpu_set_pc; cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; + cc->gdb_read_register = sparc_cpu_gdb_read_register; + cc->gdb_write_register = sparc_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->do_unassigned_access = sparc_cpu_unassigned_access; cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug; diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c index 460c0b7197..3de3242b29 100644 --- a/target-sparc/gdbstub.c +++ b/target-sparc/gdbstub.c @@ -17,6 +17,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" #ifdef TARGET_ABI32 #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val) @@ -24,8 +27,11 @@ #define gdb_get_rega(buf, val) gdb_get_regl(buf, val) #endif -static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) +int sparc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; + if (n < 8) { /* g0..g7 */ return gdb_get_rega(mem_buf, env->gregs[n]); @@ -98,8 +104,10 @@ static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) +int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; #if defined(TARGET_ABI32) abi_ulong tmp; diff --git a/target-xtensa/Makefile.objs b/target-xtensa/Makefile.objs index 644b7f99bb..5c150a870f 100644 --- a/target-xtensa/Makefile.objs +++ b/target-xtensa/Makefile.objs @@ -3,3 +3,4 @@ obj-y += core-dc232b.o obj-y += core-dc233c.o obj-y += core-fsf.o obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += gdbstub.o diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index 1b9479eb9c..c6cc2d91f4 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -87,5 +87,7 @@ void xtensa_cpu_do_interrupt(CPUState *cpu); void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 560fa0c058..e966aa0a79 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -133,6 +133,8 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = xtensa_cpu_do_interrupt; cc->dump_state = xtensa_cpu_dump_state; cc->set_pc = xtensa_cpu_set_pc; + cc->gdb_read_register = xtensa_cpu_gdb_read_register; + cc->gdb_write_register = xtensa_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug; #endif diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c index c963563f1f..9e13b20c46 100644 --- a/target-xtensa/gdbstub.c +++ b/target-xtensa/gdbstub.c @@ -17,9 +17,14 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include "config.h" +#include "qemu-common.h" +#include "exec/gdbstub.h" -static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) +int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + XtensaCPU *cpu = XTENSA_CPU(cs); + CPUXtensaState *env = &cpu->env; const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; if (n < 0 || n >= env->config->gdb_regmap.num_regs) { @@ -55,8 +60,10 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) } } -static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) +int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { + XtensaCPU *cpu = XTENSA_CPU(cs); + CPUXtensaState *env = &cpu->env; uint32_t tmp; const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; From 90431220be42d773084d88635961a45febb01c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 14:39:41 +0200 Subject: [PATCH 24/25] target-cris: Factor out CPUClass::gdb_read_register() hook for v10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- target-cris/cpu-qom.h | 1 + target-cris/cpu.c | 4 ++++ target-cris/gdbstub.c | 10 ++++------ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index 3e92ea011d..75593667d6 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -81,6 +81,7 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +int crisv10_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 8fcc95d994..45f2d6bacf 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -175,6 +175,7 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data) ccc->vr = 8; cc->do_interrupt = crisv10_cpu_do_interrupt; + cc->gdb_read_register = crisv10_cpu_gdb_read_register; } static void crisv9_cpu_class_init(ObjectClass *oc, void *data) @@ -184,6 +185,7 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data) ccc->vr = 9; cc->do_interrupt = crisv10_cpu_do_interrupt; + cc->gdb_read_register = crisv10_cpu_gdb_read_register; } static void crisv10_cpu_class_init(ObjectClass *oc, void *data) @@ -193,6 +195,7 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data) ccc->vr = 10; cc->do_interrupt = crisv10_cpu_do_interrupt; + cc->gdb_read_register = crisv10_cpu_gdb_read_register; } static void crisv11_cpu_class_init(ObjectClass *oc, void *data) @@ -202,6 +205,7 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data) ccc->vr = 11; cc->do_interrupt = crisv10_cpu_do_interrupt; + cc->gdb_read_register = crisv10_cpu_gdb_read_register; } static void crisv32_cpu_class_init(ObjectClass *oc, void *data) diff --git a/target-cris/gdbstub.c b/target-cris/gdbstub.c index 958a370e06..5db3683ab6 100644 --- a/target-cris/gdbstub.c +++ b/target-cris/gdbstub.c @@ -21,9 +21,11 @@ #include "qemu-common.h" #include "exec/gdbstub.h" -static int -read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) +int crisv10_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; + if (n < 15) { return gdb_get_reg32(mem_buf, env->regs[n]); } @@ -57,10 +59,6 @@ int cris_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) CPUCRISState *env = &cpu->env; uint8_t srs; - if (env->pregs[PR_VR] < 32) { - return read_register_crisv10(env, mem_buf, n); - } - srs = env->pregs[PR_SRS]; if (n < 16) { return gdb_get_reg32(mem_buf, env->regs[n]); From 5b24c64188b8253e2f004191c7e8d4a799f90eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Jul 2013 15:08:22 +0200 Subject: [PATCH 25/25] cpu: Introduce CPUClass::gdb_core_xml_file for GDB_CORE_XML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the GDB_CORE_XML define in gdbstub.c with a CPUClass field. Use first_cpu for qSupported and qXfer:features:read: for now. Add a stub for xml_builtin. Signed-off-by: Andreas Färber --- gdbstub.c | 42 +++++++++++++------------------------ include/qom/cpu.h | 2 ++ stubs/Makefile.objs | 1 + stubs/gdbstub.c | 5 +++++ target-arm/cpu.c | 1 + target-m68k/cpu.c | 1 + target-ppc/translate_init.c | 5 +++++ 7 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 stubs/gdbstub.c diff --git a/gdbstub.c b/gdbstub.c index d8a5a0e698..1af25a6fe6 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -485,25 +485,6 @@ static int put_packet(GDBState *s, const char *buf) return put_packet_binary(s, buf, strlen(buf)); } -#if defined(TARGET_PPC) - -#if defined (TARGET_PPC64) -#define GDB_CORE_XML "power64-core.xml" -#else -#define GDB_CORE_XML "power-core.xml" -#endif - -#elif defined (TARGET_ARM) - -#define GDB_CORE_XML "arm-core.xml" - -#elif defined (TARGET_M68K) - -#define GDB_CORE_XML "cf-core.xml" - -#endif - -#ifdef GDB_CORE_XML /* Encode data using the encoding for 'x' packets. */ static int memtox(char *buf, const char *mem, int len) { @@ -525,7 +506,8 @@ static int memtox(char *buf, const char *mem, int len) return p - buf; } -static const char *get_feature_xml(const char *p, const char **newp) +static const char *get_feature_xml(const char *p, const char **newp, + CPUClass *cc) { size_t len; int i; @@ -549,7 +531,7 @@ static const char *get_feature_xml(const char *p, const char **newp) "" "" "", - GDB_CORE_XML); + cc->gdb_core_xml_file); for (r = cpu->gdb_regs; r; r = r->next) { pstrcat(target_xml, sizeof(target_xml), "gdb_core_xml_file != NULL) { + pstrcat(buf, sizeof(buf), ";qXfer:features:read+"); + } put_packet(s, buf); break; } -#ifdef GDB_CORE_XML if (strncmp(p, "Xfer:features:read:", 19) == 0) { const char *xml; target_ulong total_len; + cc = CPU_GET_CLASS(first_cpu); + if (cc->gdb_core_xml_file == NULL) { + goto unknown_command; + } + gdb_has_xml = true; p += 19; - xml = get_feature_xml(p, &p); + xml = get_feature_xml(p, &p, cc); if (!xml) { snprintf(buf, sizeof(buf), "E00"); put_packet(s, buf); @@ -1180,7 +1167,6 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet_binary(s, buf, len + 1); break; } -#endif /* Unrecognised 'q' command. */ goto unknown_command; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index c001474b6c..0d6e95c0b6 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -84,6 +84,7 @@ struct TranslationBlock; * @gdb_write_register: Callback for letting GDB write a register. * @vmsd: State description for migration. * @gdb_num_core_regs: Number of core registers accessible to GDB. + * @gdb_core_xml_file: File name for core registers GDB XML description. * * Represents a CPU family or model. */ @@ -125,6 +126,7 @@ typedef struct CPUClass { const struct VMStateDescription *vmsd; int gdb_num_core_regs; + const char *gdb_core_xml_file; } CPUClass; struct KVMState; diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 9b701b4714..f306cbada3 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -7,6 +7,7 @@ stub-obj-y += fdset-add-fd.o stub-obj-y += fdset-find-fd.o stub-obj-y += fdset-get-fd.o stub-obj-y += fdset-remove-fd.o +stub-obj-y += gdbstub.o stub-obj-y += get-fd.o stub-obj-y += get-vm-name.o stub-obj-y += iothread-lock.o diff --git a/stubs/gdbstub.c b/stubs/gdbstub.c new file mode 100644 index 0000000000..c1dbfe7fb7 --- /dev/null +++ b/stubs/gdbstub.c @@ -0,0 +1,5 @@ +#include "qemu-common.h" + +const char *const xml_builtin[][2] = { + { NULL, NULL } +}; diff --git a/target-arm/cpu.c b/target-arm/cpu.c index a493cc2239..87d35c6bf2 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -831,6 +831,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->vmsd = &vmstate_arm_cpu; #endif cc->gdb_num_core_regs = 26; + cc->gdb_core_xml_file = "arm-core.xml"; } static void cpu_register(const ARMCPUInfo *info) diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 01a70f194d..c0bcb0dbce 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -197,6 +197,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) #endif dc->vmsd = &vmstate_m68k_cpu; cc->gdb_num_core_regs = 18; + cc->gdb_core_xml_file = "cf-core.xml"; } static void register_cpu_type(const M68kCPUInfo *info) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 370d243b52..8215946e39 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8465,6 +8465,11 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) #endif cc->gdb_num_core_regs = 71; +#if defined(TARGET_PPC64) + cc->gdb_core_xml_file = "power64-core.xml"; +#else + cc->gdb_core_xml_file = "power-core.xml"; +#endif } static const TypeInfo ppc_cpu_type_info = {