Lines Matching +full:armv8 +full:- +full:based

1 // SPDX-License-Identifier: GPL-2.0-only
3 * ARMv8 PMUv3 Performance Events handling code.
8 * This code is based heavily on the ARMv7 perf event code.
27 /* ARMv8 Cortex-A53 specific event types. */
30 /* ARMv8 Cavium ThunderX specific event types. */
38 * ARMv8 Architectural defined events, not all of these may
40 * be disabled at run-time based on the PMCEID registers.
164 return sprintf(page, "event=0x%04llx\n", pmu_attr->id); in armv8pmu_events_sysfs_show()
268 if (pmu_attr->id < ARMV8_PMUV3_MAX_COMMON_EVENTS && in armv8pmu_event_attr_is_visible()
269 test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) in armv8pmu_event_attr_is_visible()
270 return attr->mode; in armv8pmu_event_attr_is_visible()
272 if (pmu_attr->id >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE) { in armv8pmu_event_attr_is_visible()
273 u64 id = pmu_attr->id - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; in armv8pmu_event_attr_is_visible()
276 test_bit(id, cpu_pmu->pmceid_ext_bitmap)) in armv8pmu_event_attr_is_visible()
277 return attr->mode; in armv8pmu_event_attr_is_visible()
289 PMU_FORMAT_ATTR(event, "config:0-15");
294 return event->attr.config1 & 0x1; in armv8pmu_event_is_64bit()
313 u32 slots = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS_MASK; in slots_show()
338 * We unconditionally enable ARMv8.5-PMU long event counter support
339 * (64-bit events) where supported. Indicate if this arm_pmu has long
344 return (cpu_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_5); in armv8pmu_has_long_event()
355 int idx = event->hw.idx; in armv8pmu_event_is_chained()
356 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); in armv8pmu_event_is_chained()
365 * ARMv8 low level PMU access
372 (((x) - ARMV8_IDX_COUNTER0) & ARMV8_PMU_COUNTER_MASK)
472 int idx = event->hw.idx; in armv8pmu_read_hw_counter()
477 val = (val << 32) | armv8pmu_read_evcntr(idx - 1); in armv8pmu_read_hw_counter()
482 * The cycle counter is always a 64-bit counter. When ARMV8_PMU_PMCR_LP
483 * is set the event counters also become 64-bit counters. Unless the
485 * interrupt upon 32-bit overflow - we achieve this by applying a bias.
489 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); in armv8pmu_event_needs_bias()
490 struct hw_perf_event *hwc = &event->hw; in armv8pmu_event_needs_bias()
491 int idx = hwc->idx; in armv8pmu_event_needs_bias()
521 struct hw_perf_event *hwc = &event->hw; in armv8pmu_read_counter()
522 int idx = hwc->idx; in armv8pmu_read_counter()
543 int idx = event->hw.idx; in armv8pmu_write_hw_counter()
547 armv8pmu_write_evcntr(idx - 1, lower_32_bits(value)); in armv8pmu_write_hw_counter()
555 struct hw_perf_event *hwc = &event->hw; in armv8pmu_write_counter()
556 int idx = hwc->idx; in armv8pmu_write_counter()
576 struct hw_perf_event *hwc = &event->hw; in armv8pmu_write_event_type()
577 int idx = hwc->idx; in armv8pmu_write_event_type()
588 armv8pmu_write_evtype(idx - 1, hwc->config_base); in armv8pmu_write_event_type()
592 write_sysreg(hwc->config_base, pmccfiltr_el0); in armv8pmu_write_event_type()
594 armv8pmu_write_evtype(idx, hwc->config_base); in armv8pmu_write_event_type()
600 int counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); in armv8pmu_event_cnten_mask()
604 mask |= BIT(counter - 1); in armv8pmu_event_cnten_mask()
620 struct perf_event_attr *attr = &event->attr; in armv8pmu_enable_event_counter()
642 struct perf_event_attr *attr = &event->attr; in armv8pmu_disable_event_counter()
659 u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); in armv8pmu_enable_event_irq()
674 u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); in armv8pmu_disable_event_irq()
749 struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events); in armv8pmu_handle_irq()
774 for (idx = 0; idx < cpu_pmu->num_events; ++idx) { in armv8pmu_handle_irq()
775 struct perf_event *event = cpuc->events[idx]; in armv8pmu_handle_irq()
789 hwc = &event->hw; in armv8pmu_handle_irq()
791 perf_sample_data_init(&data, 0, hwc->last_period); in armv8pmu_handle_irq()
801 cpu_pmu->disable(event); in armv8pmu_handle_irq()
813 for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; idx ++) { in armv8pmu_get_single_idx()
814 if (!test_and_set_bit(idx, cpuc->used_mask)) in armv8pmu_get_single_idx()
817 return -EAGAIN; in armv8pmu_get_single_idx()
829 for (idx = ARMV8_IDX_COUNTER0 + 1; idx < cpu_pmu->num_events; idx += 2) { in armv8pmu_get_chain_idx()
830 if (!test_and_set_bit(idx, cpuc->used_mask)) { in armv8pmu_get_chain_idx()
832 if (!test_and_set_bit(idx - 1, cpuc->used_mask)) in armv8pmu_get_chain_idx()
835 clear_bit(idx, cpuc->used_mask); in armv8pmu_get_chain_idx()
838 return -EAGAIN; in armv8pmu_get_chain_idx()
844 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); in armv8pmu_get_event_idx()
845 struct hw_perf_event *hwc = &event->hw; in armv8pmu_get_event_idx()
846 unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT; in armv8pmu_get_event_idx()
850 if (!test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) in armv8pmu_get_event_idx()
867 int idx = event->hw.idx; in armv8pmu_clear_event_idx()
869 clear_bit(idx, cpuc->used_mask); in armv8pmu_clear_event_idx()
871 clear_bit(idx - 1, cpuc->used_mask); in armv8pmu_clear_event_idx()
882 if (attr->exclude_idle) in armv8pmu_set_event_filter()
883 return -EPERM; in armv8pmu_set_event_filter()
892 if (!attr->exclude_kernel && !attr->exclude_host) in armv8pmu_set_event_filter()
894 if (attr->exclude_guest) in armv8pmu_set_event_filter()
896 if (attr->exclude_host) in armv8pmu_set_event_filter()
899 if (!attr->exclude_hv && !attr->exclude_host) in armv8pmu_set_event_filter()
906 if (attr->exclude_kernel) in armv8pmu_set_event_filter()
909 if (attr->exclude_user) in armv8pmu_set_event_filter()
916 event->config_base = config_base; in armv8pmu_set_event_filter()
923 unsigned long evtype = event->hw.config_base & ARMV8_PMU_EVTYPE_EVENT; in armv8pmu_filter_match()
961 struct arm_pmu *armpmu = to_arm_pmu(event->pmu); in __armv8_pmuv3_map_event()
968 event->hw.flags |= ARMPMU_EVT_64BIT; in __armv8_pmuv3_map_event()
972 && test_bit(hw_event_id, armpmu->pmceid_bitmap)) { in __armv8_pmuv3_map_event()
1020 struct arm_pmu *cpu_pmu = probe->pmu; in __armv8pmu_probe_pmu()
1032 cpu_pmu->pmuver = pmuver; in __armv8pmu_probe_pmu()
1033 probe->present = true; in __armv8pmu_probe_pmu()
1036 cpu_pmu->num_events = (armv8pmu_pmcr_read() >> ARMV8_PMU_PMCR_N_SHIFT) in __armv8pmu_probe_pmu()
1040 cpu_pmu->num_events += 1; in __armv8pmu_probe_pmu()
1045 bitmap_from_arr32(cpu_pmu->pmceid_bitmap, in __armv8pmu_probe_pmu()
1051 bitmap_from_arr32(cpu_pmu->pmceid_ext_bitmap, in __armv8pmu_probe_pmu()
1056 cpu_pmu->reg_pmmir = read_cpuid(PMMIR_EL1); in __armv8pmu_probe_pmu()
1058 cpu_pmu->reg_pmmir = 0; in __armv8pmu_probe_pmu()
1069 ret = smp_call_function_any(&cpu_pmu->supported_cpus, in armv8pmu_probe_pmu()
1075 return probe.present ? 0 : -ENODEV; in armv8pmu_probe_pmu()
1088 cpu_pmu->handle_irq = armv8pmu_handle_irq; in armv8_pmu_init()
1089 cpu_pmu->enable = armv8pmu_enable_event; in armv8_pmu_init()
1090 cpu_pmu->disable = armv8pmu_disable_event; in armv8_pmu_init()
1091 cpu_pmu->read_counter = armv8pmu_read_counter; in armv8_pmu_init()
1092 cpu_pmu->write_counter = armv8pmu_write_counter; in armv8_pmu_init()
1093 cpu_pmu->get_event_idx = armv8pmu_get_event_idx; in armv8_pmu_init()
1094 cpu_pmu->clear_event_idx = armv8pmu_clear_event_idx; in armv8_pmu_init()
1095 cpu_pmu->start = armv8pmu_start; in armv8_pmu_init()
1096 cpu_pmu->stop = armv8pmu_stop; in armv8_pmu_init()
1097 cpu_pmu->reset = armv8pmu_reset; in armv8_pmu_init()
1098 cpu_pmu->set_event_filter = armv8pmu_set_event_filter; in armv8_pmu_init()
1099 cpu_pmu->filter_match = armv8pmu_filter_match; in armv8_pmu_init()
1101 cpu_pmu->name = name; in armv8_pmu_init()
1102 cpu_pmu->map_event = map_event; in armv8_pmu_init()
1103 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ? in armv8_pmu_init()
1105 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = format ? in armv8_pmu_init()
1107 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ? in armv8_pmu_init()
1216 {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init},
1217 {.compatible = "arm,cortex-a34-pmu", .data = armv8_a34_pmu_init},
1218 {.compatible = "arm,cortex-a35-pmu", .data = armv8_a35_pmu_init},
1219 {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init},
1220 {.compatible = "arm,cortex-a55-pmu", .data = armv8_a55_pmu_init},
1221 {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init},
1222 {.compatible = "arm,cortex-a65-pmu", .data = armv8_a65_pmu_init},
1223 {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init},
1224 {.compatible = "arm,cortex-a73-pmu", .data = armv8_a73_pmu_init},
1225 {.compatible = "arm,cortex-a75-pmu", .data = armv8_a75_pmu_init},
1226 {.compatible = "arm,cortex-a76-pmu", .data = armv8_a76_pmu_init},
1227 {.compatible = "arm,cortex-a77-pmu", .data = armv8_a77_pmu_init},
1228 {.compatible = "arm,neoverse-e1-pmu", .data = armv8_e1_pmu_init},
1229 {.compatible = "arm,neoverse-n1-pmu", .data = armv8_n1_pmu_init},
1230 {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init},
1231 {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init},
1265 userpg->cap_user_time = 0; in device_initcall()
1266 userpg->cap_user_time_zero = 0; in device_initcall()
1267 userpg->cap_user_time_short = 0; in device_initcall()
1272 if (rd->read_sched_clock != arch_timer_read_counter) in device_initcall()
1275 userpg->time_mult = rd->mult; in device_initcall()
1276 userpg->time_shift = rd->shift; in device_initcall()
1277 userpg->time_zero = rd->epoch_ns; in device_initcall()
1278 userpg->time_cycles = rd->epoch_cyc; in device_initcall()
1279 userpg->time_mask = rd->sched_clock_mask; in device_initcall()
1286 ns = mul_u64_u32_shr(rd->epoch_cyc, rd->mult, rd->shift); in device_initcall()
1287 userpg->time_zero -= ns; in device_initcall()
1291 userpg->time_offset = userpg->time_zero - now; in device_initcall()
1296 * 32-bit value (now specifies a 64-bit value) - refer in device_initcall()
1299 if (userpg->time_shift == 32) { in device_initcall()
1300 userpg->time_shift = 31; in device_initcall()
1301 userpg->time_mult >>= 1; in device_initcall()
1308 userpg->cap_user_time = 1; in device_initcall()
1309 userpg->cap_user_time_zero = 1; in device_initcall()
1310 userpg->cap_user_time_short = 1; in device_initcall()