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_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 272 int 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 285 int 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 303 static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) 304 { 305 if (n < 32) { 306 if (env->misa & RVD) { 307 return gdb_get_reg64(mem_buf, env->fpr[n]); 308 } 309 if (env->misa & RVF) { 310 return gdb_get_reg32(mem_buf, env->fpr[n]); 311 } 312 /* there is hole between ft11 and fflags in fpu.xml */ 313 } else if (n < 36 && n > 32) { 314 target_ulong val = 0; 315 int result; 316 /* 317 * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP 318 * register 33, so we recalculate the map index. 319 * This also works for CSR_FRM and CSR_FCSR. 320 */ 321 result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], &val, 322 0, 0); 323 if (result == 0) { 324 return gdb_get_regl(mem_buf, val); 325 } 326 } 327 return 0; 328 } 329 330 static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) 331 { 332 if (n < 32) { 333 env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */ 334 return sizeof(uint64_t); 335 /* there is hole between ft11 and fflags in fpu.xml */ 336 } else if (n < 36 && n > 32) { 337 target_ulong val = ldtul_p(mem_buf); 338 int result; 339 /* 340 * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP 341 * register 33, so we recalculate the map index. 342 * This also works for CSR_FRM and CSR_FCSR. 343 */ 344 result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], NULL, 345 val, -1); 346 if (result == 0) { 347 return sizeof(target_ulong); 348 } 349 } 350 return 0; 351 } 352 353 static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n) 354 { 355 if (n < ARRAY_SIZE(csr_register_map)) { 356 target_ulong val = 0; 357 int result; 358 359 result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0); 360 if (result == 0) { 361 return gdb_get_regl(mem_buf, val); 362 } 363 } 364 return 0; 365 } 366 367 static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n) 368 { 369 if (n < ARRAY_SIZE(csr_register_map)) { 370 target_ulong val = ldtul_p(mem_buf); 371 int result; 372 373 result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1); 374 if (result == 0) { 375 return sizeof(target_ulong); 376 } 377 } 378 return 0; 379 } 380 381 static int riscv_gdb_get_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) 382 { 383 if (n == 0) { 384 #ifdef CONFIG_USER_ONLY 385 return gdb_get_regl(mem_buf, 0); 386 #else 387 return gdb_get_regl(mem_buf, cs->priv); 388 #endif 389 } 390 return 0; 391 } 392 393 static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) 394 { 395 if (n == 0) { 396 #ifndef CONFIG_USER_ONLY 397 cs->priv = ldtul_p(mem_buf) & 0x3; 398 if (cs->priv == PRV_H) { 399 cs->priv = PRV_S; 400 } 401 #endif 402 return sizeof(target_ulong); 403 } 404 return 0; 405 } 406 407 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) 408 { 409 RISCVCPU *cpu = RISCV_CPU(cs); 410 CPURISCVState *env = &cpu->env; 411 if (env->misa & RVD) { 412 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu, 413 36, "riscv-64bit-fpu.xml", 0); 414 } else if (env->misa & RVF) { 415 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu, 416 36, "riscv-32bit-fpu.xml", 0); 417 } 418 #if defined(TARGET_RISCV32) 419 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, 420 240, "riscv-32bit-csr.xml", 0); 421 422 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, 423 1, "riscv-32bit-virtual.xml", 0); 424 #elif defined(TARGET_RISCV64) 425 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, 426 240, "riscv-64bit-csr.xml", 0); 427 428 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, 429 1, "riscv-64bit-virtual.xml", 0); 430 #endif 431 } 432