amu_helpers.S 6.05 KB
Newer Older
1
/*
2
 * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <assert_macros.S>
#include <asm_macros.S>

	.globl	amu_group0_cnt_read_internal
	.globl	amu_group0_cnt_write_internal
	.globl	amu_group1_cnt_read_internal
	.globl	amu_group1_cnt_write_internal
	.globl	amu_group1_set_evtype_internal

/*
 * uint64_t amu_group0_cnt_read_internal(int idx);
 *
 * Given `idx`, read the corresponding AMU counter
21
 * and return it in `r0` and `r1`.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 */
func amu_group0_cnt_read_internal
#if ENABLE_ASSERTIONS
	/* `idx` should be between [0, 3] */
	mov	r1, r0
	lsr	r1, r1, #2
	cmp	r1, #0
	ASM_ASSERT(eq)
#endif

	/*
	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
	 * in the table below.
	 */
	adr	r1, 1f
	lsl	r0, r0, #3	/* each ldcopr16/bx lr sequence is 8 bytes */
	add	r1, r1, r0
	bx	r1
1:
	ldcopr16	r0, r1, AMEVCNTR00	/* index 0 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR01	/* index 1 */
	bx 		lr
	ldcopr16	r0, r1, AMEVCNTR02	/* index 2 */
	bx 		lr
	ldcopr16	r0, r1, AMEVCNTR03	/* index 3 */
	bx 		lr
endfunc amu_group0_cnt_read_internal

/*
 * void amu_group0_cnt_write_internal(int idx, uint64_t val);
 *
 * Given `idx`, write `val` to the corresponding AMU counter.
55
56
 * `idx` is passed in `r0` and `val` is passed in `r2` and `r3`.
 * `r1` is used as a scratch register.
57
58
59
60
 */
func amu_group0_cnt_write_internal
#if ENABLE_ASSERTIONS
	/* `idx` should be between [0, 3] */
61
62
63
	mov	r1, r0
	lsr	r1, r1, #2
	cmp	r1, #0
64
65
66
67
68
69
70
	ASM_ASSERT(eq)
#endif

	/*
	 * Given `idx` calculate address of stcopr16/bx lr instruction pair
	 * in the table below.
	 */
71
	adr	r1, 1f
72
	lsl	r0, r0, #3	/* each stcopr16/bx lr sequence is 8 bytes */
73
74
	add	r1, r1, r0
	bx	r1
75
76

1:
77
	stcopr16	r2, r3, AMEVCNTR00	/* index 0 */
78
	bx		lr
79
	stcopr16	r2, r3, AMEVCNTR01	/* index 1 */
80
	bx		lr
81
	stcopr16	r2, r3, AMEVCNTR02	/* index 2 */
82
	bx		lr
83
	stcopr16	r2, r3, AMEVCNTR03	/* index 3 */
84
	bx		lr
85
86
87
88
89
90
endfunc amu_group0_cnt_write_internal

/*
 * uint64_t amu_group1_cnt_read_internal(int idx);
 *
 * Given `idx`, read the corresponding AMU counter
91
 * and return it in `r0` and `r1`.
92
93
94
95
 */
func amu_group1_cnt_read_internal
#if ENABLE_ASSERTIONS
	/* `idx` should be between [0, 15] */
96
97
98
	mov	r1, r0
	lsr	r1, r1, #4
	cmp	r1, #0
99
100
101
102
103
104
105
106
107
108
109
110
111
	ASM_ASSERT(eq)
#endif

	/*
	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
	 * in the table below.
	 */
	adr	r1, 1f
	lsl	r0, r0, #3	/* each ldcopr16/bx lr sequence is 8 bytes */
	add	r1, r1, r0
	bx	r1

1:
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
	ldcopr16	r0, r1, AMEVCNTR10	/* index 0 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR11	/* index 1 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR12	/* index 2 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR13	/* index 3 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR14	/* index 4 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR15	/* index 5 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR16	/* index 6 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR17	/* index 7 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR18	/* index 8 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR19	/* index 9 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR1A	/* index 10 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR1B	/* index 11 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR1C	/* index 12 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR1D	/* index 13 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR1E	/* index 14 */
	bx		lr
	ldcopr16	r0, r1, AMEVCNTR1F	/* index 15 */
	bx		lr
144
145
146
147
148
149
endfunc amu_group1_cnt_read_internal

/*
 * void amu_group1_cnt_write_internal(int idx, uint64_t val);
 *
 * Given `idx`, write `val` to the corresponding AMU counter.
150
151
 * `idx` is passed in `r0` and `val` is passed in `r2` and `r3`.
 * `r1` is used as a scratch register.
152
153
154
155
 */
func amu_group1_cnt_write_internal
#if ENABLE_ASSERTIONS
	/* `idx` should be between [0, 15] */
