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