GDB has no knowledge of the R5900 LO1/HI1 registers and of the
upper halves of its 128-bit GPRs. Add a org.qemu.gdb.mips.r5900
feature with lo1, hi1 and r0_hi..r31_hi, transferred as 64-bit.

Unfortunately we need to gate on TARGET_MIPS64 because the
gpr_hi[] upper halves are only declared there.

Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
 configs/targets/mips64-softmmu.mak   |  2 +-
 configs/targets/mips64el-softmmu.mak |  2 +-
 target/mips/gdbstub.c                | 46 +++++++++++++++++++++++++++
 gdbstub/gdb-xml/mips64-r5900.xml     | 47 ++++++++++++++++++++++++++++
 4 files changed, 95 insertions(+), 2 deletions(-)
 create mode 100644 gdbstub/gdb-xml/mips64-r5900.xml

diff --git a/configs/targets/mips64-softmmu.mak 
b/configs/targets/mips64-softmmu.mak
index 03db5ef74abc..b96e91559c9a 100644
--- a/configs/targets/mips64-softmmu.mak
+++ b/configs/targets/mips64-softmmu.mak
@@ -3,4 +3,4 @@ TARGET_BASE_ARCH=mips
 TARGET_BIG_ENDIAN=y
 TARGET_LONG_BITS=64
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
-TARGET_XML_FILES= mips64-cpu.xml mips64-cp0.xml mips64-fpu.xml
+TARGET_XML_FILES= mips64-cpu.xml mips64-cp0.xml mips64-fpu.xml mips64-r5900.xml
diff --git a/configs/targets/mips64el-softmmu.mak 
b/configs/targets/mips64el-softmmu.mak
index b3433d8cf7ab..089f2c0c7c43 100644
--- a/configs/targets/mips64el-softmmu.mak
+++ b/configs/targets/mips64el-softmmu.mak
@@ -2,4 +2,4 @@ TARGET_ARCH=mips64
 TARGET_BASE_ARCH=mips
 TARGET_LONG_BITS=64
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
-TARGET_XML_FILES= mips64-cpu.xml mips64-cp0.xml mips64-fpu.xml
+TARGET_XML_FILES= mips64-cpu.xml mips64-cp0.xml mips64-fpu.xml mips64-r5900.xml
diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c
index e21eb6f67fbd..3678f2c696c8 100644
--- a/target/mips/gdbstub.c
+++ b/target/mips/gdbstub.c
@@ -243,6 +243,45 @@ static int mips_gdb_write_fpu(CPUState *cs, uint8_t *buf, 
int n)
                                        MIPS_GDB_FPU_LEGACY_BASE + n);
 }
 
+#if defined(TARGET_MIPS64)
+/* org.qemu.gdb.mips.r5900: lo1, hi1, r0_hi..r31_hi */
+static int r5900_gdb_read_regs(CPUState *cs, GByteArray *buf, int n)
+{
+    CPUMIPSState *env = cpu_env(cs);
+
+    switch (n) {
+    case 0:
+        return gdb_get_reg64(buf, env->active_tc.LO[1]);
+    case 1:
+        return gdb_get_reg64(buf, env->active_tc.HI[1]);
+    default:
+        return gdb_get_reg64(buf, env->active_tc.gpr_hi[n - 2]);
+    }
+}
+
+static int r5900_gdb_write_regs(CPUState *cs, uint8_t *buf, int n)
+{
+    CPUMIPSState *env = cpu_env(cs);
+    uint64_t val = ldn_p(buf, 8);
+
+    switch (n) {
+    case 0:
+        env->active_tc.LO[1] = val;
+        break;
+    case 1:
+        env->active_tc.HI[1] = val;
+        break;
+    case 2:
+        /* r0 is hardwired to zero */
+        break;
+    default:
+        env->active_tc.gpr_hi[n - 2] = val;
+        break;
+    }
+    return 8;
+}
+#endif /* TARGET_MIPS64 */
+
 void mips_cpu_gdb_class_init_xml(CPUClass *cc)
 {
     cc->gdb_core_xml_file = target_long_bits() == 64 ? "mips64-cpu.xml"
@@ -262,4 +301,11 @@ void mips_cpu_register_gdb_regs(CPUState *cs)
                              gdb_find_static_feature(cp0_xml));
     gdb_register_coprocessor(cs, mips_gdb_read_fpu, mips_gdb_write_fpu,
                              gdb_find_static_feature(fpu_xml));
