Home | History | Annotate | Download | only in aarch64
      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