1 /* 2 * QEMU RISC-V Native Debug Support 3 * 4 * Copyright (c) 2022 Wind River Systems, Inc. 5 * 6 * Author: 7 * Bin Meng <bin.meng@windriver.com> 8 * 9 * This provides the native debug support via the Trigger Module, as defined 10 * in the RISC-V Debug Specification: 11 * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf 12 * 13 * This program is free software; you can redistribute it and/or modify it 14 * under the terms and conditions of the GNU General Public License, 15 * version 2 or later, as published by the Free Software Foundation. 16 * 17 * This program is distributed in the hope it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 20 * more details. 21 * 22 * You should have received a copy of the GNU General Public License along with 23 * this program. If not, see <http://www.gnu.org/licenses/>. 24 */ 25 26 #include "qemu/osdep.h" 27 #include "qemu/log.h" 28 #include "qapi/error.h" 29 #include "cpu.h" 30 #include "trace.h" 31 #include "exec/exec-all.h" 32 33 /* 34 * The following M-mode trigger CSRs are implemented: 35 * 36 * - tselect 37 * - tdata1 38 * - tdata2 39 * - tdata3 40 * 41 * We don't support writable 'type' field in the tdata1 register, so there is 42 * no need to implement the "tinfo" CSR. 43 * 44 * The following triggers are implemented: 45 * 46 * Index | Type | tdata mapping | Description 47 * ------+------+------------------------+------------ 48 * 0 | 2 | tdata1, tdata2 | Address / Data Match 49 * 1 | 2 | tdata1, tdata2 | Address / Data Match 50 */ 51 52 /* tdata availability of a trigger */ 53 typedef bool tdata_avail[TDATA_NUM]; 54 55 static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = { 56 [TRIGGER_TYPE_NO_EXIST] = { false, false, false }, 57 [TRIGGER_TYPE_AD_MATCH] = { true, true, true }, 58 [TRIGGER_TYPE_INST_CNT] = { true, false, true }, 59 [TRIGGER_TYPE_INT] = { true, true, true }, 60 [TRIGGER_TYPE_EXCP] = { true, true, true }, 61 [TRIGGER_TYPE_AD_MATCH6] = { true, true, true }, 62 [TRIGGER_TYPE_EXT_SRC] = { true, false, false }, 63 [TRIGGER_TYPE_UNAVAIL] = { true, true, true } 64 }; 65 66 /* only breakpoint size 1/2/4/8 supported */ 67 static int access_size[SIZE_NUM] = { 68 [SIZE_ANY] = 0, 69 [SIZE_1B] = 1, 70 [SIZE_2B] = 2, 71 [SIZE_4B] = 4, 72 [SIZE_6B] = -1, 73 [SIZE_8B] = 8, 74 [6 ... 15] = -1, 75 }; 76 77 static inline target_ulong extract_trigger_type(CPURISCVState *env, 78 target_ulong tdata1) 79 { 80 switch (riscv_cpu_mxl(env)) { 81 case MXL_RV32: 82 return extract32(tdata1, 28, 4); 83 case MXL_RV64: 84 case MXL_RV128: 85 return extract64(tdata1, 60, 4); 86 default: 87 g_assert_not_reached(); 88 } 89 } 90 91 static inline target_ulong get_trigger_type(CPURISCVState *env, 92 target_ulong trigger_index) 93 { 94 target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol; 95 return extract_trigger_type(env, tdata1); 96 } 97 98 static inline target_ulong build_tdata1(CPURISCVState *env, 99 trigger_type_t type, 100 bool dmode, target_ulong data) 101 { 102 target_ulong tdata1; 103 104 switch (riscv_cpu_mxl(env)) { 105 case MXL_RV32: 106 tdata1 = RV32_TYPE(type) | 107 (dmode ? RV32_DMODE : 0) | 108 (data & RV32_DATA_MASK); 109 break; 110 case MXL_RV64: 111 case MXL_RV128: 112 tdata1 = RV64_TYPE(type) | 113 (dmode ? RV64_DMODE : 0) | 114 (data & RV64_DATA_MASK); 115 break; 116 default: 117 g_assert_not_reached(); 118 } 119 120 return tdata1; 121 } 122 123 bool tdata_available(CPURISCVState *env, int tdata_index) 124 { 125 int trigger_type = get_trigger_type(env, env->trigger_cur); 126 127 if (unlikely(tdata_index >= TDATA_NUM)) { 128 return false; 129 } 130 131 if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) { 132 return false; 133 } 134 135 return tdata_mapping[trigger_type][tdata_index]; 136 } 137 138 target_ulong tselect_csr_read(CPURISCVState *env) 139 { 140 return env->trigger_cur; 141 } 142 143 void tselect_csr_write(CPURISCVState *env, target_ulong val) 144 { 145 /* all target_ulong bits of tselect are implemented */ 146 env->trigger_cur = val; 147 } 148 149 static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val, 150 trigger_type_t t) 151 { 152 uint32_t type, dmode; 153 target_ulong tdata1; 154 155 switch (riscv_cpu_mxl(env)) { 156 case MXL_RV32: 157 type = extract32(val, 28, 4); 158 dmode = extract32(val, 27, 1); 159 tdata1 = RV32_TYPE(t); 160 break; 161 case MXL_RV64: 162 case MXL_RV128: 163 type = extract64(val, 60, 4); 164 dmode = extract64(val, 59, 1); 165 tdata1 = RV64_TYPE(t); 166 break; 167 default: 168 g_assert_not_reached(); 169 } 170 171 if (type != t) { 172 qemu_log_mask(LOG_GUEST_ERROR, 173 "ignoring type write to tdata1 register\n"); 174 } 175 176 if (dmode != 0) { 177 qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); 178 } 179 180 return tdata1; 181 } 182 183 static inline void warn_always_zero_bit(target_ulong val, target_ulong mask, 184 const char *msg) 185 { 186 if (val & mask) { 187 qemu_log_mask(LOG_UNIMP, "%s bit is always zero\n", msg); 188 } 189 } 190 191 static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl) 192 { 193 uint32_t size, sizelo, sizehi = 0; 194 195 if (riscv_cpu_mxl(env) == MXL_RV64) { 196 sizehi = extract32(ctrl, 21, 2); 197 } 198 sizelo = extract32(ctrl, 16, 2); 199 size = (sizehi << 2) | sizelo; 200 201 return size; 202 } 203 204 static inline bool type2_breakpoint_enabled(target_ulong ctrl) 205 { 206 bool mode = !!(ctrl & (TYPE2_U | TYPE2_S | TYPE2_M)); 207 bool rwx = !!(ctrl & (TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); 208 209 return mode && rwx; 210 } 211 212 static target_ulong type2_mcontrol_validate(CPURISCVState *env, 213 target_ulong ctrl) 214 { 215 target_ulong val; 216 uint32_t size; 217 218 /* validate the generic part first */ 219 val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH); 220 221 /* validate unimplemented (always zero) bits */ 222 warn_always_zero_bit(ctrl, TYPE2_MATCH, "match"); 223 warn_always_zero_bit(ctrl, TYPE2_CHAIN, "chain"); 224 warn_always_zero_bit(ctrl, TYPE2_ACTION, "action"); 225 warn_always_zero_bit(ctrl, TYPE2_TIMING, "timing"); 226 warn_always_zero_bit(ctrl, TYPE2_SELECT, "select"); 227 warn_always_zero_bit(ctrl, TYPE2_HIT, "hit"); 228 229 /* validate size encoding */ 230 size = type2_breakpoint_size(env, ctrl); 231 if (access_size[size] == -1) { 232 qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n", 233 size); 234 } else { 235 val |= (ctrl & TYPE2_SIZELO); 236 if (riscv_cpu_mxl(env) == MXL_RV64) { 237 val |= (ctrl & TYPE2_SIZEHI); 238 } 239 } 240 241 /* keep the mode and attribute bits */ 242 val |= (ctrl & (TYPE2_U | TYPE2_S | TYPE2_M | 243 TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); 244 245 return val; 246 } 247 248 static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index) 249 { 250 target_ulong ctrl = env->type2_trig[index].mcontrol; 251 target_ulong addr = env->type2_trig[index].maddress; 252 bool enabled = type2_breakpoint_enabled(ctrl); 253 CPUState *cs = env_cpu(env); 254 int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; 255 uint32_t size; 256 257 if (!enabled) { 258 return; 259 } 260 261 if (ctrl & TYPE2_EXEC) { 262 cpu_breakpoint_insert(cs, addr, flags, &env->type2_trig[index].bp); 263 } 264 265 if (ctrl & TYPE2_LOAD) { 266 flags |= BP_MEM_READ; 267 } 268 if (ctrl & TYPE2_STORE) { 269 flags |= BP_MEM_WRITE; 270 } 271 272 if (flags & BP_MEM_ACCESS) { 273 size = type2_breakpoint_size(env, ctrl); 274 if (size != 0) { 275 cpu_watchpoint_insert(cs, addr, size, flags, 276 &env->type2_trig[index].wp); 277 } else { 278 cpu_watchpoint_insert(cs, addr, 8, flags, 279 &env->type2_trig[index].wp); 280 } 281 } 282 } 283 284 static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index) 285 { 286 CPUState *cs = env_cpu(env); 287 288 if (env->type2_trig[index].bp) { 289 cpu_breakpoint_remove_by_ref(cs, env->type2_trig[index].bp); 290 env->type2_trig[index].bp = NULL; 291 } 292 293 if (env->type2_trig[index].wp) { 294 cpu_watchpoint_remove_by_ref(cs, env->type2_trig[index].wp); 295 env->type2_trig[index].wp = NULL; 296 } 297 } 298 299 static target_ulong type2_reg_read(CPURISCVState *env, 300 target_ulong index, int tdata_index) 301 { 302 target_ulong tdata; 303 304 switch (tdata_index) { 305 case TDATA1: 306 tdata = env->type2_trig[index].mcontrol; 307 break; 308 case TDATA2: 309 tdata = env->type2_trig[index].maddress; 310 break; 311 default: 312 g_assert_not_reached(); 313 } 314 315 return tdata; 316 } 317 318 static void type2_reg_write(CPURISCVState *env, target_ulong index, 319 int tdata_index, target_ulong val) 320 { 321 target_ulong new_val; 322 323 switch (tdata_index) { 324 case TDATA1: 325 new_val = type2_mcontrol_validate(env, val); 326 if (new_val != env->type2_trig[index].mcontrol) { 327 env->type2_trig[index].mcontrol = new_val; 328 type2_breakpoint_remove(env, index); 329 type2_breakpoint_insert(env, index); 330 } 331 break; 332 case TDATA2: 333 if (val != env->type2_trig[index].maddress) { 334 env->type2_trig[index].maddress = val; 335 type2_breakpoint_remove(env, index); 336 type2_breakpoint_insert(env, index); 337 } 338 break; 339 default: 340 g_assert_not_reached(); 341 } 342 343 return; 344 } 345 346 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index) 347 { 348 int trigger_type = get_trigger_type(env, env->trigger_cur); 349 350 switch (trigger_type) { 351 case TRIGGER_TYPE_AD_MATCH: 352 return type2_reg_read(env, env->trigger_cur, tdata_index); 353 break; 354 case TRIGGER_TYPE_INST_CNT: 355 case TRIGGER_TYPE_INT: 356 case TRIGGER_TYPE_EXCP: 357 case TRIGGER_TYPE_AD_MATCH6: 358 case TRIGGER_TYPE_EXT_SRC: 359 qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", 360 trigger_type); 361 break; 362 case TRIGGER_TYPE_NO_EXIST: 363 case TRIGGER_TYPE_UNAVAIL: 364 qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n", 365 trigger_type); 366 break; 367 default: 368 g_assert_not_reached(); 369 } 370 371 return 0; 372 } 373 374 void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val) 375 { 376 int trigger_type; 377 378 if (tdata_index == TDATA1) { 379 trigger_type = extract_trigger_type(env, val); 380 } else { 381 trigger_type = get_trigger_type(env, env->trigger_cur); 382 } 383 384 switch (trigger_type) { 385 case TRIGGER_TYPE_AD_MATCH: 386 type2_reg_write(env, env->trigger_cur, tdata_index, val); 387 break; 388 case TRIGGER_TYPE_INST_CNT: 389 case TRIGGER_TYPE_INT: 390 case TRIGGER_TYPE_EXCP: 391 case TRIGGER_TYPE_AD_MATCH6: 392 case TRIGGER_TYPE_EXT_SRC: 393 qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", 394 trigger_type); 395 break; 396 case TRIGGER_TYPE_NO_EXIST: 397 case TRIGGER_TYPE_UNAVAIL: 398 qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n", 399 trigger_type); 400 break; 401 default: 402 g_assert_not_reached(); 403 } 404 } 405 406 void riscv_cpu_debug_excp_handler(CPUState *cs) 407 { 408 RISCVCPU *cpu = RISCV_CPU(cs); 409 CPURISCVState *env = &cpu->env; 410 411 if (cs->watchpoint_hit) { 412 if (cs->watchpoint_hit->flags & BP_CPU) { 413 cs->watchpoint_hit = NULL; 414 riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0); 415 } 416 } else { 417 if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { 418 riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0); 419 } 420 } 421 } 422 423 bool riscv_cpu_debug_check_breakpoint(CPUState *cs) 424 { 425 RISCVCPU *cpu = RISCV_CPU(cs); 426 CPURISCVState *env = &cpu->env; 427 CPUBreakpoint *bp; 428 target_ulong ctrl; 429 target_ulong pc; 430 int trigger_type; 431 int i; 432 433 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { 434 for (i = 0; i < RV_MAX_TRIGGERS; i++) { 435 trigger_type = get_trigger_type(env, i); 436 437 switch (trigger_type) { 438 case TRIGGER_TYPE_AD_MATCH: 439 ctrl = env->type2_trig[i].mcontrol; 440 pc = env->type2_trig[i].maddress; 441 442 if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { 443 /* check U/S/M bit against current privilege level */ 444 if ((ctrl >> 3) & BIT(env->priv)) { 445 return true; 446 } 447 } 448 break; 449 default: 450 /* other trigger types are not supported or irrelevant */ 451 break; 452 } 453 } 454 } 455 456 return false; 457 } 458 459 bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) 460 { 461 RISCVCPU *cpu = RISCV_CPU(cs); 462 CPURISCVState *env = &cpu->env; 463 target_ulong ctrl; 464 target_ulong addr; 465 int trigger_type; 466 int flags; 467 int i; 468 469 for (i = 0; i < RV_MAX_TRIGGERS; i++) { 470 trigger_type = get_trigger_type(env, i); 471 472 switch (trigger_type) { 473 case TRIGGER_TYPE_AD_MATCH: 474 ctrl = env->type2_trig[i].mcontrol; 475 addr = env->type2_trig[i].maddress; 476 flags = 0; 477 478 if (ctrl & TYPE2_LOAD) { 479 flags |= BP_MEM_READ; 480 } 481 if (ctrl & TYPE2_STORE) { 482 flags |= BP_MEM_WRITE; 483 } 484 485 if ((wp->flags & flags) && (wp->vaddr == addr)) { 486 /* check U/S/M bit against current privilege level */ 487 if ((ctrl >> 3) & BIT(env->priv)) { 488 return true; 489 } 490 } 491 break; 492 default: 493 /* other trigger types are not supported */ 494 break; 495 } 496 } 497 498 return false; 499 } 500 501 void riscv_trigger_init(CPURISCVState *env) 502 { 503 target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0); 504 int i; 505 506 /* init to type 2 triggers */ 507 for (i = 0; i < RV_MAX_TRIGGERS; i++) { 508 /* 509 * type = TRIGGER_TYPE_AD_MATCH 510 * dmode = 0 (both debug and M-mode can write tdata) 511 * maskmax = 0 (unimplemented, always 0) 512 * sizehi = 0 (match against any size, RV64 only) 513 * hit = 0 (unimplemented, always 0) 514 * select = 0 (always 0, perform match on address) 515 * timing = 0 (always 0, trigger before instruction) 516 * sizelo = 0 (match against any size) 517 * action = 0 (always 0, raise a breakpoint exception) 518 * chain = 0 (unimplemented, always 0) 519 * match = 0 (always 0, when any compare value equals tdata2) 520 */ 521 env->type2_trig[i].mcontrol = tdata1; 522 env->type2_trig[i].maddress = 0; 523 env->type2_trig[i].bp = NULL; 524 env->type2_trig[i].wp = NULL; 525 } 526 } 527