156
157
158
	mov	r1, r0
	lsr	r1, r1, #4
	cmp	r1, #0
159
160
161
162
163
164
165
	ASM_ASSERT(eq)
#endif

	/*
	 * Given `idx` calculate address of ldcopr16/bx lr instruction pair
	 * in the table below.
	 */
166
	adr	r1, 1f
167
	lsl	r0, r0, #3	/* each stcopr16/bx lr sequence is 8 bytes */
168
169
	add	r1, r1, r0
	bx	r1
170
171

1:
172
	stcopr16	r2, r3, AMEVCNTR10	/* index 0 */
173
	bx		lr
174
	stcopr16	r2, r3, AMEVCNTR11	/* index 1 */
175
	bx		lr
176
	stcopr16	r2, r3, AMEVCNTR12	/* index 2 */
177
	bx		lr
178
	stcopr16	r2, r3, AMEVCNTR13	/* index 3 */
179
	bx		lr
180
	stcopr16	r2, r3, AMEVCNTR14	/* index 4 */
181
	bx		lr
182
	stcopr16	r2, r3, AMEVCNTR15	/* index 5 */
183
	bx		lr
184
	stcopr16	r2, r3, AMEVCNTR16	/* index 6 */
185
	bx		lr
186
	stcopr16	r2, r3, AMEVCNTR17	/* index 7 */
187
	bx		lr
188
	stcopr16	r2, r3, AMEVCNTR18	/* index 8 */
189
	bx		lr
190
	stcopr16	r2, r3, AMEVCNTR19	/* index 9 */
191
	bx		lr
192
	stcopr16	r2, r3, AMEVCNTR1A	/* index 10 */
193
	bx		lr
194
	stcopr16	r2, r3, AMEVCNTR1B	/* index 11 */
195
	bx		lr
196
	stcopr16	r2, r3, AMEVCNTR1C	/* index 12 */
197
	bx		lr
198
	stcopr16	r2, r3, AMEVCNTR1D	/* index 13 */
199
	bx		lr
200
	stcopr16	r2, r3, AMEVCNTR1E	/* index 14 */
201
	bx		lr
202
	stcopr16	r2, r3, AMEVCNTR1F	/* index 15 */
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
	bx		lr
endfunc amu_group1_cnt_write_internal

/*
 * void amu_group1_set_evtype_internal(int idx, unsigned int val);
 *
 * Program the AMU event type register indexed by `idx`
 * with the value `val`.
 */
func amu_group1_set_evtype_internal
#if ENABLE_ASSERTIONS
	/* `idx` should be between [0, 15] */
	mov	r2, r0
	lsr	r2, r2, #4
	cmp	r2, #0
	ASM_ASSERT(eq)

	/* val should be between [0, 65535] */
	mov	r2, r1
	lsr	r2, r2, #16
	cmp	r2, #0
	ASM_ASSERT(eq)
#endif

	/*
	 * Given `idx` calculate address of stcopr/bx lr instruction pair
	 * in the table below.
	 */
	adr	r2, 1f
	lsl	r0, r0, #3	/* each stcopr/bx lr sequence is 8 bytes */
	add	r2, r2, r0
	bx	r2

1:
237
	stcopr	r1, AMEVTYPER10 /* index 0 */
238
	bx	lr
239
	stcopr	r1, AMEVTYPER11 /* index 1 */
240
	bx	lr
241
	stcopr	r1, AMEVTYPER12 /* index 2 */
242
	bx	lr
243
	stcopr	r1, AMEVTYPER13 /* index 3 */
244
	bx	lr
245
	stcopr	r1, AMEVTYPER14 /* index 4 */
246
	bx	lr
247
	stcopr	r1, AMEVTYPER15 /* index 5 */
248
	bx	lr
249
	stcopr	r1, AMEVTYPER16 /* index 6 */
250
	bx	lr
251
	stcopr	r1, AMEVTYPER17 /* index 7 */
252
	bx	lr
253
	stcopr	r1, AMEVTYPER18 /* index 8 */
254
	bx	lr
255
	stcopr	r1, AMEVTYPER19 /* index 9 */
256
	bx	lr
257
	stcopr	r1, AMEVTYPER1A /* index 10 */
258
	bx	lr
259
	stcopr	r1, AMEVTYPER1B /* index 11 */
260
	bx	lr
261
	stcopr	r1, AMEVTYPER1C /* index 12 */
262
	bx	lr
263
	stcopr	r1, AMEVTYPER1D /* index 13 */
264
	bx	lr
265
	stcopr	r1, AMEVTYPER1E /* index 14 */
266
	bx	lr
267
	stcopr	r1, AMEVTYPER1F /* index 15 */
268
269
	bx	lr
endfunc amu_group1_set_evtype_internal