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