xref: /openbmc/qemu/target/ppc/gdbstub.c (revision d044b7c3)
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
10  * version 2.1 of the License, or (at your option) any later version.
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  */
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "exec/gdbstub.h"
23 #include "gdbstub/helpers.h"
24 #include "internal.h"
25 
26 static 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;
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 */
42         return 8;
43     case 66 + 32: /* cr */
44     case 69 + 32: /* xer */
45         return 4;
46     default:
47         return 0;
48     }
49 }
50 
51 static 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 */
65     case 69:
66         /* xer */
67         return 4;
68     case 64:
69         /* nip */
70     case 65:
71         /* msr */
72     case 67:
73         /* lr */
74     case 68:
75         /* ctr */
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 
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;
91  * TARGET_BIG_ENDIAN is set to the proper ordering for the
92  * binary, and cannot be changed.  For system mode,
93  * TARGET_BIG_ENDIAN is always set, and we must check the current
94  * mode of the chip to see if we're running in little-endian.
95  */
96 void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
97 {
98 #ifndef CONFIG_USER_ONLY
99     if (!FIELD_EX64(env->msr, MSR, LE)) {
100         /* do nothing */
101     } else if (len == 4) {
102         bswap32s((uint32_t *)mem_buf);
103     } else if (len == 8) {
104         bswap64s((uint64_t *)mem_buf);
105     } else if (len == 16) {
106         bswap128s((Int128 *)mem_buf);
107     } else {
108         g_assert_not_reached();
109     }
110 #endif
111 }
112 
113 /*
114  * Old gdb always expects FP registers.  Newer (xml-aware) gdb only
115  * expects whatever the target description contains.  Due to a
116  * historical mishap the FP registers appear in between core integer
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.
119  */
120 
121 int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
122 {
123     PowerPCCPU *cpu = POWERPC_CPU(cs);
124     CPUPPCState *env = &cpu->env;
125     uint8_t *mem_buf;
126     int r = ppc_gdb_register_len(n);
127 
128     if (!r) {
129         return r;
130     }
131 
132     if (n < 32) {
133         /* gprs */
134         gdb_get_regl(buf, env->gpr[n]);
135     } else if (n < 64) {
136         /* fprs */
137         gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
138     } else {
139         switch (n) {
140         case 64:
141             gdb_get_regl(buf, env->nip);
142             break;
143         case 65:
144             gdb_get_regl(buf, env->msr);
145             break;
146         case 66:
147             {
148                 uint32_t cr = 0;
149                 int i;
150                 for (i = 0; i < 8; i++) {
151                     cr |= env->crf[i] << (32 - ((i + 1) * 4));
152                 }
153                 gdb_get_reg32(buf, cr);
154                 break;
155             }
156         case 67:
157             gdb_get_regl(buf, env->lr);
158             break;
159         case 68:
160             gdb_get_regl(buf, env->ctr);
161             break;
162         case 69:
163             gdb_get_reg32(buf, cpu_read_xer(env));
164             break;
165         case 70:
166             gdb_get_reg32(buf, env->fpscr);
167             break;
168         }
169     }
170     mem_buf = buf->data + buf->len - r;
171     ppc_maybe_bswap_register(env, mem_buf, r);
172     return r;
173 }
174 
175 int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
176 {
177     PowerPCCPU *cpu = POWERPC_CPU(cs);
178     CPUPPCState *env = &cpu->env;
179     uint8_t *mem_buf;
180     int r = ppc_gdb_register_len_apple(n);
181 
182     if (!r) {
183         return r;
184     }
185 
186     if (n < 32) {
187         /* gprs */
188         gdb_get_reg64(buf, env->gpr[n]);
189     } else if (n < 64) {
190         /* fprs */
191         gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
192     } else if (n < 96) {
193         /* Altivec */
194         gdb_get_reg64(buf, n - 64);
195         gdb_get_reg64(buf, 0);
196     } else {
197         switch (n) {
198         case 64 + 32:
199             gdb_get_reg64(buf, env->nip);
200             break;
201         case 65 + 32:
202             gdb_get_reg64(buf, env->msr);
203             break;
204         case 66 + 32:
205             {
206                 uint32_t cr = 0;
207                 int i;
208                 for (i = 0; i < 8; i++) {
209                     cr |= env->crf[i] << (32 - ((i + 1) * 4));
210                 }
211                 gdb_get_reg32(buf, cr);
212                 break;
213             }
214         case 67 + 32:
215             gdb_get_reg64(buf, env->lr);
216             break;
217         case 68 + 32:
218             gdb_get_reg64(buf, env->ctr);
219             break;
220         case 69 + 32:
221             gdb_get_reg32(buf, cpu_read_xer(env));
222             break;
223         case 70 + 32:
224             gdb_get_reg64(buf, env->fpscr);
225             break;
226         }
227     }
228     mem_buf = buf->data + buf->len - r;
229     ppc_maybe_bswap_register(env, mem_buf, r);
230     return r;
231 }
232 
233 int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
234 {
235     PowerPCCPU *cpu = POWERPC_CPU(cs);
236     CPUPPCState *env = &cpu->env;
237     int r = ppc_gdb_register_len(n);
238 
239     if (!r) {
240         return r;
241     }
242     ppc_maybe_bswap_register(env, mem_buf, r);
243     if (n < 32) {
244         /* gprs */
245         env->gpr[n] = ldtul_p(mem_buf);
246     } else if (n < 64) {
247         /* fprs */
248         *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
249     } else {
250         switch (n) {
251         case 64:
252             env->nip = ldtul_p(mem_buf);
253             break;
254         case 65:
255             ppc_store_msr(env, ldtul_p(mem_buf));
256             break;
257         case 66:
258             {
259                 uint32_t cr = ldl_p(mem_buf);
260                 int i;
261                 for (i = 0; i < 8; i++) {
262                     env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
263                 }
264                 break;
265             }
266         case 67:
267             env->lr = ldtul_p(mem_buf);
268             break;
269         case 68:
270             env->ctr = ldtul_p(mem_buf);
271             break;
272         case 69:
273             cpu_write_xer(env, ldl_p(mem_buf));
274             break;
275         case 70:
276             /* fpscr */
277             ppc_store_fpscr(env, ldtul_p(mem_buf));
278             break;
279         }
280     }
281     return r;
282 }
283 int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
284 {
285     PowerPCCPU *cpu = POWERPC_CPU(cs);
286     CPUPPCState *env = &cpu->env;
287     int r = ppc_gdb_register_len_apple(n);
288 
289     if (!r) {
290         return r;
291     }
292     ppc_maybe_bswap_register(env, mem_buf, r);
293     if (n < 32) {
294         /* gprs */
295         env->gpr[n] = ldq_p(mem_buf);
296     } else if (n < 64) {
297         /* fprs */
298         *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
299     } else {
300         switch (n) {
301         case 64 + 32:
302             env->nip = ldq_p(mem_buf);
303             break;
304         case 65 + 32:
305             ppc_store_msr(env, ldq_p(mem_buf));
306             break;
307         case 66 + 32:
308             {
309                 uint32_t cr = ldl_p(mem_buf);
310                 int i;
311                 for (i = 0; i < 8; i++) {
312                     env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
313                 }
314                 break;
315             }
316         case 67 + 32:
317             env->lr = ldq_p(mem_buf);
318             break;
319         case 68 + 32:
320             env->ctr = ldq_p(mem_buf);
321             break;
322         case 69 + 32:
323             cpu_write_xer(env, ldl_p(mem_buf));
324             break;
325         case 70 + 32:
326             /* fpscr */
327             ppc_store_fpscr(env, ldq_p(mem_buf));
328             break;
329         }
330     }
331     return r;
332 }
333 
334 #ifndef CONFIG_USER_ONLY
335 void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu)
336 {
337     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
338     CPUPPCState *env = &cpu->env;
339     GString *xml;
340     char *spr_name;
341     unsigned int num_regs = 0;
342     int i;
343 
344     if (pcc->gdb_spr_xml) {
345         return;
346     }
347 
348     xml = g_string_new("<?xml version=\"1.0\"?>");
349     g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
350     g_string_append(xml, "<feature name=\"org.qemu.power.spr\">");
351 
352     for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
353         ppc_spr_t *spr = &env->spr_cb[i];
354 
355         if (!spr->name) {
356             continue;
357         }
358 
359         spr_name = g_ascii_strdown(spr->name, -1);
360         g_string_append_printf(xml, "<reg name=\"%s\"", spr_name);
361         g_free(spr_name);
362 
363         g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS);
364         g_string_append(xml, " group=\"spr\"/>");
365 
366         /*
367          * GDB identifies registers based on the order they are
368          * presented in the XML. These ids will not match QEMU's
369          * representation (which follows the PowerISA).
370          *
371          * Store the position of the current register description so
372          * we can make the correspondence later.
373          */
374         spr->gdb_id = num_regs;
375         num_regs++;
376     }
377 
378     g_string_append(xml, "</feature>");
379 
380     pcc->gdb_num_sprs = num_regs;
381     pcc->gdb_spr_xml = g_string_free(xml, false);
382 }
383 
384 const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
385 {
386     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
387 
388     if (strcmp(xml_name, "power-spr.xml") == 0) {
389         return pcc->gdb_spr_xml;
390     }
391     return NULL;
392 }
393 #endif
394 
395 #if !defined(CONFIG_USER_ONLY)
396 static int gdb_find_spr_idx(CPUPPCState *env, int n)
397 {
398     int i;
399 
400     for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
401         ppc_spr_t *spr = &env->spr_cb[i];
402 
403         if (spr->name && spr->gdb_id == n) {
404             return i;
405         }
406     }
407     return -1;
408 }
409 
410 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
411 {
412     int reg;
413     int len;
414 
415     reg = gdb_find_spr_idx(env, n);
416     if (reg < 0) {
417         return 0;
418     }
419 
420     len = TARGET_LONG_SIZE;
421     gdb_get_regl(buf, env->spr[reg]);
422     ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
423     return len;
424 }
425 
426 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
427 {
428     int reg;
429     int len;
430 
431     reg = gdb_find_spr_idx(env, n);
432     if (reg < 0) {
433         return 0;
434     }
435 
436     len = TARGET_LONG_SIZE;
437     ppc_maybe_bswap_register(env, mem_buf, len);
438     env->spr[reg] = ldn_p(mem_buf, len);
439 
440     return len;
441 }
442 #endif
443 
444 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
445 {
446     uint8_t *mem_buf;
447     if (n < 32) {
448         gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
449         mem_buf = gdb_get_reg_ptr(buf, 8);
450         ppc_maybe_bswap_register(env, mem_buf, 8);
451         return 8;
452     }
453     if (n == 32) {
454         gdb_get_reg32(buf, env->fpscr);
455         mem_buf = gdb_get_reg_ptr(buf, 4);
456         ppc_maybe_bswap_register(env, mem_buf, 4);
457         return 4;
458     }
459     return 0;
460 }
461 
462 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
463 {
464     if (n < 32) {
465         ppc_maybe_bswap_register(env, mem_buf, 8);
466         *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
467         return 8;
468     }
469     if (n == 32) {
470         ppc_maybe_bswap_register(env, mem_buf, 4);
471         ppc_store_fpscr(env, ldl_p(mem_buf));
472         return 4;
473     }
474     return 0;
475 }
476 
477 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
478 {
479     uint8_t *mem_buf;
480 
481     if (n < 32) {
482         ppc_avr_t *avr = cpu_avr_ptr(env, n);
483         gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
484         mem_buf = gdb_get_reg_ptr(buf, 16);
485         ppc_maybe_bswap_register(env, mem_buf, 16);
486         return 16;
487     }
488     if (n == 32) {
489         gdb_get_reg32(buf, ppc_get_vscr(env));
490         mem_buf = gdb_get_reg_ptr(buf, 4);
491         ppc_maybe_bswap_register(env, mem_buf, 4);
492         return 4;
493     }
494     if (n == 33) {
495         gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
496         mem_buf = gdb_get_reg_ptr(buf, 4);
497         ppc_maybe_bswap_register(env, mem_buf, 4);
498         return 4;
499     }
500     return 0;
501 }
502 
503 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
504 {
505     if (n < 32) {
506         ppc_avr_t *avr = cpu_avr_ptr(env, n);
507         ppc_maybe_bswap_register(env, mem_buf, 16);
508         avr->VsrD(0) = ldq_p(mem_buf);
509         avr->VsrD(1) = ldq_p(mem_buf + 8);
510         return 16;
511     }
512     if (n == 32) {
513         ppc_maybe_bswap_register(env, mem_buf, 4);
514         ppc_store_vscr(env, ldl_p(mem_buf));
515         return 4;
516     }
517     if (n == 33) {
518         ppc_maybe_bswap_register(env, mem_buf, 4);
519         env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
520         return 4;
521     }
522     return 0;
523 }
524 
525 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
526 {
527     if (n < 32) {
528 #if defined(TARGET_PPC64)
529         gdb_get_reg32(buf, env->gpr[n] >> 32);
530         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
531 #else
532         gdb_get_reg32(buf, env->gprh[n]);
533 #endif
534         return 4;
535     }
536     if (n == 32) {
537         gdb_get_reg64(buf, env->spe_acc);
538         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
539         return 8;
540     }
541     if (n == 33) {
542         gdb_get_reg32(buf, env->spe_fscr);
543         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
544         return 4;
545     }
546     return 0;
547 }
548 
549 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
550 {
551     if (n < 32) {
552 #if defined(TARGET_PPC64)
553         target_ulong lo = (uint32_t)env->gpr[n];
554         target_ulong hi;
555 
556         ppc_maybe_bswap_register(env, mem_buf, 4);
557 
558         hi = (target_ulong)ldl_p(mem_buf) << 32;
559         env->gpr[n] = lo | hi;
560 #else
561         env->gprh[n] = ldl_p(mem_buf);
562 #endif
563         return 4;
564     }
565     if (n == 32) {
566         ppc_maybe_bswap_register(env, mem_buf, 8);
567         env->spe_acc = ldq_p(mem_buf);
568         return 8;
569     }
570     if (n == 33) {
571         ppc_maybe_bswap_register(env, mem_buf, 4);
572         env->spe_fscr = ldl_p(mem_buf);
573         return 4;
574     }
575     return 0;
576 }
577 
578 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
579 {
580     if (n < 32) {
581         gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
582         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
583         return 8;
584     }
585     return 0;
586 }
587 
588 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
589 {
590     if (n < 32) {
591         ppc_maybe_bswap_register(env, mem_buf, 8);
592         *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
593         return 8;
594     }
595     return 0;
596 }
597 
598 gchar *ppc_gdb_arch_name(CPUState *cs)
599 {
600 #if defined(TARGET_PPC64)
601     return g_strdup("powerpc:common64");
602 #else
603     return g_strdup("powerpc:common");
604 #endif
605 }
606 
607 void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
608 {
609     if (pcc->insns_flags & PPC_FLOAT) {
610         gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
611                                  33, "power-fpu.xml", 0);
612     }
613     if (pcc->insns_flags & PPC_ALTIVEC) {
614         gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
615                                  34, "power-altivec.xml", 0);
616     }
617     if (pcc->insns_flags & PPC_SPE) {
618         gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
619                                  34, "power-spe.xml", 0);
620     }
621     if (pcc->insns_flags2 & PPC2_VSX) {
622         gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
623                                  32, "power-vsx.xml", 0);
624     }
625 #ifndef CONFIG_USER_ONLY
626     gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
627                              pcc->gdb_num_sprs, "power-spr.xml", 0);
628 #endif
629 }
630