1 /*
2  * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef AMU_H
8 #define AMU_H
9 
10 #include <stdbool.h>
11 #include <stdint.h>
12 
13 #include <lib/cassert.h>
14 #include <lib/utils_def.h>
15 
16 #include <context.h>
17 #include <platform_def.h>
18 
19 /* All group 0 counters */
20 #define AMU_GROUP0_COUNTERS_MASK	U(0xf)
21 #define AMU_GROUP0_NR_COUNTERS		U(4)
22 
23 #ifdef PLAT_AMU_GROUP1_COUNTERS_MASK
24 #define AMU_GROUP1_COUNTERS_MASK	PLAT_AMU_GROUP1_COUNTERS_MASK
25 #else
26 #define AMU_GROUP1_COUNTERS_MASK	U(0)
27 #endif
28 
29 /* Calculate number of group 1 counters */
30 #if (AMU_GROUP1_COUNTERS_MASK	& (1 << 15))
31 #define	AMU_GROUP1_NR_COUNTERS		16U
32 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 14))
33 #define	AMU_GROUP1_NR_COUNTERS		15U
34 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 13))
35 #define	AMU_GROUP1_NR_COUNTERS		14U
36 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 12))
37 #define	AMU_GROUP1_NR_COUNTERS		13U
38 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 11))
39 #define	AMU_GROUP1_NR_COUNTERS		12U
40 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 10))
41 #define	AMU_GROUP1_NR_COUNTERS		11U
42 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 9))
43 #define	AMU_GROUP1_NR_COUNTERS		10U
44 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 8))
45 #define	AMU_GROUP1_NR_COUNTERS		9U
46 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 7))
47 #define	AMU_GROUP1_NR_COUNTERS		8U
48 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 6))
49 #define	AMU_GROUP1_NR_COUNTERS		7U
50 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 5))
51 #define	AMU_GROUP1_NR_COUNTERS		6U
52 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 4))
53 #define	AMU_GROUP1_NR_COUNTERS		5U
54 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 3))
55 #define	AMU_GROUP1_NR_COUNTERS		4U
56 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 2))
57 #define	AMU_GROUP1_NR_COUNTERS		3U
58 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 1))
59 #define	AMU_GROUP1_NR_COUNTERS		2U
60 #elif (AMU_GROUP1_COUNTERS_MASK	& (1 << 0))
61 #define	AMU_GROUP1_NR_COUNTERS		1U
62 #else
63 #define	AMU_GROUP1_NR_COUNTERS		0U
64 #endif
65 
66 CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask);
67 
68 struct amu_ctx {
69 	uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS];
70 #if __aarch64__
71 	/* Architected event counter 1 does not have an offset register. */
72 	uint64_t group0_voffsets[AMU_GROUP0_NR_COUNTERS-1];
73 #endif
74 
75 #if AMU_GROUP1_NR_COUNTERS
76 	uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS];
77 #if __aarch64__
78 	uint64_t group1_voffsets[AMU_GROUP1_NR_COUNTERS];
79 #endif
80 #endif
81 };
82 
83 unsigned int amu_get_version(void);
84 #if __aarch64__
85 void amu_enable(bool el2_unused, cpu_context_t *ctx);
86 #else
87 void amu_enable(bool el2_unused);
88 #endif
89 
90 /* Group 0 configuration helpers */
91 uint64_t amu_group0_cnt_read(unsigned int idx);
92 void amu_group0_cnt_write(unsigned int idx, uint64_t val);
93 
94 #if __aarch64__
95 uint64_t amu_group0_voffset_read(unsigned int idx);
96 void amu_group0_voffset_write(unsigned int idx, uint64_t val);
97 #endif
98 
99 #if AMU_GROUP1_NR_COUNTERS
100 bool amu_group1_supported(void);
101 
102 /* Group 1 configuration helpers */
103 uint64_t amu_group1_cnt_read(unsigned int idx);
104 void amu_group1_cnt_write(unsigned int idx, uint64_t val);
105 void amu_group1_set_evtype(unsigned int idx, unsigned int val);
106 
107 #if __aarch64__
108 uint64_t amu_group1_voffset_read(unsigned int idx);
109 void amu_group1_voffset_write(unsigned int idx, uint64_t val);
110 #endif
111 
112 #endif
113 
114 #endif /* AMU_H */
115