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