Zephyr API Documentation 4.3.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
lib_helpers.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#ifndef ZEPHYR_INCLUDE_ARCH_ARM64_LIB_HELPERS_H_
8#define ZEPHYR_INCLUDE_ARCH_ARM64_LIB_HELPERS_H_
9
10#ifndef _ASMLANGUAGE
11
13#include <stdint.h>
14
16
17/* All the macros need a memory clobber */
18
19#define read_sysreg(reg) \
20({ \
21 uint64_t reg_val; \
22 __asm__ volatile ("mrs %0, " STRINGIFY(reg) \
23 : "=r" (reg_val) :: "memory"); \
24 reg_val; \
25})
26
27#define write_sysreg(val, reg) \
28({ \
29 uint64_t reg_val = val; \
30 __asm__ volatile ("msr " STRINGIFY(reg) ", %0" \
31 :: "r" (reg_val) : "memory"); \
32})
33
34#define zero_sysreg(reg) \
35({ \
36 __asm__ volatile ("msr " STRINGIFY(reg) ", xzr" \
37 ::: "memory"); \
38})
39
40#define MAKE_REG_HELPER(reg) \
41 static ALWAYS_INLINE uint64_t read_##reg(void) \
42 { \
43 return read_sysreg(reg); \
44 } \
45 static ALWAYS_INLINE void write_##reg(uint64_t val) \
46 { \
47 write_sysreg(val, reg); \
48 } \
49 static ALWAYS_INLINE void zero_##reg(void) \
50 { \
51 zero_sysreg(reg); \
52 }
53
54#define MAKE_REG_HELPER_EL123(reg) \
55 MAKE_REG_HELPER(reg##_el1) \
56 MAKE_REG_HELPER(reg##_el2) \
57 MAKE_REG_HELPER(reg##_el3)
58
59MAKE_REG_HELPER(ccsidr_el1);
60MAKE_REG_HELPER(clidr_el1);
61MAKE_REG_HELPER(cntfrq_el0);
62MAKE_REG_HELPER(cnthctl_el2);
63MAKE_REG_HELPER(cnthp_ctl_el2);
64MAKE_REG_HELPER(cnthps_ctl_el2);
65MAKE_REG_HELPER(cntv_ctl_el0)
66MAKE_REG_HELPER(cntv_cval_el0)
67MAKE_REG_HELPER(cntp_cval_el0)
68MAKE_REG_HELPER(cntps_cval_el1)
69MAKE_REG_HELPER(cntvct_el0);
70MAKE_REG_HELPER(cntvoff_el2);
71MAKE_REG_HELPER(currentel);
72MAKE_REG_HELPER(csselr_el1);
74MAKE_REG_HELPER(hcr_el2);
75MAKE_REG_HELPER(id_aa64pfr0_el1);
76MAKE_REG_HELPER(id_aa64pfr1_el1);
77MAKE_REG_HELPER(id_aa64mmfr0_el1);
78MAKE_REG_HELPER(id_aa64isar0_el1);
79MAKE_REG_HELPER(id_aa64isar1_el1);
80MAKE_REG_HELPER(id_aa64isar2_el1);
81MAKE_REG_HELPER(mpidr_el1);
82MAKE_REG_HELPER(par_el1);
83#if !defined(CONFIG_ARMV8_R)
84MAKE_REG_HELPER(scr_el3);
85#endif /* CONFIG_ARMV8_R */
86MAKE_REG_HELPER(tpidrro_el0);
87MAKE_REG_HELPER(vmpidr_el2);
88MAKE_REG_HELPER(sp_el0);
89
90MAKE_REG_HELPER_EL123(actlr)
91MAKE_REG_HELPER_EL123(cpacr)
92MAKE_REG_HELPER_EL123(cptr)
93MAKE_REG_HELPER_EL123(elr)
94MAKE_REG_HELPER_EL123(esr)
95MAKE_REG_HELPER_EL123(far)
96MAKE_REG_HELPER_EL123(mair)
97MAKE_REG_HELPER_EL123(sctlr)
98MAKE_REG_HELPER_EL123(spsr)
99MAKE_REG_HELPER_EL123(tcr)
100MAKE_REG_HELPER_EL123(ttbr0)
101MAKE_REG_HELPER_EL123(vbar)
102MAKE_REG_HELPER_EL123(zcr)
103
104#if defined(CONFIG_ARM_MPU)
105/* Armv8-R aarch64 mpu registers */
106#define mpuir_el1 S3_0_c0_c0_4
107#define prselr_el1 S3_0_c6_c2_1
108#define prbar_el1 S3_0_c6_c8_0
109#define prlar_el1 S3_0_c6_c8_1
110
111MAKE_REG_HELPER(mpuir_el1);
112MAKE_REG_HELPER(prselr_el1);
113MAKE_REG_HELPER(prbar_el1);
114MAKE_REG_HELPER(prlar_el1);
115#endif
116
117static ALWAYS_INLINE void enable_debug_exceptions(void)
118{
119 __asm__ volatile ("msr DAIFClr, %0"
120 :: "i" (DAIFCLR_DBG_BIT) : "memory");
121}
122
123static ALWAYS_INLINE void disable_debug_exceptions(void)
124{
125 __asm__ volatile ("msr DAIFSet, %0"
126 :: "i" (DAIFSET_DBG_BIT) : "memory");
127}
128
129static ALWAYS_INLINE void enable_serror_exceptions(void)
130{
131 __asm__ volatile ("msr DAIFClr, %0"
132 :: "i" (DAIFCLR_ABT_BIT) : "memory");
133}
134
135static ALWAYS_INLINE void disable_serror_exceptions(void)
136{
137 __asm__ volatile ("msr DAIFSet, %0"
138 :: "i" (DAIFSET_ABT_BIT) : "memory");
139}
140
141static ALWAYS_INLINE void enable_irq(void)
142{
143 __asm__ volatile ("msr DAIFClr, %0"
144 :: "i" (DAIFCLR_IRQ_BIT) : "memory");
145}
146
147static ALWAYS_INLINE void disable_irq(void)
148{
149 __asm__ volatile ("msr DAIFSet, %0"
150 :: "i" (DAIFSET_IRQ_BIT) : "memory");
151}
152
153static ALWAYS_INLINE void enable_fiq(void)
154{
155 __asm__ volatile ("msr DAIFClr, %0"
156 :: "i" (DAIFCLR_FIQ_BIT) : "memory");
157}
158
159static ALWAYS_INLINE void disable_fiq(void)
160{
161 __asm__ volatile ("msr DAIFSet, %0"
162 :: "i" (DAIFSET_FIQ_BIT) : "memory");
163}
164
165#define sev() __asm__ volatile("sev" : : : "memory")
166#define wfe() __asm__ volatile("wfe" : : : "memory")
167#define wfi() __asm__ volatile("wfi" : : : "memory")
168
169static inline bool is_el_implemented(unsigned int el)
170{
171 unsigned int shift;
172
173 if (el > 3) {
174 return false;
175 }
176
177 shift = ID_AA64PFR0_EL1_SHIFT * el;
178
179 return (((read_id_aa64pfr0_el1() >> shift) & ID_AA64PFR0_ELX_MASK) != 0U);
180}
181
182static inline bool is_el_highest_implemented(void)
183{
184 uint32_t el_highest;
185 uint32_t curr_el;
186
187 el_highest = read_id_aa64pfr0_el1() & 0xFFFF;
188 el_highest = (31U - __builtin_clz(el_highest)) / 4;
189
190 curr_el = GET_EL(read_currentel());
191
192 if (curr_el < el_highest) {
193 return false;
194 }
195
196 return true;
197}
198
199static inline bool is_el2_sec_supported(void)
200{
201 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
202 ID_AA64PFR0_SEL2_MASK) != 0U);
203}
204
205static inline bool is_in_secure_state(void)
206{
207 /* We cannot read SCR_EL3 from EL2 or EL1 */
208 return !IS_ENABLED(CONFIG_ARMV8_A_NS);
209}
210
211static inline bool is_sve_implemented(void)
212{
213 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) & ID_AA64PFR0_SVE_MASK) != 0U);
214}
215
216#ifdef CONFIG_ARM_PAC
217/* PAC Key Register Helpers */
218MAKE_REG_HELPER(apiakeylo_el1);
219MAKE_REG_HELPER(apiakeyhi_el1);
220MAKE_REG_HELPER(apibkeylo_el1);
221MAKE_REG_HELPER(apibkeyhi_el1);
222MAKE_REG_HELPER(apdakeylo_el1);
223MAKE_REG_HELPER(apdakeyhi_el1);
224MAKE_REG_HELPER(apdbkeylo_el1);
225MAKE_REG_HELPER(apdbkeyhi_el1);
226MAKE_REG_HELPER(apgakeylo_el1);
227MAKE_REG_HELPER(apgakeyhi_el1);
228#endif /* CONFIG_ARM_PAC */
229
231
232#endif /* !_ASMLANGUAGE */
233
234#endif /* ZEPHYR_INCLUDE_ARCH_ARM64_LIB_HELPERS_H_ */
#define MAKE_REG_HELPER(reg, op1, CRn, CRm, op2)
Definition lib_helpers.h:45
#define IS_ENABLED(config_macro)
Check for macro definition in compiler-visible expressions.
Definition util_macro.h:148
#define ALWAYS_INLINE
Definition common.h:160
__UINT32_TYPE__ uint32_t
Definition stdint.h:90