]> git.proxmox.com Git - mirror_qemu.git/blame - target/ppc/gdbstub.c
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into...
[mirror_qemu.git] / target / ppc / gdbstub.c
CommitLineData
0980bfab
AF
1/*
2 * PowerPC gdb server stub
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 * Copyright (c) 2013 SUSE LINUX Products GmbH
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
6bd039cd 10 * version 2.1 of the License, or (at your option) any later version.
0980bfab
AF
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
0d75590d 20#include "qemu/osdep.h"
33c11879 21#include "cpu.h"
5b50e790 22#include "exec/gdbstub.h"
4ea5fe99 23#include "gdbstub/helpers.h"
35a5d74e 24#include "internal.h"
0980bfab 25
b3cad3ab
AG
26static int ppc_gdb_register_len_apple(int n)
27{
28 switch (n) {
29 case 0 ... 31:
30 /* gprs */
31 return 8;
32 case 32 ... 63:
33 /* fprs */
34 return 8;
35 case 64 ... 95:
36 return 16;
02381ec1
DG
37 case 64 + 32: /* nip */
38 case 65 + 32: /* msr */
39 case 67 + 32: /* lr */
40 case 68 + 32: /* ctr */
41 case 70 + 32: /* fpscr */
b3cad3ab 42 return 8;
02381ec1
DG
43 case 66 + 32: /* cr */
44 case 69 + 32: /* xer */
b3cad3ab
AG
45 return 4;
46 default:
47 return 0;
48 }
49}
50
c46e9831
TF
51static int ppc_gdb_register_len(int n)
52{
53 switch (n) {
54 case 0 ... 31:
55 /* gprs */
56 return sizeof(target_ulong);
57 case 32 ... 63:
58 /* fprs */
59 if (gdb_has_xml) {
60 return 0;
61 }
62 return 8;
63 case 66:
64 /* cr */
a2f04333
MM
65 case 69:
66 /* xer */
c46e9831
TF
67 return 4;
68 case 64:
69 /* nip */
70 case 65:
71 /* msr */
72 case 67:
73 /* lr */
74 case 68:
75 /* ctr */
c46e9831
TF
76 return sizeof(target_ulong);
77 case 70:
78 /* fpscr */
79 if (gdb_has_xml) {
80 return 0;
81 }
82 return sizeof(target_ulong);
83 default:
84 return 0;
85 }
86}
87
02381ec1
DG
88/*
89 * We need to present the registers to gdb in the "current" memory
90 * ordering. For user-only mode we get this for free;
ee3eb3a7 91 * TARGET_BIG_ENDIAN is set to the proper ordering for the
02381ec1 92 * binary, and cannot be changed. For system mode,
ee3eb3a7 93 * TARGET_BIG_ENDIAN is always set, and we must check the current
02381ec1
DG
94 * mode of the chip to see if we're running in little-endian.
95 */
376dbce0 96void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
8a286ce4 97{
be5c9dda 98#ifndef CONFIG_USER_ONLY
1922322c 99 if (!FIELD_EX64(env->msr, MSR, LE)) {
be5c9dda
RH
100 /* do nothing */
101 } else if (len == 4) {
8a286ce4
TF
102 bswap32s((uint32_t *)mem_buf);
103 } else if (len == 8) {
104 bswap64s((uint64_t *)mem_buf);
0ff16b6b
MF
105 } else if (len == 16) {
106 bswap128s((Int128 *)mem_buf);
8a286ce4
TF
107 } else {
108 g_assert_not_reached();
109 }
be5c9dda 110#endif
8a286ce4
TF
111}
112
02381ec1
DG
113/*
114 * Old gdb always expects FP registers. Newer (xml-aware) gdb only
0980bfab
AF
115 * expects whatever the target description contains. Due to a
116 * historical mishap the FP registers appear in between core integer
02381ec1
DG
117 * regs and PC, MSR, CR, and so forth. We hack round this by giving
118 * the FP regs zero size when talking to a newer gdb.
0980bfab
AF
119 */
120
a010bdbe 121int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
0980bfab 122{
5b50e790
AF
123 PowerPCCPU *cpu = POWERPC_CPU(cs);
124 CPUPPCState *env = &cpu->env;
a010bdbe 125 uint8_t *mem_buf;
c46e9831
TF
126 int r = ppc_gdb_register_len(n);
127
128 if (!r) {
129 return r;
130 }
5b50e790 131
0980bfab
AF
132 if (n < 32) {
133 /* gprs */
a010bdbe 134 gdb_get_regl(buf, env->gpr[n]);
0980bfab
AF
135 } else if (n < 64) {
136 /* fprs */
34510e32 137 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
0980bfab
AF
138 } else {
139 switch (n) {
140 case 64:
a010bdbe 141 gdb_get_regl(buf, env->nip);
c46e9831 142 break;
0980bfab 143 case 65:
a010bdbe 144 gdb_get_regl(buf, env->msr);
c46e9831 145 break;
0980bfab
AF
146 case 66:
147 {
2060436a 148 uint32_t cr = ppc_get_cr(env);
a010bdbe 149 gdb_get_reg32(buf, cr);
c46e9831 150 break;
0980bfab
AF
151 }
152 case 67:
a010bdbe 153 gdb_get_regl(buf, env->lr);
c46e9831 154 break;
0980bfab 155 case 68:
a010bdbe 156 gdb_get_regl(buf, env->ctr);
c46e9831 157 break;
0980bfab 158 case 69:
7974dc59 159 gdb_get_reg32(buf, cpu_read_xer(env));
c46e9831 160 break;
0980bfab 161 case 70:
a010bdbe 162 gdb_get_reg32(buf, env->fpscr);
c46e9831 163 break;
0980bfab
AF
164 }
165 }
a010bdbe 166 mem_buf = buf->data + buf->len - r;
376dbce0 167 ppc_maybe_bswap_register(env, mem_buf, r);
c46e9831 168 return r;
0980bfab
AF
169}
170
a010bdbe 171int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
b3cad3ab
AG
172{
173 PowerPCCPU *cpu = POWERPC_CPU(cs);
174 CPUPPCState *env = &cpu->env;
a010bdbe 175 uint8_t *mem_buf;
b3cad3ab
AG
176 int r = ppc_gdb_register_len_apple(n);
177
178 if (!r) {
179 return r;
180 }
181
182 if (n < 32) {
183 /* gprs */
a010bdbe 184 gdb_get_reg64(buf, env->gpr[n]);
b3cad3ab
AG
185 } else if (n < 64) {
186 /* fprs */
34510e32 187 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
b3cad3ab
AG
188 } else if (n < 96) {
189 /* Altivec */
a010bdbe
AB
190 gdb_get_reg64(buf, n - 64);
191 gdb_get_reg64(buf, 0);
b3cad3ab
AG
192 } else {
193 switch (n) {
194 case 64 + 32:
a010bdbe 195 gdb_get_reg64(buf, env->nip);
b3cad3ab
AG
196 break;
197 case 65 + 32:
a010bdbe 198 gdb_get_reg64(buf, env->msr);
b3cad3ab
AG
199 break;
200 case 66 + 32:
201 {
2060436a 202 uint32_t cr = ppc_get_cr(env);
a010bdbe 203 gdb_get_reg32(buf, cr);
b3cad3ab
AG
204 break;
205 }
206 case 67 + 32:
a010bdbe 207 gdb_get_reg64(buf, env->lr);
b3cad3ab
AG
208 break;
209 case 68 + 32:
a010bdbe 210 gdb_get_reg64(buf, env->ctr);
b3cad3ab
AG
211 break;
212 case 69 + 32:
7974dc59 213 gdb_get_reg32(buf, cpu_read_xer(env));
b3cad3ab
AG
214 break;
215 case 70 + 32:
a010bdbe 216 gdb_get_reg64(buf, env->fpscr);
b3cad3ab
AG
217 break;
218 }
219 }
a010bdbe 220 mem_buf = buf->data + buf->len - r;
376dbce0 221 ppc_maybe_bswap_register(env, mem_buf, r);
b3cad3ab
AG
222 return r;
223}
224
5b50e790 225int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
0980bfab 226{
5b50e790
AF
227 PowerPCCPU *cpu = POWERPC_CPU(cs);
228 CPUPPCState *env = &cpu->env;
c46e9831 229 int r = ppc_gdb_register_len(n);
5b50e790 230
c46e9831
TF
231 if (!r) {
232 return r;
233 }
376dbce0 234 ppc_maybe_bswap_register(env, mem_buf, r);
0980bfab
AF
235 if (n < 32) {
236 /* gprs */
237 env->gpr[n] = ldtul_p(mem_buf);
0980bfab
AF
238 } else if (n < 64) {
239 /* fprs */
34510e32 240 *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
0980bfab
AF
241 } else {
242 switch (n) {
243 case 64:
244 env->nip = ldtul_p(mem_buf);
c46e9831 245 break;
0980bfab
AF
246 case 65:
247 ppc_store_msr(env, ldtul_p(mem_buf));
c46e9831 248 break;
0980bfab
AF
249 case 66:
250 {
251 uint32_t cr = ldl_p(mem_buf);
2060436a 252 ppc_set_cr(env, cr);
c46e9831 253 break;
0980bfab
AF
254 }
255 case 67:
256 env->lr = ldtul_p(mem_buf);
c46e9831 257 break;
0980bfab
AF
258 case 68:
259 env->ctr = ldtul_p(mem_buf);
c46e9831 260 break;
0980bfab 261 case 69:
7974dc59 262 cpu_write_xer(env, ldl_p(mem_buf));
c46e9831 263 break;
0980bfab
AF
264 case 70:
265 /* fpscr */
fe43ba97 266 ppc_store_fpscr(env, ldtul_p(mem_buf));
c46e9831 267 break;
0980bfab
AF
268 }
269 }
c46e9831 270 return r;
0980bfab 271}
b3cad3ab
AG
272int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
273{
274 PowerPCCPU *cpu = POWERPC_CPU(cs);
275 CPUPPCState *env = &cpu->env;
276 int r = ppc_gdb_register_len_apple(n);
277
278 if (!r) {
279 return r;
280 }
376dbce0 281 ppc_maybe_bswap_register(env, mem_buf, r);
b3cad3ab
AG
282 if (n < 32) {
283 /* gprs */
284 env->gpr[n] = ldq_p(mem_buf);
285 } else if (n < 64) {
286 /* fprs */
34510e32 287 *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
b3cad3ab
AG
288 } else {
289 switch (n) {
290 case 64 + 32:
291 env->nip = ldq_p(mem_buf);
292 break;
293 case 65 + 32:
294 ppc_store_msr(env, ldq_p(mem_buf));
295 break;
296 case 66 + 32:
297 {
298 uint32_t cr = ldl_p(mem_buf);
2060436a 299 ppc_set_cr(env, cr);
b3cad3ab
AG
300 break;
301 }
302 case 67 + 32:
303 env->lr = ldq_p(mem_buf);
304 break;
305 case 68 + 32:
306 env->ctr = ldq_p(mem_buf);
307 break;
308 case 69 + 32:
7974dc59 309 cpu_write_xer(env, ldl_p(mem_buf));
b3cad3ab
AG
310 break;
311 case 70 + 32:
312 /* fpscr */
fe43ba97 313 ppc_store_fpscr(env, ldq_p(mem_buf));
b3cad3ab
AG
314 break;
315 }
316 }
317 return r;
318}
707c7c2e
FR
319
320#ifndef CONFIG_USER_ONLY
321void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu)
322{
323 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
324 CPUPPCState *env = &cpu->env;
325 GString *xml;
326 char *spr_name;
327 unsigned int num_regs = 0;
328 int i;
329
981562ed
NP
330 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
331 ppc_spr_t *spr = &env->spr_cb[i];
332
333 if (!spr->name) {
334 continue;
335 }
336
337 /*
338 * GDB identifies registers based on the order they are
339 * presented in the XML. These ids will not match QEMU's
340 * representation (which follows the PowerISA).
341 *
342 * Store the position of the current register description so
343 * we can make the correspondence later.
344 */
345 spr->gdb_id = num_regs;
346 num_regs++;
347 }
348
707c7c2e
FR
349 if (pcc->gdb_spr_xml) {
350 return;
351 }
352
353 xml = g_string_new("<?xml version=\"1.0\"?>");
354 g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
355 g_string_append(xml, "<feature name=\"org.qemu.power.spr\">");
356
357 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
358 ppc_spr_t *spr = &env->spr_cb[i];
359
360 if (!spr->name) {
361 continue;
362 }
363
364 spr_name = g_ascii_strdown(spr->name, -1);
365 g_string_append_printf(xml, "<reg name=\"%s\"", spr_name);
366 g_free(spr_name);
367
368 g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS);
369 g_string_append(xml, " group=\"spr\"/>");
707c7c2e
FR
370 }
371
372 g_string_append(xml, "</feature>");
373
374 pcc->gdb_num_sprs = num_regs;
375 pcc->gdb_spr_xml = g_string_free(xml, false);
376}
377
378const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
379{
380 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
381
382 if (strcmp(xml_name, "power-spr.xml") == 0) {
383 return pcc->gdb_spr_xml;
384 }
385 return NULL;
386}
387#endif
35a5d74e 388
35a5d74e
BL
389#if !defined(CONFIG_USER_ONLY)
390static int gdb_find_spr_idx(CPUPPCState *env, int n)
391{
392 int i;
393
394 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
395 ppc_spr_t *spr = &env->spr_cb[i];
396
397 if (spr->name && spr->gdb_id == n) {
398 return i;
399 }
400 }
401 return -1;
402}
403
404static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
405{
406 int reg;
407 int len;
408
409 reg = gdb_find_spr_idx(env, n);
410 if (reg < 0) {
411 return 0;
412 }
413
414 len = TARGET_LONG_SIZE;
415 gdb_get_regl(buf, env->spr[reg]);
416 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
417 return len;
418}
419
420static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
421{
422 int reg;
423 int len;
424
425 reg = gdb_find_spr_idx(env, n);
426 if (reg < 0) {
427 return 0;
428 }
429
430 len = TARGET_LONG_SIZE;
431 ppc_maybe_bswap_register(env, mem_buf, len);
432 env->spr[reg] = ldn_p(mem_buf, len);
433
434 return len;
435}
436#endif
437
438static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
439{
440 uint8_t *mem_buf;
441 if (n < 32) {
442 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
443 mem_buf = gdb_get_reg_ptr(buf, 8);
444 ppc_maybe_bswap_register(env, mem_buf, 8);
445 return 8;
446 }
447 if (n == 32) {
448 gdb_get_reg32(buf, env->fpscr);
449 mem_buf = gdb_get_reg_ptr(buf, 4);
450 ppc_maybe_bswap_register(env, mem_buf, 4);
451 return 4;
452 }
453 return 0;
454}
455
456static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
457{
458 if (n < 32) {
459 ppc_maybe_bswap_register(env, mem_buf, 8);
460 *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
461 return 8;
462 }
463 if (n == 32) {
464 ppc_maybe_bswap_register(env, mem_buf, 4);
fe43ba97 465 ppc_store_fpscr(env, ldl_p(mem_buf));
35a5d74e
BL
466 return 4;
467 }
468 return 0;
469}
470
471static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
472{
473 uint8_t *mem_buf;
474
475 if (n < 32) {
476 ppc_avr_t *avr = cpu_avr_ptr(env, n);
0ff16b6b 477 gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
35a5d74e 478 mem_buf = gdb_get_reg_ptr(buf, 16);
0ff16b6b 479 ppc_maybe_bswap_register(env, mem_buf, 16);
35a5d74e
BL
480 return 16;
481 }
482 if (n == 32) {
c19940db 483 gdb_get_reg32(buf, ppc_get_vscr(env));
35a5d74e
BL
484 mem_buf = gdb_get_reg_ptr(buf, 4);
485 ppc_maybe_bswap_register(env, mem_buf, 4);
486 return 4;
487 }
488 if (n == 33) {
489 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
490 mem_buf = gdb_get_reg_ptr(buf, 4);
491 ppc_maybe_bswap_register(env, mem_buf, 4);
492 return 4;
493 }
494 return 0;
495}
496
497static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
498{
499 if (n < 32) {
500 ppc_avr_t *avr = cpu_avr_ptr(env, n);
0ff16b6b
MF
501 ppc_maybe_bswap_register(env, mem_buf, 16);
502 avr->VsrD(0) = ldq_p(mem_buf);
503 avr->VsrD(1) = ldq_p(mem_buf + 8);
35a5d74e
BL
504 return 16;
505 }
506 if (n == 32) {
507 ppc_maybe_bswap_register(env, mem_buf, 4);
c19940db 508 ppc_store_vscr(env, ldl_p(mem_buf));
35a5d74e
BL
509 return 4;
510 }
511 if (n == 33) {
512 ppc_maybe_bswap_register(env, mem_buf, 4);
513 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
514 return 4;
515 }
516 return 0;
517}
518
519static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
520{
521 if (n < 32) {
522#if defined(TARGET_PPC64)
523 gdb_get_reg32(buf, env->gpr[n] >> 32);
524 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
525#else
526 gdb_get_reg32(buf, env->gprh[n]);
527#endif
528 return 4;
529 }
530 if (n == 32) {
531 gdb_get_reg64(buf, env->spe_acc);
532 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
533 return 8;
534 }
535 if (n == 33) {
536 gdb_get_reg32(buf, env->spe_fscr);
537 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
538 return 4;
539 }
540 return 0;
541}
542
543static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
544{
545 if (n < 32) {
546#if defined(TARGET_PPC64)
547 target_ulong lo = (uint32_t)env->gpr[n];
548 target_ulong hi;
549
550 ppc_maybe_bswap_register(env, mem_buf, 4);
551
552 hi = (target_ulong)ldl_p(mem_buf) << 32;
553 env->gpr[n] = lo | hi;
554#else
555 env->gprh[n] = ldl_p(mem_buf);
556#endif
557 return 4;
558 }
559 if (n == 32) {
560 ppc_maybe_bswap_register(env, mem_buf, 8);
561 env->spe_acc = ldq_p(mem_buf);
562 return 8;
563 }
564 if (n == 33) {
565 ppc_maybe_bswap_register(env, mem_buf, 4);
566 env->spe_fscr = ldl_p(mem_buf);
567 return 4;
568 }
569 return 0;
570}
571
572static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
573{
574 if (n < 32) {
575 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
576 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
577 return 8;
578 }
579 return 0;
580}
581
582static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
583{
584 if (n < 32) {
585 ppc_maybe_bswap_register(env, mem_buf, 8);
586 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
587 return 8;
588 }
589 return 0;
590}
591
592gchar *ppc_gdb_arch_name(CPUState *cs)
593{
594#if defined(TARGET_PPC64)
595 return g_strdup("powerpc:common64");
596#else
597 return g_strdup("powerpc:common");
598#endif
599}
600
601void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
602{
603 if (pcc->insns_flags & PPC_FLOAT) {
604 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
605 33, "power-fpu.xml", 0);
606 }
607 if (pcc->insns_flags & PPC_ALTIVEC) {
608 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
609 34, "power-altivec.xml", 0);
610 }
611 if (pcc->insns_flags & PPC_SPE) {
612 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
613 34, "power-spe.xml", 0);
614 }
615 if (pcc->insns_flags2 & PPC2_VSX) {
616 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
617 32, "power-vsx.xml", 0);
618 }
619#ifndef CONFIG_USER_ONLY
620 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
621 pcc->gdb_num_sprs, "power-spr.xml", 0);
622#endif
623}