xref: /arm-trusted-firmware/lib/cpus/aarch64/cpuamu.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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