xref: /openbmc/qemu/target/riscv/pmu.c (revision abaf3e5b)
1 /*
2  * RISC-V PMU file.
3  *
4  * Copyright (c) 2021 Western Digital Corporation or its affiliates.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2 or later, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "qemu/log.h"
21 #include "cpu.h"
22 #include "pmu.h"
23 #include "sysemu/cpu-timers.h"
24 #include "sysemu/device_tree.h"
25 
26 #define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */
27 #define MAKE_32BIT_MASK(shift, length) \
28         (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
29 
30 /*
31  * To keep it simple, any event can be mapped to any programmable counters in
32  * QEMU. The generic cycle & instruction count events can also be monitored
33  * using programmable counters. In that case, mcycle & minstret must continue
34  * to provide the correct value as well. Heterogeneous PMU per hart is not
35  * supported yet. Thus, number of counters are same across all harts.
36  */
37 void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
38 {
39     uint32_t fdt_event_ctr_map[15] = {};
40     uint32_t cmask;
41 
42     /* All the programmable counters can map to any event */
43     cmask = MAKE_32BIT_MASK(3, num_ctrs);
44 
45    /*
46     * The event encoding is specified in the SBI specification
47     * Event idx is a 20bits wide number encoded as follows:
48     * event_idx[19:16] = type
49     * event_idx[15:0] = code
50     * The code field in cache events are encoded as follows:
51     * event_idx.code[15:3] = cache_id
52     * event_idx.code[2:1] = op_id
53     * event_idx.code[0:0] = result_id
54     */
55 
56    /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */
57    fdt_event_ctr_map[0] = cpu_to_be32(0x00000001);
58    fdt_event_ctr_map[1] = cpu_to_be32(0x00000001);
59    fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0);
60 
61    /* SBI_PMU_HW_INSTRUCTIONS: 0x02 : type(0x00) */
62    fdt_event_ctr_map[3] = cpu_to_be32(0x00000002);
63    fdt_event_ctr_map[4] = cpu_to_be32(0x00000002);
64    fdt_event_ctr_map[5] = cpu_to_be32(cmask | 1 << 2);
65 
66    /* SBI_PMU_HW_CACHE_DTLB : 0x03 READ : 0x00 MISS : 0x00 type(0x01) */
67    fdt_event_ctr_map[6] = cpu_to_be32(0x00010019);
68    fdt_event_ctr_map[7] = cpu_to_be32(0x00010019);
69    fdt_event_ctr_map[8] = cpu_to_be32(cmask);
70 
71    /* SBI_PMU_HW_CACHE_DTLB : 0x03 WRITE : 0x01 MISS : 0x00 type(0x01) */
72    fdt_event_ctr_map[9] = cpu_to_be32(0x0001001B);
73    fdt_event_ctr_map[10] = cpu_to_be32(0x0001001B);
74    fdt_event_ctr_map[11] = cpu_to_be32(cmask);
75 
76    /* SBI_PMU_HW_CACHE_ITLB : 0x04 READ : 0x00 MISS : 0x00 type(0x01) */
77    fdt_event_ctr_map[12] = cpu_to_be32(0x00010021);
78    fdt_event_ctr_map[13] = cpu_to_be32(0x00010021);
79    fdt_event_ctr_map[14] = cpu_to_be32(cmask);
80 
81    /* This a OpenSBI specific DT property documented in OpenSBI docs */
82    qemu_fdt_setprop(fdt, pmu_name, "riscv,event-to-mhpmcounters",
83                     fdt_event_ctr_map, sizeof(fdt_event_ctr_map));
84 }
85 
86 static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx)
87 {
88     if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS ||
89         !(cpu->pmu_avail_ctrs & BIT(ctr_idx))) {
90         return false;
91     } else {
92         return true;
93     }
94 }
95 
96 static bool riscv_pmu_counter_enabled(RISCVCPU *cpu, uint32_t ctr_idx)
97 {
98     CPURISCVState *env = &cpu->env;
99 
100     if (riscv_pmu_counter_valid(cpu, ctr_idx) &&
101         !get_field(env->mcountinhibit, BIT(ctr_idx))) {
102         return true;
103     } else {
104         return false;
105     }
106 }
107 
108 static int riscv_pmu_incr_ctr_rv32(RISCVCPU *cpu, uint32_t ctr_idx)
109 {
110     CPURISCVState *env = &cpu->env;
111     target_ulong max_val = UINT32_MAX;
112     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
113     bool virt_on = env->virt_enabled;
114 
115     /* Privilege mode filtering */
116     if ((env->priv == PRV_M &&
117         (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_MINH)) ||
118         (env->priv == PRV_S && virt_on &&
119         (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VSINH)) ||
120         (env->priv == PRV_U && virt_on &&
121         (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VUINH)) ||
122         (env->priv == PRV_S && !virt_on &&
123         (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_SINH)) ||
124         (env->priv == PRV_U && !virt_on &&
125         (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_UINH))) {
126         return 0;
127     }
128 
129     /* Handle the overflow scenario */
130     if (counter->mhpmcounter_val == max_val) {
131         if (counter->mhpmcounterh_val == max_val) {
132             counter->mhpmcounter_val = 0;
133             counter->mhpmcounterh_val = 0;
134             /* Generate interrupt only if OF bit is clear */
135             if (!(env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_OF)) {
136                 env->mhpmeventh_val[ctr_idx] |= MHPMEVENTH_BIT_OF;
137                 riscv_cpu_update_mip(env, MIP_LCOFIP, BOOL_TO_MASK(1));
138             }
139         } else {
140             counter->mhpmcounterh_val++;
141         }
142     } else {
143         counter->mhpmcounter_val++;
144     }
145 
146     return 0;
147 }
148 
149 static int riscv_pmu_incr_ctr_rv64(RISCVCPU *cpu, uint32_t ctr_idx)
150 {
151     CPURISCVState *env = &cpu->env;
152     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
153     uint64_t max_val = UINT64_MAX;
154     bool virt_on = env->virt_enabled;
155 
156     /* Privilege mode filtering */
157     if ((env->priv == PRV_M &&
158         (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_MINH)) ||
159         (env->priv == PRV_S && virt_on &&
160         (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VSINH)) ||
161         (env->priv == PRV_U && virt_on &&
162         (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VUINH)) ||
163         (env->priv == PRV_S && !virt_on &&
164         (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_SINH)) ||
165         (env->priv == PRV_U && !virt_on &&
166         (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_UINH))) {
167         return 0;
168     }
169 
170     /* Handle the overflow scenario */
171     if (counter->mhpmcounter_val == max_val) {
172         counter->mhpmcounter_val = 0;
173         /* Generate interrupt only if OF bit is clear */
174         if (!(env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_OF)) {
175             env->mhpmevent_val[ctr_idx] |= MHPMEVENT_BIT_OF;
176             riscv_cpu_update_mip(env, MIP_LCOFIP, BOOL_TO_MASK(1));
177         }
178     } else {
179         counter->mhpmcounter_val++;
180     }
181     return 0;
182 }
183 
184 int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx)
185 {
186     uint32_t ctr_idx;
187     int ret;
188     CPURISCVState *env = &cpu->env;
189     gpointer value;
190 
191     if (!cpu->cfg.pmu_num) {
192         return 0;
193     }
194     value = g_hash_table_lookup(cpu->pmu_event_ctr_map,
195                                 GUINT_TO_POINTER(event_idx));
196     if (!value) {
197         return -1;
198     }
199 
200     ctr_idx = GPOINTER_TO_UINT(value);
201     if (!riscv_pmu_counter_enabled(cpu, ctr_idx) ||
202         get_field(env->mcountinhibit, BIT(ctr_idx))) {
203         return -1;
204     }
205 
206     if (riscv_cpu_mxl(env) == MXL_RV32) {
207         ret = riscv_pmu_incr_ctr_rv32(cpu, ctr_idx);
208     } else {
209         ret = riscv_pmu_incr_ctr_rv64(cpu, ctr_idx);
210     }
211 
212     return ret;
213 }
214 
215 bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
216                                         uint32_t target_ctr)
217 {
218     RISCVCPU *cpu;
219     uint32_t event_idx;
220     uint32_t ctr_idx;
221 
222     /* Fixed instret counter */
223     if (target_ctr == 2) {
224         return true;
225     }
226 
227     cpu = env_archcpu(env);
228     if (!cpu->pmu_event_ctr_map) {
229         return false;
230     }
231 
232     event_idx = RISCV_PMU_EVENT_HW_INSTRUCTIONS;
233     ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
234                                GUINT_TO_POINTER(event_idx)));
235     if (!ctr_idx) {
236         return false;
237     }
238 
239     return target_ctr == ctr_idx ? true : false;
240 }
241 
242 bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr)
243 {
244     RISCVCPU *cpu;
245     uint32_t event_idx;
246     uint32_t ctr_idx;
247 
248     /* Fixed mcycle counter */
249     if (target_ctr == 0) {
250         return true;
251     }
252 
253     cpu = env_archcpu(env);
254     if (!cpu->pmu_event_ctr_map) {
255         return false;
256     }
257 
258     event_idx = RISCV_PMU_EVENT_HW_CPU_CYCLES;
259     ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
260                                GUINT_TO_POINTER(event_idx)));
261 
262     /* Counter zero is not used for event_ctr_map */
263     if (!ctr_idx) {
264         return false;
265     }
266 
267     return (target_ctr == ctr_idx) ? true : false;
268 }
269 
270 static gboolean pmu_remove_event_map(gpointer key, gpointer value,
271                                      gpointer udata)
272 {
273     return (GPOINTER_TO_UINT(value) == GPOINTER_TO_UINT(udata)) ? true : false;
274 }
275 
276 static int64_t pmu_icount_ticks_to_ns(int64_t value)
277 {
278     int64_t ret = 0;
279 
280     if (icount_enabled()) {
281         ret = icount_to_ns(value);
282     } else {
283         ret = (NANOSECONDS_PER_SECOND / RISCV_TIMEBASE_FREQ) * value;
284     }
285 
286     return ret;
287 }
288 
289 int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
290                                uint32_t ctr_idx)
291 {
292     uint32_t event_idx;
293     RISCVCPU *cpu = env_archcpu(env);
294 
295     if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) {
296         return -1;
297     }
298 
299     /*
300      * Expected mhpmevent value is zero for reset case. Remove the current
301      * mapping.
302      */
303     if (!value) {
304         g_hash_table_foreach_remove(cpu->pmu_event_ctr_map,
305                                     pmu_remove_event_map,
306                                     GUINT_TO_POINTER(ctr_idx));
307         return 0;
308     }
309 
310     event_idx = value & MHPMEVENT_IDX_MASK;
311     if (g_hash_table_lookup(cpu->pmu_event_ctr_map,
312                             GUINT_TO_POINTER(event_idx))) {
313         return 0;
314     }
315 
316     switch (event_idx) {
317     case RISCV_PMU_EVENT_HW_CPU_CYCLES:
318     case RISCV_PMU_EVENT_HW_INSTRUCTIONS:
319     case RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS:
320     case RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS:
321     case RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS:
322         break;
323     default:
324         /* We don't support any raw events right now */
325         return -1;
326     }
327     g_hash_table_insert(cpu->pmu_event_ctr_map, GUINT_TO_POINTER(event_idx),
328                         GUINT_TO_POINTER(ctr_idx));
329 
330     return 0;
331 }
332 
333 static void pmu_timer_trigger_irq(RISCVCPU *cpu,
334                                   enum riscv_pmu_event_idx evt_idx)
335 {
336     uint32_t ctr_idx;
337     CPURISCVState *env = &cpu->env;
338     PMUCTRState *counter;
339     target_ulong *mhpmevent_val;
340     uint64_t of_bit_mask;
341     int64_t irq_trigger_at;
342 
343     if (evt_idx != RISCV_PMU_EVENT_HW_CPU_CYCLES &&
344         evt_idx != RISCV_PMU_EVENT_HW_INSTRUCTIONS) {
345         return;
346     }
347 
348     ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
349                                GUINT_TO_POINTER(evt_idx)));
350     if (!riscv_pmu_counter_enabled(cpu, ctr_idx)) {
351         return;
352     }
353 
354     if (riscv_cpu_mxl(env) == MXL_RV32) {
355         mhpmevent_val = &env->mhpmeventh_val[ctr_idx];
356         of_bit_mask = MHPMEVENTH_BIT_OF;
357      } else {
358         mhpmevent_val = &env->mhpmevent_val[ctr_idx];
359         of_bit_mask = MHPMEVENT_BIT_OF;
360     }
361 
362     counter = &env->pmu_ctrs[ctr_idx];
363     if (counter->irq_overflow_left > 0) {
364         irq_trigger_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
365                         counter->irq_overflow_left;
366         timer_mod_anticipate_ns(cpu->pmu_timer, irq_trigger_at);
367         counter->irq_overflow_left = 0;
368         return;
369     }
370 
371     if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) {
372         /* Generate interrupt only if OF bit is clear */
373         if (!(*mhpmevent_val & of_bit_mask)) {
374             *mhpmevent_val |= of_bit_mask;
375             riscv_cpu_update_mip(env, MIP_LCOFIP, BOOL_TO_MASK(1));
376         }
377     }
378 }
379 
380 /* Timer callback for instret and cycle counter overflow */
381 void riscv_pmu_timer_cb(void *priv)
382 {
383     RISCVCPU *cpu = priv;
384 
385     /* Timer event was triggered only for these events */
386     pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_CPU_CYCLES);
387     pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_INSTRUCTIONS);
388 }
389 
390 int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx)
391 {
392     uint64_t overflow_delta, overflow_at;
393     int64_t overflow_ns, overflow_left = 0;
394     RISCVCPU *cpu = env_archcpu(env);
395     PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
396 
397     if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) {
398         return -1;
399     }
400 
401     if (value) {
402         overflow_delta = UINT64_MAX - value + 1;
403     } else {
404         overflow_delta = UINT64_MAX;
405     }
406 
407     /*
408      * QEMU supports only int64_t timers while RISC-V counters are uint64_t.
409      * Compute the leftover and save it so that it can be reprogrammed again
410      * when timer expires.
411      */
412     if (overflow_delta > INT64_MAX) {
413         overflow_left = overflow_delta - INT64_MAX;
414     }
415 
416     if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
417         riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
418         overflow_ns = pmu_icount_ticks_to_ns((int64_t)overflow_delta);
419         overflow_left = pmu_icount_ticks_to_ns(overflow_left) ;
420     } else {
421         return -1;
422     }
423     overflow_at = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
424                   overflow_ns;
425 
426     if (overflow_at > INT64_MAX) {
427         overflow_left += overflow_at - INT64_MAX;
428         counter->irq_overflow_left = overflow_left;
429         overflow_at = INT64_MAX;
430     }
431     timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
432 
433     return 0;
434 }
435 
436 
437 int riscv_pmu_init(RISCVCPU *cpu, int num_counters)
438 {
439     if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) {
440         return -1;
441     }
442 
443     cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
444     if (!cpu->pmu_event_ctr_map) {
445         /* PMU support can not be enabled */
446         qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n");
447         cpu->cfg.pmu_num = 0;
448         return -1;
449     }
450 
451     /* Create a bitmask of available programmable counters */
452     cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters);
453 
454     return 0;
455 }
456