1 /* 2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef __ARCH_HELPERS_H__ 32 #define __ARCH_HELPERS_H__ 33 34 #include <arch.h> /* for additional register definitions */ 35 #include <cdefs.h> /* For __dead2 */ 36 #include <stdint.h> 37 38 /********************************************************************** 39 * Macros which create inline functions to read or write CPU system 40 * registers 41 *********************************************************************/ 42 43 #define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \ 44 static inline uint64_t read_ ## _name(void) \ 45 { \ 46 uint64_t v; \ 47 __asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \ 48 return v; \ 49 } 50 51 #define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \ 52 static inline void write_ ## _name(uint64_t v) \ 53 { \ 54 __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \ 55 } 56 57 #define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name) \ 58 static inline void write_ ## _name(const uint64_t v) \ 59 { \ 60 __asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v)); \ 61 } 62 63 /* Define read function for system register */ 64 #define DEFINE_SYSREG_READ_FUNC(_name) \ 65 _DEFINE_SYSREG_READ_FUNC(_name, _name) 66 67 /* Define read & write function for system register */ 68 #define DEFINE_SYSREG_RW_FUNCS(_name) \ 69 _DEFINE_SYSREG_READ_FUNC(_name, _name) \ 70 _DEFINE_SYSREG_WRITE_FUNC(_name, _name) 71 72 /* Define read & write function for renamed system register */ 73 #define DEFINE_RENAME_SYSREG_RW_FUNCS(_name, _reg_name) \ 74 _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \ 75 _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) 76 77 /* Define write function for special system registers */ 78 #define DEFINE_SYSREG_WRITE_CONST_FUNC(_name) \ 79 _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _name) 80 81 82 /********************************************************************** 83 * Macros to create inline functions for system instructions 84 *********************************************************************/ 85 86 /* Define function for simple system instruction */ 87 #define DEFINE_SYSOP_FUNC(_op) \ 88 static inline void _op(void) \ 89 { \ 90 __asm__ (#_op); \ 91 } 92 93 /* Define function for system instruction with type specifier */ 94 #define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \ 95 static inline void _op ## _type(void) \ 96 { \ 97 __asm__ (#_op " " #_type); \ 98 } 99 100 /* Define function for system instruction with register parameter */ 101 #define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type) \ 102 static inline void _op ## _type(uint64_t v) \ 103 { \ 104 __asm__ (#_op " " #_type ", %0" : : "r" (v)); \ 105 } 106 107 /******************************************************************************* 108 * Aarch64 translation tables manipulation helper prototypes 109 ******************************************************************************/ 110 uint64_t create_table_desc(uint64_t *next_table_ptr); 111 uint64_t create_block_desc(uint64_t desc, uint64_t addr, uint32_t level); 112 uint64_t create_device_block(uint64_t output_addr, uint32_t level, uint32_t ns); 113 uint64_t create_romem_block(uint64_t output_addr, uint32_t level, uint32_t ns); 114 uint64_t create_rwmem_block(uint64_t output_addr, uint32_t level, uint32_t ns); 115 116 /******************************************************************************* 117 * TLB maintenance accessor prototypes 118 ******************************************************************************/ 119 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1) 120 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle1is) 121 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2) 122 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle2is) 123 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3) 124 DEFINE_SYSOP_TYPE_FUNC(tlbi, alle3is) 125 DEFINE_SYSOP_TYPE_FUNC(tlbi, vmalle1) 126 127 /******************************************************************************* 128 * Cache maintenance accessor prototypes 129 ******************************************************************************/ 130 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, isw) 131 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cisw) 132 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, csw) 133 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvac) 134 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, ivac) 135 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac) 136 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau) 137 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva) 138 139 void flush_dcache_range(uint64_t, uint64_t); 140 void inv_dcache_range(uint64_t, uint64_t); 141 void dcsw_op_louis(uint32_t); 142 void dcsw_op_all(uint32_t); 143 144 void disable_mmu_el3(void); 145 void disable_mmu_icache_el3(void); 146 147 /******************************************************************************* 148 * Misc. accessor prototypes 149 ******************************************************************************/ 150 151 DEFINE_SYSREG_WRITE_CONST_FUNC(daifset) 152 DEFINE_SYSREG_WRITE_CONST_FUNC(daifclr) 153 154 #define enable_irq() write_daifclr(DAIF_IRQ_BIT) 155 #define enable_fiq() write_daifclr(DAIF_FIQ_BIT) 156 #define enable_serror() write_daifclr(DAIF_ABT_BIT) 157 #define enable_debug_exceptions() write_daifclr(DAIF_DBG_BIT) 158 #define disable_irq() write_daifset(DAIF_IRQ_BIT) 159 #define disable_fiq() write_daifset(DAIF_FIQ_BIT) 160 #define disable_serror() write_daifset(DAIF_ABT_BIT) 161 #define disable_debug_exceptions() write_daifset(DAIF_DBG_BIT) 162 163 DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) 164 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) 165 DEFINE_SYSREG_READ_FUNC(CurrentEl) 166 DEFINE_SYSREG_RW_FUNCS(daif) 167 DEFINE_SYSREG_RW_FUNCS(spsr_el1) 168 DEFINE_SYSREG_RW_FUNCS(spsr_el2) 169 DEFINE_SYSREG_RW_FUNCS(spsr_el3) 170 DEFINE_SYSREG_RW_FUNCS(elr_el1) 171 DEFINE_SYSREG_RW_FUNCS(elr_el2) 172 DEFINE_SYSREG_RW_FUNCS(elr_el3) 173 174 DEFINE_SYSOP_FUNC(wfi) 175 DEFINE_SYSOP_FUNC(wfe) 176 DEFINE_SYSOP_FUNC(sev) 177 DEFINE_SYSOP_TYPE_FUNC(dsb, sy) 178 DEFINE_SYSOP_TYPE_FUNC(dmb, sy) 179 DEFINE_SYSOP_TYPE_FUNC(dsb, ish) 180 DEFINE_SYSOP_TYPE_FUNC(dmb, ish) 181 DEFINE_SYSOP_FUNC(isb) 182 183 uint32_t get_afflvl_shift(uint32_t); 184 uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t); 185 186 187 void __dead2 eret(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, 188 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7); 189 void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, 190 uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7); 191 192 /******************************************************************************* 193 * System register accessor prototypes 194 ******************************************************************************/ 195 DEFINE_SYSREG_READ_FUNC(midr_el1) 196 DEFINE_SYSREG_READ_FUNC(mpidr_el1) 197 198 DEFINE_SYSREG_RW_FUNCS(scr_el3) 199 DEFINE_SYSREG_RW_FUNCS(hcr_el2) 200 201 DEFINE_SYSREG_RW_FUNCS(vbar_el1) 202 DEFINE_SYSREG_RW_FUNCS(vbar_el2) 203 DEFINE_SYSREG_RW_FUNCS(vbar_el3) 204 205 DEFINE_SYSREG_RW_FUNCS(sctlr_el1) 206 DEFINE_SYSREG_RW_FUNCS(sctlr_el2) 207 DEFINE_SYSREG_RW_FUNCS(sctlr_el3) 208 209 DEFINE_SYSREG_RW_FUNCS(actlr_el1) 210 DEFINE_SYSREG_RW_FUNCS(actlr_el2) 211 DEFINE_SYSREG_RW_FUNCS(actlr_el3) 212 213 DEFINE_SYSREG_RW_FUNCS(esr_el1) 214 DEFINE_SYSREG_RW_FUNCS(esr_el2) 215 DEFINE_SYSREG_RW_FUNCS(esr_el3) 216 217 DEFINE_SYSREG_RW_FUNCS(afsr0_el1) 218 DEFINE_SYSREG_RW_FUNCS(afsr0_el2) 219 DEFINE_SYSREG_RW_FUNCS(afsr0_el3) 220 221 DEFINE_SYSREG_RW_FUNCS(afsr1_el1) 222 DEFINE_SYSREG_RW_FUNCS(afsr1_el2) 223 DEFINE_SYSREG_RW_FUNCS(afsr1_el3) 224 225 DEFINE_SYSREG_RW_FUNCS(far_el1) 226 DEFINE_SYSREG_RW_FUNCS(far_el2) 227 DEFINE_SYSREG_RW_FUNCS(far_el3) 228 229 DEFINE_SYSREG_RW_FUNCS(mair_el1) 230 DEFINE_SYSREG_RW_FUNCS(mair_el2) 231 DEFINE_SYSREG_RW_FUNCS(mair_el3) 232 233 DEFINE_SYSREG_RW_FUNCS(amair_el1) 234 DEFINE_SYSREG_RW_FUNCS(amair_el2) 235 DEFINE_SYSREG_RW_FUNCS(amair_el3) 236 237 DEFINE_SYSREG_READ_FUNC(rvbar_el1) 238 DEFINE_SYSREG_READ_FUNC(rvbar_el2) 239 DEFINE_SYSREG_READ_FUNC(rvbar_el3) 240 241 DEFINE_SYSREG_RW_FUNCS(rmr_el1) 242 DEFINE_SYSREG_RW_FUNCS(rmr_el2) 243 DEFINE_SYSREG_RW_FUNCS(rmr_el3) 244 245 DEFINE_SYSREG_RW_FUNCS(tcr_el1) 246 DEFINE_SYSREG_RW_FUNCS(tcr_el2) 247 DEFINE_SYSREG_RW_FUNCS(tcr_el3) 248 249 DEFINE_SYSREG_RW_FUNCS(ttbr0_el1) 250 DEFINE_SYSREG_RW_FUNCS(ttbr0_el2) 251 DEFINE_SYSREG_RW_FUNCS(ttbr0_el3) 252 253 DEFINE_SYSREG_RW_FUNCS(ttbr1_el1) 254 255 DEFINE_SYSREG_RW_FUNCS(cptr_el2) 256 DEFINE_SYSREG_RW_FUNCS(cptr_el3) 257 258 DEFINE_SYSREG_RW_FUNCS(cpacr_el1) 259 DEFINE_SYSREG_RW_FUNCS(cntfrq_el0) 260 DEFINE_SYSREG_RW_FUNCS(cntps_ctl_el1) 261 DEFINE_SYSREG_RW_FUNCS(cntps_tval_el1) 262 DEFINE_SYSREG_RW_FUNCS(cntps_cval_el1) 263 DEFINE_SYSREG_READ_FUNC(cntpct_el0) 264 DEFINE_SYSREG_RW_FUNCS(cnthctl_el2) 265 266 DEFINE_SYSREG_RW_FUNCS(tpidr_el3) 267 268 DEFINE_SYSREG_RW_FUNCS(cntvoff_el2) 269 270 DEFINE_SYSREG_RW_FUNCS(vpidr_el2) 271 DEFINE_SYSREG_RW_FUNCS(vmpidr_el2) 272 273 DEFINE_SYSREG_READ_FUNC(isr_el1) 274 275 /* GICv3 System Registers */ 276 277 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1) 278 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2) 279 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3) 280 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_pmr_el1, ICC_PMR_EL1) 281 282 283 #define IS_IN_EL(x) \ 284 (GET_EL(read_CurrentEl()) == MODE_EL##x) 285 286 #define IS_IN_EL1() IS_IN_EL(1) 287 #define IS_IN_EL3() IS_IN_EL(3) 288 289 /* Previously defined accesor functions with incomplete register names */ 290 291 #define read_current_el() read_CurrentEl() 292 293 #define dsb() dsbsy() 294 295 #define read_midr() read_midr_el1() 296 297 #define read_mpidr() read_mpidr_el1() 298 299 #define read_scr() read_scr_el3() 300 #define write_scr(_v) write_scr_el3(_v) 301 302 #define read_hcr() read_hcr_el2() 303 #define write_hcr(_v) write_hcr_el2(_v) 304 305 #define read_cpacr() read_cpacr_el1() 306 #define write_cpacr(_v) write_cpacr_el1(_v) 307 308 #endif /* __ARCH_HELPERS_H__ */ 309