target/sparc: Restore 'gdb-xml/sparc64-cp0.xml'
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 Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260219191955.83815-12-philmd@linaro.org>
Philippe Mathieu-Daudé committed
Feb 15, 2026 at 02:38 UTC
891601f2e4d254fd29ae72b1f60c3a58ce96a97d
6 files changed
+131
-90
MAINTAINERS
+1
@@ -402,6 +402,7 @@ M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
402
M: Artyom Tarasenko <atar4qemu@gmail.com>
403
S: Maintained
404
F: target/sparc/
405
+F: gdb-xml/sparc*.xml
406
F: hw/sparc/
407
F: hw/sparc64/
408
F: include/hw/sparc/sparc64.h
configs/targets/sparc64-linux-user.mak
+1
-1
@@ -4,6 +4,6 @@ TARGET_ABI_DIR=sparc
4
TARGET_SYSTBL_ABI=common,64
5
TARGET_SYSTBL=syscall.tbl
6
TARGET_BIG_ENDIAN=y
7
-TARGET_XML_FILES=gdb-xml/sparc64-core.xml
7
+TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
8
TARGET_LONG_BITS=64
9
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
configs/targets/sparc64-softmmu.mak
+1
-1
@@ -1,7 +1,7 @@
1
TARGET_ARCH=sparc64
2
TARGET_BASE_ARCH=sparc
3
TARGET_BIG_ENDIAN=y
4
-TARGET_XML_FILES=gdb-xml/sparc64-core.xml
4
+TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
5
TARGET_LONG_BITS=64
6
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
7
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
gdb-xml/sparc64-core.xml
-7
@@ -89,11 +89,4 @@
89
<reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
90
<reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
91
<reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
92
-
93
- <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
94
- <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
95
- <reg name="state" bitsize="64" type="uint64" regnum="82"/>
96
- <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
97
- <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
98
- <reg name="y" bitsize="64" type="uint64" regnum="85"/>
92
</feature>
gdb-xml/sparc64-cp0.xml
new
+16
@@ -0,0 +1,16 @@
1
+<?xml version="1.0"?>
2
+<!-- Copyright (C) 2013-2026 Free Software Foundation, Inc.
3
+
4
+ Copying and distribution of this file, with or without modification,
5
+ are permitted in any medium without royalty provided the copyright
6
+ notice and this notice are preserved. -->
7
+
8
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
9
+<feature name="org.gnu.gdb.sparc.cp0">
10
+ <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
11
+ <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
12
+ <reg name="state" bitsize="64" type="uint64" regnum="82"/>
13
+ <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
14
+ <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
15
+ <reg name="y" bitsize="64" type="uint64" regnum="85"/>
16
+</feature>
target/sparc/gdbstub.c
+112
-81
@@ -18,6 +18,7 @@
18
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
*/
20
#include "qemu/osdep.h"
21
+#include "exec/gdbstub.h"
22
#include "cpu.h"
23
#include "gdbstub/helpers.h"
24
@@ -48,27 +49,6 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
49
return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
50
}
51
}
51
- /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
52
- switch (n) {
53
- case 64:
54
- return gdb_get_rega(mem_buf, env->y);
55
- case 65:
56
- return gdb_get_rega(mem_buf, cpu_get_psr(env));
57
- case 66:
58
- return gdb_get_rega(mem_buf, env->wim);
59
- case 67:
60
- return gdb_get_rega(mem_buf, env->tbr);
61
- case 68:
62
- return gdb_get_rega(mem_buf, env->pc);
63
- case 69:
64
- return gdb_get_rega(mem_buf, env->npc);
65
- case 70:
66
- return gdb_get_rega(mem_buf, cpu_get_fsr(env));
67
- case 71:
68
- return gdb_get_rega(mem_buf, 0); /* csr */
69
- default:
70
- return gdb_get_rega(mem_buf, 0);
71
- }
52
#else
53
if (n < 64) {
54
/* f0-f31 */
@@ -87,21 +67,51 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
67
*/
68
return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll);
69
}
70
+#endif
71
+ return 0;
72
+}
73
+
74
+__attribute__((unused))
75
+static int sparc_cp0_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
76
+{
77
+ CPUSPARCState *env = cpu_env(cs);
78
+
79
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
80
+ /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
81
+ switch (n) {
82
+ case 0:
83
+ return gdb_get_rega(mem_buf, env->y);
84
+ case 1:
85
+ return gdb_get_rega(mem_buf, cpu_get_psr(env));
86
+ case 2:
87
+ return gdb_get_rega(mem_buf, env->wim);
88
+ case 3:
89
+ return gdb_get_rega(mem_buf, env->tbr);
90
+ case 4:
91
+ return gdb_get_rega(mem_buf, env->pc);
92
+ case 5:
93
+ return gdb_get_rega(mem_buf, env->npc);
94
+ case 6:
95
+ return gdb_get_rega(mem_buf, cpu_get_fsr(env));
96
+ case 7:
97
+ return gdb_get_rega(mem_buf, 0); /* csr */
98
+ }
99
+#else
100
switch (n) {
91
- case 80:
101
+ case 0:
102
return gdb_get_regl(mem_buf, env->pc);
93
- case 81:
103
+ case 1:
104
return gdb_get_regl(mem_buf, env->npc);
95
- case 82:
105
+ case 2:
106
return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
107
((env->asi & 0xff) << 24) |
108
((env->pstate & 0xfff) << 8) |
109
cpu_get_cwp64(env));
100
- case 83:
110
+ case 3:
111
return gdb_get_regl(mem_buf, cpu_get_fsr(env));
102
- case 84:
112
+ case 4:
113
return gdb_get_regl(mem_buf, env->fprs);
104
- case 85:
114
+ case 5:
115
return gdb_get_regl(mem_buf, env->y);
116
}
117
#endif
@@ -138,33 +148,6 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
148
} else {
149
env->fpr[(n - 32) / 2].l.upper = tmp;
150
}
141
- } else {
142
- /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
143
- switch (n) {
144
- case 64:
145
- env->y = tmp;
146
- break;
147
- case 65:
148
- cpu_put_psr(env, tmp);
149
- break;
150
- case 66:
151
- env->wim = tmp;
152
- break;
153
- case 67:
154
- env->tbr = tmp;
155
- break;
156
- case 68:
157
- env->pc = tmp;
158
- break;
159
- case 69:
160
- env->npc = tmp;
161
- break;
162
- case 70:
163
- cpu_put_fsr(env, tmp);
164
- break;
165
- default:
166
- return 0;
167
- }
151
}
152
return 4;
153
#else
@@ -185,32 +168,77 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
168
* n == 79: f62 : env->fpr[31]
169
*/
170
env->fpr[(n - 64) + 16].ll = tmp;
188
- } else {
189
- switch (n) {
190
- case 80:
191
- env->pc = tmp;
192
- break;
193
- case 81:
194
- env->npc = tmp;
195
- break;
196
- case 82:
197
- cpu_put_ccr(env, tmp >> 32);
198
- env->asi = (tmp >> 24) & 0xff;
199
- env->pstate = (tmp >> 8) & 0xfff;
200
- cpu_put_cwp64(env, tmp & 0xff);
201
- break;
202
- case 83:
203
- cpu_put_fsr(env, tmp);
204
- break;
205
- case 84:
206
- env->fprs = tmp;
207
- break;
208
- case 85:
209
- env->y = tmp;
210
- break;
211
- default:
212
- return 0;
213
- }
171
+ }
172
+ return 8;
173
+#endif
174
+}
175
+
176
+__attribute__((unused))
177
+static int sparc_cp0_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
178
+{
179
+ CPUSPARCState *env = cpu_env(cs);
180
+
181
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
182
+ uint32_t tmp;
183
+
184
+ tmp = ldl_p(mem_buf);
185
+
186
+ /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
187
+ switch (n) {
188
+ case 0:
189
+ env->y = tmp;
190
+ break;
191
+ case 1:
192
+ cpu_put_psr(env, tmp);
193
+ break;
194
+ case 2:
195
+ env->wim = tmp;
196
+ break;
197
+ case 3:
198
+ env->tbr = tmp;
199
+ break;
200
+ case 4:
201
+ env->pc = tmp;
202
+ break;
203
+ case 5:
204
+ env->npc = tmp;
205
+ break;
206
+ case 6:
207
+ cpu_put_fsr(env, tmp);
208
+ break;
209
+ default:
210
+ return 0;
211
+ }
212
+ return 4;
213
+#else
214
+ uint64_t tmp;
215
+
216
+ tmp = ldq_p(mem_buf);
217
+
218
+ switch (n) {
219
+ case 0:
220
+ env->pc = tmp;
221
+ break;
222
+ case 1:
223
+ env->npc = tmp;
224
+ break;
225
+ case 2:
226
+ cpu_put_ccr(env, tmp >> 32);
227
+ env->asi = (tmp >> 24) & 0xff;
228
+ env->pstate = (tmp >> 8) & 0xfff;
229
+ cpu_put_cwp64(env, tmp & 0xff);
230
+ break;
231
+ case 3:
232
+ cpu_put_fsr(env, tmp);
233
+ break;
234
+ case 4:
235
+ env->fprs = tmp;
236
+ break;
237
+ case 5:
238
+ env->y = tmp;
239
+ break;
240
+ default:
241
+ return 0;
242
}
243
return 8;
244
#endif
@@ -221,6 +249,9 @@ void sparc_cpu_register_gdb_regs(CPUState *cs)
249
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
250
/* Not yet supported */
251
#else
224
- /* Not yet supported */
252
+ gdb_register_coprocessor(cs, sparc_cp0_gdb_read_register,
253
+ sparc_cp0_gdb_write_register,
254
+ gdb_find_static_feature("sparc64-cp0.xml"),
255
+ 0);
256
#endif
257
}