xref: /aosp_15_r20/external/arm-trusted-firmware/lib/cpus/aarch64/cpuamu.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
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 Park int 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 Park void 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 Park void 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