Lines Matching +full:default +full:- +full:trigger
2 * QEMU RISC-V Native Debug Support
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
31 #include "exec/helper-proto.h"
33 #include "system/cpu-timers.h"
37 * The following M-mode trigger CSRs are implemented:
39 * - tselect
40 * - tdata1
41 * - tdata2
42 * - tdata3
43 * - tinfo
45 * The following triggers are initialized by default:
48 * ------+------+------------------------+------------
53 /* tdata availability of a trigger */
73 [SIZE_6B] = -1,
75 [6 ... 15] = -1,
87 default: in extract_trigger_type()
95 return extract_trigger_type(env, env->tdata1[trigger_index]); in get_trigger_type()
101 target_ulong tdata1 = env->tdata1[trigger_index]; in get_trigger_action()
116 qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", in get_trigger_action()
121 qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n", in get_trigger_action()
124 default: in get_trigger_action()
149 default: in build_tdata1()
158 int trigger_type = get_trigger_type(env, env->trigger_cur); in tdata_available()
169 return env->trigger_cur; in tselect_csr_read()
175 env->trigger_cur = val; in tselect_csr_write()
197 default: in tdata1_validate()
252 default: in textra_validate()
274 default: in textra_validate()
300 default: in do_trigger_action()
306 * Check the privilege level of specific trigger matches CPU's current privilege
312 target_ulong ctrl = env->tdata1[trigger_index]; in trigger_priv_match()
316 /* type 2 trigger cannot be fired in VU/VS mode */ in trigger_priv_match()
317 if (env->virt_enabled) { in trigger_priv_match()
321 if ((ctrl >> 3) & BIT(env->priv)) { in trigger_priv_match()
326 if (env->virt_enabled) { in trigger_priv_match()
328 if ((ctrl >> 23) & BIT(env->priv)) { in trigger_priv_match()
333 if ((ctrl >> 3) & BIT(env->priv)) { in trigger_priv_match()
339 if (env->virt_enabled) { in trigger_priv_match()
341 if ((ctrl >> 25) & BIT(env->priv)) { in trigger_priv_match()
346 if ((ctrl >> 6) & BIT(env->priv)) { in trigger_priv_match()
354 qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", type); in trigger_priv_match()
358 qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exist\n", in trigger_priv_match()
361 default: in trigger_priv_match()
371 target_ulong textra = env->tdata3[trigger_index]; in trigger_textra_match()
389 default: in trigger_textra_match()
399 if (mhvalue != env->mcontext) { in trigger_textra_match()
403 default: in trigger_textra_match()
418 /* type 2 trigger */
458 if (access_size[size] == -1) { in type2_mcontrol_validate()
477 target_ulong ctrl = env->tdata1[index]; in type2_breakpoint_insert()
478 target_ulong addr = env->tdata2[index]; in type2_breakpoint_insert()
489 cpu_breakpoint_insert(cs, addr, flags, &env->cpu_breakpoint[index]); in type2_breakpoint_insert()
503 &env->cpu_watchpoint[index]); in type2_breakpoint_insert()
508 &env->cpu_watchpoint[index]); in type2_breakpoint_insert()
517 if (env->cpu_breakpoint[index]) { in type2_breakpoint_remove()
518 cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]); in type2_breakpoint_remove()
519 env->cpu_breakpoint[index] = NULL; in type2_breakpoint_remove()
522 if (env->cpu_watchpoint[index]) { in type2_breakpoint_remove()
523 cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]); in type2_breakpoint_remove()
524 env->cpu_watchpoint[index] = NULL; in type2_breakpoint_remove()
536 if (new_val != env->tdata1[index]) { in type2_reg_write()
537 env->tdata1[index] = new_val; in type2_reg_write()
543 if (val != env->tdata2[index]) { in type2_reg_write()
544 env->tdata2[index] = val; in type2_reg_write()
550 env->tdata3[index] = textra_validate(env, val); in type2_reg_write()
552 default: in type2_reg_write()
557 /* type 6 trigger */
586 if (access_size[size] == -1) { in type6_mcontrol6_validate()
602 target_ulong ctrl = env->tdata1[index]; in type6_breakpoint_insert()
603 target_ulong addr = env->tdata2[index]; in type6_breakpoint_insert()
614 cpu_breakpoint_insert(cs, addr, flags, &env->cpu_breakpoint[index]); in type6_breakpoint_insert()
629 &env->cpu_watchpoint[index]); in type6_breakpoint_insert()
632 &env->cpu_watchpoint[index]); in type6_breakpoint_insert()
650 if (new_val != env->tdata1[index]) { in type6_reg_write()
651 env->tdata1[index] = new_val; in type6_reg_write()
657 if (val != env->tdata2[index]) { in type6_reg_write()
658 env->tdata2[index] = val; in type6_reg_write()
664 env->tdata3[index] = textra_validate(env, val); in type6_reg_write()
666 default: in type6_reg_write()
671 /* icount trigger type */
675 return get_field(env->tdata1[index], ITRIGGER_COUNT); in itrigger_get_count()
681 env->tdata1[index] = set_field(env->tdata1[index], in itrigger_set_count()
687 target_ulong tdata1 = env->tdata1[index]; in check_itrigger_priv()
688 if (env->virt_enabled) { in check_itrigger_priv()
690 return (get_field(tdata1, ITRIGGER_VS) == env->priv) || in check_itrigger_priv()
691 (get_field(tdata1, ITRIGGER_VU) == env->priv); in check_itrigger_priv()
694 return (get_field(tdata1, ITRIGGER_M) == env->priv) || in check_itrigger_priv()
695 (get_field(tdata1, ITRIGGER_S) == env->priv) || in check_itrigger_priv()
696 (get_field(tdata1, ITRIGGER_U) == env->priv); in check_itrigger_priv()
734 itrigger_set_count(env, i, count--); in helper_itrigger_match()
736 env->itrigger_enabled = riscv_itrigger_enabled(env); in helper_itrigger_match()
749 int64_t last_icount = env->last_icount, current_icount; in riscv_itrigger_update_count()
750 current_icount = env->last_icount = icount_get_raw(); in riscv_itrigger_update_count()
771 executed = current_icount - last_icount; in riscv_itrigger_update_count()
772 itrigger_set_count(env, i, count - executed); in riscv_itrigger_update_count()
782 timer_mod(env->itrigger_timer[i], in riscv_itrigger_update_count()
827 if (new_val != env->tdata1[index]) { in itrigger_reg_write()
828 env->tdata1[index] = new_val; in itrigger_reg_write()
830 env->last_icount = icount_get_raw(); in itrigger_reg_write()
832 timer_mod(env->itrigger_timer[index], in itrigger_reg_write()
833 env->last_icount + itrigger_get_count(env, index)); in itrigger_reg_write()
835 env->itrigger_enabled = riscv_itrigger_enabled(env); in itrigger_reg_write()
841 "tdata2 is not supported for icount trigger\n"); in itrigger_reg_write()
844 env->tdata3[index] = textra_validate(env, val); in itrigger_reg_write()
846 default: in itrigger_reg_write()
853 int count = itrigger_get_count(env, env->trigger_cur), executed; in itrigger_get_adjust_count()
854 if ((count != 0) && check_itrigger_priv(env, env->trigger_cur)) { in itrigger_get_adjust_count()
855 executed = icount_get_raw() - env->last_icount; in itrigger_get_adjust_count()
867 env->tdata1[env->trigger_cur]); in tdata_csr_read()
869 return deposit64(env->tdata1[env->trigger_cur], 10, 14, in tdata_csr_read()
872 return env->tdata1[env->trigger_cur]; in tdata_csr_read()
874 return env->tdata2[env->trigger_cur]; in tdata_csr_read()
876 return env->tdata3[env->trigger_cur]; in tdata_csr_read()
877 default: in tdata_csr_read()
889 trigger_type = get_trigger_type(env, env->trigger_cur); in tdata_csr_write()
894 type2_reg_write(env, env->trigger_cur, tdata_index, val); in tdata_csr_write()
897 type6_reg_write(env, env->trigger_cur, tdata_index, val); in tdata_csr_write()
900 itrigger_reg_write(env, env->trigger_cur, tdata_index, val); in tdata_csr_write()
905 qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n", in tdata_csr_write()
910 qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n", in tdata_csr_write()
913 default: in tdata_csr_write()
928 CPURISCVState *env = &cpu->env; in riscv_cpu_debug_excp_handler()
930 if (cs->watchpoint_hit) { in riscv_cpu_debug_excp_handler()
931 if (cs->watchpoint_hit->flags & BP_CPU) { in riscv_cpu_debug_excp_handler()
935 if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { in riscv_cpu_debug_excp_handler()
944 CPURISCVState *env = &cpu->env; in riscv_cpu_debug_check_breakpoint()
951 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { in riscv_cpu_debug_check_breakpoint()
961 ctrl = env->tdata1[i]; in riscv_cpu_debug_check_breakpoint()
962 pc = env->tdata2[i]; in riscv_cpu_debug_check_breakpoint()
964 if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { in riscv_cpu_debug_check_breakpoint()
965 env->badaddr = pc; in riscv_cpu_debug_check_breakpoint()
970 ctrl = env->tdata1[i]; in riscv_cpu_debug_check_breakpoint()
971 pc = env->tdata2[i]; in riscv_cpu_debug_check_breakpoint()
973 if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) { in riscv_cpu_debug_check_breakpoint()
974 env->badaddr = pc; in riscv_cpu_debug_check_breakpoint()
978 default: in riscv_cpu_debug_check_breakpoint()
979 /* other trigger types are not supported or irrelevant */ in riscv_cpu_debug_check_breakpoint()
991 CPURISCVState *env = &cpu->env; in riscv_cpu_debug_check_watchpoint()
1007 ctrl = env->tdata1[i]; in riscv_cpu_debug_check_watchpoint()
1008 addr = env->tdata2[i]; in riscv_cpu_debug_check_watchpoint()
1018 if ((wp->flags & flags) && (wp->vaddr == addr)) { in riscv_cpu_debug_check_watchpoint()
1023 ctrl = env->tdata1[i]; in riscv_cpu_debug_check_watchpoint()
1024 addr = env->tdata2[i]; in riscv_cpu_debug_check_watchpoint()
1034 if ((wp->flags & flags) && (wp->vaddr == addr)) { in riscv_cpu_debug_check_watchpoint()
1038 default: in riscv_cpu_debug_check_watchpoint()
1039 /* other trigger types are not supported */ in riscv_cpu_debug_check_watchpoint()
1052 env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL, in riscv_trigger_realize()
1066 * dmode = 0 (both debug and M-mode can write tdata) in riscv_trigger_reset_hold()
1071 * timing = 0 (always 0, trigger before instruction) in riscv_trigger_reset_hold()
1077 env->tdata1[i] = tdata1; in riscv_trigger_reset_hold()
1078 env->tdata2[i] = 0; in riscv_trigger_reset_hold()
1079 env->tdata3[i] = 0; in riscv_trigger_reset_hold()
1080 env->cpu_breakpoint[i] = NULL; in riscv_trigger_reset_hold()
1081 env->cpu_watchpoint[i] = NULL; in riscv_trigger_reset_hold()
1082 timer_del(env->itrigger_timer[i]); in riscv_trigger_reset_hold()
1085 env->mcontext = 0; in riscv_trigger_reset_hold()