qemu/target/riscv/gdbstub.c
<<
>>
Prefs
   1/*
   2 * RISC-V GDB Server Stub
   3 *
   4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2 or later, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along with
  16 * this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include "qemu/osdep.h"
  20#include "exec/gdbstub.h"
  21#include "cpu.h"
  22
  23struct TypeSize {
  24    const char *gdb_type;
  25    const char *id;
  26    int size;
  27    const char suffix;
  28};
  29
  30static const struct TypeSize vec_lanes[] = {
  31    /* quads */
  32    { "uint128", "quads", 128, 'q' },
  33    /* 64 bit */
  34    { "uint64", "longs", 64, 'l' },
  35    /* 32 bit */
  36    { "uint32", "words", 32, 'w' },
  37    /* 16 bit */
  38    { "uint16", "shorts", 16, 's' },
  39    /*
  40     * TODO: currently there is no reliable way of telling
  41     * if the remote gdb actually understands ieee_half so
  42     * we don't expose it in the target description for now.
  43     * { "ieee_half", 16, 'h', 'f' },
  44     */
  45    /* bytes */
  46    { "uint8", "bytes", 8, 'b' },
  47};
  48
  49int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
  50{
  51    RISCVCPU *cpu = RISCV_CPU(cs);
  52    CPURISCVState *env = &cpu->env;
  53    target_ulong tmp;
  54
  55    if (n < 32) {
  56        tmp = env->gpr[n];
  57    } else if (n == 32) {
  58        tmp = env->pc;
  59    } else {
  60        return 0;
  61    }
  62
  63    switch (env->misa_mxl_max) {
  64    case MXL_RV32:
  65        return gdb_get_reg32(mem_buf, tmp);
  66    case MXL_RV64:
  67    case MXL_RV128:
  68        return gdb_get_reg64(mem_buf, tmp);
  69    default:
  70        g_assert_not_reached();
  71    }
  72    return 0;
  73}
  74
  75int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
  76{
  77    RISCVCPU *cpu = RISCV_CPU(cs);
  78    CPURISCVState *env = &cpu->env;
  79    int length = 0;
  80    target_ulong tmp;
  81
  82    switch (env->misa_mxl_max) {
  83    case MXL_RV32:
  84        tmp = (int32_t)ldl_p(mem_buf);
  85        length = 4;
  86        break;
  87    case MXL_RV64:
  88    case MXL_RV128:
  89        if (env->xl < MXL_RV64) {
  90            tmp = (int32_t)ldq_p(mem_buf);
  91        } else {
  92            tmp = ldq_p(mem_buf);
  93        }
  94        length = 8;
  95        break;
  96    default:
  97        g_assert_not_reached();
  98    }
  99    if (n > 0 && n < 32) {
 100        env->gpr[n] = tmp;
 101    } else if (n == 32) {
 102        env->pc = tmp;
 103    }
 104
 105    return length;
 106}
 107
 108static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
 109{
 110    if (n < 32) {
 111        if (env->misa_ext & RVD) {
 112            return gdb_get_reg64(buf, env->fpr[n]);
 113        }
 114        if (env->misa_ext & RVF) {
 115            return gdb_get_reg32(buf, env->fpr[n]);
 116        }
 117    }
 118    return 0;
 119}
 120
 121static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
 122{
 123    if (n < 32) {
 124        env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
 125        return sizeof(uint64_t);
 126    }
 127    return 0;
 128}
 129
 130/*
 131 * Convert register index number passed by GDB to the correspond
 132 * vector CSR number. Vector CSRs are defined after vector registers
 133 * in dynamic generated riscv-vector.xml, thus the starting register index
 134 * of vector CSRs is 32.
 135 * Return 0 if register index number is out of range.
 136 */
 137static int riscv_gdb_vector_csrno(int num_regs)
 138{
 139    /*
 140     * The order of vector CSRs in the switch case
 141     * should match with the order defined in csr_ops[].
 142     */
 143    switch (num_regs) {
 144    case 32:
 145        return CSR_VSTART;
 146    case 33:
 147        return CSR_VXSAT;
 148    case 34:
 149        return CSR_VXRM;
 150    case 35:
 151        return CSR_VCSR;
 152    case 36:
 153        return CSR_VL;
 154    case 37:
 155        return CSR_VTYPE;
 156    case 38:
 157        return CSR_VLENB;
 158    default:
 159        /* Unknown register. */
 160        return 0;
 161    }
 162}
 163
 164static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
 165{
 166    uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
 167    if (n < 32) {
 168        int i;
 169        int cnt = 0;
 170        for (i = 0; i < vlenb; i += 8) {
 171            cnt += gdb_get_reg64(buf,
 172                                 env->vreg[(n * vlenb + i) / 8]);
 173        }
 174        return cnt;
 175    }
 176
 177    int csrno = riscv_gdb_vector_csrno(n);
 178
 179    if (!csrno) {
 180        return 0;
 181    }
 182
 183    target_ulong val = 0;
 184    int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
 185
 186    if (result == RISCV_EXCP_NONE) {
 187        return gdb_get_regl(buf, val);
 188    }
 189
 190    return 0;
 191}
 192
 193static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
 194{
 195    uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
 196    if (n < 32) {
 197        int i;
 198        for (i = 0; i < vlenb; i += 8) {
 199            env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
 200        }
 201        return vlenb;
 202    }
 203
 204    int csrno = riscv_gdb_vector_csrno(n);
 205
 206    if (!csrno) {
 207        return 0;
 208    }
 209
 210    target_ulong val = ldtul_p(mem_buf);
 211    int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
 212
 213    if (result == RISCV_EXCP_NONE) {
 214        return sizeof(target_ulong);
 215    }
 216
 217    return 0;
 218}
 219
 220static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
 221{
 222    if (n < CSR_TABLE_SIZE) {
 223        target_ulong val = 0;
 224        int result;
 225
 226        result = riscv_csrrw_debug(env, n, &val, 0, 0);
 227        if (result == RISCV_EXCP_NONE) {
 228            return gdb_get_regl(buf, val);
 229        }
 230    }
 231    return 0;
 232}
 233
 234static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
 235{
 236    if (n < CSR_TABLE_SIZE) {
 237        target_ulong val = ldtul_p(mem_buf);
 238        int result;
 239
 240        result = riscv_csrrw_debug(env, n, NULL, val, -1);
 241        if (result == RISCV_EXCP_NONE) {
 242            return sizeof(target_ulong);
 243        }
 244    }
 245    return 0;
 246}
 247
 248static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n)
 249{
 250    if (n == 0) {
 251#ifdef CONFIG_USER_ONLY
 252        return gdb_get_regl(buf, 0);
 253#else
 254        return gdb_get_regl(buf, cs->priv);
 255#endif
 256    }
 257    return 0;
 258}
 259
 260static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
 261{
 262    if (n == 0) {
 263#ifndef CONFIG_USER_ONLY
 264        cs->priv = ldtul_p(mem_buf) & 0x3;
 265        if (cs->priv == PRV_H) {
 266            cs->priv = PRV_S;
 267        }
 268#endif
 269        return sizeof(target_ulong);
 270    }
 271    return 0;
 272}
 273
 274static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
 275{
 276    RISCVCPU *cpu = RISCV_CPU(cs);
 277    CPURISCVState *env = &cpu->env;
 278    GString *s = g_string_new(NULL);
 279    riscv_csr_predicate_fn predicate;
 280    int bitsize = 16 << env->misa_mxl_max;
 281    int i;
 282
 283    /* Until gdb knows about 128-bit registers */
 284    if (bitsize > 64) {
 285        bitsize = 64;
 286    }
 287
 288    g_string_printf(s, "<?xml version=\"1.0\"?>");
 289    g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
 290    g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
 291
 292    for (i = 0; i < CSR_TABLE_SIZE; i++) {
 293        predicate = csr_ops[i].predicate;
 294        if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
 295            if (csr_ops[i].name) {
 296                g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
 297            } else {
 298                g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
 299            }
 300            g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
 301            g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
 302        }
 303    }
 304
 305    g_string_append_printf(s, "</feature>");
 306
 307    cpu->dyn_csr_xml = g_string_free(s, false);
 308    return CSR_TABLE_SIZE;
 309}
 310
 311static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
 312{
 313    RISCVCPU *cpu = RISCV_CPU(cs);
 314    GString *s = g_string_new(NULL);
 315    g_autoptr(GString) ts = g_string_new("");
 316    int reg_width = cpu->cfg.vlen;
 317    int num_regs = 0;
 318    int i;
 319
 320    g_string_printf(s, "<?xml version=\"1.0\"?>");
 321    g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
 322    g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.vector\">");
 323
 324    /* First define types and totals in a whole VL */
 325    for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
 326        int count = reg_width / vec_lanes[i].size;
 327        g_string_printf(ts, "%s", vec_lanes[i].id);
 328        g_string_append_printf(s,
 329                               "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
 330                               ts->str, vec_lanes[i].gdb_type, count);
 331    }
 332
 333    /* Define unions */
 334    g_string_append_printf(s, "<union id=\"riscv_vector\">");
 335    for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
 336        g_string_append_printf(s, "<field name=\"%c\" type=\"%s\"/>",
 337                               vec_lanes[i].suffix,
 338                               vec_lanes[i].id);
 339    }
 340    g_string_append(s, "</union>");
 341
 342    /* Define vector registers */
 343    for (i = 0; i < 32; i++) {
 344        g_string_append_printf(s,
 345                               "<reg name=\"v%d\" bitsize=\"%d\""
 346                               " regnum=\"%d\" group=\"vector\""
 347                               " type=\"riscv_vector\"/>",
 348                               i, reg_width, base_reg++);
 349        num_regs++;
 350    }
 351
 352    /* Define vector CSRs */
 353    const char *vector_csrs[7] = {
 354        "vstart", "vxsat", "vxrm", "vcsr",
 355        "vl", "vtype", "vlenb"
 356    };
 357
 358    for (i = 0; i < 7; i++) {
 359        g_string_append_printf(s,
 360                               "<reg name=\"%s\" bitsize=\"%d\""
 361                               " regnum=\"%d\" group=\"vector\""
 362                               " type=\"int\"/>",
 363                               vector_csrs[i], TARGET_LONG_BITS, base_reg++);
 364        num_regs++;
 365    }
 366
 367    g_string_append_printf(s, "</feature>");
 368
 369    cpu->dyn_vreg_xml = g_string_free(s, false);
 370    return num_regs;
 371}
 372
 373void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
 374{
 375    RISCVCPU *cpu = RISCV_CPU(cs);
 376    CPURISCVState *env = &cpu->env;
 377    if (env->misa_ext & RVD) {
 378        gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
 379                                 32, "riscv-64bit-fpu.xml", 0);
 380    } else if (env->misa_ext & RVF) {
 381        gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
 382                                 32, "riscv-32bit-fpu.xml", 0);
 383    }
 384    if (env->misa_ext & RVV) {
 385        gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector,
 386                                 ricsv_gen_dynamic_vector_xml(cs,
 387                                                              cs->gdb_num_regs),
 388                                 "riscv-vector.xml", 0);
 389    }
 390    switch (env->misa_mxl_max) {
 391    case MXL_RV32:
 392        gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
 393                                 riscv_gdb_set_virtual,
 394                                 1, "riscv-32bit-virtual.xml", 0);
 395        break;
 396    case MXL_RV64:
 397    case MXL_RV128:
 398        gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
 399                                 riscv_gdb_set_virtual,
 400                                 1, "riscv-64bit-virtual.xml", 0);
 401        break;
 402    default:
 403        g_assert_not_reached();
 404    }
 405
 406    gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
 407                             riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
 408                             "riscv-csr.xml", 0);
 409}
 410