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