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: 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 --- target-sparc/cpu.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'target-sparc') diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index d1d0339..388a632 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 = { -- cgit v1.1 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: 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 --- target-sparc/gdbstub.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 target-sparc/gdbstub.c (limited to 'target-sparc') diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c new file mode 100644 index 0000000..914f586 --- /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 +} -- cgit v1.1 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: 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 --- target-sparc/gdbstub.c | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'target-sparc') diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c index 914f586..460c0b7 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; -- cgit v1.1 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: 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 --- target-sparc/Makefile.objs | 1 + target-sparc/cpu-qom.h | 2 ++ target-sparc/cpu.c | 2 ++ target-sparc/gdbstub.c | 12 ++++++++++-- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'target-sparc') diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs index 9fc42ea..1cd81cc 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 39d975b..8e3e0de 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 388a632..c7b4a90 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 460c0b7..3de3242 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; -- cgit v1.1