Re: [RFC PATCH v4 13/30] target/loongarch: Add gdb support.
On 1/8/22 17:14, Xiaojuan Yang wrote: Signed-off-by: Xiaojuan Yang Signed-off-by: Song Gao --- configs/targets/loongarch64-softmmu.mak | 1 + gdb-xml/loongarch-base64.xml| 43 +++ gdb-xml/loongarch-fpu64.xml | 57 +++ target/loongarch/cpu.c | 7 ++ target/loongarch/gdbstub.c | 97 + target/loongarch/internals.h| 10 +++ target/loongarch/meson.build| 1 + 7 files changed, 216 insertions(+) create mode 100644 configs/targets/loongarch64-softmmu.mak create mode 100644 gdb-xml/loongarch-base64.xml create mode 100644 gdb-xml/loongarch-fpu64.xml create mode 100644 target/loongarch/gdbstub.c diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak new file mode 100644 index 00..f33fa1590b --- /dev/null +++ b/configs/targets/loongarch64-softmmu.mak @@ -0,0 +1 @@ +TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml new file mode 100644 index 00..f2af2a4b6e --- /dev/null +++ b/gdb-xml/loongarch-base64.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml new file mode 100644 index 00..e52cf89fbc --- /dev/null +++ b/gdb-xml/loongarch-fpu64.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I know this file is copied from binutils, but aren't FCC registers 1-bit each? They are just predicates after all... Clarification from Loongson toolchain people would be appreciated. + + diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index caab59b83a..8d0be47d4b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -146,11 +146,18 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA, name); } +if (cs->exception_index == EXCCODE_INT && + (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))) { +env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1); +goto set_DERA; +} switch (cs->exception_index) { case EXCCODE_DBP: env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1); env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC); +goto set_DERA; +set_DERA: env->CSR_DERA = env->pc; env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1); env->pc = env->CSR_EENTRY + 0x480; diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c new file mode 100644 index 00..2fec9364de --- /dev/null +++ b/target/loongarch/gdbstub.c @@ -0,0 +1,97 @@ +/* + * LOONGARCH gdb server stub + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" +#include "internals.h" +#include "exec/gdbstub.h" +#include "exec/helper-proto.h" + +int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; + +if (0 <= n && n < 32) { +return gdb_get_regl(mem_buf, env->gpr[n]); +} else if (n == 32) { +return gdb_get_regl(mem_buf, env->pc); +} +return 0; +} + +int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; +target_ulong tmp = ldtul_p(mem_buf); + +if (0 <= n && n < 32) { +return env->gpr[n] = tmp, sizeof(target_ulong); +} else if (n == 32) { +return env->pc = tmp, sizeof(target_ulong); +} +return 0; +} + +static int loongarch_gdb_get_fpu(CPULoongArchState *env, + GByteArray *mem_buf, int n) +{ +if (0 <= n && n < 32) { +return gdb_get_reg64(mem_buf, env->fpr[n]); +} else if (32 <= n && n < 40) { +return gdb_get_reg8(mem_buf, env->cf[n - 32]); +} else if (n == 40) { +return gdb_get_reg32(mem_buf, env->fcsr0); +} +return 0; +} + +static int loongarch_gdb_set_fpu(CPULoongArchState *env, + uint8_t *mem_buf, int n) +{ +if (0 <= n && n < 32) { +return env->fpr[n] = ldq_p(mem_buf), 8; +} else if (32 <= n && n < 40) { +return env->cf[n - 32] = ldub_p(mem_buf), 1; +} else if (n == 40) { +return env->fcsr0 = ldl_p(mem_buf), 4; +} +return 0; +} + +void
[RFC PATCH v4 13/30] target/loongarch: Add gdb support.
Signed-off-by: Xiaojuan Yang Signed-off-by: Song Gao --- configs/targets/loongarch64-softmmu.mak | 1 + gdb-xml/loongarch-base64.xml| 43 +++ gdb-xml/loongarch-fpu64.xml | 57 +++ target/loongarch/cpu.c | 7 ++ target/loongarch/gdbstub.c | 97 + target/loongarch/internals.h| 10 +++ target/loongarch/meson.build| 1 + 7 files changed, 216 insertions(+) create mode 100644 configs/targets/loongarch64-softmmu.mak create mode 100644 gdb-xml/loongarch-base64.xml create mode 100644 gdb-xml/loongarch-fpu64.xml create mode 100644 target/loongarch/gdbstub.c diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak new file mode 100644 index 00..f33fa1590b --- /dev/null +++ b/configs/targets/loongarch64-softmmu.mak @@ -0,0 +1 @@ +TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml new file mode 100644 index 00..f2af2a4b6e --- /dev/null +++ b/gdb-xml/loongarch-base64.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml new file mode 100644 index 00..e52cf89fbc --- /dev/null +++ b/gdb-xml/loongarch-fpu64.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index caab59b83a..8d0be47d4b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -146,11 +146,18 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA, name); } +if (cs->exception_index == EXCCODE_INT && + (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))) { +env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1); +goto set_DERA; +} switch (cs->exception_index) { case EXCCODE_DBP: env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1); env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC); +goto set_DERA; +set_DERA: env->CSR_DERA = env->pc; env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1); env->pc = env->CSR_EENTRY + 0x480; diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c new file mode 100644 index 00..2fec9364de --- /dev/null +++ b/target/loongarch/gdbstub.c @@ -0,0 +1,97 @@ +/* + * LOONGARCH gdb server stub + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "cpu.h" +#include "internals.h" +#include "exec/gdbstub.h" +#include "exec/helper-proto.h" + +int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; + +if (0 <= n && n < 32) { +return gdb_get_regl(mem_buf, env->gpr[n]); +} else if (n == 32) { +return gdb_get_regl(mem_buf, env->pc); +} +return 0; +} + +int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; +target_ulong tmp = ldtul_p(mem_buf); + +if (0 <= n && n < 32) { +return env->gpr[n] = tmp, sizeof(target_ulong); +} else if (n == 32) { +return env->pc = tmp, sizeof(target_ulong); +} +return 0; +} + +static int loongarch_gdb_get_fpu(CPULoongArchState *env, + GByteArray *mem_buf, int n) +{ +if (0 <= n && n < 32) { +return gdb_get_reg64(mem_buf, env->fpr[n]); +} else if (32 <= n && n < 40) { +return gdb_get_reg8(mem_buf, env->cf[n - 32]); +} else if (n == 40) { +return gdb_get_reg32(mem_buf, env->fcsr0); +} +return 0; +} + +static int loongarch_gdb_set_fpu(CPULoongArchState *env, + uint8_t *mem_buf, int n) +{ +if (0 <= n && n < 32) { +return env->fpr[n] = ldq_p(mem_buf), 8; +} else if (32 <= n && n < 40) { +return env->cf[n - 32] = ldub_p(mem_buf), 1; +} else if (n == 40) { +return env->fcsr0 = ldl_p(mem_buf), 4; +} +return 0; +} + +void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) +{ +gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, + 41, "loongarch-fpu64.xml", 0); +} + +int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf, +