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 29 static 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_MTINST, 134 CSR_MTVAL2, 135 CSR_PMPCFG0, 136 CSR_PMPCFG1, 137 CSR_PMPCFG2, 138 CSR_PMPCFG3, 139 CSR_PMPADDR0, 140 CSR_PMPADDR1, 141 CSR_PMPADDR2, 142 CSR_PMPADDR3, 143 CSR_PMPADDR4, 144 CSR_PMPADDR5, 145 CSR_PMPADDR6, 146 CSR_PMPADDR7, 147 CSR_PMPADDR8, 148 CSR_PMPADDR9, 149 CSR_PMPADDR10, 150 CSR_PMPADDR11, 151 CSR_PMPADDR12, 152 CSR_PMPADDR13, 153 CSR_PMPADDR14, 154 CSR_PMPADDR15, 155 CSR_MCYCLE, 156 CSR_MINSTRET, 157 CSR_MHPMCOUNTER3, 158 CSR_MHPMCOUNTER4, 159 CSR_MHPMCOUNTER5, 160 CSR_MHPMCOUNTER6, 161 CSR_MHPMCOUNTER7, 162 CSR_MHPMCOUNTER8, 163 CSR_MHPMCOUNTER9, 164 CSR_MHPMCOUNTER10, 165 CSR_MHPMCOUNTER11, 166 CSR_MHPMCOUNTER12, 167 CSR_MHPMCOUNTER13, 168 CSR_MHPMCOUNTER14, 169 CSR_MHPMCOUNTER15, 170 CSR_MHPMCOUNTER16, 171 CSR_MHPMCOUNTER17, 172 CSR_MHPMCOUNTER18, 173 CSR_MHPMCOUNTER19, 174 CSR_MHPMCOUNTER20, 175 CSR_MHPMCOUNTER21, 176 CSR_MHPMCOUNTER22, 177 CSR_MHPMCOUNTER23, 178 CSR_MHPMCOUNTER24, 179 CSR_MHPMCOUNTER25, 180 CSR_MHPMCOUNTER26, 181 CSR_MHPMCOUNTER27, 182 CSR_MHPMCOUNTER28, 183 CSR_MHPMCOUNTER29, 184 CSR_MHPMCOUNTER30, 185 CSR_MHPMCOUNTER31, 186 CSR_MCYCLEH, 187 CSR_MINSTRETH, 188 CSR_MHPMCOUNTER3H, 189 CSR_MHPMCOUNTER4H, 190 CSR_MHPMCOUNTER5H, 191 CSR_MHPMCOUNTER6H, 192 CSR_MHPMCOUNTER7H, 193 CSR_MHPMCOUNTER8H, 194 CSR_MHPMCOUNTER9H, 195 CSR_MHPMCOUNTER10H, 196 CSR_MHPMCOUNTER11H, 197 CSR_MHPMCOUNTER12H, 198 CSR_MHPMCOUNTER13H, 199 CSR_MHPMCOUNTER14H, 200 CSR_MHPMCOUNTER15H, 201 CSR_MHPMCOUNTER16H, 202 CSR_MHPMCOUNTER17H, 203 CSR_MHPMCOUNTER18H, 204 CSR_MHPMCOUNTER19H, 205 CSR_MHPMCOUNTER20H, 206 CSR_MHPMCOUNTER21H, 207 CSR_MHPMCOUNTER22H, 208 CSR_MHPMCOUNTER23H, 209 CSR_MHPMCOUNTER24H, 210 CSR_MHPMCOUNTER25H, 211 CSR_MHPMCOUNTER26H, 212 CSR_MHPMCOUNTER27H, 213 CSR_MHPMCOUNTER28H, 214 CSR_MHPMCOUNTER29H, 215 CSR_MHPMCOUNTER30H, 216 CSR_MHPMCOUNTER31H, 217 CSR_MHPMEVENT3, 218 CSR_MHPMEVENT4, 219 CSR_MHPMEVENT5, 220 CSR_MHPMEVENT6, 221 CSR_MHPMEVENT7, 222 CSR_MHPMEVENT8, 223 CSR_MHPMEVENT9, 224 CSR_MHPMEVENT10, 225 CSR_MHPMEVENT11, 226 CSR_MHPMEVENT12, 227 CSR_MHPMEVENT13, 228 CSR_MHPMEVENT14, 229 CSR_MHPMEVENT15, 230 CSR_MHPMEVENT16, 231 CSR_MHPMEVENT17, 232 CSR_MHPMEVENT18, 233 CSR_MHPMEVENT19, 234 CSR_MHPMEVENT20, 235 CSR_MHPMEVENT21, 236 CSR_MHPMEVENT22, 237 CSR_MHPMEVENT23, 238 CSR_MHPMEVENT24, 239 CSR_MHPMEVENT25, 240 CSR_MHPMEVENT26, 241 CSR_MHPMEVENT27, 242 CSR_MHPMEVENT28, 243 CSR_MHPMEVENT29, 244 CSR_MHPMEVENT30, 245 CSR_MHPMEVENT31, 246 CSR_TSELECT, 247 CSR_TDATA1, 248 CSR_TDATA2, 249 CSR_TDATA3, 250 CSR_DCSR, 251 CSR_DPC, 252 CSR_DSCRATCH, 253 CSR_HSTATUS, 254 CSR_HEDELEG, 255 CSR_HIDELEG, 256 CSR_HIE, 257 CSR_HCOUNTEREN, 258 CSR_HTVAL, 259 CSR_HIP, 260 CSR_HTINST, 261 CSR_HGATP, 262 CSR_MBASE, 263 CSR_MBOUND, 264 CSR_MIBASE, 265 CSR_MIBOUND, 266 CSR_MDBASE, 267 CSR_MDBOUND, 268 CSR_MUCOUNTEREN, 269 CSR_MSCOUNTEREN, 270 CSR_MHCOUNTEREN, 271 }; 272 273 int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) 274 { 275 RISCVCPU *cpu = RISCV_CPU(cs); 276 CPURISCVState *env = &cpu->env; 277 278 if (n < 32) { 279 return gdb_get_regl(mem_buf, env->gpr[n]); 280 } else if (n == 32) { 281 return gdb_get_regl(mem_buf, env->pc); 282 } 283 return 0; 284 } 285 286 int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 287 { 288 RISCVCPU *cpu = RISCV_CPU(cs); 289 CPURISCVState *env = &cpu->env; 290 291 if (n == 0) { 292 /* discard writes to x0 */ 293 return sizeof(target_ulong); 294 } else if (n < 32) { 295 env->gpr[n] = ldtul_p(mem_buf); 296 return sizeof(target_ulong); 297 } else if (n == 32) { 298 env->pc = ldtul_p(mem_buf); 299 return sizeof(target_ulong); 300 } 301 return 0; 302 } 303 304 static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) 305 { 306 if (n < 32) { 307 if (env->misa & RVD) { 308 return gdb_get_reg64(mem_buf, env->fpr[n]); 309 } 310 if (env->misa & RVF) { 311 return gdb_get_reg32(mem_buf, env->fpr[n]); 312 } 313 /* there is hole between ft11 and fflags in fpu.xml */ 314 } else if (n < 36 && n > 32) { 315 target_ulong val = 0; 316 int result; 317 /* 318 * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP 319 * register 33, so we recalculate the map index. 320 * This also works for CSR_FRM and CSR_FCSR. 321 */ 322 result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], &val, 323 0, 0); 324 if (result == 0) { 325 return gdb_get_regl(mem_buf, val); 326 } 327 } 328 return 0; 329 } 330 331 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) 332 { 333 if (n < 32) { 334 env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */ 335 return sizeof(uint64_t); 336 /* there is hole between ft11 and fflags in fpu.xml */ 337 } else if (n < 36 && n > 32) { 338 target_ulong val = ldtul_p(mem_buf); 339 int result; 340 /* 341 * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP 342 * register 33, so we recalculate the map index. 343 * This also works for CSR_FRM and CSR_FCSR. 344 */ 345 result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], NULL, 346 val, -1); 347 if (result == 0) { 348 return sizeof(target_ulong); 349 } 350 } 351 return 0; 352 } 353 354 static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n) 355 { 356 if (n < ARRAY_SIZE(csr_register_map)) { 357 target_ulong val = 0; 358 int result; 359 360 result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0); 361 if (result == 0) { 362 return gdb_get_regl(mem_buf, val); 363 } 364 } 365 return 0; 366 } 367 368 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n) 369 { 370 if (n < ARRAY_SIZE(csr_register_map)) { 371 target_ulong val = ldtul_p(mem_buf); 372 int result; 373 374 result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1); 375 if (result == 0) { 376 return sizeof(target_ulong); 377 } 378 } 379 return 0; 380 } 381 382 static int riscv_gdb_get_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) 383 { 384 if (n == 0) { 385 #ifdef CONFIG_USER_ONLY 386 return gdb_get_regl(mem_buf, 0); 387 #else 388 return gdb_get_regl(mem_buf, cs->priv); 389 #endif 390 } 391 return 0; 392 } 393 394 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) 395 { 396 if (n == 0) { 397 #ifndef CONFIG_USER_ONLY 398 cs->priv = ldtul_p(mem_buf) & 0x3; 399 if (cs->priv == PRV_H) { 400 cs->priv = PRV_S; 401 } 402 #endif 403 return sizeof(target_ulong); 404 } 405 return 0; 406 } 407 408 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) 409 { 410 RISCVCPU *cpu = RISCV_CPU(cs); 411 CPURISCVState *env = &cpu->env; 412 if (env->misa & RVD) { 413 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu, 414 36, "riscv-64bit-fpu.xml", 0); 415 } else if (env->misa & RVF) { 416 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu, 417 36, "riscv-32bit-fpu.xml", 0); 418 } 419 #if defined(TARGET_RISCV32) 420 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, 421 240, "riscv-32bit-csr.xml", 0); 422 423 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, 424 1, "riscv-32bit-virtual.xml", 0); 425 #elif defined(TARGET_RISCV64) 426 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, 427 240, "riscv-64bit-csr.xml", 0); 428 429 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, 430 1, "riscv-64bit-virtual.xml", 0); 431 #endif 432 } 433