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 return extract_trigger_type(env, env->tdata1[trigger_index]); 95 } 96 97 static inline target_ulong build_tdata1(CPURISCVState *env, 98 trigger_type_t type, 99 bool dmode, target_ulong data) 100 { 101 target_ulong tdata1; 102 103 switch (riscv_cpu_mxl(env)) { 104 case MXL_RV32: 105 tdata1 = RV32_TYPE(type) | 106 (dmode ? RV32_DMODE : 0) | 107 (data & RV32_DATA_MASK); 108 break; 109 case MXL_RV64: 110 case MXL_RV128: 111 tdata1 = RV64_TYPE(type) | 112 (dmode ? RV64_DMODE : 0) | 113 (data & RV64_DATA_MASK); 114 break; 115 default: 116 g_assert_not_reached(); 117 } 118 119 return tdata1; 120 } 121 122 bool tdata_available(CPURISCVState *env, int tdata_index) 123 { 124 int trigger_type = get_trigger_type(env, env->trigger_cur); 125 126 if (unlikely(tdata_index >= TDATA_NUM)) { 127 return false; 128 } 129 130 if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) { 131 return false; 132 } 133 134 return tdata_mapping[trigger_type][tdata_index]; 135 } 136 137 target_ulong tselect_csr_read(CPURISCVState *env) 138 { 139 return env->trigger_cur; 140 } 141 142 void tselect_csr_write(CPURISCVState *env, target_ulong val) 143 { 144 /* all target_ulong bits of tselect are implemented */ 145 env->trigger_cur = val; 146 } 147 148 static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val, 149 trigger_type_t t) 150 { 151 uint32_t type, dmode; 152 target_ulong tdata1; 153 154 switch (riscv_cpu_mxl(env)) { 155 case MXL_RV32: 156 type = extract32(val, 28, 4); 157 dmode = extract32(val, 27, 1); 158 tdata1 = RV32_TYPE(t); 159 break; 160 case MXL_RV64: 161 case MXL_RV128: 162 type = extract64(val, 60, 4); 163 dmode = extract64(val, 59, 1); 164 tdata1 = RV64_TYPE(t); 165 break; 166 default: 167 g_assert_not_reached(); 168 } 169 170 if (type != t) { 171 qemu_log_mask(LOG_GUEST_ERROR, 172 "ignoring type write to tdata1 register\n"); 173 } 174 175 if (dmode != 0) { 176 qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); 177 } 178 179 return tdata1; 180 } 181 182 static inline void warn_always_zero_bit(target_ulong val, target_ulong mask, 183 const char *msg) 184 { 185 if (val & mask) { 186 qemu_log_mask(LOG_UNIMP, "%s bit is always zero\n", msg); 187 } 188 } 189 190 /* type 2 trigger */ 191 192 static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl) 193 { 194 uint32_t size, sizelo, sizehi = 0; 195 196 if (riscv_cpu_mxl(env) == MXL_RV64) { 197 sizehi = extract32(ctrl, 21, 2); 198 } 199 sizelo = extract32(ctrl, 16, 2); 200 size = (sizehi << 2) | sizelo; 201 202 return size; 203 } 204 205 static inline bool type2_breakpoint_enabled(target_ulong ctrl) 206 { 207 bool mode = !!(ctrl & (TYPE2_U | TYPE2_S | TYPE2_M)); 208 bool rwx = !!(ctrl & (TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); 209 210 return mode && rwx; 211 } 212 213 static target_ulong type2_mcontrol_validate(CPURISCVState *env, 214 target_ulong ctrl) 215 { 216 target_ulong val; 217 uint32_t size; 218 219 /* validate the generic part first */ 220 val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH); 221 222 /* validate unimplemented (always zero) bits */ 223 warn_always_zero_bit(ctrl, TYPE2_MATCH, "match"); 224 warn_always_zero_bit(ctrl, TYPE2_CHAIN, "chain"); 225 warn_always_zero_bit(ctrl, TYPE2_ACTION, "action"); 226 warn_always_zero_bit(ctrl, TYPE2_TIMING, "timing"); 227 warn_always_zero_bit(ctrl, TYPE2_SELECT, "select"); 228 warn_always_zero_bit(ctrl, TYPE2_HIT, "hit"); 229 230 /* validate size encoding */ 231 size = type2_breakpoint_size(env, ctrl); 232 if (access_size[size] == -1) { 233 qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n", 234 size); 235 } else { 236 val |= (ctrl & TYPE2_SIZELO); 237 if (riscv_cpu_mxl(env) == MXL_RV64) { 238 val |= (ctrl & TYPE2_SIZEHI); 239 } 240 } 241 242 /* keep the mode and attribute bits */ 243 val |= (ctrl & (TYPE2_U | TYPE2_S | TYPE2_M | 244 TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); 245 246 return val; 247 } 248 249 static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index) 250 { 251 target_ulong ctrl = env->tdata1[index]; 252 target_ulong addr = env->tdata2[index]; 253 bool enabled = type2_breakpoint_enabled(ctrl); 254 CPUState *cs = env_cpu(env); 255 int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; 256 uint32_t size; 257 258 if (!enabled) { 259 return; 260 } 261 262 if (ctrl & TYPE2_EXEC) { 263 cpu_breakpoint_insert(cs, addr, flags, &env->cpu_breakpoint[index]); 264 } 265 266 if (ctrl & TYPE2_LOAD) { 267 flags |= BP_MEM_READ; 268 } 269 if (ctrl & TYPE2_STORE) { 270 flags |= BP_MEM_WRITE; 271 } 272 273 if (flags & BP_MEM_ACCESS) { 274 size = type2_breakpoint_size(env, ctrl); 275 if (size != 0) { 276 cpu_watchpoint_insert(cs, addr, size, flags, 277 &env->cpu_watchpoint[index]); 278 } else { 279 cpu_watchpoint_insert(cs, addr, 8, flags, 280 &env->cpu_watchpoint[index]); 281 } 282 } 283 } 284 285 static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index) 286 { 287 CPUState *cs = env_cpu(env); 288 289 if (env->cpu_breakpoint[index]) { 290 cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]); 291 env->cpu_breakpoint[index] = NULL; 292 } 293 294 if (env->cpu_watchpoint[index]) { 295 cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]); 296 env->cpu_watchpoint[index] = NULL; 297 } 298 } 299 300 static void type2_reg_write(CPURISCVState *env, target_ulong index, 301 int tdata_index, target_ulong val) 302 { 303 target_ulong new_val; 304 305 switch (tdata_index) { 306 case TDATA1: 307 new_val = type2_mcontrol_validate(env, val); 308 if (new_val != env->tdata1[index]) { 309 env->tdata1[index] = new_val; 310 type2_breakpoint_remove(env, index); 311 type2_breakpoint_insert(env, index); 312 } 313 break; 314 case TDATA2: 315 if (val != env->tdata2[index]) { 316 env->tdata2[index] = val; 317 type2_breakpoint_remove(env, index); 318 type2_breakpoint_insert(env, index); 319 } 320 break; 321 case TDATA3: 322 qemu_log_mask(LOG_UNIMP, 323 "tdata3 is not supported for type 2 trigger\n"); 324 break; 325 default: 326 g_assert_not_reached(); 327 } 328 329 return; 330 } 331 332 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index) 333 { 334 switch (tdata_index) { 335 case TDATA1: 336 return env->tdata1[env->trigger_cur]; 337 case TDATA2: 338 return env->tdata2[env->trigger_cur]; 339 case TDATA3: 340 return env->tdata3[env->trigger_cur]; 341 default: 342 g_assert_not_reached(); 343 } 344 } 345 346 void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val) 347 { 348 int trigger_type; 349 350 if (tdata_index == TDATA1) { 351 trigger_type = extract_trigger_type(env, val); 352 } else { 353 trigger_type = get_trigger_type(env, env->trigger_cur); 354 } 355 356 switch (trigger_type) { 357 case TRIGGER_TYPE_AD_MATCH: 358 type2_reg_write(env, env->trigger_cur, tdata_index, val); 359 break; 360 case TRIGGER_TYPE_INST_CNT: 361 case TRIGGER_TYPE_INT: 362 case TRIGGER_TYPE_EXCP: 363 case TRIGGER_TYPE_AD_MATCH6: 364 case TRIGGER_TYPE_EXT_SRC: 365 qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", 366 trigger_type); 367 break; 368 case TRIGGER_TYPE_NO_EXIST: 369 case TRIGGER_TYPE_UNAVAIL: 370 qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n", 371 trigger_type); 372 break; 373 default: 374 g_assert_not_reached(); 375 } 376 } 377 378 void riscv_cpu_debug_excp_handler(CPUState *cs) 379 { 380 RISCVCPU *cpu = RISCV_CPU(cs); 381 CPURISCVState *env = &cpu->env; 382 383 if (cs->watchpoint_hit) { 384 if (cs->watchpoint_hit->flags & BP_CPU) { 385 cs->watchpoint_hit = NULL; 386 riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0); 387 } 388 } else { 389 if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { 390 riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0); 391 } 392 } 393 } 394 395 bool riscv_cpu_debug_check_breakpoint(CPUState *cs) 396 { 397 RISCVCPU *cpu = RISCV_CPU(cs); 398 CPURISCVState *env = &cpu->env; 399 CPUBreakpoint *bp; 400 target_ulong ctrl; 401 target_ulong pc; 402 int trigger_type; 403 int i; 404 405 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { 406 for (i = 0; i < RV_MAX_TRIGGERS; i++) { 407 trigger_type = get_trigger_type(env, i); 408 409 switch (trigger_type) { 410 case TRIGGER_TYPE_AD_MATCH: 411 ctrl = env->tdata1[i]; 412 pc = env->tdata2[i]; 413 414 if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { 415 /* check U/S/M bit against current privilege level */ 416 if ((ctrl >> 3) & BIT(env->priv)) { 417 return true; 418 } 419 } 420 break; 421 default: 422 /* other trigger types are not supported or irrelevant */ 423 break; 424 } 425 } 426 } 427 428 return false; 429 } 430 431 bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) 432 { 433 RISCVCPU *cpu = RISCV_CPU(cs); 434 CPURISCVState *env = &cpu->env; 435 target_ulong ctrl; 436 target_ulong addr; 437 int trigger_type; 438 int flags; 439 int i; 440 441 for (i = 0; i < RV_MAX_TRIGGERS; i++) { 442 trigger_type = get_trigger_type(env, i); 443 444 switch (trigger_type) { 445 case TRIGGER_TYPE_AD_MATCH: 446 ctrl = env->tdata1[i]; 447 addr = env->tdata2[i]; 448 flags = 0; 449 450 if (ctrl & TYPE2_LOAD) { 451 flags |= BP_MEM_READ; 452 } 453 if (ctrl & TYPE2_STORE) { 454 flags |= BP_MEM_WRITE; 455 } 456 457 if ((wp->flags & flags) && (wp->vaddr == addr)) { 458 /* check U/S/M bit against current privilege level */ 459 if ((ctrl >> 3) & BIT(env->priv)) { 460 return true; 461 } 462 } 463 break; 464 default: 465 /* other trigger types are not supported */ 466 break; 467 } 468 } 469 470 return false; 471 } 472 473 void riscv_trigger_init(CPURISCVState *env) 474 { 475 target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0); 476 int i; 477 478 /* init to type 2 triggers */ 479 for (i = 0; i < RV_MAX_TRIGGERS; i++) { 480 /* 481 * type = TRIGGER_TYPE_AD_MATCH 482 * dmode = 0 (both debug and M-mode can write tdata) 483 * maskmax = 0 (unimplemented, always 0) 484 * sizehi = 0 (match against any size, RV64 only) 485 * hit = 0 (unimplemented, always 0) 486 * select = 0 (always 0, perform match on address) 487 * timing = 0 (always 0, trigger before instruction) 488 * sizelo = 0 (match against any size) 489 * action = 0 (always 0, raise a breakpoint exception) 490 * chain = 0 (unimplemented, always 0) 491 * match = 0 (always 0, when any compare value equals tdata2) 492 */ 493 env->tdata1[i] = tdata1; 494 env->tdata2[i] = 0; 495 env->tdata3[i] = 0; 496 env->cpu_breakpoint[i] = NULL; 497 env->cpu_watchpoint[i] = NULL; 498 } 499 } 500