static void get_capabilities(struct quadd_comm_cap *cap) { int i, event; unsigned int extra = 0; struct quadd_events_cap *events_cap = &cap->events_cap; cap->pmu = ctx.pmu ? 1 : 0; cap->l2_cache = 0; if (ctx.pl310) { cap->l2_cache = 1; cap->l2_multiple_events = 0; } else if (ctx.pmu) { struct source_info *s = &ctx.pmu_info; for (i = 0; i < s->nr_supported_events; i++) { event = s->supported_events[i]; if (event == QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES || event == QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES || event == QUADD_EVENT_TYPE_L2_ICACHE_MISSES) { cap->l2_cache = 1; cap->l2_multiple_events = 1; break; } } } events_cap->cpu_cycles = 0; events_cap->l1_dcache_read_misses = 0; events_cap->l1_dcache_write_misses = 0; events_cap->l1_icache_misses = 0; events_cap->instructions = 0; events_cap->branch_instructions = 0; events_cap->branch_misses = 0; events_cap->bus_cycles = 0; events_cap->l2_dcache_read_misses = 0; events_cap->l2_dcache_write_misses = 0; events_cap->l2_icache_misses = 0; if (ctx.pl310) { struct source_info *s = &ctx.pl310_info; for (i = 0; i < s->nr_supported_events; i++) { int event = s->supported_events[i]; switch (event) { case QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES: events_cap->l2_dcache_read_misses = 1; break; case QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES: events_cap->l2_dcache_write_misses = 1; break; case QUADD_EVENT_TYPE_L2_ICACHE_MISSES: events_cap->l2_icache_misses = 1; break; default: pr_err_once("%s: error: invalid event\n", __func__); return; } } } if (ctx.pmu) { struct source_info *s = &ctx.pmu_info; for (i = 0; i < s->nr_supported_events; i++) { int event = s->supported_events[i]; switch (event) { case QUADD_EVENT_TYPE_CPU_CYCLES: events_cap->cpu_cycles = 1; break; case QUADD_EVENT_TYPE_INSTRUCTIONS: events_cap->instructions = 1; break; case QUADD_EVENT_TYPE_BRANCH_INSTRUCTIONS: events_cap->branch_instructions = 1; break; case QUADD_EVENT_TYPE_BRANCH_MISSES: events_cap->branch_misses = 1; break; case QUADD_EVENT_TYPE_BUS_CYCLES: events_cap->bus_cycles = 1; break; case QUADD_EVENT_TYPE_L1_DCACHE_READ_MISSES: events_cap->l1_dcache_read_misses = 1; break; case QUADD_EVENT_TYPE_L1_DCACHE_WRITE_MISSES: events_cap->l1_dcache_write_misses = 1; break; case QUADD_EVENT_TYPE_L1_ICACHE_MISSES: events_cap->l1_icache_misses = 1; break; case QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES: events_cap->l2_dcache_read_misses = 1; break; case QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES: events_cap->l2_dcache_write_misses = 1; break; case QUADD_EVENT_TYPE_L2_ICACHE_MISSES: events_cap->l2_icache_misses = 1; break; default: pr_err_once("%s: error: invalid event\n", __func__); return; } } } cap->tegra_lp_cluster = quadd_is_cpu_with_lp_cluster(); cap->power_rate = 1; cap->blocked_read = 1; extra |= QUADD_COMM_CAP_EXTRA_BT_KERNEL_CTX; extra |= QUADD_COMM_CAP_EXTRA_GET_MMAP; extra |= QUADD_COMM_CAP_EXTRA_GROUP_SAMPLES; extra |= QUADD_COMM_CAP_EXTRA_BT_UNWIND_TABLES; extra |= QUADD_COMM_CAP_EXTRA_SUPPORT_AARCH64; extra |= QUADD_COMM_CAP_EXTRA_SPECIAL_ARCH_MMAP; extra |= QUADD_COMM_CAP_EXTRA_UNWIND_MIXED; extra |= QUADD_COMM_CAP_EXTRA_UNW_ENTRY_TYPE; extra |= QUADD_COMM_CAP_EXTRA_RB_MMAP_OP; if (ctx.hrt->tc) extra |= QUADD_COMM_CAP_EXTRA_ARCH_TIMER; cap->reserved[QUADD_COMM_CAP_IDX_EXTRA] = extra; }
static void get_capabilities(struct quadd_comm_cap *cap) { int i, event; struct quadd_events_cap *events_cap = &cap->events_cap; cap->pmu = ctx.pmu ? 1 : 0; cap->l2_cache = 0; if (ctx.pl310) { cap->l2_cache = 1; cap->l2_multiple_events = 0; } else if (ctx.pmu) { struct source_info *s = &ctx.pmu_info; for (i = 0; i < s->nr_supported_events; i++) { event = s->supported_events[i]; if (event == QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES || event == QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES || event == QUADD_EVENT_TYPE_L2_ICACHE_MISSES) { cap->l2_cache = 1; cap->l2_multiple_events = 1; break; } } } events_cap->cpu_cycles = 0; events_cap->l1_dcache_read_misses = 0; events_cap->l1_dcache_write_misses = 0; events_cap->l1_icache_misses = 0; events_cap->instructions = 0; events_cap->branch_instructions = 0; events_cap->branch_misses = 0; events_cap->bus_cycles = 0; events_cap->l2_dcache_read_misses = 0; events_cap->l2_dcache_write_misses = 0; events_cap->l2_icache_misses = 0; if (ctx.pl310) { struct source_info *s = &ctx.pl310_info; for (i = 0; i < s->nr_supported_events; i++) { int event = s->supported_events[i]; switch (event) { case QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES: events_cap->l2_dcache_read_misses = 1; break; case QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES: events_cap->l2_dcache_write_misses = 1; break; case QUADD_EVENT_TYPE_L2_ICACHE_MISSES: events_cap->l2_icache_misses = 1; break; default: BUG(); break; } } } if (ctx.pmu) { struct source_info *s = &ctx.pmu_info; for (i = 0; i < s->nr_supported_events; i++) { int event = s->supported_events[i]; switch (event) { case QUADD_EVENT_TYPE_CPU_CYCLES: events_cap->cpu_cycles = 1; break; case QUADD_EVENT_TYPE_INSTRUCTIONS: events_cap->instructions = 1; break; case QUADD_EVENT_TYPE_BRANCH_INSTRUCTIONS: events_cap->branch_instructions = 1; break; case QUADD_EVENT_TYPE_BRANCH_MISSES: events_cap->branch_misses = 1; break; case QUADD_EVENT_TYPE_BUS_CYCLES: events_cap->bus_cycles = 1; break; case QUADD_EVENT_TYPE_L1_DCACHE_READ_MISSES: events_cap->l1_dcache_read_misses = 1; break; case QUADD_EVENT_TYPE_L1_DCACHE_WRITE_MISSES: events_cap->l1_dcache_write_misses = 1; break; case QUADD_EVENT_TYPE_L1_ICACHE_MISSES: events_cap->l1_icache_misses = 1; break; case QUADD_EVENT_TYPE_L2_DCACHE_READ_MISSES: events_cap->l2_dcache_read_misses = 1; break; case QUADD_EVENT_TYPE_L2_DCACHE_WRITE_MISSES: events_cap->l2_dcache_write_misses = 1; break; case QUADD_EVENT_TYPE_L2_ICACHE_MISSES: events_cap->l2_icache_misses = 1; break; default: BUG(); break; } } } cap->tegra_lp_cluster = quadd_is_cpu_with_lp_cluster(); cap->power_rate = 1; cap->blocked_read = 0; }