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