1 /* 2 * Copyright (c) 2013-2017, 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 <stdint.h> 13 #include <sys/types.h> 14 15 /********************************************************************** 16 * Macros which create inline functions to read or write CPU system 17 * registers 18 *********************************************************************/ 19 20 #define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \ 21 static inline uint64_t read_ ## _name(void) \ 22 { \ 23 uint64_t v; \ 24 __asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \ 25 return v; \ 26 } 27 28 #define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \ 29 static inline void write_ ## _name(uint64_t v) \ 30 { \ 31 __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \ 32 } 33 34 #define SYSREG_WRITE_CONST(reg_name, v) \ 35 __asm__ volatile ("msr " #reg_name ", %0" : : "i" (v)) 36 37 /* Define read function for system register */ 38 #define DEFINE_SYSREG_READ_FUNC(_name) \ 39 _DEFINE_SYSREG_READ_FUNC(_name, _name) 40 41 /* Define read & write function for system register */ 42 #define DEFINE_SYSREG_RW_FUNCS(_name) \ 43 _DEFINE_SYSREG_READ_FUNC(_name, _name) \ 44 _DEFINE_SYSREG_WRITE_FUNC(_name, _name) 45 46 /* Define read & write function for renamed system register */ 47 #define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name) \ 48 _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \ 49 _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) 50 51 /* Define read function for renamed system register */ 52 #define DEFINE_RENAME_SYSREG_READ_FUNC(_name, _reg_name) \ 53 _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) 54 55 /* Define write function for renamed system register */ 56 #define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \ 57 _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) 58 59 /********************************************************************** 60 * Macros to create inline functions for system instructions 61 *********************************************************************/ 62 63 /* Define function for simple system instruction */ 64 #define DEFINE_SYSOP_FUNC(_op) \ 65 static inline void _op(void) \ 66 { \ 67 __asm__ (#_op); \ 68 } 69 70 /* Define function for system instruction with type specifier */ 71 #define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \ 72 static inline void _op ## _type(void) \ 73 { \ 74 __asm__ (#_op " " #_type); \ 75 } 76 77 /* Define function for system instruction with register parameter */ 78 #define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type) \ 79 static inline void _op ## _type(uint64_t v) \ 80 { \ 81 __asm__ (#_op " " #_type ", %0" : : "r" (v)); \ 82 } 83 84 /******************************************************************************* 85 * TLB maintenance accessor prototypes 86 ******************************************************************************/ 87 88 #if ERRATA_A57_813419 89 /* 90 * Define function for TLBI instruction with type specifier that implements 91 * the workaround for errata 813419 of Cortex-A57. 92 */ 93 #define DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_FUNC(_type)\ 94 static inline void tlbi ## _type(void) \ 95 { \ 96 __asm__("tlbi " #_type "\n" \ 97 "dsb ish\n" \ 98 "tlbi " #_type); \ 99 } 100 101 /* 102 * Define function for TLBI instruction with register parameter that implements 103 * the workaround for errata 813419 of Cortex-A57. 104 */ 105 #define DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_PARAM_FUNC(_type) \ 106 static inline void tlbi ## _type(uint64_t v) \ 107 { \ 108 __asm__("tlbi " #_type ", %0\n" \ 109 "dsb ish\n" \ 110 "tlbi " #_type ", %0" : : "r" (v)); \ 111 } 112 #endif /* ERRATA_A57_813419 */ 113 114 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1) 115 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is) 116 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2) 117 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is) 118 #if ERRATA_A57_813419 119 DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_FUNC(alle3) 120 DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_FUNC(alle3is) 121 #else 122 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3) 123 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is) 124 #endif 125 DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1) 126 127 DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaae1is) 128 DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vaale1is) 129 DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae2is) 130 DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale2is) 131 #if ERRATA_A57_813419 132 DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_PARAM_FUNC(vae3is) 133 DEFINE_TLBIOP_ERRATA_A57_813419_TYPE_PARAM_FUNC(vale3is) 134 #else 135 DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vae3is) 136 DEFINE_SYSOP_TYPE_PARAM_FUNC(tlbi, vale3is) 137 #endif 138 139 /******************************************************************************* 140 * Cache maintenance accessor prototypes 141 ******************************************************************************/ 142 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw) 143 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw) 144 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw) 145 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac) 146 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac) 147 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac) 148 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau) 149 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva) 150 151 /******************************************************************************* 152 * Address translation accessor prototypes 153 ******************************************************************************/ 154 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r) 155 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w) 156 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r) 157 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w) 158 159 void flush_dcache_range(uintptr_t addr, size_t size); 160 void clean_dcache_range(uintptr_t addr, size_t size); 161 void inv_dcache_range(uintptr_t addr, size_t size); 162 163 void dcsw_op_louis(u_register_t op_type); 164 void dcsw_op_all(u_register_t op_type); 165 166 void disable_mmu_el1(void); 167 void disable_mmu_el3(void); 168 void disable_mmu_icache_el1(void); 169 void disable_mmu_icache_el3(void); 170 171 /******************************************************************************* 172 * Misc. accessor prototypes 173 ******************************************************************************/ 174 175 #define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val) 176 #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val) 177 178 DEFINE_SYSREG_READ_FUNC(par_el1) 179 DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) 180 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) 181 DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1) 182 DEFINE_SYSREG_READ_FUNC(CurrentEl) 183 DEFINE_SYSREG_RW_FUNCS(daif) 184 DEFINE_SYSREG_RW_FUNCS(spsr_el1) 185 DEFINE_SYSREG_RW_FUNCS(spsr_el2) 186 DEFINE_SYSREG_RW_FUNCS(spsr_el3) 187 DEFINE_SYSREG_RW_FUNCS(elr_el1) 188 DEFINE_SYSREG_RW_FUNCS(elr_el2) 189 DEFINE_SYSREG_RW_FUNCS(elr_el3) 190 191 DEFINE_SYSOP_FUNC(wfi) 192 DEFINE_SYSOP_FUNC(wfe) 193 DEFINE_SYSOP_FUNC(sev) 194 DEFINE_SYSOP_TYPE_FUNC(dsb, sy) 195 DEFINE_SYSOP_TYPE_FUNC(dmb, sy) 196 DEFINE_SYSOP_TYPE_FUNC(dmb, st) 197 DEFINE_SYSOP_TYPE_FUNC(dmb, ld) 198 DEFINE_SYSOP_TYPE_FUNC(dsb, ish) 199 DEFINE_SYSOP_TYPE_FUNC(dsb, ishst) 200 DEFINE_SYSOP_TYPE_FUNC(dmb, ish) 201 DEFINE_SYSOP_TYPE_FUNC(dmb, ishst) 202 DEFINE_SYSOP_FUNC(isb) 203 204 uint32_t get_afflvl_shift(uint32_t); 205 uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t); 206 207 208 void __dead2 eret(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, 209 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7); 210 void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, 211 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7); 212 213 /******************************************************************************* 214 * System register accessor prototypes 215 ******************************************************************************/ 216 DEFINE_SYSREG_READ_FUNC(midr_el1) 217 DEFINE_SYSREG_READ_FUNC(mpidr_el1) 218 DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1) 219 220 DEFINE_SYSREG_RW_FUNCS(scr_el3) 221 DEFINE_SYSREG_RW_FUNCS(hcr_el2) 222 223 DEFINE_SYSREG_RW_FUNCS(vbar_el1) 224 DEFINE_SYSREG_RW_FUNCS(vbar_el2) 225 DEFINE_SYSREG_RW_FUNCS(vbar_el3) 226 227 DEFINE_SYSREG_RW_FUNCS(sctlr_el1) 228 DEFINE_SYSREG_RW_FUNCS(sctlr_el2) 229 DEFINE_SYSREG_RW_FUNCS(sctlr_el3) 230 231 DEFINE_SYSREG_RW_FUNCS(actlr_el1) 232 DEFINE_SYSREG_RW_FUNCS(actlr_el2) 233 DEFINE_SYSREG_RW_FUNCS(actlr_el3) 234 235 DEFINE_SYSREG_RW_FUNCS(esr_el1) 236 DEFINE_SYSREG_RW_FUNCS(esr_el2) 237 DEFINE_SYSREG_RW_FUNCS(esr_el3) 238 239 DEFINE_SYSREG_RW_FUNCS(afsr0_el1) 240 DEFINE_SYSREG_RW_FUNCS(afsr0_el2) 241 DEFINE_SYSREG_RW_FUNCS(afsr0_el3) 242 243 DEFINE_SYSREG_RW_FUNCS(afsr1_el1) 244 DEFINE_SYSREG_RW_FUNCS(afsr1_el2) 245 DEFINE_SYSREG_RW_FUNCS(afsr1_el3) 246 247 DEFINE_SYSREG_RW_FUNCS(far_el1) 248 DEFINE_SYSREG_RW_FUNCS(far_el2) 249 DEFINE_SYSREG_RW_FUNCS(far_el3) 250 251 DEFINE_SYSREG_RW_FUNCS(mair_el1) 252 DEFINE_SYSREG_RW_FUNCS(mair_el2) 253 DEFINE_SYSREG_RW_FUNCS(mair_el3) 254 255 DEFINE_SYSREG_RW_FUNCS(amair_el1) 256 DEFINE_SYSREG_RW_FUNCS(amair_el2) 257 DEFINE_SYSREG_RW_FUNCS(amair_el3) 258 259 DEFINE_SYSREG_READ_FUNC(rvbar_el1) 260 DEFINE_SYSREG_READ_FUNC(rvbar_el2) 261 DEFINE_SYSREG_READ_FUNC(rvbar_el3) 262 263 DEFINE_SYSREG_RW_FUNCS(rmr_el1) 264 DEFINE_SYSREG_RW_FUNCS(rmr_el2) 265 DEFINE_SYSREG_RW_FUNCS(rmr_el3) 266 267 DEFINE_SYSREG_RW_FUNCS(tcr_el1) 268 DEFINE_SYSREG_RW_FUNCS(tcr_el2) 269 DEFINE_SYSREG_RW_FUNCS(tcr_el3) 270 271 DEFINE_SYSREG_RW_FUNCS(ttbr0_el1) 272 DEFINE_SYSREG_RW_FUNCS(ttbr0_el2) 273 DEFINE_SYSREG_RW_FUNCS(ttbr0_el3) 274 275 DEFINE_SYSREG_RW_FUNCS(ttbr1_el1) 276 277 DEFINE_SYSREG_RW_FUNCS(vttbr_el2) 278 279 DEFINE_SYSREG_RW_FUNCS(cptr_el2) 280 DEFINE_SYSREG_RW_FUNCS(cptr_el3) 281 282 DEFINE_SYSREG_RW_FUNCS(cpacr_el1) 283 DEFINE_SYSREG_RW_FUNCS(cntfrq_el0) 284 DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1) 285 DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1) 286 DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1) 287 DEFINE_SYSREG_READ_FUNC(cntpct_el0) 288 DEFINE_SYSREG_RW_FUNCS(cnthctl_el2) 289 290 DEFINE_SYSREG_RW_FUNCS(tpidr_el3) 291 292 DEFINE_SYSREG_RW_FUNCS(cntvoff_el2) 293 294 DEFINE_SYSREG_RW_FUNCS(vpidr_el2) 295 DEFINE_SYSREG_RW_FUNCS(vmpidr_el2) 296 DEFINE_SYSREG_RW_FUNCS(cntp_ctl_el0) 297 298 DEFINE_SYSREG_READ_FUNC(isr_el1) 299 300 DEFINE_SYSREG_READ_FUNC(ctr_el0) 301 302 DEFINE_SYSREG_RW_FUNCS(mdcr_el2) 303 DEFINE_SYSREG_RW_FUNCS(hstr_el2) 304 DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2) 305 DEFINE_SYSREG_RW_FUNCS(pmcr_el0) 306 307 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1) 308 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2) 309 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3) 310 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1) 311 DEFINE_RENAME_SYSREG_READ_FUNC(icc_rpr_el1, ICC_RPR_EL1) 312 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen1_el3, ICC_IGRPEN1_EL3) 313 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0_EL1) 314 DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir0_el1, ICC_HPPIR0_EL1) 315 DEFINE_RENAME_SYSREG_READ_FUNC(icc_hppir1_el1, ICC_HPPIR1_EL1) 316 DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar0_el1, ICC_IAR0_EL1) 317 DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar1_el1, ICC_IAR1_EL1) 318 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir0_el1, ICC_EOIR0_EL1) 319 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1) 320 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1) 321 322 323 #define IS_IN_EL(x) \ 324 (GET_EL(read_CurrentEl()) == MODE_EL##x) 325 326 #define IS_IN_EL1() IS_IN_EL(1) 327 #define IS_IN_EL3() IS_IN_EL(3) 328 329 /* 330 * Check if an EL is implemented from AA64PFR0 register fields. 'el' argument 331 * must be one of 1, 2 or 3. 332 */ 333 #define EL_IMPLEMENTED(el) \ 334 ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL##el##_SHIFT) \ 335 & ID_AA64PFR0_ELX_MASK) 336 337 /* Previously defined accesor functions with incomplete register names */ 338 339 #define read_current_el() read_CurrentEl() 340 341 #define dsb() dsbsy() 342 343 #define read_midr() read_midr_el1() 344 345 #define read_mpidr() read_mpidr_el1() 346 347 #define read_scr() read_scr_el3() 348 #define write_scr(_v) write_scr_el3(_v) 349 350 #define read_hcr() read_hcr_el2() 351 #define write_hcr(_v) write_hcr_el2(_v) 352 353 #define read_cpacr() read_cpacr_el1() 354 #define write_cpacr(_v) write_cpacr_el1(_v) 355 356 #endif /* __ARCH_HELPERS_H__ */ 357