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()
265 if (pmu_attr->id < ARMV8_PMUV3_MAX_COMMON_EVENTS && in armv8pmu_event_attr_is_visible()
266 test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) in armv8pmu_event_attr_is_visible()
267 return attr->mode; in armv8pmu_event_attr_is_visible()
269 if (pmu_attr->id >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE) { in armv8pmu_event_attr_is_visible()
270 u64 id = pmu_attr->id - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; in armv8pmu_event_attr_is_visible()
273 test_bit(id, cpu_pmu->pmceid_ext_bitmap)) in armv8pmu_event_attr_is_visible()
274 return attr->mode; in armv8pmu_event_attr_is_visible()
286 PMU_FORMAT_ATTR(event, "config:0-15");
291 return event->attr.config1 & 0x1; in armv8pmu_event_is_64bit()
310 u32 slots = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS_MASK; in slots_show()
322 u32 bus_slots = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_SLOTS_SHIFT) in bus_slots_show()
335 u32 bus_width = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_WIDTH_SHIFT) in bus_width_show()
341 val = 1 << (bus_width - 1); in bus_width_show()
368 * We unconditionally enable ARMv8.5-PMU long event counter support
369 * (64-bit events) where supported. Indicate if this arm_pmu has long
374 return (cpu_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_5); in armv8pmu_has_long_event()
385 int idx = event->hw.idx; in armv8pmu_event_is_chained()
386 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); in armv8pmu_event_is_chained()
395 * ARMv8 low level PMU access
402 (((x) - ARMV8_IDX_COUNTER0) & ARMV8_PMU_COUNTER_MASK)
502 int idx = event->hw.idx; in armv8pmu_read_hw_counter()
506 val = (val << 32) | armv8pmu_read_evcntr(idx - 1); in armv8pmu_read_hw_counter()
511 * The cycle counter is always a 64-bit counter. When ARMV8_PMU_PMCR_LP
512 * is set the event counters also become 64-bit counters. Unless the
514 * interrupt upon 32-bit overflow - we achieve this by applying a bias.
518 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); in armv8pmu_event_needs_bias()
519 struct hw_perf_event *hwc = &event->hw; in armv8pmu_event_needs_bias()
520 int idx = hwc->idx; in armv8pmu_event_needs_bias()
550 struct hw_perf_event *hwc = &event->hw; in armv8pmu_read_counter()
551 int idx = hwc->idx; in armv8pmu_read_counter()
572 int idx = event->hw.idx; in armv8pmu_write_hw_counter()
576 armv8pmu_write_evcntr(idx - 1, lower_32_bits(value)); in armv8pmu_write_hw_counter()
584 struct hw_perf_event *hwc = &event->hw; in armv8pmu_write_counter()
585 int idx = hwc->idx; in armv8pmu_write_counter()
605 struct hw_perf_event *hwc = &event->hw; in armv8pmu_write_event_type()
606 int idx = hwc->idx; in armv8pmu_write_event_type()
617 armv8pmu_write_evtype(idx - 1, hwc->config_base); in armv8pmu_write_event_type()
621 write_sysreg(hwc->config_base, pmccfiltr_el0); in armv8pmu_write_event_type()
623 armv8pmu_write_evtype(idx, hwc->config_base); in armv8pmu_write_event_type()
629 int counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); in armv8pmu_event_cnten_mask()
633 mask |= BIT(counter - 1); in armv8pmu_event_cnten_mask()
649 struct perf_event_attr *attr = &event->attr; in armv8pmu_enable_event_counter()
671 struct perf_event_attr *attr = &event->attr; in armv8pmu_disable_event_counter()
688 u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); in armv8pmu_enable_event_irq()
703 u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); in armv8pmu_disable_event_irq()
778 struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events); in armv8pmu_handle_irq()
803 for (idx = 0; idx < cpu_pmu->num_events; ++idx) { in armv8pmu_handle_irq()
804 struct perf_event *event = cpuc->events[idx]; in armv8pmu_handle_irq()
818 hwc = &event->hw; in armv8pmu_handle_irq()
820 perf_sample_data_init(&data, 0, hwc->last_period); in armv8pmu_handle_irq()
830 cpu_pmu->disable(event); in armv8pmu_handle_irq()
842 for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; idx++) { in armv8pmu_get_single_idx()
843 if (!test_and_set_bit(idx, cpuc->used_mask)) in armv8pmu_get_single_idx()
846 return -EAGAIN; in armv8pmu_get_single_idx()
858 for (idx = ARMV8_IDX_COUNTER0 + 1; idx < cpu_pmu->num_events; idx += 2) { in armv8pmu_get_chain_idx()
859 if (!test_and_set_bit(idx, cpuc->used_mask)) { in armv8pmu_get_chain_idx()
861 if (!test_and_set_bit(idx - 1, cpuc->used_mask)) in armv8pmu_get_chain_idx()
864 clear_bit(idx, cpuc->used_mask); in armv8pmu_get_chain_idx()
867 return -EAGAIN; in armv8pmu_get_chain_idx()
873 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); in armv8pmu_get_event_idx()
874 struct hw_perf_event *hwc = &event->hw; in armv8pmu_get_event_idx()
875 unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT; in armv8pmu_get_event_idx()
879 if (!test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) in armv8pmu_get_event_idx()
896 int idx = event->hw.idx; in armv8pmu_clear_event_idx()
898 clear_bit(idx, cpuc->used_mask); in armv8pmu_clear_event_idx()
900 clear_bit(idx - 1, cpuc->used_mask); in armv8pmu_clear_event_idx()
911 if (attr->exclude_idle) in armv8pmu_set_event_filter()
912 return -EPERM; in armv8pmu_set_event_filter()
921 if (!attr->exclude_kernel && !attr->exclude_host) in armv8pmu_set_event_filter()
923 if (attr->exclude_guest) in armv8pmu_set_event_filter()
925 if (attr->exclude_host) in armv8pmu_set_event_filter()
928 if (!attr->exclude_hv && !attr->exclude_host) in armv8pmu_set_event_filter()
935 if (attr->exclude_kernel) in armv8pmu_set_event_filter()
938 if (attr->exclude_user) in armv8pmu_set_event_filter()
945 event->config_base = config_base; in armv8pmu_set_event_filter()
952 unsigned long evtype = event->hw.config_base & ARMV8_PMU_EVTYPE_EVENT; in armv8pmu_filter_match()
990 struct arm_pmu *armpmu = to_arm_pmu(event->pmu); in __armv8_pmuv3_map_event()
997 event->hw.flags |= ARMPMU_EVT_64BIT; in __armv8_pmuv3_map_event()
1001 && test_bit(hw_event_id, armpmu->pmceid_bitmap)) { in __armv8_pmuv3_map_event()
1049 struct arm_pmu *cpu_pmu = probe->pmu; in __armv8pmu_probe_pmu()
1061 cpu_pmu->pmuver = pmuver; in __armv8pmu_probe_pmu()
1062 probe->present = true; in __armv8pmu_probe_pmu()
1065 cpu_pmu->num_events = (armv8pmu_pmcr_read() >> ARMV8_PMU_PMCR_N_SHIFT) in __armv8pmu_probe_pmu()
1069 cpu_pmu->num_events += 1; in __armv8pmu_probe_pmu()
1074 bitmap_from_arr32(cpu_pmu->pmceid_bitmap, in __armv8pmu_probe_pmu()
1080 bitmap_from_arr32(cpu_pmu->pmceid_ext_bitmap, in __armv8pmu_probe_pmu()
1085 cpu_pmu->reg_pmmir = read_cpuid(PMMIR_EL1); in __armv8pmu_probe_pmu()
1087 cpu_pmu->reg_pmmir = 0; in __armv8pmu_probe_pmu()
1098 ret = smp_call_function_any(&cpu_pmu->supported_cpus, in armv8pmu_probe_pmu()
1104 return probe.present ? 0 : -ENODEV; in armv8pmu_probe_pmu()
1117 cpu_pmu->handle_irq = armv8pmu_handle_irq; in armv8_pmu_init()
1118 cpu_pmu->enable = armv8pmu_enable_event; in armv8_pmu_init()
1119 cpu_pmu->disable = armv8pmu_disable_event; in armv8_pmu_init()
1120 cpu_pmu->read_counter = armv8pmu_read_counter; in armv8_pmu_init()
1121 cpu_pmu->write_counter = armv8pmu_write_counter; in armv8_pmu_init()
1122 cpu_pmu->get_event_idx = armv8pmu_get_event_idx; in armv8_pmu_init()
1123 cpu_pmu->clear_event_idx = armv8pmu_clear_event_idx; in armv8_pmu_init()
1124 cpu_pmu->start = armv8pmu_start; in armv8_pmu_init()
1125 cpu_pmu->stop = armv8pmu_stop; in armv8_pmu_init()
1126 cpu_pmu->reset = armv8pmu_reset; in armv8_pmu_init()
1127 cpu_pmu->set_event_filter = armv8pmu_set_event_filter; in armv8_pmu_init()
1128 cpu_pmu->filter_match = armv8pmu_filter_match; in armv8_pmu_init()
1130 cpu_pmu->name = name; in armv8_pmu_init()
1131 cpu_pmu->map_event = map_event; in armv8_pmu_init()
1132 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ? in armv8_pmu_init()
1134 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = format ? in armv8_pmu_init()
1136 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ? in armv8_pmu_init()
1251 {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init},
1252 {.compatible = "arm,cortex-a34-pmu", .data = armv8_a34_pmu_init},
1253 {.compatible = "arm,cortex-a35-pmu", .data = armv8_a35_pmu_init},
1254 {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init},
1255 {.compatible = "arm,cortex-a55-pmu", .data = armv8_a55_pmu_init},
1256 {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init},
1257 {.compatible = "arm,cortex-a65-pmu", .data = armv8_a65_pmu_init},
1258 {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init},
1259 {.compatible = "arm,cortex-a73-pmu", .data = armv8_a73_pmu_init},
1260 {.compatible = "arm,cortex-a75-pmu", .data = armv8_a75_pmu_init},
1261 {.compatible = "arm,cortex-a76-pmu", .data = armv8_a76_pmu_init},
1262 {.compatible = "arm,cortex-a77-pmu", .data = armv8_a77_pmu_init},
1263 {.compatible = "arm,cortex-a78-pmu", .data = armv8_a78_pmu_init},
1264 {.compatible = "arm,neoverse-e1-pmu", .data = armv8_e1_pmu_init},
1265 {.compatible = "arm,neoverse-n1-pmu", .data = armv8_n1_pmu_init},
1266 {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init},
1267 {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init},
1301 userpg->cap_user_time = 0; in device_initcall()
1302 userpg->cap_user_time_zero = 0; in device_initcall()
1303 userpg->cap_user_time_short = 0; in device_initcall()
1308 if (rd->read_sched_clock != arch_timer_read_counter) in device_initcall()
1311 userpg->time_mult = rd->mult; in device_initcall()
1312 userpg->time_shift = rd->shift; in device_initcall()
1313 userpg->time_zero = rd->epoch_ns; in device_initcall()
1314 userpg->time_cycles = rd->epoch_cyc; in device_initcall()
1315 userpg->time_mask = rd->sched_clock_mask; in device_initcall()
1322 ns = mul_u64_u32_shr(rd->epoch_cyc, rd->mult, rd->shift); in device_initcall()
1323 userpg->time_zero -= ns; in device_initcall()
1327 userpg->time_offset = userpg->time_zero - now; in device_initcall()
1332 * 32-bit value (now specifies a 64-bit value) - refer in device_initcall()
1335 if (userpg->time_shift == 32) { in device_initcall()
1336 userpg->time_shift = 31; in device_initcall()
1337 userpg->time_mult >>= 1; in device_initcall()
1344 userpg->cap_user_time = 1; in device_initcall()
1345 userpg->cap_user_time_zero = 1; in device_initcall()
1346 userpg->cap_user_time_short = 1; in device_initcall()