blob: 0f6d799eab99962232c94fadd80d44f548efd638 [file] [log] [blame]
Dimitris Papastamos525c37a2017-11-13 09:49:45 +00001/*
johpow01fa59c6f2020-10-02 13:41:11 -05002 * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
Dimitris Papastamos525c37a2017-11-13 09:49:45 +00003 *
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
johpow01fa59c6f2020-10-02 13:41:11 -050017 /* FEAT_AMUv1p1 virtualisation offset register functions */
18 .globl amu_group0_voffset_read_internal
19 .globl amu_group0_voffset_write_internal
20 .globl amu_group1_voffset_read_internal
21 .globl amu_group1_voffset_write_internal
22
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000023/*
24 * uint64_t amu_group0_cnt_read_internal(int idx);
25 *
26 * Given `idx`, read the corresponding AMU counter
27 * and return it in `x0`.
28 */
29func amu_group0_cnt_read_internal
Alexei Fedorov90f2e882019-05-24 12:17:09 +010030 adr x1, 1f
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000031#if ENABLE_ASSERTIONS
32 /*
33 * It can be dangerous to call this function with an
34 * out of bounds index. Ensure `idx` is valid.
35 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +010036 tst x0, #~3
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000037 ASM_ASSERT(eq)
38#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000039 /*
40 * Given `idx` calculate address of mrs/ret instruction pair
41 * in the table below.
42 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +010043 add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
44#if ENABLE_BTI
45 add x1, x1, x0, lsl #2 /* + "bti j" instruction */
46#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000047 br x1
48
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100491: read AMEVCNTR00_EL0 /* index 0 */
50 read AMEVCNTR01_EL0 /* index 1 */
51 read AMEVCNTR02_EL0 /* index 2 */
52 read AMEVCNTR03_EL0 /* index 3 */
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000053endfunc amu_group0_cnt_read_internal
54
55/*
56 * void amu_group0_cnt_write_internal(int idx, uint64_t val);
57 *
58 * Given `idx`, write `val` to the corresponding AMU counter.
59 */
60func amu_group0_cnt_write_internal
Alexei Fedorov90f2e882019-05-24 12:17:09 +010061 adr x2, 1f
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000062#if ENABLE_ASSERTIONS
63 /*
64 * It can be dangerous to call this function with an
65 * out of bounds index. Ensure `idx` is valid.
66 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +010067 tst x0, #~3
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000068 ASM_ASSERT(eq)
69#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000070 /*
71 * Given `idx` calculate address of mrs/ret instruction pair
72 * in the table below.
73 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +010074 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
75#if ENABLE_BTI
76 add x2, x2, x0, lsl #2 /* + "bti j" instruction */
77#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000078 br x2
79
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100801: write AMEVCNTR00_EL0 /* index 0 */
81 write AMEVCNTR01_EL0 /* index 1 */
82 write AMEVCNTR02_EL0 /* index 2 */
83 write AMEVCNTR03_EL0 /* index 3 */
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000084endfunc amu_group0_cnt_write_internal
85
Chris Kay925fda42021-05-25 10:42:56 +010086#if ENABLE_AMU_AUXILIARY_COUNTERS
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000087/*
88 * uint64_t amu_group1_cnt_read_internal(int idx);
89 *
90 * Given `idx`, read the corresponding AMU counter
91 * and return it in `x0`.
92 */
93func amu_group1_cnt_read_internal
Alexei Fedorov90f2e882019-05-24 12:17:09 +010094 adr x1, 1f
Dimitris Papastamos525c37a2017-11-13 09:49:45 +000095#if ENABLE_ASSERTIONS
96 /*
97 * It can be dangerous to call this function with an
98 * out of bounds index. Ensure `idx` is valid.
99 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100100 tst x0, #~0xF
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000101 ASM_ASSERT(eq)
102#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000103 /*
104 * Given `idx` calculate address of mrs/ret instruction pair
105 * in the table below.
106 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100107 add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
108#if ENABLE_BTI
109 add x1, x1, x0, lsl #2 /* + "bti j" instruction */
110#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000111 br x1
112
Alexei Fedorov90f2e882019-05-24 12:17:09 +01001131: read AMEVCNTR10_EL0 /* index 0 */
114 read AMEVCNTR11_EL0 /* index 1 */
115 read AMEVCNTR12_EL0 /* index 2 */
116 read AMEVCNTR13_EL0 /* index 3 */
117 read AMEVCNTR14_EL0 /* index 4 */
118 read AMEVCNTR15_EL0 /* index 5 */
119 read AMEVCNTR16_EL0 /* index 6 */
120 read AMEVCNTR17_EL0 /* index 7 */
121 read AMEVCNTR18_EL0 /* index 8 */
122 read AMEVCNTR19_EL0 /* index 9 */
123 read AMEVCNTR1A_EL0 /* index 10 */
124 read AMEVCNTR1B_EL0 /* index 11 */
125 read AMEVCNTR1C_EL0 /* index 12 */
126 read AMEVCNTR1D_EL0 /* index 13 */
127 read AMEVCNTR1E_EL0 /* index 14 */
128 read AMEVCNTR1F_EL0 /* index 15 */
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000129endfunc amu_group1_cnt_read_internal
130
131/*
132 * void amu_group1_cnt_write_internal(int idx, uint64_t val);
133 *
134 * Given `idx`, write `val` to the corresponding AMU counter.
135 */
136func amu_group1_cnt_write_internal
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100137 adr x2, 1f
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000138#if ENABLE_ASSERTIONS
139 /*
140 * It can be dangerous to call this function with an
141 * out of bounds index. Ensure `idx` is valid.
142 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100143 tst x0, #~0xF
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000144 ASM_ASSERT(eq)
145#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000146 /*
147 * Given `idx` calculate address of mrs/ret instruction pair
148 * in the table below.
149 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100150 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
151#if ENABLE_BTI
152 add x2, x2, x0, lsl #2 /* + "bti j" instruction */
153#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000154 br x2
155
Alexei Fedorov90f2e882019-05-24 12:17:09 +01001561: write AMEVCNTR10_EL0 /* index 0 */
157 write AMEVCNTR11_EL0 /* index 1 */
158 write AMEVCNTR12_EL0 /* index 2 */
159 write AMEVCNTR13_EL0 /* index 3 */
160 write AMEVCNTR14_EL0 /* index 4 */
161 write AMEVCNTR15_EL0 /* index 5 */
162 write AMEVCNTR16_EL0 /* index 6 */
163 write AMEVCNTR17_EL0 /* index 7 */
164 write AMEVCNTR18_EL0 /* index 8 */
165 write AMEVCNTR19_EL0 /* index 9 */
166 write AMEVCNTR1A_EL0 /* index 10 */
167 write AMEVCNTR1B_EL0 /* index 11 */
168 write AMEVCNTR1C_EL0 /* index 12 */
169 write AMEVCNTR1D_EL0 /* index 13 */
170 write AMEVCNTR1E_EL0 /* index 14 */
171 write AMEVCNTR1F_EL0 /* index 15 */
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000172endfunc amu_group1_cnt_write_internal
173
174/*
175 * void amu_group1_set_evtype_internal(int idx, unsigned int val);
176 *
177 * Program the AMU event type register indexed by `idx`
178 * with the value `val`.
179 */
180func amu_group1_set_evtype_internal
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100181 adr x2, 1f
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000182#if ENABLE_ASSERTIONS
183 /*
184 * It can be dangerous to call this function with an
185 * out of bounds index. Ensure `idx` is valid.
186 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100187 tst x0, #~0xF
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000188 ASM_ASSERT(eq)
189
190 /* val should be between [0, 65535] */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100191 tst x1, #~0xFFFF
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000192 ASM_ASSERT(eq)
193#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000194 /*
195 * Given `idx` calculate address of msr/ret instruction pair
196 * in the table below.
197 */
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100198 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
199#if ENABLE_BTI
200 add x2, x2, x0, lsl #2 /* + "bti j" instruction */
201#endif
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000202 br x2
203
Alexei Fedorov90f2e882019-05-24 12:17:09 +01002041: write AMEVTYPER10_EL0 /* index 0 */
205 write AMEVTYPER11_EL0 /* index 1 */
206 write AMEVTYPER12_EL0 /* index 2 */
207 write AMEVTYPER13_EL0 /* index 3 */
208 write AMEVTYPER14_EL0 /* index 4 */
209 write AMEVTYPER15_EL0 /* index 5 */
210 write AMEVTYPER16_EL0 /* index 6 */
211 write AMEVTYPER17_EL0 /* index 7 */
212 write AMEVTYPER18_EL0 /* index 8 */
213 write AMEVTYPER19_EL0 /* index 9 */
214 write AMEVTYPER1A_EL0 /* index 10 */
215 write AMEVTYPER1B_EL0 /* index 11 */
216 write AMEVTYPER1C_EL0 /* index 12 */
217 write AMEVTYPER1D_EL0 /* index 13 */
218 write AMEVTYPER1E_EL0 /* index 14 */
219 write AMEVTYPER1F_EL0 /* index 15 */
Dimitris Papastamos525c37a2017-11-13 09:49:45 +0000220endfunc amu_group1_set_evtype_internal
Chris Kay925fda42021-05-25 10:42:56 +0100221#endif
johpow01fa59c6f2020-10-02 13:41:11 -0500222
223/*
224 * Accessor functions for virtual offset registers added with FEAT_AMUv1p1
225 */
226
227/*
228 * uint64_t amu_group0_voffset_read_internal(int idx);
229 *
230 * Given `idx`, read the corresponding AMU virtual offset register
231 * and return it in `x0`.
232 */
233func amu_group0_voffset_read_internal
234 adr x1, 1f
235#if ENABLE_ASSERTIONS
236 /*
237 * It can be dangerous to call this function with an
238 * out of bounds index. Ensure `idx` is valid.
239 */
240 tst x0, #~3
241 ASM_ASSERT(eq)
242 /* Make sure idx != 1 since AMEVCNTVOFF01_EL2 does not exist */
243 cmp x0, #1
244 ASM_ASSERT(ne)
245#endif
246 /*
247 * Given `idx` calculate address of mrs/ret instruction pair
248 * in the table below.
249 */
250 add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
251#if ENABLE_BTI
252 add x1, x1, x0, lsl #2 /* + "bti j" instruction */
253#endif
254 br x1
255
2561: read AMEVCNTVOFF00_EL2 /* index 0 */
257 .skip 8 /* AMEVCNTVOFF01_EL2 does not exist */
258#if ENABLE_BTI
259 .skip 4
260#endif
261 read AMEVCNTVOFF02_EL2 /* index 2 */
262 read AMEVCNTVOFF03_EL2 /* index 3 */
263endfunc amu_group0_voffset_read_internal
264
265/*
266 * void amu_group0_voffset_write_internal(int idx, uint64_t val);
267 *
268 * Given `idx`, write `val` to the corresponding AMU virtual offset register.
269 */
270func amu_group0_voffset_write_internal
271 adr x2, 1f
272#if ENABLE_ASSERTIONS
273 /*
274 * It can be dangerous to call this function with an
275 * out of bounds index. Ensure `idx` is valid.
276 */
277 tst x0, #~3
278 ASM_ASSERT(eq)
279 /* Make sure idx != 1 since AMEVCNTVOFF01_EL2 does not exist */
280 cmp x0, #1
281 ASM_ASSERT(ne)
282#endif
283 /*
284 * Given `idx` calculate address of mrs/ret instruction pair
285 * in the table below.
286 */
287 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
288#if ENABLE_BTI
289 add x2, x2, x0, lsl #2 /* + "bti j" instruction */
290#endif
291 br x2
292
2931: write AMEVCNTVOFF00_EL2 /* index 0 */
294 .skip 8 /* AMEVCNTVOFF01_EL2 does not exist */
295#if ENABLE_BTI
296 .skip 4
297#endif
298 write AMEVCNTVOFF02_EL2 /* index 2 */
299 write AMEVCNTVOFF03_EL2 /* index 3 */
300endfunc amu_group0_voffset_write_internal
301
Chris Kay925fda42021-05-25 10:42:56 +0100302#if ENABLE_AMU_AUXILIARY_COUNTERS
johpow01fa59c6f2020-10-02 13:41:11 -0500303/*
304 * uint64_t amu_group1_voffset_read_internal(int idx);
305 *
306 * Given `idx`, read the corresponding AMU virtual offset register
307 * and return it in `x0`.
308 */
309func amu_group1_voffset_read_internal
310 adr x1, 1f
311#if ENABLE_ASSERTIONS
312 /*
313 * It can be dangerous to call this function with an
314 * out of bounds index. Ensure `idx` is valid.
315 */
316 tst x0, #~0xF
317 ASM_ASSERT(eq)
318#endif
319 /*
320 * Given `idx` calculate address of mrs/ret instruction pair
321 * in the table below.
322 */
323 add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
324#if ENABLE_BTI
325 add x1, x1, x0, lsl #2 /* + "bti j" instruction */
326#endif
327 br x1
328
3291: read AMEVCNTVOFF10_EL2 /* index 0 */
330 read AMEVCNTVOFF11_EL2 /* index 1 */
331 read AMEVCNTVOFF12_EL2 /* index 2 */
332 read AMEVCNTVOFF13_EL2 /* index 3 */
333 read AMEVCNTVOFF14_EL2 /* index 4 */
334 read AMEVCNTVOFF15_EL2 /* index 5 */
335 read AMEVCNTVOFF16_EL2 /* index 6 */
336 read AMEVCNTVOFF17_EL2 /* index 7 */
337 read AMEVCNTVOFF18_EL2 /* index 8 */
338 read AMEVCNTVOFF19_EL2 /* index 9 */
339 read AMEVCNTVOFF1A_EL2 /* index 10 */
340 read AMEVCNTVOFF1B_EL2 /* index 11 */
341 read AMEVCNTVOFF1C_EL2 /* index 12 */
342 read AMEVCNTVOFF1D_EL2 /* index 13 */
343 read AMEVCNTVOFF1E_EL2 /* index 14 */
344 read AMEVCNTVOFF1F_EL2 /* index 15 */
345endfunc amu_group1_voffset_read_internal
346
347/*
348 * void amu_group1_voffset_write_internal(int idx, uint64_t val);
349 *
350 * Given `idx`, write `val` to the corresponding AMU virtual offset register.
351 */
352func amu_group1_voffset_write_internal
353 adr x2, 1f
354#if ENABLE_ASSERTIONS
355 /*
356 * It can be dangerous to call this function with an
357 * out of bounds index. Ensure `idx` is valid.
358 */
359 tst x0, #~0xF
360 ASM_ASSERT(eq)
361#endif
362 /*
363 * Given `idx` calculate address of mrs/ret instruction pair
364 * in the table below.
365 */
366 add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
367#if ENABLE_BTI
368 add x2, x2, x0, lsl #2 /* + "bti j" instruction */
369#endif
370 br x2
371
3721: write AMEVCNTVOFF10_EL2 /* index 0 */
373 write AMEVCNTVOFF11_EL2 /* index 1 */
374 write AMEVCNTVOFF12_EL2 /* index 2 */
375 write AMEVCNTVOFF13_EL2 /* index 3 */
376 write AMEVCNTVOFF14_EL2 /* index 4 */
377 write AMEVCNTVOFF15_EL2 /* index 5 */
378 write AMEVCNTVOFF16_EL2 /* index 6 */
379 write AMEVCNTVOFF17_EL2 /* index 7 */
380 write AMEVCNTVOFF18_EL2 /* index 8 */
381 write AMEVCNTVOFF19_EL2 /* index 9 */
382 write AMEVCNTVOFF1A_EL2 /* index 10 */
383 write AMEVCNTVOFF1B_EL2 /* index 11 */
384 write AMEVCNTVOFF1C_EL2 /* index 12 */
385 write AMEVCNTVOFF1D_EL2 /* index 13 */
386 write AMEVCNTVOFF1E_EL2 /* index 14 */
387 write AMEVCNTVOFF1F_EL2 /* index 15 */
388endfunc amu_group1_voffset_write_internal
Chris Kay925fda42021-05-25 10:42:56 +0100389#endif