Lines Matching +full:event +full:- +full:to +full:- +full:mhpmcounters

2  * RISC-V PMU file.
21 #include "qemu/error-report.h"
25 #include "system/cpu-timers.h"
31 * To keep it simple, any event can be mapped to any programmable counters in
34 * to provide the correct value as well. Heterogeneous PMU per hart is not
42 * The event encoding is specified in the SBI specification in riscv_pmu_generate_fdt_node()
43 * Event idx is a 20bits wide number encoded as follows: in riscv_pmu_generate_fdt_node()
78 qemu_fdt_setprop(fdt, pmu_name, "riscv,event-to-mhpmcounters", in riscv_pmu_generate_fdt_node()
85 !(cpu->pmu_avail_ctrs & BIT(ctr_idx))) { in riscv_pmu_counter_valid()
94 CPURISCVState *env = &cpu->env; in riscv_pmu_counter_enabled()
97 !get_field(env->mcountinhibit, BIT(ctr_idx))) { in riscv_pmu_counter_enabled()
106 CPURISCVState *env = &cpu->env; in riscv_pmu_incr_ctr_rv32()
108 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; in riscv_pmu_incr_ctr_rv32()
109 bool virt_on = env->virt_enabled; in riscv_pmu_incr_ctr_rv32()
112 if ((env->priv == PRV_M && in riscv_pmu_incr_ctr_rv32()
113 (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_MINH)) || in riscv_pmu_incr_ctr_rv32()
114 (env->priv == PRV_S && virt_on && in riscv_pmu_incr_ctr_rv32()
115 (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VSINH)) || in riscv_pmu_incr_ctr_rv32()
116 (env->priv == PRV_U && virt_on && in riscv_pmu_incr_ctr_rv32()
117 (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VUINH)) || in riscv_pmu_incr_ctr_rv32()
118 (env->priv == PRV_S && !virt_on && in riscv_pmu_incr_ctr_rv32()
119 (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_SINH)) || in riscv_pmu_incr_ctr_rv32()
120 (env->priv == PRV_U && !virt_on && in riscv_pmu_incr_ctr_rv32()
121 (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_UINH))) { in riscv_pmu_incr_ctr_rv32()
126 if (counter->mhpmcounter_val == max_val) { in riscv_pmu_incr_ctr_rv32()
127 if (counter->mhpmcounterh_val == max_val) { in riscv_pmu_incr_ctr_rv32()
128 counter->mhpmcounter_val = 0; in riscv_pmu_incr_ctr_rv32()
129 counter->mhpmcounterh_val = 0; in riscv_pmu_incr_ctr_rv32()
131 if (!(env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_OF)) { in riscv_pmu_incr_ctr_rv32()
132 env->mhpmeventh_val[ctr_idx] |= MHPMEVENTH_BIT_OF; in riscv_pmu_incr_ctr_rv32()
136 counter->mhpmcounterh_val++; in riscv_pmu_incr_ctr_rv32()
139 counter->mhpmcounter_val++; in riscv_pmu_incr_ctr_rv32()
147 CPURISCVState *env = &cpu->env; in riscv_pmu_incr_ctr_rv64()
148 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; in riscv_pmu_incr_ctr_rv64()
150 bool virt_on = env->virt_enabled; in riscv_pmu_incr_ctr_rv64()
153 if ((env->priv == PRV_M && in riscv_pmu_incr_ctr_rv64()
154 (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_MINH)) || in riscv_pmu_incr_ctr_rv64()
155 (env->priv == PRV_S && virt_on && in riscv_pmu_incr_ctr_rv64()
156 (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VSINH)) || in riscv_pmu_incr_ctr_rv64()
157 (env->priv == PRV_U && virt_on && in riscv_pmu_incr_ctr_rv64()
158 (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VUINH)) || in riscv_pmu_incr_ctr_rv64()
159 (env->priv == PRV_S && !virt_on && in riscv_pmu_incr_ctr_rv64()
160 (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_SINH)) || in riscv_pmu_incr_ctr_rv64()
161 (env->priv == PRV_U && !virt_on && in riscv_pmu_incr_ctr_rv64()
162 (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_UINH))) { in riscv_pmu_incr_ctr_rv64()
167 if (counter->mhpmcounter_val == max_val) { in riscv_pmu_incr_ctr_rv64()
168 counter->mhpmcounter_val = 0; in riscv_pmu_incr_ctr_rv64()
170 if (!(env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_OF)) { in riscv_pmu_incr_ctr_rv64()
171 env->mhpmevent_val[ctr_idx] |= MHPMEVENT_BIT_OF; in riscv_pmu_incr_ctr_rv64()
175 counter->mhpmcounter_val++; in riscv_pmu_incr_ctr_rv64()
181 * Information needed to update counters:
182 * new_priv, new_virt: To correctly save starting snapshot for the newly
184 * old_priv, old_virt: To correctly select previous snapshot for old priv
185 * and compute delta. Also to select correct counter
186 * to inc. Look at arrays being indexed with env->priv.
188 * To avoid the complexity of calling this function, we assume that
189 * env->priv and env->virt_enabled contain old priv and old virt and
206 if (env->virt_enabled) { in riscv_pmu_icount_update_priv()
207 g_assert(env->priv <= PRV_S); in riscv_pmu_icount_update_priv()
208 counter_arr = env->pmu_fixed_ctrs[1].counter_virt; in riscv_pmu_icount_update_priv()
209 snapshot_prev = env->pmu_fixed_ctrs[1].counter_virt_prev; in riscv_pmu_icount_update_priv()
211 counter_arr = env->pmu_fixed_ctrs[1].counter; in riscv_pmu_icount_update_priv()
212 snapshot_prev = env->pmu_fixed_ctrs[1].counter_prev; in riscv_pmu_icount_update_priv()
217 snapshot_new = env->pmu_fixed_ctrs[1].counter_virt_prev; in riscv_pmu_icount_update_priv()
219 snapshot_new = env->pmu_fixed_ctrs[1].counter_prev; in riscv_pmu_icount_update_priv()
223 * new_priv can be same as env->priv. So we need to calculate in riscv_pmu_icount_update_priv()
226 delta = current_icount - snapshot_prev[env->priv]; in riscv_pmu_icount_update_priv()
229 counter_arr[env->priv] += delta; in riscv_pmu_icount_update_priv()
246 if (env->virt_enabled) { in riscv_pmu_cycle_update_priv()
247 g_assert(env->priv <= PRV_S); in riscv_pmu_cycle_update_priv()
248 counter_arr = env->pmu_fixed_ctrs[0].counter_virt; in riscv_pmu_cycle_update_priv()
249 snapshot_prev = env->pmu_fixed_ctrs[0].counter_virt_prev; in riscv_pmu_cycle_update_priv()
251 counter_arr = env->pmu_fixed_ctrs[0].counter; in riscv_pmu_cycle_update_priv()
252 snapshot_prev = env->pmu_fixed_ctrs[0].counter_prev; in riscv_pmu_cycle_update_priv()
257 snapshot_new = env->pmu_fixed_ctrs[0].counter_virt_prev; in riscv_pmu_cycle_update_priv()
259 snapshot_new = env->pmu_fixed_ctrs[0].counter_prev; in riscv_pmu_cycle_update_priv()
262 delta = current_ticks - snapshot_prev[env->priv]; in riscv_pmu_cycle_update_priv()
265 counter_arr[env->priv] += delta; in riscv_pmu_cycle_update_priv()
279 CPURISCVState *env = &cpu->env; in riscv_pmu_incr_ctr()
282 if (!cpu->cfg.pmu_mask) { in riscv_pmu_incr_ctr()
285 value = g_hash_table_lookup(cpu->pmu_event_ctr_map, in riscv_pmu_incr_ctr()
288 return -1; in riscv_pmu_incr_ctr()
293 return -1; in riscv_pmu_incr_ctr()
318 if (!cpu->pmu_event_ctr_map) { in riscv_pmu_ctr_monitor_instructions()
323 ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map, in riscv_pmu_ctr_monitor_instructions()
344 if (!cpu->pmu_event_ctr_map) { in riscv_pmu_ctr_monitor_cycles()
349 ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map, in riscv_pmu_ctr_monitor_cycles()
385 if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) { in riscv_pmu_update_event_map()
386 return -1; in riscv_pmu_update_event_map()
394 g_hash_table_foreach_remove(cpu->pmu_event_ctr_map, in riscv_pmu_update_event_map()
401 if (g_hash_table_lookup(cpu->pmu_event_ctr_map, in riscv_pmu_update_event_map()
415 return -1; in riscv_pmu_update_event_map()
417 g_hash_table_insert(cpu->pmu_event_ctr_map, GUINT_TO_POINTER(event_idx), in riscv_pmu_update_event_map()
429 mhpmevent_val = env->mhpmeventh_val[ctr_idx]; in pmu_hpmevent_is_of_set()
432 mhpmevent_val = env->mhpmevent_val[ctr_idx]; in pmu_hpmevent_is_of_set()
445 mhpmevent_val = &env->mhpmeventh_val[ctr_idx]; in pmu_hpmevent_set_of_if_clear()
448 mhpmevent_val = &env->mhpmevent_val[ctr_idx]; in pmu_hpmevent_set_of_if_clear()
464 CPURISCVState *env = &cpu->env; in pmu_timer_trigger_irq()
475 ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map, in pmu_timer_trigger_irq()
486 counter = &env->pmu_ctrs[ctr_idx]; in pmu_timer_trigger_irq()
487 if (counter->irq_overflow_left > 0) { in pmu_timer_trigger_irq()
489 counter->irq_overflow_left; in pmu_timer_trigger_irq()
490 timer_mod_anticipate_ns(cpu->pmu_timer, irq_trigger_at); in pmu_timer_trigger_irq()
491 counter->irq_overflow_left = 0; in pmu_timer_trigger_irq()
496 ctr_val = counter->mhpmcounter_val; in pmu_timer_trigger_irq()
501 ((uint64_t)counter->mhpmcounterh_val << 32); in pmu_timer_trigger_irq()
515 if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) { in pmu_timer_trigger_irq()
527 /* Timer event was triggered only for these events */ in riscv_pmu_timer_cb()
537 PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; in riscv_pmu_setup_timer()
539 /* No need to setup a timer if LCOFI is disabled when OF is set */ in riscv_pmu_setup_timer()
540 if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf || in riscv_pmu_setup_timer()
542 return -1; in riscv_pmu_setup_timer()
546 overflow_delta = UINT64_MAX - value + 1; in riscv_pmu_setup_timer()
552 * QEMU supports only int64_t timers while RISC-V counters are uint64_t. in riscv_pmu_setup_timer()
557 overflow_left = overflow_delta - INT64_MAX; in riscv_pmu_setup_timer()
565 return -1; in riscv_pmu_setup_timer()
573 overflow_left += overflow_at - INT64_MAX; in riscv_pmu_setup_timer()
574 counter->irq_overflow_left = overflow_left; in riscv_pmu_setup_timer()
577 timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at); in riscv_pmu_setup_timer()
585 if (cpu->cfg.pmu_mask & (COUNTEREN_CY | COUNTEREN_TM | COUNTEREN_IR)) { in riscv_pmu_init()
586 error_setg(errp, "\"pmu-mask\" contains invalid bits (0-2) set"); in riscv_pmu_init()
590 if (ctpop32(cpu->cfg.pmu_mask) > (RV_MAX_MHPMCOUNTERS - 3)) { in riscv_pmu_init()
595 cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal); in riscv_pmu_init()
596 if (!cpu->pmu_event_ctr_map) { in riscv_pmu_init()
597 error_setg(errp, "Unable to allocate PMU event hash table"); in riscv_pmu_init()
601 cpu->pmu_avail_ctrs = cpu->cfg.pmu_mask; in riscv_pmu_init()