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