|
@@ -326,10 +326,22 @@ static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
|
|
[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED,
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+static ssize_t
|
|
|
+armv8pmu_events_sysfs_show(struct device *dev,
|
|
|
+ struct device_attribute *attr, char *page)
|
|
|
+{
|
|
|
+ struct perf_pmu_events_attr *pmu_attr;
|
|
|
+
|
|
|
+ pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
|
|
|
+
|
|
|
+ return sprintf(page, "event=0x%03llx\n", pmu_attr->id);
|
|
|
+}
|
|
|
+
|
|
|
#define ARMV8_EVENT_ATTR_RESOLVE(m) #m
|
|
|
#define ARMV8_EVENT_ATTR(name, config) \
|
|
|
- PMU_EVENT_ATTR_STRING(name, armv8_event_attr_##name, \
|
|
|
- "event=" ARMV8_EVENT_ATTR_RESOLVE(config))
|
|
|
+ PMU_EVENT_ATTR(name, armv8_event_attr_##name, \
|
|
|
+ config, armv8pmu_events_sysfs_show)
|
|
|
|
|
|
ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR);
|
|
|
ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL);
|
|
@@ -434,9 +446,27 @@ static struct attribute *armv8_pmuv3_event_attrs[] = {
|
|
|
NULL,
|
|
|
};
|
|
|
|
|
|
+static umode_t
|
|
|
+armv8pmu_event_attr_is_visible(struct kobject *kobj,
|
|
|
+ struct attribute *attr, int unused)
|
|
|
+{
|
|
|
+ struct device *dev = kobj_to_dev(kobj);
|
|
|
+ struct pmu *pmu = dev_get_drvdata(dev);
|
|
|
+ struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu);
|
|
|
+ struct perf_pmu_events_attr *pmu_attr;
|
|
|
+
|
|
|
+ pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr.attr);
|
|
|
+
|
|
|
+ if (test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap))
|
|
|
+ return attr->mode;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static struct attribute_group armv8_pmuv3_events_attr_group = {
|
|
|
.name = "events",
|
|
|
.attrs = armv8_pmuv3_event_attrs,
|
|
|
+ .is_visible = armv8pmu_event_attr_is_visible,
|
|
|
};
|
|
|
|
|
|
PMU_FORMAT_ATTR(event, "config:0-9");
|
|
@@ -859,22 +889,31 @@ static int armv8_thunder_map_event(struct perf_event *event)
|
|
|
ARMV8_PMU_EVTYPE_EVENT);
|
|
|
}
|
|
|
|
|
|
-static void armv8pmu_read_num_pmnc_events(void *info)
|
|
|
+static void __armv8pmu_probe_pmu(void *info)
|
|
|
{
|
|
|
- int *nb_cnt = info;
|
|
|
+ struct arm_pmu *cpu_pmu = info;
|
|
|
+ u32 pmceid[2];
|
|
|
|
|
|
/* Read the nb of CNTx counters supported from PMNC */
|
|
|
- *nb_cnt = (armv8pmu_pmcr_read() >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK;
|
|
|
+ cpu_pmu->num_events = (armv8pmu_pmcr_read() >> ARMV8_PMU_PMCR_N_SHIFT)
|
|
|
+ & ARMV8_PMU_PMCR_N_MASK;
|
|
|
|
|
|
/* Add the CPU cycles counter */
|
|
|
- *nb_cnt += 1;
|
|
|
+ cpu_pmu->num_events += 1;
|
|
|
+
|
|
|
+ pmceid[0] = read_sysreg(pmceid0_el0);
|
|
|
+ pmceid[1] = read_sysreg(pmceid1_el0);
|
|
|
+
|
|
|
+ bitmap_from_u32array(cpu_pmu->pmceid_bitmap,
|
|
|
+ ARMV8_PMUV3_MAX_COMMON_EVENTS, pmceid,
|
|
|
+ ARRAY_SIZE(pmceid));
|
|
|
}
|
|
|
|
|
|
-static int armv8pmu_probe_num_events(struct arm_pmu *arm_pmu)
|
|
|
+static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu)
|
|
|
{
|
|
|
- return smp_call_function_any(&arm_pmu->supported_cpus,
|
|
|
- armv8pmu_read_num_pmnc_events,
|
|
|
- &arm_pmu->num_events, 1);
|
|
|
+ return smp_call_function_any(&cpu_pmu->supported_cpus,
|
|
|
+ __armv8pmu_probe_pmu,
|
|
|
+ cpu_pmu, 1);
|
|
|
}
|
|
|
|
|
|
static void armv8_pmu_init(struct arm_pmu *cpu_pmu)
|
|
@@ -897,7 +936,8 @@ static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu)
|
|
|
armv8_pmu_init(cpu_pmu);
|
|
|
cpu_pmu->name = "armv8_pmuv3";
|
|
|
cpu_pmu->map_event = armv8_pmuv3_map_event;
|
|
|
- return armv8pmu_probe_num_events(cpu_pmu);
|
|
|
+ cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
|
|
|
+ return armv8pmu_probe_pmu(cpu_pmu);
|
|
|
}
|
|
|
|
|
|
static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
|
|
@@ -906,7 +946,7 @@ static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
|
|
|
cpu_pmu->name = "armv8_cortex_a53";
|
|
|
cpu_pmu->map_event = armv8_a53_map_event;
|
|
|
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
|
|
|
- return armv8pmu_probe_num_events(cpu_pmu);
|
|
|
+ return armv8pmu_probe_pmu(cpu_pmu);
|
|
|
}
|
|
|
|
|
|
static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
|
|
@@ -915,7 +955,7 @@ static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
|
|
|
cpu_pmu->name = "armv8_cortex_a57";
|
|
|
cpu_pmu->map_event = armv8_a57_map_event;
|
|
|
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
|
|
|
- return armv8pmu_probe_num_events(cpu_pmu);
|
|
|
+ return armv8pmu_probe_pmu(cpu_pmu);
|
|
|
}
|
|
|
|
|
|
static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu)
|
|
@@ -924,7 +964,7 @@ static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu)
|
|
|
cpu_pmu->name = "armv8_cortex_a72";
|
|
|
cpu_pmu->map_event = armv8_a57_map_event;
|
|
|
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
|
|
|
- return armv8pmu_probe_num_events(cpu_pmu);
|
|
|
+ return armv8pmu_probe_pmu(cpu_pmu);
|
|
|
}
|
|
|
|
|
|
static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu)
|
|
@@ -933,7 +973,7 @@ static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu)
|
|
|
cpu_pmu->name = "armv8_cavium_thunder";
|
|
|
cpu_pmu->map_event = armv8_thunder_map_event;
|
|
|
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
|
|
|
- return armv8pmu_probe_num_events(cpu_pmu);
|
|
|
+ return armv8pmu_probe_pmu(cpu_pmu);
|
|
|
}
|
|
|
|
|
|
static const struct of_device_id armv8_pmu_of_device_ids[] = {
|