1 /* 2 * Copyright (c) 2022 IoT.bzh 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Armv8-R AArch32 architecture helpers. 7 * 8 */ 9 10 #ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_LIB_HELPERS_H_ 11 #define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_LIB_HELPERS_H_ 12 13 #ifndef _ASMLANGUAGE 14 15 #include <stdint.h> 16 17 #define read_sysreg32(op1, CRn, CRm, op2) \ 18 ({ \ 19 uint32_t val; \ 20 __asm__ volatile ("mrc p15, " #op1 ", %0, c" #CRn ", c" \ 21 #CRm ", " #op2 : "=r" (val) :: "memory"); \ 22 val; \ 23 }) 24 25 #define write_sysreg32(val, op1, CRn, CRm, op2) \ 26 ({ \ 27 __asm__ volatile ("mcr p15, " #op1 ", %0, c" #CRn ", c" \ 28 #CRm ", " #op2 :: "r" (val) : "memory"); \ 29 }) 30 31 #define read_sysreg64(op1, CRm) \ 32 ({ \ 33 uint64_t val; \ 34 __asm__ volatile ("mrrc p15, " #op1 ", %Q0, %R0, c" \ 35 #CRm : "=r" (val) :: "memory"); \ 36 val; \ 37 }) 38 39 #define write_sysreg64(val, op1, CRm) \ 40 ({ \ 41 __asm__ volatile ("mcrr p15, " #op1 ", %Q0, %R0, c" \ 42 #CRm :: "r" (val) : "memory"); \ 43 }) 44 45 #define MAKE_REG_HELPER(reg, op1, CRn, CRm, op2) \ 46 static ALWAYS_INLINE uint32_t read_##reg(void) \ 47 { \ 48 return read_sysreg32(op1, CRn, CRm, op2); \ 49 } \ 50 static ALWAYS_INLINE void write_##reg(uint32_t val) \ 51 { \ 52 write_sysreg32(val, op1, CRn, CRm, op2); \ 53 } 54 55 #define MAKE_REG64_HELPER(reg, op1, CRm) \ 56 static ALWAYS_INLINE uint64_t read_##reg(void) \ 57 { \ 58 return read_sysreg64(op1, CRm); \ 59 } \ 60 static ALWAYS_INLINE void write_##reg(uint64_t val) \ 61 { \ 62 write_sysreg64(val, op1, CRm); \ 63 } 64 65 MAKE_REG_HELPER(mpuir, 0, 0, 0, 4); 66 MAKE_REG_HELPER(mpidr, 0, 0, 0, 5); 67 MAKE_REG_HELPER(sctlr, 0, 1, 0, 0); 68 MAKE_REG_HELPER(prselr, 0, 6, 2, 1); 69 MAKE_REG_HELPER(prbar, 0, 6, 3, 0); 70 MAKE_REG_HELPER(prlar, 0, 6, 3, 1); 71 MAKE_REG_HELPER(mair0, 0, 10, 2, 0); 72 MAKE_REG_HELPER(vbar, 0, 12, 0, 0); 73 MAKE_REG_HELPER(cntv_ctl, 0, 14, 3, 1); 74 MAKE_REG_HELPER(ctr, 0, 0, 0, 1); 75 MAKE_REG_HELPER(tpidruro, 0, 13, 0, 3); 76 MAKE_REG64_HELPER(ICC_SGI1R, 0, 12); 77 MAKE_REG64_HELPER(cntvct, 1, 14); 78 MAKE_REG64_HELPER(cntv_cval, 3, 14); 79 80 /* 81 * GIC v3 compatibility macros: 82 * ARMv8 AArch32 profile has no mention of 83 * ELx in the register names. 84 * We define them anyway to reuse the GICv3 driver 85 * made for AArch64. 86 */ 87 88 /* ICC_PMR */ 89 MAKE_REG_HELPER(ICC_PMR_EL1, 0, 4, 6, 0); 90 /* ICC_IAR1 */ 91 MAKE_REG_HELPER(ICC_IAR1_EL1, 0, 12, 12, 0); 92 /* ICC_EOIR1 */ 93 MAKE_REG_HELPER(ICC_EOIR1_EL1, 0, 12, 12, 1); 94 /* ICC_SRE */ 95 MAKE_REG_HELPER(ICC_SRE_EL1, 0, 12, 12, 5); 96 /* ICC_IGRPEN1 */ 97 MAKE_REG_HELPER(ICC_IGRPEN1_EL1, 0, 12, 12, 7); 98 99 #define write_sysreg(val, reg) write_##reg(val) 100 #define read_sysreg(reg) read_##reg() 101 102 #define sev() __asm__ volatile("sev" : : : "memory") 103 #define wfe() __asm__ volatile("wfe" : : : "memory") 104 105 #endif /* !_ASMLANGUAGE */ 106 #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_LIB_HELPERS_H_ */ 107