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
  23/*
  24 * The GDB CSR xml files list them in documentation order, not numerical order,
  25 * and are missing entries for unnamed CSRs.  So we need to map the gdb numbers
  26 * to the hardware numbers.
  27 */
  28
  29static int csr_register_map[] = {
  30    CSR_USTATUS,
  31    CSR_UIE,
  32    CSR_UTVEC,
  33    CSR_USCRATCH,
  34    CSR_UEPC,
  35    CSR_UCAUSE,
  36    CSR_UTVAL,
  37    CSR_UIP,
  38    CSR_FFLAGS,
  39    CSR_FRM,
  40    CSR_FCSR,
  41    CSR_CYCLE,
  42    CSR_TIME,
  43    CSR_INSTRET,
  44    CSR_HPMCOUNTER3,
  45    CSR_HPMCOUNTER4,
  46    CSR_HPMCOUNTER5,
  47    CSR_HPMCOUNTER6,
  48    CSR_HPMCOUNTER7,
  49    CSR_HPMCOUNTER8,
  50    CSR_HPMCOUNTER9,
  51    CSR_HPMCOUNTER10,
  52    CSR_HPMCOUNTER11,
  53    CSR_HPMCOUNTER12,
  54    CSR_HPMCOUNTER13,
  55    CSR_HPMCOUNTER14,
  56    CSR_HPMCOUNTER15,
  57    CSR_HPMCOUNTER16,
  58    CSR_HPMCOUNTER17,
  59    CSR_HPMCOUNTER18,
  60    CSR_HPMCOUNTER19,
  61    CSR_HPMCOUNTER20,
  62    CSR_HPMCOUNTER21,
  63    CSR_HPMCOUNTER22,
  64    CSR_HPMCOUNTER23,
  65    CSR_HPMCOUNTER24,
  66    CSR_HPMCOUNTER25,
  67    CSR_HPMCOUNTER26,
  68    CSR_HPMCOUNTER27,
  69    CSR_HPMCOUNTER28,
  70    CSR_HPMCOUNTER29,
  71    CSR_HPMCOUNTER30,
  72    CSR_HPMCOUNTER31,
  73    CSR_CYCLEH,
  74    CSR_TIMEH,
  75    CSR_INSTRETH,
  76    CSR_HPMCOUNTER3H,
  77    CSR_HPMCOUNTER4H,
  78    CSR_HPMCOUNTER5H,
  79    CSR_HPMCOUNTER6H,
  80    CSR_HPMCOUNTER7H,
  81    CSR_HPMCOUNTER8H,
  82    CSR_HPMCOUNTER9H,
  83    CSR_HPMCOUNTER10H,
  84    CSR_HPMCOUNTER11H,
  85    CSR_HPMCOUNTER12H,
  86    CSR_HPMCOUNTER13H,
  87    CSR_HPMCOUNTER14H,
  88    CSR_HPMCOUNTER15H,
  89    CSR_HPMCOUNTER16H,
  90    CSR_HPMCOUNTER17H,
  91    CSR_HPMCOUNTER18H,
  92    CSR_HPMCOUNTER19H,
  93    CSR_HPMCOUNTER20H,
  94    CSR_HPMCOUNTER21H,
  95    CSR_HPMCOUNTER22H,
  96    CSR_HPMCOUNTER23H,
  97    CSR_HPMCOUNTER24H,
  98    CSR_HPMCOUNTER25H,
  99    CSR_HPMCOUNTER26H,
 100    CSR_HPMCOUNTER27H,
 101    CSR_HPMCOUNTER28H,
 102    CSR_HPMCOUNTER29H,
 103    CSR_HPMCOUNTER30H,
 104    CSR_HPMCOUNTER31H,
 105    CSR_SSTATUS,
 106    CSR_SEDELEG,
 107    CSR_SIDELEG,
 108    CSR_SIE,
 109    CSR_STVEC,
 110    CSR_SCOUNTEREN,
 111    CSR_SSCRATCH,
 112    CSR_SEPC,
 113    CSR_SCAUSE,
 114    CSR_STVAL,
 115    CSR_SIP,
 116    CSR_SATP,
 117    CSR_MVENDORID,
 118    CSR_MARCHID,
 119    CSR_MIMPID,
 120    CSR_MHARTID,
 121    CSR_MSTATUS,
 122    CSR_MISA,
 123    CSR_MEDELEG,
 124    CSR_MIDELEG,
 125    CSR_MIE,
 126    CSR_MTVEC,
 127    CSR_MCOUNTEREN,
 128    CSR_MSCRATCH,
 129    CSR_MEPC,
 130    CSR_MCAUSE,
 131    CSR_MTVAL,
 132    CSR_MIP,
 133    CSR_PMPCFG0,
 134    CSR_PMPCFG1,
 135    CSR_PMPCFG2,
 136    CSR_PMPCFG3,
 137    CSR_PMPADDR0,
 138    CSR_PMPADDR1,
 139    CSR_PMPADDR2,
 140    CSR_PMPADDR3,
 141    CSR_PMPADDR4,
 142    CSR_PMPADDR5,
 143    CSR_PMPADDR6,
 144    CSR_PMPADDR7,
 145    CSR_PMPADDR8,
 146    CSR_PMPADDR9,
 147    CSR_PMPADDR10,
 148    CSR_PMPADDR11,
 149    CSR_PMPADDR12,
 150    CSR_PMPADDR13,
 151    CSR_PMPADDR14,
 152    CSR_PMPADDR15,
 153    CSR_MCYCLE,
 154    CSR_MINSTRET,
 155    CSR_MHPMCOUNTER3,
 156    CSR_MHPMCOUNTER4,
 157    CSR_MHPMCOUNTER5,
 158    CSR_MHPMCOUNTER6,
 159    CSR_MHPMCOUNTER7,
 160    CSR_MHPMCOUNTER8,
 161    CSR_MHPMCOUNTER9,
 162    CSR_MHPMCOUNTER10,
 163    CSR_MHPMCOUNTER11,
 164    CSR_MHPMCOUNTER12,
 165    CSR_MHPMCOUNTER13,
 166    CSR_MHPMCOUNTER14,
 167    CSR_MHPMCOUNTER15,
 168    CSR_MHPMCOUNTER16,
 169    CSR_MHPMCOUNTER17,
 170    CSR_MHPMCOUNTER18,
 171    CSR_MHPMCOUNTER19,
 172    CSR_MHPMCOUNTER20,
 173    CSR_MHPMCOUNTER21,
 174    CSR_MHPMCOUNTER22,
 175    CSR_MHPMCOUNTER23,
 176    CSR_MHPMCOUNTER24,
 177    CSR_MHPMCOUNTER25,
 178    CSR_MHPMCOUNTER26,
 179    CSR_MHPMCOUNTER27,
 180    CSR_MHPMCOUNTER28,
 181    CSR_MHPMCOUNTER29,
 182    CSR_MHPMCOUNTER30,
 183    CSR_MHPMCOUNTER31,
 184    CSR_MCYCLEH,
 185    CSR_MINSTRETH,
 186    CSR_MHPMCOUNTER3H,
 187    CSR_MHPMCOUNTER4H,
 188    CSR_MHPMCOUNTER5H,
 189    CSR_MHPMCOUNTER6H,
 190    CSR_MHPMCOUNTER7H,
 191    CSR_MHPMCOUNTER8H,
 192    CSR_MHPMCOUNTER9H,
 193    CSR_MHPMCOUNTER10H,
 194    CSR_MHPMCOUNTER11H,
 195    CSR_MHPMCOUNTER12H,
 196    CSR_MHPMCOUNTER13H,
 197    CSR_MHPMCOUNTER14H,
 198    CSR_MHPMCOUNTER15H,
 199    CSR_MHPMCOUNTER16H,
 200    CSR_MHPMCOUNTER17H,
 201    CSR_MHPMCOUNTER18H,
 202    CSR_MHPMCOUNTER19H,
 203    CSR_MHPMCOUNTER20H,
 204    CSR_MHPMCOUNTER21H,
 205    CSR_MHPMCOUNTER22H,
 206    CSR_MHPMCOUNTER23H,
 207    CSR_MHPMCOUNTER24H,
 208    CSR_MHPMCOUNTER25H,
 209    CSR_MHPMCOUNTER26H,
 210    CSR_MHPMCOUNTER27H,
 211    CSR_MHPMCOUNTER28H,
 212    CSR_MHPMCOUNTER29H,
 213    CSR_MHPMCOUNTER30H,
 214    CSR_MHPMCOUNTER31H,
 215    CSR_MHPMEVENT3,
 216    CSR_MHPMEVENT4,
 217    CSR_MHPMEVENT5,
 218    CSR_MHPMEVENT6,
 219    CSR_MHPMEVENT7,
 220    CSR_MHPMEVENT8,
 221    CSR_MHPMEVENT9,
 222    CSR_MHPMEVENT10,
 223    CSR_MHPMEVENT11,
 224    CSR_MHPMEVENT12,
 225    CSR_MHPMEVENT13,
 226    CSR_MHPMEVENT14,
 227    CSR_MHPMEVENT15,
 228    CSR_MHPMEVENT16,
 229    CSR_MHPMEVENT17,
 230    CSR_MHPMEVENT18,
 231    CSR_MHPMEVENT19,
 232    CSR_MHPMEVENT20,
 233    CSR_MHPMEVENT21,
 234    CSR_MHPMEVENT22,
 235    CSR_MHPMEVENT23,
 236    CSR_MHPMEVENT24,
 237    CSR_MHPMEVENT25,
 238    CSR_MHPMEVENT26,
 239    CSR_MHPMEVENT27,
 240    CSR_MHPMEVENT28,
 241    CSR_MHPMEVENT29,
 242    CSR_MHPMEVENT30,
 243    CSR_MHPMEVENT31,
 244    CSR_TSELECT,
 245    CSR_TDATA1,
 246    CSR_TDATA2,
 247    CSR_TDATA3,
 248    CSR_DCSR,
 249    CSR_DPC,
 250    CSR_DSCRATCH,
 251    CSR_HSTATUS,
 252    CSR_HEDELEG,
 253    CSR_HIDELEG,
 254    CSR_HIE,
 255    CSR_HTVEC,
 256    CSR_HSCRATCH,
 257    CSR_HEPC,
 258    CSR_HCAUSE,
 259    CSR_HBADADDR,
 260    CSR_HIP,
 261    CSR_MBASE,
 262    CSR_MBOUND,
 263    CSR_MIBASE,
 264    CSR_MIBOUND,
 265    CSR_MDBASE,
 266    CSR_MDBOUND,
 267    CSR_MUCOUNTEREN,
 268    CSR_MSCOUNTEREN,
 269    CSR_MHCOUNTEREN,
 270};
 271
 272int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
 273{
 274    RISCVCPU *cpu = RISCV_CPU(cs);
 275    CPURISCVState *env = &cpu->env;
 276
 277    if (n < 32) {
 278        return gdb_get_regl(mem_buf, env->gpr[n]);
 279    } else if (n == 32) {
 280        return gdb_get_regl(mem_buf, env->pc);
 281    }
 282    return 0;
 283}
 284
 285int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 286{
 287    RISCVCPU *cpu = RISCV_CPU(cs);
 288    CPURISCVState *env = &cpu->env;
 289
 290    if (n == 0) {
 291        /* discard writes to x0 */
 292        return sizeof(target_ulong);
 293    } else if (n < 32) {
 294        env->gpr[n] = ldtul_p(mem_buf);
 295        return sizeof(target_ulong);
 296    } else if (n == 32) {
 297        env->pc = ldtul_p(mem_buf);
 298        return sizeof(target_ulong);
 299    }
 300    return 0;
 301}
 302
 303static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
 304{
 305    if (n < 32) {
 306        return gdb_get_reg64(mem_buf, env->fpr[n]);
 307    /* there is hole between ft11 and fflags in fpu.xml */
 308    } else if (n < 36 && n > 32) {
 309        target_ulong val = 0;
 310        int result;
 311        /*
 312         * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
 313         * register 33, so we recalculate the map index.
 314         * This also works for CSR_FRM and CSR_FCSR.
 315         */
 316        result = riscv_csrrw_debug(env, n - 33 +  8, &val, 0, 0);
 317        if (result == 0) {
 318            return gdb_get_regl(mem_buf, val);
 319        }
 320    }
 321    return 0;
 322}
 323
 324static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
 325{
 326    if (n < 32) {
 327        env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
 328        return sizeof(uint64_t);
 329    /* there is hole between ft11 and fflags in fpu.xml */
 330    } else if (n < 36 && n > 32) {
 331        target_ulong val = ldtul_p(mem_buf);
 332        int result;
 333        /*
 334         * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
 335         * register 33, so we recalculate the map index.
 336         * This also works for CSR_FRM and CSR_FCSR.
 337         */
 338        result = riscv_csrrw_debug(env, n - 33 + 8, NULL, val, -1);
 339        if (result == 0) {
 340            return sizeof(target_ulong);
 341        }
 342    }
 343    return 0;
 344}
 345
 346static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
 347{
 348    if (n < ARRAY_SIZE(csr_register_map)) {
 349        target_ulong val = 0;
 350        int result;
 351
 352        result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0);
 353        if (result == 0) {
 354            return gdb_get_regl(mem_buf, val);
 355        }
 356    }
 357    return 0;
 358}
 359
 360static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
 361{
 362    if (n < ARRAY_SIZE(csr_register_map)) {
 363        target_ulong val = ldtul_p(mem_buf);
 364        int result;
 365
 366        result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1);
 367        if (result == 0) {
 368            return sizeof(target_ulong);
 369        }
 370    }
 371    return 0;
 372}
 373
 374void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
 375{
 376    RISCVCPU *cpu = RISCV_CPU(cs);
 377    CPURISCVState *env = &cpu->env;
 378#if defined(TARGET_RISCV32)
 379    if (env->misa & RVF) {
 380        gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
 381                                 36, "riscv-32bit-fpu.xml", 0);
 382    }
 383
 384    gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
 385                             4096, "riscv-32bit-csr.xml", 0);
 386#elif defined(TARGET_RISCV64)
 387    if (env->misa & RVF) {
 388        gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
 389                                 36, "riscv-64bit-fpu.xml", 0);
 390    }
 391
 392    gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
 393                             4096, "riscv-64bit-csr.xml", 0);
 394#endif
 395}
 396