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