@samitouri / QOSamiQemu / commits / 891601f2e4

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 }