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