Restore gdb-xml/sparc64-cp0.xml from mainstream binutils, tag
'binutils-2_46', found in the gdb/features/sparc/folder [*].
Extract sparc_cp0_gdb_write_register() out of
sparc_cpu_gdb_read_register() and sparc_cp0_gdb_write_register()
out of sparc_cpu_gdb_write_register(), taking care to update the
register indexes in the switch cases.
Register these helpers with a call to gdb_register_coprocessor()
in sparc_cpu_register_gdb_regs().
[*] https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=gdb/features/sparc;hb=refs/tags/binutils-2_46
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
configs/targets/sparc64-linux-user.mak | 2 +-
configs/targets/sparc64-softmmu.mak | 2 +-
target/sparc/gdbstub.c | 193 ++++++++++++++-----------
gdb-xml/sparc64-core.xml | 7 -
gdb-xml/sparc64-cp0.xml | 16 ++
5 files changed, 130 insertions(+), 90 deletions(-)
create mode 100644 gdb-xml/sparc64-cp0.xml
diff --git a/configs/targets/sparc64-linux-user.mak b/configs/targets/sparc64-linux-user.mak
index 3bbd8495210..930f7e13ab9 100644
--- a/configs/targets/sparc64-linux-user.mak
+++ b/configs/targets/sparc64-linux-user.mak
@@ -4,6 +4,6 @@ TARGET_ABI_DIR=sparc
TARGET_SYSTBL_ABI=common,64
TARGET_SYSTBL=syscall.tbl
TARGET_BIG_ENDIAN=y
-TARGET_XML_FILES=gdb-xml/sparc64-core.xml
+TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/sparc64-softmmu.mak b/configs/targets/sparc64-softmmu.mak
index 8a0290c2093..22e7f3c94a7 100644
--- a/configs/targets/sparc64-softmmu.mak
+++ b/configs/targets/sparc64-softmmu.mak
@@ -1,7 +1,7 @@
TARGET_ARCH=sparc64
TARGET_BASE_ARCH=sparc
TARGET_BIG_ENDIAN=y
-TARGET_XML_FILES=gdb-xml/sparc64-core.xml
+TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c
index 79d661fbc10..bdd759dd0a9 100644
--- a/target/sparc/gdbstub.c
+++ b/target/sparc/gdbstub.c
@@ -18,6 +18,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
+#include "exec/gdbstub.h"
#include "cpu.h"
#include "gdbstub/helpers.h"
@@ -48,27 +49,6 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
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:
- return gdb_get_rega(mem_buf, env->y);
- case 65:
- return gdb_get_rega(mem_buf, cpu_get_psr(env));
- case 66:
- return gdb_get_rega(mem_buf, env->wim);
- case 67:
- return gdb_get_rega(mem_buf, env->tbr);
- case 68:
- return gdb_get_rega(mem_buf, env->pc);
- case 69:
- return gdb_get_rega(mem_buf, env->npc);
- case 70:
- return gdb_get_rega(mem_buf, cpu_get_fsr(env));
- case 71:
- return gdb_get_rega(mem_buf, 0); /* csr */
- default:
- return gdb_get_rega(mem_buf, 0);
- }
#else
if (n < 64) {
/* f0-f31 */
@@ -87,21 +67,51 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
*/
return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll);
}
+#endif
+ return 0;
+}
+
+__attribute__((unused))
+static int sparc_cp0_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+ CPUSPARCState *env = cpu_env(cs);
+
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
+ /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
switch (n) {
- case 80:
+ case 0:
+ return gdb_get_rega(mem_buf, env->y);
+ case 1:
+ return gdb_get_rega(mem_buf, cpu_get_psr(env));
+ case 2:
+ return gdb_get_rega(mem_buf, env->wim);
+ case 3:
+ return gdb_get_rega(mem_buf, env->tbr);
+ case 4:
+ return gdb_get_rega(mem_buf, env->pc);
+ case 5:
+ return gdb_get_rega(mem_buf, env->npc);
+ case 6:
+ return gdb_get_rega(mem_buf, cpu_get_fsr(env));
+ case 7:
+ return gdb_get_rega(mem_buf, 0); /* csr */
+ }
+#else
+ switch (n) {
+ case 0:
return gdb_get_regl(mem_buf, env->pc);
- case 81:
+ case 1:
return gdb_get_regl(mem_buf, env->npc);
- case 82:
+ case 2:
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:
+ case 3:
return gdb_get_regl(mem_buf, cpu_get_fsr(env));
- case 84:
+ case 4:
return gdb_get_regl(mem_buf, env->fprs);
- case 85:
+ case 5:
return gdb_get_regl(mem_buf, env->y);
}
#endif
@@ -138,33 +148,6 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
} 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:
- cpu_put_fsr(env, tmp);
- break;
- default:
- return 0;
- }
}
return 4;
#else
@@ -185,32 +168,77 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
* n == 79: f62 : env->fpr[31]
*/
env->fpr[(n - 64) + 16].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:
- cpu_put_fsr(env, tmp);
- break;
- case 84:
- env->fprs = tmp;
- break;
- case 85:
- env->y = tmp;
- break;
- default:
- return 0;
- }
+ }
+ return 8;
+#endif
+}
+
+__attribute__((unused))
+static int sparc_cp0_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ CPUSPARCState *env = cpu_env(cs);
+
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
+ uint32_t tmp;
+
+ tmp = ldl_p(mem_buf);
+
+ /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ switch (n) {
+ case 0:
+ env->y = tmp;
+ break;
+ case 1:
+ cpu_put_psr(env, tmp);
+ break;
+ case 2:
+ env->wim = tmp;
+ break;
+ case 3:
+ env->tbr = tmp;
+ break;
+ case 4:
+ env->pc = tmp;
+ break;
+ case 5:
+ env->npc = tmp;
+ break;
+ case 6:
+ cpu_put_fsr(env, tmp);
+ break;
+ default:
+ return 0;
+ }
+ return 4;
+#else
+ uint64_t tmp;
+
+ tmp = ldq_p(mem_buf);
+
+ switch (n) {
+ case 0:
+ env->pc = tmp;
+ break;
+ case 1:
+ env->npc = tmp;
+ break;
+ case 2:
+ cpu_put_ccr(env, tmp >> 32);
+ env->asi = (tmp >> 24) & 0xff;
+ env->pstate = (tmp >> 8) & 0xfff;
+ cpu_put_cwp64(env, tmp & 0xff);
+ break;
+ case 3:
+ cpu_put_fsr(env, tmp);
+ break;
+ case 4:
+ env->fprs = tmp;
+ break;
+ case 5:
+ env->y = tmp;
+ break;
+ default:
+ return 0;
}
return 8;
#endif
@@ -221,6 +249,9 @@ void sparc_cpu_register_gdb_regs(CPUState *cs)
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
/* Not yet supported */
#else
- /* Not yet supported */
+ gdb_register_coprocessor(cs, sparc_cp0_gdb_read_register,
+ sparc_cp0_gdb_write_register,
+ gdb_find_static_feature("sparc64-cp0.xml"),
+ 0);
#endif
}
diff --git a/gdb-xml/sparc64-core.xml b/gdb-xml/sparc64-core.xml
index 375b9bb0cc6..1c26d8c01c1 100644
--- a/gdb-xml/sparc64-core.xml
+++ b/gdb-xml/sparc64-core.xml
@@ -89,11 +89,4 @@
<reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
<reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
<reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
-
- <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
- <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
- <reg name="state" bitsize="64" type="uint64" regnum="82"/>
- <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
- <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
- <reg name="y" bitsize="64" type="uint64" regnum="85"/>
</feature>
diff --git a/gdb-xml/sparc64-cp0.xml b/gdb-xml/sparc64-cp0.xml
new file mode 100644
index 00000000000..9b938dc7ecc
--- /dev/null
+++ b/gdb-xml/sparc64-cp0.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2026 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+ <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
+ <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
+ <reg name="state" bitsize="64" type="uint64" regnum="82"/>
+ <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
+ <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
+ <reg name="y" bitsize="64" type="uint64" regnum="85"/>
+</feature>
--
2.52.0