1*95799e36SBin Meng /* 2*95799e36SBin Meng * QEMU RISC-V Native Debug Support 3*95799e36SBin Meng * 4*95799e36SBin Meng * Copyright (c) 2022 Wind River Systems, Inc. 5*95799e36SBin Meng * 6*95799e36SBin Meng * Author: 7*95799e36SBin Meng * Bin Meng <bin.meng@windriver.com> 8*95799e36SBin Meng * 9*95799e36SBin Meng * This provides the native debug support via the Trigger Module, as defined 10*95799e36SBin Meng * in the RISC-V Debug Specification: 11*95799e36SBin Meng * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf 12*95799e36SBin Meng * 13*95799e36SBin Meng * This program is free software; you can redistribute it and/or modify it 14*95799e36SBin Meng * under the terms and conditions of the GNU General Public License, 15*95799e36SBin Meng * version 2 or later, as published by the Free Software Foundation. 16*95799e36SBin Meng * 17*95799e36SBin Meng * This program is distributed in the hope it will be useful, but WITHOUT 18*95799e36SBin Meng * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19*95799e36SBin Meng * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 20*95799e36SBin Meng * more details. 21*95799e36SBin Meng * 22*95799e36SBin Meng * You should have received a copy of the GNU General Public License along with 23*95799e36SBin Meng * this program. If not, see <http://www.gnu.org/licenses/>. 24*95799e36SBin Meng */ 25*95799e36SBin Meng 26*95799e36SBin Meng #include "qemu/osdep.h" 27*95799e36SBin Meng #include "qemu/log.h" 28*95799e36SBin Meng #include "qapi/error.h" 29*95799e36SBin Meng #include "cpu.h" 30*95799e36SBin Meng #include "trace.h" 31*95799e36SBin Meng #include "exec/exec-all.h" 32*95799e36SBin Meng 33*95799e36SBin Meng /* 34*95799e36SBin Meng * The following M-mode trigger CSRs are implemented: 35*95799e36SBin Meng * 36*95799e36SBin Meng * - tselect 37*95799e36SBin Meng * - tdata1 38*95799e36SBin Meng * - tdata2 39*95799e36SBin Meng * - tdata3 40*95799e36SBin Meng * 41*95799e36SBin Meng * We don't support writable 'type' field in the tdata1 register, so there is 42*95799e36SBin Meng * no need to implement the "tinfo" CSR. 43*95799e36SBin Meng * 44*95799e36SBin Meng * The following triggers are implemented: 45*95799e36SBin Meng * 46*95799e36SBin Meng * Index | Type | tdata mapping | Description 47*95799e36SBin Meng * ------+------+------------------------+------------ 48*95799e36SBin Meng * 0 | 2 | tdata1, tdata2 | Address / Data Match 49*95799e36SBin Meng * 1 | 2 | tdata1, tdata2 | Address / Data Match 50*95799e36SBin Meng */ 51*95799e36SBin Meng 52*95799e36SBin Meng /* tdata availability of a trigger */ 53*95799e36SBin Meng typedef bool tdata_avail[TDATA_NUM]; 54*95799e36SBin Meng 55*95799e36SBin Meng static tdata_avail tdata_mapping[TRIGGER_NUM] = { 56*95799e36SBin Meng [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false }, 57*95799e36SBin Meng }; 58*95799e36SBin Meng 59*95799e36SBin Meng /* only breakpoint size 1/2/4/8 supported */ 60*95799e36SBin Meng static int access_size[SIZE_NUM] = { 61*95799e36SBin Meng [SIZE_ANY] = 0, 62*95799e36SBin Meng [SIZE_1B] = 1, 63*95799e36SBin Meng [SIZE_2B] = 2, 64*95799e36SBin Meng [SIZE_4B] = 4, 65*95799e36SBin Meng [SIZE_6B] = -1, 66*95799e36SBin Meng [SIZE_8B] = 8, 67*95799e36SBin Meng [6 ... 15] = -1, 68*95799e36SBin Meng }; 69*95799e36SBin Meng 70*95799e36SBin Meng static inline target_ulong trigger_type(CPURISCVState *env, 71*95799e36SBin Meng trigger_type_t type) 72*95799e36SBin Meng { 73*95799e36SBin Meng target_ulong tdata1; 74*95799e36SBin Meng 75*95799e36SBin Meng switch (riscv_cpu_mxl(env)) { 76*95799e36SBin Meng case MXL_RV32: 77*95799e36SBin Meng tdata1 = RV32_TYPE(type); 78*95799e36SBin Meng break; 79*95799e36SBin Meng case MXL_RV64: 80*95799e36SBin Meng tdata1 = RV64_TYPE(type); 81*95799e36SBin Meng break; 82*95799e36SBin Meng default: 83*95799e36SBin Meng g_assert_not_reached(); 84*95799e36SBin Meng } 85*95799e36SBin Meng 86*95799e36SBin Meng return tdata1; 87*95799e36SBin Meng } 88*95799e36SBin Meng 89*95799e36SBin Meng bool tdata_available(CPURISCVState *env, int tdata_index) 90*95799e36SBin Meng { 91*95799e36SBin Meng if (unlikely(tdata_index >= TDATA_NUM)) { 92*95799e36SBin Meng return false; 93*95799e36SBin Meng } 94*95799e36SBin Meng 95*95799e36SBin Meng if (unlikely(env->trigger_cur >= TRIGGER_NUM)) { 96*95799e36SBin Meng return false; 97*95799e36SBin Meng } 98*95799e36SBin Meng 99*95799e36SBin Meng return tdata_mapping[env->trigger_cur][tdata_index]; 100*95799e36SBin Meng } 101*95799e36SBin Meng 102*95799e36SBin Meng target_ulong tselect_csr_read(CPURISCVState *env) 103*95799e36SBin Meng { 104*95799e36SBin Meng return env->trigger_cur; 105*95799e36SBin Meng } 106*95799e36SBin Meng 107*95799e36SBin Meng void tselect_csr_write(CPURISCVState *env, target_ulong val) 108*95799e36SBin Meng { 109*95799e36SBin Meng /* all target_ulong bits of tselect are implemented */ 110*95799e36SBin Meng env->trigger_cur = val; 111*95799e36SBin Meng } 112*95799e36SBin Meng 113*95799e36SBin Meng static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val, 114*95799e36SBin Meng trigger_type_t t) 115*95799e36SBin Meng { 116*95799e36SBin Meng uint32_t type, dmode; 117*95799e36SBin Meng target_ulong tdata1; 118*95799e36SBin Meng 119*95799e36SBin Meng switch (riscv_cpu_mxl(env)) { 120*95799e36SBin Meng case MXL_RV32: 121*95799e36SBin Meng type = extract32(val, 28, 4); 122*95799e36SBin Meng dmode = extract32(val, 27, 1); 123*95799e36SBin Meng tdata1 = RV32_TYPE(t); 124*95799e36SBin Meng break; 125*95799e36SBin Meng case MXL_RV64: 126*95799e36SBin Meng type = extract64(val, 60, 4); 127*95799e36SBin Meng dmode = extract64(val, 59, 1); 128*95799e36SBin Meng tdata1 = RV64_TYPE(t); 129*95799e36SBin Meng break; 130*95799e36SBin Meng default: 131*95799e36SBin Meng g_assert_not_reached(); 132*95799e36SBin Meng } 133*95799e36SBin Meng 134*95799e36SBin Meng if (type != t) { 135*95799e36SBin Meng qemu_log_mask(LOG_GUEST_ERROR, 136*95799e36SBin Meng "ignoring type write to tdata1 register\n"); 137*95799e36SBin Meng } 138*95799e36SBin Meng if (dmode != 0) { 139*95799e36SBin Meng qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); 140*95799e36SBin Meng } 141*95799e36SBin Meng 142*95799e36SBin Meng return tdata1; 143*95799e36SBin Meng } 144*95799e36SBin Meng 145*95799e36SBin Meng static inline void warn_always_zero_bit(target_ulong val, target_ulong mask, 146*95799e36SBin Meng const char *msg) 147*95799e36SBin Meng { 148*95799e36SBin Meng if (val & mask) { 149*95799e36SBin Meng qemu_log_mask(LOG_UNIMP, "%s bit is always zero\n", msg); 150*95799e36SBin Meng } 151*95799e36SBin Meng } 152*95799e36SBin Meng 153*95799e36SBin Meng static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl) 154*95799e36SBin Meng { 155*95799e36SBin Meng uint32_t size, sizelo, sizehi = 0; 156*95799e36SBin Meng 157*95799e36SBin Meng if (riscv_cpu_mxl(env) == MXL_RV64) { 158*95799e36SBin Meng sizehi = extract32(ctrl, 21, 2); 159*95799e36SBin Meng } 160*95799e36SBin Meng sizelo = extract32(ctrl, 16, 2); 161*95799e36SBin Meng size = (sizehi << 2) | sizelo; 162*95799e36SBin Meng 163*95799e36SBin Meng return size; 164*95799e36SBin Meng } 165*95799e36SBin Meng 166*95799e36SBin Meng static inline bool type2_breakpoint_enabled(target_ulong ctrl) 167*95799e36SBin Meng { 168*95799e36SBin Meng bool mode = !!(ctrl & (TYPE2_U | TYPE2_S | TYPE2_M)); 169*95799e36SBin Meng bool rwx = !!(ctrl & (TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); 170*95799e36SBin Meng 171*95799e36SBin Meng return mode && rwx; 172*95799e36SBin Meng } 173*95799e36SBin Meng 174*95799e36SBin Meng static target_ulong type2_mcontrol_validate(CPURISCVState *env, 175*95799e36SBin Meng target_ulong ctrl) 176*95799e36SBin Meng { 177*95799e36SBin Meng target_ulong val; 178*95799e36SBin Meng uint32_t size; 179*95799e36SBin Meng 180*95799e36SBin Meng /* validate the generic part first */ 181*95799e36SBin Meng val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH); 182*95799e36SBin Meng 183*95799e36SBin Meng /* validate unimplemented (always zero) bits */ 184*95799e36SBin Meng warn_always_zero_bit(ctrl, TYPE2_MATCH, "match"); 185*95799e36SBin Meng warn_always_zero_bit(ctrl, TYPE2_CHAIN, "chain"); 186*95799e36SBin Meng warn_always_zero_bit(ctrl, TYPE2_ACTION, "action"); 187*95799e36SBin Meng warn_always_zero_bit(ctrl, TYPE2_TIMING, "timing"); 188*95799e36SBin Meng warn_always_zero_bit(ctrl, TYPE2_SELECT, "select"); 189*95799e36SBin Meng warn_always_zero_bit(ctrl, TYPE2_HIT, "hit"); 190*95799e36SBin Meng 191*95799e36SBin Meng /* validate size encoding */ 192*95799e36SBin Meng size = type2_breakpoint_size(env, ctrl); 193*95799e36SBin Meng if (access_size[size] == -1) { 194*95799e36SBin Meng qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n", 195*95799e36SBin Meng size); 196*95799e36SBin Meng } else { 197*95799e36SBin Meng val |= (ctrl & TYPE2_SIZELO); 198*95799e36SBin Meng if (riscv_cpu_mxl(env) == MXL_RV64) { 199*95799e36SBin Meng val |= (ctrl & TYPE2_SIZEHI); 200*95799e36SBin Meng } 201*95799e36SBin Meng } 202*95799e36SBin Meng 203*95799e36SBin Meng /* keep the mode and attribute bits */ 204*95799e36SBin Meng val |= (ctrl & (TYPE2_U | TYPE2_S | TYPE2_M | 205*95799e36SBin Meng TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); 206*95799e36SBin Meng 207*95799e36SBin Meng return val; 208*95799e36SBin Meng } 209*95799e36SBin Meng 210*95799e36SBin Meng static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index) 211*95799e36SBin Meng { 212*95799e36SBin Meng target_ulong ctrl = env->type2_trig[index].mcontrol; 213*95799e36SBin Meng target_ulong addr = env->type2_trig[index].maddress; 214*95799e36SBin Meng bool enabled = type2_breakpoint_enabled(ctrl); 215*95799e36SBin Meng CPUState *cs = env_cpu(env); 216*95799e36SBin Meng int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; 217*95799e36SBin Meng uint32_t size; 218*95799e36SBin Meng 219*95799e36SBin Meng if (!enabled) { 220*95799e36SBin Meng return; 221*95799e36SBin Meng } 222*95799e36SBin Meng 223*95799e36SBin Meng if (ctrl & TYPE2_EXEC) { 224*95799e36SBin Meng cpu_breakpoint_insert(cs, addr, flags, &env->type2_trig[index].bp); 225*95799e36SBin Meng } 226*95799e36SBin Meng 227*95799e36SBin Meng if (ctrl & TYPE2_LOAD) { 228*95799e36SBin Meng flags |= BP_MEM_READ; 229*95799e36SBin Meng } 230*95799e36SBin Meng if (ctrl & TYPE2_STORE) { 231*95799e36SBin Meng flags |= BP_MEM_WRITE; 232*95799e36SBin Meng } 233*95799e36SBin Meng 234*95799e36SBin Meng if (flags & BP_MEM_ACCESS) { 235*95799e36SBin Meng size = type2_breakpoint_size(env, ctrl); 236*95799e36SBin Meng if (size != 0) { 237*95799e36SBin Meng cpu_watchpoint_insert(cs, addr, size, flags, 238*95799e36SBin Meng &env->type2_trig[index].wp); 239*95799e36SBin Meng } else { 240*95799e36SBin Meng cpu_watchpoint_insert(cs, addr, 8, flags, 241*95799e36SBin Meng &env->type2_trig[index].wp); 242*95799e36SBin Meng } 243*95799e36SBin Meng } 244*95799e36SBin Meng } 245*95799e36SBin Meng 246*95799e36SBin Meng static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index) 247*95799e36SBin Meng { 248*95799e36SBin Meng CPUState *cs = env_cpu(env); 249*95799e36SBin Meng 250*95799e36SBin Meng if (env->type2_trig[index].bp) { 251*95799e36SBin Meng cpu_breakpoint_remove_by_ref(cs, env->type2_trig[index].bp); 252*95799e36SBin Meng env->type2_trig[index].bp = NULL; 253*95799e36SBin Meng } 254*95799e36SBin Meng 255*95799e36SBin Meng if (env->type2_trig[index].wp) { 256*95799e36SBin Meng cpu_watchpoint_remove_by_ref(cs, env->type2_trig[index].wp); 257*95799e36SBin Meng env->type2_trig[index].wp = NULL; 258*95799e36SBin Meng } 259*95799e36SBin Meng } 260*95799e36SBin Meng 261*95799e36SBin Meng static target_ulong type2_reg_read(CPURISCVState *env, 262*95799e36SBin Meng target_ulong trigger_index, int tdata_index) 263*95799e36SBin Meng { 264*95799e36SBin Meng uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0; 265*95799e36SBin Meng target_ulong tdata; 266*95799e36SBin Meng 267*95799e36SBin Meng switch (tdata_index) { 268*95799e36SBin Meng case TDATA1: 269*95799e36SBin Meng tdata = env->type2_trig[index].mcontrol; 270*95799e36SBin Meng break; 271*95799e36SBin Meng case TDATA2: 272*95799e36SBin Meng tdata = env->type2_trig[index].maddress; 273*95799e36SBin Meng break; 274*95799e36SBin Meng default: 275*95799e36SBin Meng g_assert_not_reached(); 276*95799e36SBin Meng } 277*95799e36SBin Meng 278*95799e36SBin Meng return tdata; 279*95799e36SBin Meng } 280*95799e36SBin Meng 281*95799e36SBin Meng static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index, 282*95799e36SBin Meng int tdata_index, target_ulong val) 283*95799e36SBin Meng { 284*95799e36SBin Meng uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0; 285*95799e36SBin Meng target_ulong new_val; 286*95799e36SBin Meng 287*95799e36SBin Meng switch (tdata_index) { 288*95799e36SBin Meng case TDATA1: 289*95799e36SBin Meng new_val = type2_mcontrol_validate(env, val); 290*95799e36SBin Meng if (new_val != env->type2_trig[index].mcontrol) { 291*95799e36SBin Meng env->type2_trig[index].mcontrol = new_val; 292*95799e36SBin Meng type2_breakpoint_remove(env, index); 293*95799e36SBin Meng type2_breakpoint_insert(env, index); 294*95799e36SBin Meng } 295*95799e36SBin Meng break; 296*95799e36SBin Meng case TDATA2: 297*95799e36SBin Meng if (val != env->type2_trig[index].maddress) { 298*95799e36SBin Meng env->type2_trig[index].maddress = val; 299*95799e36SBin Meng type2_breakpoint_remove(env, index); 300*95799e36SBin Meng type2_breakpoint_insert(env, index); 301*95799e36SBin Meng } 302*95799e36SBin Meng break; 303*95799e36SBin Meng default: 304*95799e36SBin Meng g_assert_not_reached(); 305*95799e36SBin Meng } 306*95799e36SBin Meng 307*95799e36SBin Meng return; 308*95799e36SBin Meng } 309*95799e36SBin Meng 310*95799e36SBin Meng typedef target_ulong (*tdata_read_func)(CPURISCVState *env, 311*95799e36SBin Meng target_ulong trigger_index, 312*95799e36SBin Meng int tdata_index); 313*95799e36SBin Meng 314*95799e36SBin Meng static tdata_read_func trigger_read_funcs[TRIGGER_NUM] = { 315*95799e36SBin Meng [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_read, 316*95799e36SBin Meng }; 317*95799e36SBin Meng 318*95799e36SBin Meng typedef void (*tdata_write_func)(CPURISCVState *env, 319*95799e36SBin Meng target_ulong trigger_index, 320*95799e36SBin Meng int tdata_index, 321*95799e36SBin Meng target_ulong val); 322*95799e36SBin Meng 323*95799e36SBin Meng static tdata_write_func trigger_write_funcs[TRIGGER_NUM] = { 324*95799e36SBin Meng [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_write, 325*95799e36SBin Meng }; 326*95799e36SBin Meng 327*95799e36SBin Meng target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index) 328*95799e36SBin Meng { 329*95799e36SBin Meng tdata_read_func read_func = trigger_read_funcs[env->trigger_cur]; 330*95799e36SBin Meng 331*95799e36SBin Meng return read_func(env, env->trigger_cur, tdata_index); 332*95799e36SBin Meng } 333*95799e36SBin Meng 334*95799e36SBin Meng void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val) 335*95799e36SBin Meng { 336*95799e36SBin Meng tdata_write_func write_func = trigger_write_funcs[env->trigger_cur]; 337*95799e36SBin Meng 338*95799e36SBin Meng return write_func(env, env->trigger_cur, tdata_index, val); 339*95799e36SBin Meng } 340