• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <assert_macros.S>
9#include <asm_macros.S>
10
11	.globl	amu_group0_cnt_read_internal
12	.globl	amu_group0_cnt_write_internal
13	.globl	amu_group1_cnt_read_internal
14	.globl	amu_group1_cnt_write_internal
15	.globl	amu_group1_set_evtype_internal
16
17/*
18 * uint64_t amu_group0_cnt_read_internal(int idx);
19 *
20 * Given `idx`, read the corresponding AMU counter
21 * and return it in `x0`.
22 */
23func amu_group0_cnt_read_internal
24	adr	x1, 1f
25#if ENABLE_ASSERTIONS
26	/*
27	 * It can be dangerous to call this function with an
28	 * out of bounds index.  Ensure `idx` is valid.
29	 */
30	tst	x0, #~3
31	ASM_ASSERT(eq)
32#endif
33	/*
34	 * Given `idx` calculate address of mrs/ret instruction pair
35	 * in the table below.
36	 */
37	add	x1, x1, x0, lsl #3	/* each mrs/ret sequence is 8 bytes */
38#if ENABLE_BTI
39	add	x1, x1, x0, lsl #2	/* + "bti j" instruction */
40#endif
41	br	x1
42
431:	read	AMEVCNTR00_EL0		/* index 0 */
44	read	AMEVCNTR01_EL0		/* index 1 */
45	read	AMEVCNTR02_EL0		/* index 2 */
46	read	AMEVCNTR03_EL0		/* index 3 */
47endfunc amu_group0_cnt_read_internal
48
49/*
50 * void amu_group0_cnt_write_internal(int idx, uint64_t val);
51 *
52 * Given `idx`, write `val` to the corresponding AMU counter.
53 */
54func amu_group0_cnt_write_internal
55	adr	x2, 1f
56#if ENABLE_ASSERTIONS
57	/*
58	 * It can be dangerous to call this function with an
59	 * out of bounds index.  Ensure `idx` is valid.
60	 */
61	tst	x0, #~3
62	ASM_ASSERT(eq)
63#endif
64	/*
65	 * Given `idx` calculate address of mrs/ret instruction pair
66	 * in the table below.
67	 */
68	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
69#if ENABLE_BTI
70	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
71#endif
72	br	x2
73
741:	write	AMEVCNTR00_EL0		/* index 0 */
75	write	AMEVCNTR01_EL0		/* index 1 */
76	write	AMEVCNTR02_EL0		/* index 2 */
77	write	AMEVCNTR03_EL0		/* index 3 */
78endfunc amu_group0_cnt_write_internal
79
80/*
81 * uint64_t amu_group1_cnt_read_internal(int idx);
82 *
83 * Given `idx`, read the corresponding AMU counter
84 * and return it in `x0`.
85 */
86func amu_group1_cnt_read_internal
87	adr	x1, 1f
88#if ENABLE_ASSERTIONS
89	/*
90	 * It can be dangerous to call this function with an
91	 * out of bounds index.  Ensure `idx` is valid.
92	 */
93	tst	x0, #~0xF
94	ASM_ASSERT(eq)
95#endif
96	/*
97	 * Given `idx` calculate address of mrs/ret instruction pair
98	 * in the table below.
99	 */
100	add	x1, x1, x0, lsl #3	/* each mrs/ret sequence is 8 bytes */
101#if ENABLE_BTI
102	add	x1, x1, x0, lsl #2	/* + "bti j" instruction */
103#endif
104	br	x1
105
1061:	read	AMEVCNTR10_EL0		/* index 0 */
107	read	AMEVCNTR11_EL0		/* index 1 */
108	read	AMEVCNTR12_EL0		/* index 2 */
109	read	AMEVCNTR13_EL0		/* index 3 */
110	read	AMEVCNTR14_EL0		/* index 4 */
111	read	AMEVCNTR15_EL0		/* index 5 */
112	read	AMEVCNTR16_EL0		/* index 6 */
113	read	AMEVCNTR17_EL0		/* index 7 */
114	read	AMEVCNTR18_EL0		/* index 8 */
115	read	AMEVCNTR19_EL0		/* index 9 */
116	read	AMEVCNTR1A_EL0		/* index 10 */
117	read	AMEVCNTR1B_EL0		/* index 11 */
118	read	AMEVCNTR1C_EL0		/* index 12 */
119	read	AMEVCNTR1D_EL0		/* index 13 */
120	read	AMEVCNTR1E_EL0		/* index 14 */
121	read	AMEVCNTR1F_EL0		/* index 15 */
122endfunc amu_group1_cnt_read_internal
123
124/*
125 * void amu_group1_cnt_write_internal(int idx, uint64_t val);
126 *
127 * Given `idx`, write `val` to the corresponding AMU counter.
128 */
129func amu_group1_cnt_write_internal
130	adr	x2, 1f
131#if ENABLE_ASSERTIONS
132	/*
133	 * It can be dangerous to call this function with an
134	 * out of bounds index.  Ensure `idx` is valid.
135	 */
136	tst	x0, #~0xF
137	ASM_ASSERT(eq)
138#endif
139	/*
140	 * Given `idx` calculate address of mrs/ret instruction pair
141	 * in the table below.
142	 */
143	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
144#if ENABLE_BTI
145	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
146#endif
147	br	x2
148
1491:	write	AMEVCNTR10_EL0		/* index 0 */
150	write	AMEVCNTR11_EL0		/* index 1 */
151	write	AMEVCNTR12_EL0		/* index 2 */
152	write	AMEVCNTR13_EL0		/* index 3 */
153	write	AMEVCNTR14_EL0		/* index 4 */
154	write	AMEVCNTR15_EL0		/* index 5 */
155	write	AMEVCNTR16_EL0		/* index 6 */
156	write	AMEVCNTR17_EL0		/* index 7 */
157	write	AMEVCNTR18_EL0		/* index 8 */
158	write	AMEVCNTR19_EL0		/* index 9 */
159	write	AMEVCNTR1A_EL0		/* index 10 */
160	write	AMEVCNTR1B_EL0		/* index 11 */
161	write	AMEVCNTR1C_EL0		/* index 12 */
162	write	AMEVCNTR1D_EL0		/* index 13 */
163	write	AMEVCNTR1E_EL0		/* index 14 */
164	write	AMEVCNTR1F_EL0		/* index 15 */
165endfunc amu_group1_cnt_write_internal
166
167/*
168 * void amu_group1_set_evtype_internal(int idx, unsigned int val);
169 *
170 * Program the AMU event type register indexed by `idx`
171 * with the value `val`.
172 */
173func amu_group1_set_evtype_internal
174	adr	x2, 1f
175#if ENABLE_ASSERTIONS
176	/*
177	 * It can be dangerous to call this function with an
178	 * out of bounds index.  Ensure `idx` is valid.
179	 */
180	tst	x0, #~0xF
181	ASM_ASSERT(eq)
182
183	/* val should be between [0, 65535] */
184	tst	x1, #~0xFFFF
185	ASM_ASSERT(eq)
186#endif
187	/*
188	 * Given `idx` calculate address of msr/ret instruction pair
189	 * in the table below.
190	 */
191	add	x2, x2, x0, lsl #3	/* each msr/ret sequence is 8 bytes */
192#if ENABLE_BTI
193	add	x2, x2, x0, lsl #2	/* + "bti j" instruction */
194#endif
195	br	x2
196
1971:	write	AMEVTYPER10_EL0		/* index 0 */
198	write	AMEVTYPER11_EL0		/* index 1 */
199	write	AMEVTYPER12_EL0		/* index 2 */
200	write	AMEVTYPER13_EL0		/* index 3 */
201	write	AMEVTYPER14_EL0		/* index 4 */
202	write	AMEVTYPER15_EL0		/* index 5 */
203	write	AMEVTYPER16_EL0		/* index 6 */
204	write	AMEVTYPER17_EL0		/* index 7 */
205	write	AMEVTYPER18_EL0		/* index 8 */
206	write	AMEVTYPER19_EL0		/* index 9 */
207	write	AMEVTYPER1A_EL0		/* index 10 */
208	write	AMEVTYPER1B_EL0		/* index 11 */
209	write	AMEVTYPER1C_EL0		/* index 12 */
210	write	AMEVTYPER1D_EL0		/* index 13 */
211	write	AMEVTYPER1E_EL0		/* index 14 */
212	write	AMEVTYPER1F_EL0		/* index 15 */
213endfunc amu_group1_set_evtype_internal
214