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