Zephyr Project API 4.5.0-rc2
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(tpidr_el1);
88MAKE_REG_HELPER(vmpidr_el2);
89MAKE_REG_HELPER(sp_el0);
90
91MAKE_REG_HELPER_EL123(actlr)
92MAKE_REG_HELPER_EL123(cpacr)
93MAKE_REG_HELPER_EL123(cptr)
94MAKE_REG_HELPER_EL123(elr)
95MAKE_REG_HELPER_EL123(esr)
96MAKE_REG_HELPER_EL123(far)
97MAKE_REG_HELPER_EL123(mair)
98MAKE_REG_HELPER_EL123(sctlr)
99MAKE_REG_HELPER_EL123(spsr)
100MAKE_REG_HELPER_EL123(tcr)
101MAKE_REG_HELPER_EL123(ttbr0)
102MAKE_REG_HELPER_EL123(vbar)
103MAKE_REG_HELPER_EL123(zcr)
104
105#if defined(CONFIG_ARM_MPU)
106/* Armv8-R aarch64 mpu registers */
107#define mpuir_el1 S3_0_c0_c0_4
108#define prselr_el1 S3_0_c6_c2_1
109#define prbar_el1 S3_0_c6_c8_0
110#define prlar_el1 S3_0_c6_c8_1
111
112MAKE_REG_HELPER(mpuir_el1);
113MAKE_REG_HELPER(prselr_el1);
114MAKE_REG_HELPER(prbar_el1);
115MAKE_REG_HELPER(prlar_el1);
116#endif
117
118static ALWAYS_INLINE void enable_debug_exceptions(void)
119{
120 __asm__ volatile ("msr DAIFClr, %0"
121 :: "i" (DAIFCLR_DBG_BIT) : "memory");
122}
123
124static ALWAYS_INLINE void disable_debug_exceptions(void)
125{
126 __asm__ volatile ("msr DAIFSet, %0"
127 :: "i" (DAIFSET_DBG_BIT) : "memory");
128}
129
130static ALWAYS_INLINE void enable_serror_exceptions(void)
131{
132 __asm__ volatile ("msr DAIFClr, %0"
133 :: "i" (DAIFCLR_ABT_BIT) : "memory");
134}
135
136static ALWAYS_INLINE void disable_serror_exceptions(void)
137{
138 __asm__ volatile ("msr DAIFSet, %0"
139 :: "i" (DAIFSET_ABT_BIT) : "memory");
140}
141
142static ALWAYS_INLINE void enable_irq(void)
143{
144 __asm__ volatile ("msr DAIFClr, %0"
145 :: "i" (DAIFCLR_IRQ_BIT) : "memory");
146}
147
148static ALWAYS_INLINE void disable_irq(void)
149{
150 __asm__ volatile ("msr DAIFSet, %0"
151 :: "i" (DAIFSET_IRQ_BIT) : "memory");
152}
153
154static ALWAYS_INLINE void enable_fiq(void)
155{
156 __asm__ volatile ("msr DAIFClr, %0"
157 :: "i" (DAIFCLR_FIQ_BIT) : "memory");
158}
159
160static ALWAYS_INLINE void disable_fiq(void)
161{
162 __asm__ volatile ("msr DAIFSet, %0"
163 :: "i" (DAIFSET_FIQ_BIT) : "memory");
164}
165
166#define sev() __asm__ volatile("sev" : : : "memory")
167#define wfe() __asm__ volatile("wfe" : : : "memory")
168#define wfi() __asm__ volatile("wfi" : : : "memory")
169#define wfet(v) __asm__ volatile("msr S0_3_C1_C0_0, %0" :: "r"(v) : "memory")
170#define wfit(v) __asm__ volatile("msr S0_3_C1_C0_1, %0" :: "r"(v) : "memory")
171
172static inline bool is_wfxt_implemented(void)
173{
174 return ((read_id_aa64isar2_el1() >> ID_AA64ISAR2_WFXT_SHIFT)
175 & ID_AA64ISAR2_WFXT_MASK) != 0;
176}
177
178static inline bool is_el_implemented(unsigned int el)
179{
180 unsigned int shift;
181
182 if (el > 3) {
183 return false;
184 }
185
186 shift = ID_AA64PFR0_EL1_SHIFT * el;
187
188 return (((read_id_aa64pfr0_el1() >> shift) & ID_AA64PFR0_ELX_MASK) != 0U);
189}
190
191static inline bool is_el_highest_implemented(void)
192{
193 uint32_t el_highest;
194 uint32_t curr_el;
195
196 el_highest = read_id_aa64pfr0_el1() & 0xFFFF;
197 el_highest = (31U - __builtin_clz(el_highest)) / 4;
198
199 curr_el = GET_EL(read_currentel());
200
201 if (curr_el < el_highest) {
202 return false;
203 }
204
205 return true;
206}
207
208static inline bool is_el2_sec_supported(void)
209{
210 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
211 ID_AA64PFR0_SEL2_MASK) != 0U);
212}
213
214static inline bool is_in_secure_state(void)
215{
216 /* We cannot read SCR_EL3 from EL2 or EL1 */
217 return !IS_ENABLED(CONFIG_ARMV8_A_NS);
218}
219
220static inline bool is_sve_implemented(void)
221{
222 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) & ID_AA64PFR0_SVE_MASK) != 0U);
223}
224
225#if defined(CONFIG_ARM64_PMUV3)
226MAKE_REG_HELPER(id_aa64dfr0_el1);
227MAKE_REG_HELPER(pmcr_el0);
228MAKE_REG_HELPER(pmccntr_el0);
229MAKE_REG_HELPER(pmcntenset_el0);
230MAKE_REG_HELPER(pmcntenclr_el0);
231MAKE_REG_HELPER(pmovsclr_el0);
232MAKE_REG_HELPER(pmuserenr_el0);
233MAKE_REG_HELPER(pmselr_el0);
234MAKE_REG_HELPER(pmxevtyper_el0);
235MAKE_REG_HELPER(pmxevcntr_el0);
236#endif /* CONFIG_ARM64_PMUV3 */
237
238#ifdef CONFIG_ARM_PAC
239/* PAC Key Register Helpers */
240MAKE_REG_HELPER(apiakeylo_el1);
241MAKE_REG_HELPER(apiakeyhi_el1);
242MAKE_REG_HELPER(apibkeylo_el1);
243MAKE_REG_HELPER(apibkeyhi_el1);
244MAKE_REG_HELPER(apdakeylo_el1);
245MAKE_REG_HELPER(apdakeyhi_el1);
246MAKE_REG_HELPER(apdbkeylo_el1);
247MAKE_REG_HELPER(apdbkeyhi_el1);
248MAKE_REG_HELPER(apgakeylo_el1);
249MAKE_REG_HELPER(apgakeyhi_el1);
250#endif /* CONFIG_ARM_PAC */
251
253
254#endif /* !_ASMLANGUAGE */
255
256#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:154
#define ALWAYS_INLINE
Definition common.h:186
__UINT32_TYPE__ uint32_t
Definition stdint.h:90