+
+#if defined(TARGET_MIPS64)
+    if (MIPS_CPU_GET_CLASS(cs)->cpu_def->insn_flags & INSN_R5900) {
+        gdb_register_coprocessor(cs, r5900_gdb_read_regs, r5900_gdb_write_regs,
+                                 gdb_find_static_feature("mips64-r5900.xml"));
+    }
+#endif
 }
diff --git a/gdbstub/gdb-xml/mips64-r5900.xml b/gdbstub/gdb-xml/mips64-r5900.xml
new file mode 100644
index 000000000000..6c03849824de
--- /dev/null
+++ b/gdbstub/gdb-xml/mips64-r5900.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!-- SPDX-License-Identifier: GPL-2.0-or-later -->
+
+<!--
+     Toshiba R5900 specific registers:
+     - LO1/HI1, the pipeline 1 multiply/divide unit results;
+     - the upper 64 bits of the 128-bit general purpose registers.
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.mips.r5900">
+  <reg name="lo1" bitsize="64" type="int64"/>
+  <reg name="hi1" bitsize="64" type="int64"/>
+
+  <reg name="r0_hi" bitsize="64" type="uint64"/>
+  <reg name="r1_hi" bitsize="64" type="uint64"/>
+  <reg name="r2_hi" bitsize="64" type="uint64"/>
+  <reg name="r3_hi" bitsize="64" type="uint64"/>
+  <reg name="r4_hi" bitsize="64" type="uint64"/>
+  <reg name="r5_hi" bitsize="64" type="uint64"/>
+  <reg name="r6_hi" bitsize="64" type="uint64"/>
+  <reg name="r7_hi" bitsize="64" type="uint64"/>
+  <reg name="r8_hi" bitsize="64" type="uint64"/>
+  <reg name="r9_hi" bitsize="64" type="uint64"/>
+  <reg name="r10_hi" bitsize="64" type="uint64"/>
+  <reg name="r11_hi" bitsize="64" type="uint64"/>
+  <reg name="r12_hi" bitsize="64" type="uint64"/>
+  <reg name="r13_hi" bitsize="64" type="uint64"/>
+  <reg name="r14_hi" bitsize="64" type="uint64"/>
+  <reg name="r15_hi" bitsize="64" type="uint64"/>
+  <reg name="r16_hi" bitsize="64" type="uint64"/>
+  <reg name="r17_hi" bitsize="64" type="uint64"/>
+  <reg name="r18_hi" bitsize="64" type="uint64"/>
+  <reg name="r19_hi" bitsize="64" type="uint64"/>
+  <reg name="r20_hi" bitsize="64" type="uint64"/>
+  <reg name="r21_hi" bitsize="64" type="uint64"/>
+  <reg name="r22_hi" bitsize="64" type="uint64"/>
+  <reg name="r23_hi" bitsize="64" type="uint64"/>
+  <reg name="r24_hi" bitsize="64" type="uint64"/>
+  <reg name="r25_hi" bitsize="64" type="uint64"/>
+  <reg name="r26_hi" bitsize="64" type="uint64"/>
+  <reg name="r27_hi" bitsize="64" type="uint64"/>
+  <reg name="r28_hi" bitsize="64" type="uint64"/>
+  <reg name="r29_hi" bitsize="64" type="uint64"/>
+  <reg name="r30_hi" bitsize="64" type="uint64"/>
+  <reg name="r31_hi" bitsize="64" type="uint64"/>
+</feature>
-- 
2.55.0


Reply via email to