xref: /arm-trusted-firmware/lib/extensions/amu/aarch32/amu_helpers.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu/*
2*91f16700Schasinglulu * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu *
4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu */
6*91f16700Schasinglulu
7*91f16700Schasinglulu#include <arch.h>
8*91f16700Schasinglulu#include <assert_macros.S>
9*91f16700Schasinglulu#include <asm_macros.S>
10*91f16700Schasinglulu
11*91f16700Schasinglulu	.globl	amu_group0_cnt_read_internal
12*91f16700Schasinglulu	.globl	amu_group0_cnt_write_internal
13*91f16700Schasinglulu	.globl	amu_group1_cnt_read_internal
14*91f16700Schasinglulu	.globl	amu_group1_cnt_write_internal
15*91f16700Schasinglulu	.globl	amu_group1_set_evtype_internal
16*91f16700Schasinglulu
17*91f16700Schasinglulu/*
18*91f16700Schasinglulu * uint64_t amu_group0_cnt_read_internal(int idx);
19*91f16700Schasinglulu *
20*91f16700Schasinglulu * Given `idx`, read the corresponding AMU counter
21*91f16700Schasinglulu * and return it in `r0` and `r1`.
22*91f16700Schasinglulu */
23*91f16700Schasinglulufunc amu_group0_cnt_read_internal
24*91f16700Schasinglulu#if ENABLE_ASSERTIONS
25*91f16700Schasinglulu	/* `idx` should be between [0, 3] */
26*91f16700Schasinglulu	mov	r1, r0
27*91f16700Schasinglulu	lsr	r1, r1, #2
28*91f16700Schasinglulu	cmp	r1, #0
29*91f16700Schasinglulu	ASM_ASSERT(eq)
30*91f16700Schasinglulu#endif
31*91f16700Schasinglulu
32*91f16700Schasinglulu	/*
33*91f16700Schasinglulu	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
34*91f16700Schasinglulu	 * in the table below.
35*91f16700Schasinglulu	 */
36*91f16700Schasinglulu	adr	r1, 1f
37*91f16700Schasinglulu	lsl	r0, r0, #3	/* each ldcopr16/bx lr sequence is 8 bytes */
38*91f16700Schasinglulu	add	r1, r1, r0
39*91f16700Schasinglulu	bx	r1
40*91f16700Schasinglulu1:
41*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR00	/* index 0 */
42*91f16700Schasinglulu	bx		lr
43*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR01	/* index 1 */
44*91f16700Schasinglulu	bx 		lr
45*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR02	/* index 2 */
46*91f16700Schasinglulu	bx 		lr
47*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR03	/* index 3 */
48*91f16700Schasinglulu	bx 		lr
49*91f16700Schasingluluendfunc amu_group0_cnt_read_internal
50*91f16700Schasinglulu
51*91f16700Schasinglulu/*
52*91f16700Schasinglulu * void amu_group0_cnt_write_internal(int idx, uint64_t val);
53*91f16700Schasinglulu *
54*91f16700Schasinglulu * Given `idx`, write `val` to the corresponding AMU counter.
55*91f16700Schasinglulu * `idx` is passed in `r0` and `val` is passed in `r2` and `r3`.
56*91f16700Schasinglulu * `r1` is used as a scratch register.
57*91f16700Schasinglulu */
58*91f16700Schasinglulufunc amu_group0_cnt_write_internal
59*91f16700Schasinglulu#if ENABLE_ASSERTIONS
60*91f16700Schasinglulu	/* `idx` should be between [0, 3] */
61*91f16700Schasinglulu	mov	r1, r0
62*91f16700Schasinglulu	lsr	r1, r1, #2
63*91f16700Schasinglulu	cmp	r1, #0
64*91f16700Schasinglulu	ASM_ASSERT(eq)
65*91f16700Schasinglulu#endif
66*91f16700Schasinglulu
67*91f16700Schasinglulu	/*
68*91f16700Schasinglulu	 * Given `idx` calculate address of stcopr16/bx lr instruction pair
69*91f16700Schasinglulu	 * in the table below.
70*91f16700Schasinglulu	 */
71*91f16700Schasinglulu	adr	r1, 1f
72*91f16700Schasinglulu	lsl	r0, r0, #3	/* each stcopr16/bx lr sequence is 8 bytes */
73*91f16700Schasinglulu	add	r1, r1, r0
74*91f16700Schasinglulu	bx	r1
75*91f16700Schasinglulu
76*91f16700Schasinglulu1:
77*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR00	/* index 0 */
78*91f16700Schasinglulu	bx		lr
79*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR01	/* index 1 */
80*91f16700Schasinglulu	bx		lr
81*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR02	/* index 2 */
82*91f16700Schasinglulu	bx		lr
83*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR03	/* index 3 */
84*91f16700Schasinglulu	bx		lr
85*91f16700Schasingluluendfunc amu_group0_cnt_write_internal
86*91f16700Schasinglulu
87*91f16700Schasinglulu#if ENABLE_AMU_AUXILIARY_COUNTERS
88*91f16700Schasinglulu/*
89*91f16700Schasinglulu * uint64_t amu_group1_cnt_read_internal(int idx);
90*91f16700Schasinglulu *
91*91f16700Schasinglulu * Given `idx`, read the corresponding AMU counter
92*91f16700Schasinglulu * and return it in `r0` and `r1`.
93*91f16700Schasinglulu */
94*91f16700Schasinglulufunc amu_group1_cnt_read_internal
95*91f16700Schasinglulu#if ENABLE_ASSERTIONS
96*91f16700Schasinglulu	/* `idx` should be between [0, 15] */
97*91f16700Schasinglulu	mov	r1, r0
98*91f16700Schasinglulu	lsr	r1, r1, #4
99*91f16700Schasinglulu	cmp	r1, #0
100*91f16700Schasinglulu	ASM_ASSERT(eq)
101*91f16700Schasinglulu#endif
102*91f16700Schasinglulu
103*91f16700Schasinglulu	/*
104*91f16700Schasinglulu	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
105*91f16700Schasinglulu	 * in the table below.
106*91f16700Schasinglulu	 */
107*91f16700Schasinglulu	adr	r1, 1f
108*91f16700Schasinglulu	lsl	r0, r0, #3	/* each ldcopr16/bx lr sequence is 8 bytes */
109*91f16700Schasinglulu	add	r1, r1, r0
110*91f16700Schasinglulu	bx	r1
111*91f16700Schasinglulu
112*91f16700Schasinglulu1:
113*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR10	/* index 0 */
114*91f16700Schasinglulu	bx		lr
115*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR11	/* index 1 */
116*91f16700Schasinglulu	bx		lr
117*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR12	/* index 2 */
118*91f16700Schasinglulu	bx		lr
119*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR13	/* index 3 */
120*91f16700Schasinglulu	bx		lr
121*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR14	/* index 4 */
122*91f16700Schasinglulu	bx		lr
123*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR15	/* index 5 */
124*91f16700Schasinglulu	bx		lr
125*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR16	/* index 6 */
126*91f16700Schasinglulu	bx		lr
127*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR17	/* index 7 */
128*91f16700Schasinglulu	bx		lr
129*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR18	/* index 8 */
130*91f16700Schasinglulu	bx		lr
131*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR19	/* index 9 */
132*91f16700Schasinglulu	bx		lr
133*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR1A	/* index 10 */
134*91f16700Schasinglulu	bx		lr
135*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR1B	/* index 11 */
136*91f16700Schasinglulu	bx		lr
137*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR1C	/* index 12 */
138*91f16700Schasinglulu	bx		lr
139*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR1D	/* index 13 */
140*91f16700Schasinglulu	bx		lr
141*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR1E	/* index 14 */
142*91f16700Schasinglulu	bx		lr
143*91f16700Schasinglulu	ldcopr16	r0, r1, AMEVCNTR1F	/* index 15 */
144*91f16700Schasinglulu	bx		lr
145*91f16700Schasingluluendfunc amu_group1_cnt_read_internal
146*91f16700Schasinglulu
147*91f16700Schasinglulu/*
148*91f16700Schasinglulu * void amu_group1_cnt_write_internal(int idx, uint64_t val);
149*91f16700Schasinglulu *
150*91f16700Schasinglulu * Given `idx`, write `val` to the corresponding AMU counter.
151*91f16700Schasinglulu * `idx` is passed in `r0` and `val` is passed in `r2` and `r3`.
152*91f16700Schasinglulu * `r1` is used as a scratch register.
153*91f16700Schasinglulu */
154*91f16700Schasinglulufunc amu_group1_cnt_write_internal
155*91f16700Schasinglulu#if ENABLE_ASSERTIONS
156*91f16700Schasinglulu	/* `idx` should be between [0, 15] */
157*91f16700Schasinglulu	mov	r1, r0
158*91f16700Schasinglulu	lsr	r1, r1, #4
159*91f16700Schasinglulu	cmp	r1, #0
160*91f16700Schasinglulu	ASM_ASSERT(eq)
161*91f16700Schasinglulu#endif
162*91f16700Schasinglulu
163*91f16700Schasinglulu	/*
164*91f16700Schasinglulu	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
165*91f16700Schasinglulu	 * in the table below.
166*91f16700Schasinglulu	 */
167*91f16700Schasinglulu	adr	r1, 1f
168*91f16700Schasinglulu	lsl	r0, r0, #3	/* each stcopr16/bx lr sequence is 8 bytes */
169*91f16700Schasinglulu	add	r1, r1, r0
170*91f16700Schasinglulu	bx	r1
171*91f16700Schasinglulu
172*91f16700Schasinglulu1:
173*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR10	/* index 0 */
174*91f16700Schasinglulu	bx		lr
175*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR11	/* index 1 */
176*91f16700Schasinglulu	bx		lr
177*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR12	/* index 2 */
178*91f16700Schasinglulu	bx		lr
179*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR13	/* index 3 */
180*91f16700Schasinglulu	bx		lr
181*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR14	/* index 4 */
182*91f16700Schasinglulu	bx		lr
183*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR15	/* index 5 */
184*91f16700Schasinglulu	bx		lr
185*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR16	/* index 6 */
186*91f16700Schasinglulu	bx		lr
187*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR17	/* index 7 */
188*91f16700Schasinglulu	bx		lr
189*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR18	/* index 8 */
190*91f16700Schasinglulu	bx		lr
191*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR19	/* index 9 */
192*91f16700Schasinglulu	bx		lr
193*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR1A	/* index 10 */
194*91f16700Schasinglulu	bx		lr
195*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR1B	/* index 11 */
196*91f16700Schasinglulu	bx		lr
197*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR1C	/* index 12 */
198*91f16700Schasinglulu	bx		lr
199*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR1D	/* index 13 */
200*91f16700Schasinglulu	bx		lr
201*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR1E	/* index 14 */
202*91f16700Schasinglulu	bx		lr
203*91f16700Schasinglulu	stcopr16	r2, r3, AMEVCNTR1F	/* index 15 */
204*91f16700Schasinglulu	bx		lr
205*91f16700Schasingluluendfunc amu_group1_cnt_write_internal
206*91f16700Schasinglulu
207*91f16700Schasinglulu/*
208*91f16700Schasinglulu * void amu_group1_set_evtype_internal(int idx, unsigned int val);
209*91f16700Schasinglulu *
210*91f16700Schasinglulu * Program the AMU event type register indexed by `idx`
211*91f16700Schasinglulu * with the value `val`.
212*91f16700Schasinglulu */
213*91f16700Schasinglulufunc amu_group1_set_evtype_internal
214*91f16700Schasinglulu#if ENABLE_ASSERTIONS
215*91f16700Schasinglulu	/* `idx` should be between [0, 15] */
216*91f16700Schasinglulu	mov	r2, r0
217*91f16700Schasinglulu	lsr	r2, r2, #4
218*91f16700Schasinglulu	cmp	r2, #0
219*91f16700Schasinglulu	ASM_ASSERT(eq)
220*91f16700Schasinglulu
221*91f16700Schasinglulu	/* val should be between [0, 65535] */
222*91f16700Schasinglulu	mov	r2, r1
223*91f16700Schasinglulu	lsr	r2, r2, #16
224*91f16700Schasinglulu	cmp	r2, #0
225*91f16700Schasinglulu	ASM_ASSERT(eq)
226*91f16700Schasinglulu#endif
227*91f16700Schasinglulu
228*91f16700Schasinglulu	/*
229*91f16700Schasinglulu	 * Given `idx` calculate address of stcopr/bx lr instruction pair
230*91f16700Schasinglulu	 * in the table below.
231*91f16700Schasinglulu	 */
232*91f16700Schasinglulu	adr	r2, 1f
233*91f16700Schasinglulu	lsl	r0, r0, #3	/* each stcopr/bx lr sequence is 8 bytes */
234*91f16700Schasinglulu	add	r2, r2, r0
235*91f16700Schasinglulu	bx	r2
236*91f16700Schasinglulu
237*91f16700Schasinglulu1:
238*91f16700Schasinglulu	stcopr	r1, AMEVTYPER10 /* index 0 */
239*91f16700Schasinglulu	bx	lr
240*91f16700Schasinglulu	stcopr	r1, AMEVTYPER11 /* index 1 */
241*91f16700Schasinglulu	bx	lr
242*91f16700Schasinglulu	stcopr	r1, AMEVTYPER12 /* index 2 */
243*91f16700Schasinglulu	bx	lr
244*91f16700Schasinglulu	stcopr	r1, AMEVTYPER13 /* index 3 */
245*91f16700Schasinglulu	bx	lr
246*91f16700Schasinglulu	stcopr	r1, AMEVTYPER14 /* index 4 */
247*91f16700Schasinglulu	bx	lr
248*91f16700Schasinglulu	stcopr	r1, AMEVTYPER15 /* index 5 */
249*91f16700Schasinglulu	bx	lr
250*91f16700Schasinglulu	stcopr	r1, AMEVTYPER16 /* index 6 */
251*91f16700Schasinglulu	bx	lr
252*91f16700Schasinglulu	stcopr	r1, AMEVTYPER17 /* index 7 */
253*91f16700Schasinglulu	bx	lr
254*91f16700Schasinglulu	stcopr	r1, AMEVTYPER18 /* index 8 */
255*91f16700Schasinglulu	bx	lr
256*91f16700Schasinglulu	stcopr	r1, AMEVTYPER19 /* index 9 */
257*91f16700Schasinglulu	bx	lr
258*91f16700Schasinglulu	stcopr	r1, AMEVTYPER1A /* index 10 */
259*91f16700Schasinglulu	bx	lr
260*91f16700Schasinglulu	stcopr	r1, AMEVTYPER1B /* index 11 */
261*91f16700Schasinglulu	bx	lr
262*91f16700Schasinglulu	stcopr	r1, AMEVTYPER1C /* index 12 */
263*91f16700Schasinglulu	bx	lr
264*91f16700Schasinglulu	stcopr	r1, AMEVTYPER1D /* index 13 */
265*91f16700Schasinglulu	bx	lr
266*91f16700Schasinglulu	stcopr	r1, AMEVTYPER1E /* index 14 */
267*91f16700Schasinglulu	bx	lr
268*91f16700Schasinglulu	stcopr	r1, AMEVTYPER1F /* index 15 */
269*91f16700Schasinglulu	bx	lr
270*91f16700Schasingluluendfunc amu_group1_set_evtype_internal
271*91f16700Schasinglulu#endif
272