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