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