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