qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

gdbstub.c (16297B)


      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_BIG_ENDIAN is set to the proper ordering for the
     91  * binary, and cannot be changed.  For system mode,
     92  * TARGET_BIG_ENDIAN 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 (!FIELD_EX64(env->msr, 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 }