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