blob: c313d60983498e62c9fb515654f85f6f53866941 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __ARCH_HELPERS_H__
8#define __ARCH_HELPERS_H__
9
10#include <arch.h> /* for additional register definitions */
11#include <cdefs.h> /* For __dead2 */
12#include <misc_utils.h>
13#include <stdint.h>
14#include <sys/types.h>
15
16/**********************************************************************
17 * Macros which create inline functions to read or write CPU system
18 * registers
19 *********************************************************************/
20
21#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
22static inline u_register_t read_ ## _name(void) \
23{ \
24 u_register_t v; \
25 __asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \
26 return v; \
27}
28
29#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
30static inline void write_ ## _name(u_register_t v) \
31{ \
32 __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \
33}
34
35#define SYSREG_WRITE_CONST(reg_name, v) \
36 __asm__ volatile ("msr " #reg_name ", %0" : : "i" (v))
37
38/* Define read function for system register */
39#define DEFINE_SYSREG_READ_FUNC(_name) \
40 _DEFINE_SYSREG_READ_FUNC(_name, _name)
41
42/* Define read & write function for system register */
43#define DEFINE_SYSREG_RW_FUNCS(_name) \
44 _DEFINE_SYSREG_READ_FUNC(_name, _name) \
45 _DEFINE_SYSREG_WRITE_FUNC(_name, _name)
46
47/* Define read & write function for renamed system register */
48#define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name) \
49 _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
50 _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
51
52/* Define read function for renamed system register */
53#define DEFINE_RENAME_SYSREG_READ_FUNC(_name, _reg_name) \
54 _DEFINE_SYSREG_READ_FUNC(_name, _reg_name)
55
56/* Define write function for renamed system register */
57#define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \
58 _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
59
60/**********************************************************************
61 * Macros to create inline functions for system instructions
62 *********************************************************************/
63
64/* Define function for simple system instruction */
65#define DEFINE_SYSOP_FUNC(_op) \
66static inline void _op(void) \
67{ \
68 __asm__ (#_op); \
69}
70
71/* Define function for system instruction with type specifier */
72#define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \
73static inline void _op ## _type(void) \
74{ \
75 __asm__ (#_op " " #_type); \
76}
77
78/* Define function for system instruction with register parameter */
79#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type) \
80static inline void _op ## _type(uint64_t v) \
81{ \
82 __asm__ (#_op " " #_type ", %0" : : "r" (v)); \
83}
84
85/*******************************************************************************
86 * TLB maintenance accessor prototypes
87 ******************************************************************************/
88
89DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1)
90DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is)
91DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2)
92DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is)
93DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3)
94DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is)
95DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1)
96
97DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is)
98DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is)
99DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is)
100DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is)
101DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae3is)
102DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale3is)
103
104/*******************************************************************************
105 * Cache maintenance accessor prototypes
106 ******************************************************************************/
107DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw)
108DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw)
109DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw)
110DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac)
111DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac)
112DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac)
113DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau)
114DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva)
115
116void flush_dcache_range(uintptr_t addr, size_t size);
117void clean_dcache_range(uintptr_t addr, size_t size);
118void inv_dcache_range(uintptr_t addr, size_t size);
119
120void dcsw_op_louis(u_register_t op_type);
121void dcsw_op_all(u_register_t op_type);
122
123void disable_mmu(void);
124void disable_mmu_icache(void);
125
126/*******************************************************************************
127 * Misc. accessor prototypes
128 ******************************************************************************/
129
130DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
131DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
132DEFINE_SYSREG_READ_FUNC(CurrentEl)
133DEFINE_SYSREG_READ_FUNC(ctr_el0)
134DEFINE_SYSREG_RW_FUNCS(daif)
135DEFINE_SYSREG_RW_FUNCS(spsr_el1)
136DEFINE_SYSREG_RW_FUNCS(spsr_el2)
137DEFINE_SYSREG_RW_FUNCS(elr_el1)
138DEFINE_SYSREG_RW_FUNCS(elr_el2)
139
140DEFINE_SYSOP_FUNC(wfi)
141DEFINE_SYSOP_FUNC(wfe)
142DEFINE_SYSOP_FUNC(sev)
143DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
144DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
145DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
146DEFINE_SYSOP_FUNC(isb)
147DEFINE_SYSOP_TYPE_FUNC(dmb, oshld)
148DEFINE_SYSOP_TYPE_FUNC(dmb, oshst)
149DEFINE_SYSOP_TYPE_FUNC(dmb, osh)
150DEFINE_SYSOP_TYPE_FUNC(dmb, nshld)
151DEFINE_SYSOP_TYPE_FUNC(dmb, nshst)
152DEFINE_SYSOP_TYPE_FUNC(dmb, nsh)
153DEFINE_SYSOP_TYPE_FUNC(dmb, ishld)
154DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
155DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
156DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
157DEFINE_SYSOP_TYPE_FUNC(dmb, st)
158DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
159
160#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
161#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
162
163static inline void enable_irq(void)
164{
165 /*
166 * The compiler memory barrier will prevent the compiler from
167 * scheduling non-volatile memory access after the write to the
168 * register.
169 *
170 * This could happen if some initialization code issues non-volatile
171 * accesses to an area used by an interrupt handler, in the assumption
172 * that it is safe as the interrupts are disabled at the time it does
173 * that (according to program order). However, non-volatile accesses
174 * are not necessarily in program order relatively with volatile inline
175 * assembly statements (and volatile accesses).
176 */
177 COMPILER_BARRIER();
178 write_daifclr(DAIF_IRQ_BIT);
179 isb();
180}
181
182static inline void enable_fiq(void)
183{
184 COMPILER_BARRIER();
185 write_daifclr(DAIF_FIQ_BIT);
186 isb();
187}
188
189static inline void enable_serror(void)
190{
191 COMPILER_BARRIER();
192 write_daifclr(DAIF_ABT_BIT);
193 isb();
194}
195
196static inline void enable_debug_exceptions(void)
197{
198 COMPILER_BARRIER();
199 write_daifclr(DAIF_DBG_BIT);
200 isb();
201}
202
203static inline void disable_irq(void)
204{
205 COMPILER_BARRIER();
206 write_daifset(DAIF_IRQ_BIT);
207 isb();
208}
209
210static inline void disable_fiq(void)
211{
212 COMPILER_BARRIER();
213 write_daifset(DAIF_FIQ_BIT);
214 isb();
215}
216
217static inline void disable_serror(void)
218{
219 COMPILER_BARRIER();
220 write_daifset(DAIF_ABT_BIT);
221 isb();
222}
223
224static inline void disable_debug_exceptions(void)
225{
226 COMPILER_BARRIER();
227 write_daifset(DAIF_DBG_BIT);
228 isb();
229}
230
231uint32_t get_afflvl_shift(uint32_t);
232uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t);
233
234void __dead2 eret(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
235 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
236void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3,
237 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7);
238
239/*******************************************************************************
240 * System register accessor prototypes
241 ******************************************************************************/
242DEFINE_SYSREG_READ_FUNC(midr_el1)
243DEFINE_SYSREG_READ_FUNC(mpidr_el1)
244DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1)
245
246DEFINE_SYSREG_RW_FUNCS(hcr_el2)
247
248DEFINE_SYSREG_RW_FUNCS(vbar_el1)
249DEFINE_SYSREG_RW_FUNCS(vbar_el2)
250
251DEFINE_SYSREG_RW_FUNCS(sctlr_el1)
252DEFINE_SYSREG_RW_FUNCS(sctlr_el2)
253DEFINE_SYSREG_RW_FUNCS(sctlr_el3)
254
255DEFINE_SYSREG_RW_FUNCS(actlr_el1)
256DEFINE_SYSREG_RW_FUNCS(actlr_el2)
257
258DEFINE_SYSREG_RW_FUNCS(esr_el1)
259DEFINE_SYSREG_RW_FUNCS(esr_el2)
260
261DEFINE_SYSREG_RW_FUNCS(afsr0_el1)
262DEFINE_SYSREG_RW_FUNCS(afsr0_el2)
263
264DEFINE_SYSREG_RW_FUNCS(afsr1_el1)
265DEFINE_SYSREG_RW_FUNCS(afsr1_el2)
266
267DEFINE_SYSREG_RW_FUNCS(far_el1)
268DEFINE_SYSREG_RW_FUNCS(far_el2)
269
270DEFINE_SYSREG_RW_FUNCS(mair_el1)
271DEFINE_SYSREG_RW_FUNCS(mair_el2)
272
273DEFINE_SYSREG_RW_FUNCS(amair_el1)
274DEFINE_SYSREG_RW_FUNCS(amair_el2)
275
276DEFINE_SYSREG_READ_FUNC(rvbar_el1)
277DEFINE_SYSREG_READ_FUNC(rvbar_el2)
278
279DEFINE_SYSREG_RW_FUNCS(rmr_el1)
280DEFINE_SYSREG_RW_FUNCS(rmr_el2)
281
282DEFINE_SYSREG_RW_FUNCS(tcr_el1)
283DEFINE_SYSREG_RW_FUNCS(tcr_el2)
284
285DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
286DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
287
288DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
289
290DEFINE_SYSREG_RW_FUNCS(cptr_el2)
291
292DEFINE_SYSREG_RW_FUNCS(cpacr_el1)
293DEFINE_SYSREG_RW_FUNCS(cntfrq_el0)
294DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
295DEFINE_SYSREG_RW_FUNCS(cnthp_tval_el2)
296DEFINE_SYSREG_RW_FUNCS(cnthp_cval_el2)
297DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1)
298DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1)
299DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1)
300DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0)
301DEFINE_SYSREG_RW_FUNCS(cntp_tval_el0)
302DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0)
303DEFINE_SYSREG_READ_FUNC(cntpct_el0)
304DEFINE_SYSREG_RW_FUNCS(cnthctl_el2)
305
306DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
307DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
308
309/* GICv3 System Registers */
310
311DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
312DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
313DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1)
314DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el1, ICC_IGRPEN1_EL1)
315DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
316DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1)
317DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar1_el1, ICC_IAR1_EL1)
318DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
319
320DEFINE_RENAME_SYSREG_RW_FUNCS(amcgcr_el0, AMCGCR_EL0)
321DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0)
322DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
323DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
324DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
325
326#define IS_IN_EL(x) \
327 (GET_EL(read_CurrentEl()) == MODE_EL##x)
328
329#define IS_IN_EL1() IS_IN_EL(1)
330#define IS_IN_EL2() IS_IN_EL(2)
331
332#endif /* __ARCH_HELPERS_H__ */