1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Date Author Notes
* 2018-10-06 ZhaoXiaowei the first version (cpu_gcc.S)
* 2021-05-18 Jesven the first version (context_gcc.S)
* 2024-01-06 Shell Fix barrier on irq_disable/enable
* 2024-01-18 Shell fix implicit dependency of cpuid management
* 2024-03-28 Shell Move cpu codes from context_gcc.S
*/
#ifndef __ASSEMBLY__
#define __ASSEMBLY__
#endif
#include "rtconfig.h"
#include "asm-generic.h"
#include "asm-fpu.h"
#include "armv8.h"
#ifdef RT_USING_SMP
#define rt_hw_interrupt_disable rt_hw_local_irq_disable
#define rt_hw_interrupt_enable rt_hw_local_irq_enable
#endif /* RT_USING_SMP */
.text
/**
* #ifdef RT_USING_OFW
* void rt_hw_cpu_id_set(long cpuid)
* #else
* void rt_hw_cpu_id_set(void)
* #endif
*/
.type rt_hw_cpu_id_set, @function
rt_hw_cpu_id_set:
#ifdef ARCH_USING_GENERIC_CPUID
.globl rt_hw_cpu_id_set
#else /* !ARCH_USING_GENERIC_CPUID */
.weak rt_hw_cpu_id_set
#endif /* ARCH_USING_GENERIC_CPUID */
#ifndef RT_USING_OFW
mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
#ifdef ARCH_ARM_CORTEX_A55
lsr x0, x0, #8
#endif /* ARCH_ARM_CORTEX_A55 */
and x0, x0, #15
#endif /* !RT_USING_OFW */
#ifdef ARCH_USING_HW_THREAD_SELF
msr tpidrro_el0, x0
#else /* !ARCH_USING_HW_THREAD_SELF */
msr tpidr_el1, x0
#endif /* ARCH_USING_HW_THREAD_SELF */
ret
/*
int rt_hw_cpu_id(void)
*/
.type rt_hw_cpu_id, @function
rt_hw_cpu_id:
#ifdef ARCH_USING_GENERIC_CPUID
.globl rt_hw_cpu_id
#else /* !ARCH_USING_GENERIC_CPUID */
.weak rt_hw_cpu_id
#endif /* ARCH_USING_GENERIC_CPUID */
#if RT_CPUS_NR > 1
#ifdef ARCH_USING_GENERIC_CPUID
mrs x0, tpidrro_el0
#else /* !ARCH_USING_GENERIC_CPUID */
mrs x0, tpidr_el1
#endif /* ARCH_USING_GENERIC_CPUID */
#else /* RT_CPUS_NR == 1 */
mov x0, xzr
#endif
ret
/*
void rt_hw_set_process_id(size_t id)
*/
.global rt_hw_set_process_id
rt_hw_set_process_id:
msr CONTEXTIDR_EL1, x0
ret
/*
*enable gtimer
*/
.globl rt_hw_gtimer_enable
rt_hw_gtimer_enable:
mov x0, #1
msr CNTP_CTL_EL0, x0
ret
/*
*set gtimer CNTP_TVAL_EL0 value
*/
.globl rt_hw_set_gtimer_val
rt_hw_set_gtimer_val:
msr CNTP_TVAL_EL0, x0
ret
/*
*get gtimer CNTP_TVAL_EL0 value
*/
.globl rt_hw_get_gtimer_val
rt_hw_get_gtimer_val:
mrs x0, CNTP_TVAL_EL0
ret
.globl rt_hw_get_cntpct_val
rt_hw_get_cntpct_val:
mrs x0, CNTPCT_EL0
ret
/*
* get gtimer frq value
* According to the document `Arm A-profile Architecture Registers:
* CNTFRQ_EL0, Counter-timer Frequency Register`
* Bits [63:32] are reserved, so only the lower 32 bits take effect.
*/
.globl rt_hw_get_gtimer_frq
rt_hw_get_gtimer_frq:
mrs x0, CNTFRQ_EL0
ret
.global rt_hw_interrupt_is_disabled
rt_hw_interrupt_is_disabled:
mrs x0, DAIF
tst x0, #0xc0
cset x0, NE
ret
/*
* rt_base_t rt_hw_interrupt_disable();
*/
.globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
mrs x0, DAIF
and x0, x0, #0xc0
cmp x0, #0xc0
/* branch if bits not both set(zero) */
bne 1f
ret
1:
msr DAIFSet, #3
dsb nsh
isb
ret
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
and x0, x0, #0xc0
cmp x0, #0xc0
/* branch if one of the bits not set(zero) */
bne 1f
ret
1:
isb
dsb nsh
and x0, x0, #0xc0
mrs x1, DAIF
bic x1, x1, #0xc0
orr x0, x0, x1
msr DAIF, x0
ret
.globl rt_hw_get_current_el
rt_hw_get_current_el:
mrs x0, CurrentEL
cmp x0, 0xc
b.eq 3f
cmp x0, 0x8
b.eq 2f
cmp x0, 0x4
b.eq 1f
ldr x0, =0
b 0f
3:
ldr x0, =3
b 0f
2:
ldr x0, =2
b 0f
1:
ldr x0, =1
b 0f
0:
ret
.globl rt_hw_set_current_vbar
rt_hw_set_current_vbar:
mrs x1, CurrentEL
cmp x1, 0xc
b.eq 3f
cmp x1, 0x8
b.eq 2f
cmp x1, 0x4
b.eq 1f
b 0f
3:
msr VBAR_EL3,x0
b 0f
2:
msr VBAR_EL2,x0
b 0f
1:
msr VBAR_EL1,x0
b 0f
0:
ret
.globl rt_hw_set_elx_env
rt_hw_set_elx_env:
mrs x1, CurrentEL
cmp x1, 0xc
b.eq 3f
cmp x1, 0x8
b.eq 2f
cmp x1, 0x4
b.eq 1f
b 0f
3:
mrs x0, SCR_EL3
orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */
msr SCR_EL3, x0
b 0f
2:
mrs x0, HCR_EL2
orr x0, x0, #0x38
msr HCR_EL2, x0
b 0f
1:
b 0f
0:
ret
.globl rt_cpu_vector_set_base
rt_cpu_vector_set_base:
msr VBAR_EL1, x0
ret
/**
* unsigned long rt_hw_ffz(unsigned long x)
*/
.globl rt_hw_ffz
rt_hw_ffz:
mvn x1, x0
clz x0, x1
mov x1, #0x3f
sub x0, x1, x0
ret
.globl rt_hw_clz
rt_hw_clz:
clz x0, x0
ret
/**
* Spinlock (fallback implementation)
*/
rt_hw_spin_lock_init:
.weak rt_hw_spin_lock_init
stlr wzr, [x0]
ret
rt_hw_spin_trylock:
.weak rt_hw_spin_trylock
sub sp, sp, #16
ldar w2, [x0]
add x1, sp, 8
stlr w2, [x1]
ldarh w1, [x1]
and w1, w1, 65535
add x3, sp, 10
ldarh w3, [x3]
cmp w1, w3, uxth
beq 1f
mov w0, 0
add sp, sp, 16
ret
1:
add x1, sp, 10
2:
ldaxrh w3, [x1]
add w3, w3, 1
stlxrh w4, w3, [x1]
cbnz w4, 2b
add x1, sp, 8
ldar w1, [x1]
3:
ldaxr w3, [x0]
cmp w3, w2
bne 4f
stxr w4, w1, [x0]
cbnz w4, 3b
4:
cset w0, eq
add sp, sp, 16
ret
rt_hw_spin_lock:
.weak rt_hw_spin_lock
add x1, x0, 2
1:
ldxrh w2, [x1]
add w3, w2, 1
stxrh w4, w3, [x1]
cbnz w4, 1b
and w2, w2, 65535
ldarh w1, [x0]
cmp w2, w1, uxth
beq 3f
sevl
2:
wfe
ldaxrh w1, [x0]
cmp w2, w1
bne 2b
3:
ret
rt_hw_spin_unlock:
.weak rt_hw_spin_unlock
ldxrh w1, [x0]
add w1, w1, 1
stlxrh w2, w1, [x0]
cbnz w2, rt_hw_spin_unlock
ret
|