xref: /rk3399_ARM-atf/lib/extensions/amu/aarch64/amu.c (revision 0767d50e699d3d9cb827172dd7742618d37aabe0)
1 /*
2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <amu.h>
8 #include <amu_private.h>
9 #include <arch.h>
10 #include <arch_helpers.h>
11 #include <assert.h>
12 #include <debug.h>
13 
14 #define AMU_GROUP0_NR_COUNTERS	4
15 
16 int amu_supported(void)
17 {
18 	uint64_t features;
19 
20 	features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT;
21 	return (features & ID_AA64PFR0_AMU_MASK) == 1;
22 }
23 
24 /*
25  * Enable counters.  This function is meant to be invoked
26  * by the context management library before exiting from EL3.
27  */
28 void amu_enable(int el2_unused)
29 {
30 	uint64_t v;
31 
32 	if (!amu_supported()) {
33 		WARN("Cannot enable AMU - not supported\n");
34 		return;
35 	}
36 
37 	if (el2_unused) {
38 		/*
39 		 * CPTR_EL2.TAM: Set to zero so any accesses to
40 		 * the Activity Monitor registers do not trap to EL2.
41 		 */
42 		v = read_cptr_el2();
43 		v &= ~CPTR_EL2_TAM_BIT;
44 		write_cptr_el2(v);
45 	}
46 
47 	/*
48 	 * CPTR_EL3.TAM: Set to zero so that any accesses to
49 	 * the Activity Monitor registers do not trap to EL3.
50 	 */
51 	v = read_cptr_el3();
52 	v &= ~TAM_BIT;
53 	write_cptr_el3(v);
54 
55 	/* Enable group 0 counters */
56 	write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK);
57 	/* Enable group 1 counters */
58 	write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK);
59 }
60 
61 /* Read the group 0 counter identified by the given `idx`. */
62 uint64_t amu_group0_cnt_read(int idx)
63 {
64 	assert(amu_supported());
65 	assert(idx >= 0 && idx < AMU_GROUP0_NR_COUNTERS);
66 
67 	return amu_group0_cnt_read_internal(idx);
68 }
69 
70 /* Write the group 0 counter identified by the given `idx` with `val`. */
71 void amu_group0_cnt_write(int idx, uint64_t val)
72 {
73 	assert(amu_supported());
74 	assert(idx >= 0 && idx < AMU_GROUP0_NR_COUNTERS);
75 
76 	amu_group0_cnt_write_internal(idx, val);
77 	isb();
78 }
79 
80 /* Read the group 1 counter identified by the given `idx`. */
81 uint64_t amu_group1_cnt_read(int idx)
82 {
83 	assert(amu_supported());
84 	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
85 
86 	return amu_group1_cnt_read_internal(idx);
87 }
88 
89 /* Write the group 1 counter identified by the given `idx` with `val`. */
90 void amu_group1_cnt_write(int idx, uint64_t val)
91 {
92 	assert(amu_supported());
93 	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
94 
95 	amu_group1_cnt_write_internal(idx, val);
96 	isb();
97 }
98 
99 /*
100  * Program the event type register for the given `idx` with
101  * the event number `val`.
102  */
103 void amu_group1_set_evtype(int idx, unsigned int val)
104 {
105 	assert(amu_supported());
106 	assert (idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
107 
108 	amu_group1_set_evtype_internal(idx, val);
109 	isb();
110 }
111