xref: /qemu/target/riscv/pmu.c (revision 954a6c4f7862b45617ff3b65609f0f290dcd5077)
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