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