1f06890eaSDimitris Papastamos /* 2f06890eaSDimitris Papastamos * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3f06890eaSDimitris Papastamos * 4f06890eaSDimitris Papastamos * SPDX-License-Identifier: BSD-3-Clause 5f06890eaSDimitris Papastamos */ 6f06890eaSDimitris Papastamos 7f06890eaSDimitris Papastamos #include <cpuamu.h> 8*09d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/pubsub_events.h> 9*09d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 10f06890eaSDimitris Papastamos 11714b21ffSDimitris Papastamos #define CPUAMU_NR_COUNTERS 5U 12f06890eaSDimitris Papastamos 1340692923SDaniel Boulby struct cpuamu_ctx { 14f06890eaSDimitris Papastamos uint64_t cnts[CPUAMU_NR_COUNTERS]; 15714b21ffSDimitris Papastamos unsigned int mask; 16f06890eaSDimitris Papastamos }; 17f06890eaSDimitris Papastamos 1840692923SDaniel Boulby static struct cpuamu_ctx cpuamu_ctxs[PLATFORM_CORE_COUNT]; 19f06890eaSDimitris Papastamos midr_match(unsigned int cpu_midr)20f06890eaSDimitris Papastamosint midr_match(unsigned int cpu_midr) 21f06890eaSDimitris Papastamos { 22f06890eaSDimitris Papastamos unsigned int midr, midr_mask; 23f06890eaSDimitris Papastamos 24714b21ffSDimitris Papastamos midr = (unsigned int)read_midr(); 25f06890eaSDimitris Papastamos midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | 26f06890eaSDimitris Papastamos (MIDR_PN_MASK << MIDR_PN_SHIFT); 27f06890eaSDimitris Papastamos return ((midr & midr_mask) == (cpu_midr & midr_mask)); 28f06890eaSDimitris Papastamos } 29f06890eaSDimitris Papastamos cpuamu_context_save(unsigned int nr_counters)30f06890eaSDimitris Papastamosvoid cpuamu_context_save(unsigned int nr_counters) 31f06890eaSDimitris Papastamos { 3240692923SDaniel Boulby struct cpuamu_ctx *ctx = &cpuamu_ctxs[plat_my_core_pos()]; 33714b21ffSDimitris Papastamos unsigned int i; 34f06890eaSDimitris Papastamos 35f06890eaSDimitris Papastamos assert(nr_counters <= CPUAMU_NR_COUNTERS); 36f06890eaSDimitris Papastamos 37f06890eaSDimitris Papastamos /* Save counter configuration */ 38f06890eaSDimitris Papastamos ctx->mask = cpuamu_read_cpuamcntenset_el0(); 39f06890eaSDimitris Papastamos 40f06890eaSDimitris Papastamos /* Disable counters */ 41f06890eaSDimitris Papastamos cpuamu_write_cpuamcntenclr_el0(ctx->mask); 42f06890eaSDimitris Papastamos isb(); 43f06890eaSDimitris Papastamos 44f06890eaSDimitris Papastamos /* Save counters */ 45f06890eaSDimitris Papastamos for (i = 0; i < nr_counters; i++) 46f06890eaSDimitris Papastamos ctx->cnts[i] = cpuamu_cnt_read(i); 47f06890eaSDimitris Papastamos } 48f06890eaSDimitris Papastamos cpuamu_context_restore(unsigned int nr_counters)49f06890eaSDimitris Papastamosvoid cpuamu_context_restore(unsigned int nr_counters) 50f06890eaSDimitris Papastamos { 5140692923SDaniel Boulby struct cpuamu_ctx *ctx = &cpuamu_ctxs[plat_my_core_pos()]; 52714b21ffSDimitris Papastamos unsigned int i; 53f06890eaSDimitris Papastamos 54f06890eaSDimitris Papastamos assert(nr_counters <= CPUAMU_NR_COUNTERS); 55f06890eaSDimitris Papastamos 56f06890eaSDimitris Papastamos /* 57f06890eaSDimitris Papastamos * Disable counters. They were enabled early in the 58f06890eaSDimitris Papastamos * CPU reset function. 59f06890eaSDimitris Papastamos */ 60f06890eaSDimitris Papastamos cpuamu_write_cpuamcntenclr_el0(ctx->mask); 61f06890eaSDimitris Papastamos isb(); 62f06890eaSDimitris Papastamos 63f06890eaSDimitris Papastamos /* Restore counters */ 64f06890eaSDimitris Papastamos for (i = 0; i < nr_counters; i++) 65f06890eaSDimitris Papastamos cpuamu_cnt_write(i, ctx->cnts[i]); 66f06890eaSDimitris Papastamos isb(); 67f06890eaSDimitris Papastamos 68f06890eaSDimitris Papastamos /* Restore counter configuration */ 69f06890eaSDimitris Papastamos cpuamu_write_cpuamcntenset_el0(ctx->mask); 70f06890eaSDimitris Papastamos } 71