/**
- * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2015. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
/* Maximum number of per-core counters - currently reserves enough space for two full hardware PMUs for big.LITTLE */
#define CNTMAX 16
#define CCI_400 4
+#define CCI_500 8
#define CCN_5XX 8
/* Maximum number of uncore counters */
/* + 1 for the cci-400 cycles counter */
+/* cci-500 has no cycles counter */
/* + 1 for the CCN-5xx cycles counter */
-#define UCCNT (CCI_400 + 1 + CCN_5XX + 1)
+#define UCCNT (CCI_400 + 1 + CCI_500 + CCN_5XX + 1)
/* Default to 0 if unable to probe the revision which was the previous behavior */
#define DEFAULT_CCI_REVISION 0
static int uc_attr_count;
struct gator_event {
- int curr;
- int prev;
- int prev_delta;
+ uint32_t curr;
+ uint32_t prev;
+ uint32_t prev_delta;
bool zero;
struct perf_event *pevent;
struct perf_event_attr *pevent_attr;
static void __read(int *const len, int cpu, struct gator_attr *const attr, struct gator_event *const event)
{
- int delta;
+ uint32_t delta;
struct perf_event *const ev = event->pevent;
if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
event->prev_delta = delta;
event->prev = event->curr;
per_cpu(perf_cnt, cpu)[(*len)++] = attr->key;
- if (delta < 0)
- delta *= -1;
per_cpu(perf_cnt, cpu)[(*len)++] = delta;
}
}
#endif
-static void gator_events_perf_pmu_uncore_init(const char *const name, const int type, const int count)
+static void gator_events_perf_pmu_uncore_init(const char *const name, const int type, const int count, const bool has_cycles_counter)
{
int cnt;
- snprintf(uc_attrs[uc_attr_count].name, sizeof(uc_attrs[uc_attr_count].name), "%s_ccnt", name);
- uc_attrs[uc_attr_count].type = type;
- ++uc_attr_count;
+ if (has_cycles_counter) {
+ snprintf(uc_attrs[uc_attr_count].name, sizeof(uc_attrs[uc_attr_count].name), "%s_ccnt", name);
+ uc_attrs[uc_attr_count].type = type;
+ ++uc_attr_count;
+ }
for (cnt = 0; cnt < count; ++cnt, ++uc_attr_count) {
struct gator_attr *const attr = &uc_attrs[uc_attr_count];
}
}
-static void gator_events_perf_pmu_cci_init(const int type)
+static void gator_events_perf_pmu_cci_400_init(const int type)
{
const char *cci_name;
return;
}
- gator_events_perf_pmu_uncore_init(cci_name, type, CCI_400);
+ gator_events_perf_pmu_uncore_init(cci_name, type, CCI_400, true);
}
static void gator_events_perf_pmu_cpu_init(const struct gator_cpu *const gator_cpu, const int type)
if (pe->pmu != NULL && type == pe->pmu->type) {
if (strcmp("CCI", pe->pmu->name) == 0 || strcmp("CCI_400", pe->pmu->name) == 0 || strcmp("CCI_400-r1", pe->pmu->name) == 0) {
- gator_events_perf_pmu_cci_init(type);
+ gator_events_perf_pmu_cci_400_init(type);
+ } else if (strcmp("CCI_500", pe->pmu->name) == 0) {
+ gator_events_perf_pmu_uncore_init("CCI_500", type, CCI_500, false);
} else if (strcmp("ccn", pe->pmu->name) == 0) {
- gator_events_perf_pmu_uncore_init("ARM_CCN_5XX", type, CCN_5XX);
+ gator_events_perf_pmu_uncore_init("ARM_CCN_5XX", type, CCN_5XX, true);
} else if ((gator_cpu = gator_find_cpu_by_pmu_name(pe->pmu->name)) != NULL) {
found_cpu = true;
gator_events_perf_pmu_cpu_init(gator_cpu, type);
}
if (!found_cpu) {
- const struct gator_cpu *const gator_cpu = gator_find_cpu_by_cpuid(gator_cpuid());
+ const struct gator_cpu *gator_cpu = gator_find_cpu_by_cpuid(gator_cpuid());
- if (gator_cpu == NULL)
- return -1;
+ if (gator_cpu == NULL) {
+ gator_cpu = gator_find_cpu_by_cpuid(OTHER);
+ if (gator_cpu == NULL) {
+ pr_err("gator: Didn't find cpu\n");
+ return -1;
+ }
+ }
gator_events_perf_pmu_cpu_init(gator_cpu, PERF_TYPE_RAW);
}