@@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq;
100100/* Cache the available counters in a bitmask */
101101static unsigned long cmask ;
102102
103+ static int pmu_event_find_cache (u64 config );
103104struct sbi_pmu_event_data {
104105 union {
105106 union {
@@ -412,6 +413,71 @@ static bool pmu_sbi_ctr_is_fw(int cidx)
412413 return (info -> type == SBI_PMU_CTR_TYPE_FW ) ? true : false;
413414}
414415
416+ int riscv_pmu_get_event_info (u32 type , u64 config , u64 * econfig )
417+ {
418+ int ret = - ENOENT ;
419+
420+ switch (type ) {
421+ case PERF_TYPE_HARDWARE :
422+ if (config >= PERF_COUNT_HW_MAX )
423+ return - EINVAL ;
424+ ret = pmu_hw_event_map [config ].event_idx ;
425+ break ;
426+ case PERF_TYPE_HW_CACHE :
427+ ret = pmu_event_find_cache (config );
428+ break ;
429+ case PERF_TYPE_RAW :
430+ /*
431+ * As per SBI v0.3 specification,
432+ * -- the upper 16 bits must be unused for a hardware raw event.
433+ * As per SBI v2.0 specification,
434+ * -- the upper 8 bits must be unused for a hardware raw event.
435+ * Bits 63:62 are used to distinguish between raw events
436+ * 00 - Hardware raw event
437+ * 10 - SBI firmware events
438+ * 11 - Risc-V platform specific firmware event
439+ */
440+ switch (config >> 62 ) {
441+ case 0 :
442+ if (sbi_v3_available ) {
443+ /* Return error any bits [56-63] is set as it is not allowed by the spec */
444+ if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK )) {
445+ if (econfig )
446+ * econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK ;
447+ ret = RISCV_PMU_RAW_EVENT_V2_IDX ;
448+ }
449+ /* Return error any bits [48-63] is set as it is not allowed by the spec */
450+ } else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK )) {
451+ if (econfig )
452+ * econfig = config & RISCV_PMU_RAW_EVENT_MASK ;
453+ ret = RISCV_PMU_RAW_EVENT_IDX ;
454+ }
455+ break ;
456+ case 2 :
457+ ret = (config & 0xFFFF ) | (SBI_PMU_EVENT_TYPE_FW << 16 );
458+ break ;
459+ case 3 :
460+ /*
461+ * For Risc-V platform specific firmware events
462+ * Event code - 0xFFFF
463+ * Event data - raw event encoding
464+ */
465+ ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT ;
466+ if (econfig )
467+ * econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK ;
468+ break ;
469+ default :
470+ break ;
471+ }
472+ break ;
473+ default :
474+ break ;
475+ }
476+
477+ return ret ;
478+ }
479+ EXPORT_SYMBOL_GPL (riscv_pmu_get_event_info );
480+
415481/*
416482 * Returns the counter width of a programmable counter and number of hardware
417483 * counters. As we don't support heterogeneous CPUs yet, it is okay to just
@@ -577,68 +643,14 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
577643{
578644 u32 type = event -> attr .type ;
579645 u64 config = event -> attr .config ;
580- int ret = - ENOENT ;
581646
582647 /*
583648 * Ensure we are finished checking standard hardware events for
584649 * validity before allowing userspace to configure any events.
585650 */
586651 flush_work (& check_std_events_work );
587652
588- switch (type ) {
589- case PERF_TYPE_HARDWARE :
590- if (config >= PERF_COUNT_HW_MAX )
591- return - EINVAL ;
592- ret = pmu_hw_event_map [event -> attr .config ].event_idx ;
593- break ;
594- case PERF_TYPE_HW_CACHE :
595- ret = pmu_event_find_cache (config );
596- break ;
597- case PERF_TYPE_RAW :
598- /*
599- * As per SBI v0.3 specification,
600- * -- the upper 16 bits must be unused for a hardware raw event.
601- * As per SBI v2.0 specification,
602- * -- the upper 8 bits must be unused for a hardware raw event.
603- * Bits 63:62 are used to distinguish between raw events
604- * 00 - Hardware raw event
605- * 10 - SBI firmware events
606- * 11 - Risc-V platform specific firmware event
607- */
608-
609- switch (config >> 62 ) {
610- case 0 :
611- if (sbi_v3_available ) {
612- if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK )) {
613- * econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK ;
614- ret = RISCV_PMU_RAW_EVENT_V2_IDX ;
615- }
616- } else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK )) {
617- * econfig = config & RISCV_PMU_RAW_EVENT_MASK ;
618- ret = RISCV_PMU_RAW_EVENT_IDX ;
619- }
620- break ;
621- case 2 :
622- ret = (config & 0xFFFF ) | (SBI_PMU_EVENT_TYPE_FW << 16 );
623- break ;
624- case 3 :
625- /*
626- * For Risc-V platform specific firmware events
627- * Event code - 0xFFFF
628- * Event data - raw event encoding
629- */
630- ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT ;
631- * econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK ;
632- break ;
633- default :
634- break ;
635- }
636- break ;
637- default :
638- break ;
639- }
640-
641- return ret ;
653+ return riscv_pmu_get_event_info (type , config , econfig );
642654}
643655
644656static void pmu_sbi_snapshot_free (struct riscv_pmu * pmu )
0 commit comments