1 #ifndef __ASMARM_TLS_H 2 #define __ASMARM_TLS_H 3 4 #ifdef __ASSEMBLY__ 5 #include <asm/asm-offsets.h> 6 .macro switch_tls_none, base, tp, tpuser, tmp1, tmp2 7 .endm 8 9 .macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2 10 mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register 11 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register 12 mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register 13 str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it 14 .endm 15 16 .macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2 17 ldr \tmp1, =elf_hwcap 18 ldr \tmp1, [\tmp1, #0] 19 mov \tmp2, #0xffff0fff 20 tst \tmp1, #HWCAP_TLS @ hardware TLS available? 21 streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 22 mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register 23 mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register 24 mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register 25 strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it 26 .endm 27 28 .macro switch_tls_software, base, tp, tpuser, tmp1, tmp2 29 mov \tmp1, #0xffff0fff 30 str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0 31 .endm 32 #endif 33 34 #ifdef CONFIG_TLS_REG_EMUL 35 #define tls_emu 1 36 #define has_tls_reg 1 37 #define switch_tls switch_tls_none 38 #elif defined(CONFIG_CPU_V6) 39 #define tls_emu 0 40 #define has_tls_reg (elf_hwcap & HWCAP_TLS) 41 #define switch_tls switch_tls_v6 42 #elif defined(CONFIG_CPU_32v6K) 43 #define tls_emu 0 44 #define has_tls_reg 1 45 #define switch_tls switch_tls_v6k 46 #else 47 #define tls_emu 0 48 #define has_tls_reg 0 49 #define switch_tls switch_tls_software 50 #endif 51 52 #ifndef __ASSEMBLY__ 53 static inline unsigned long get_tpuser(void) 54 { 55 unsigned long reg = 0; 56 57 if (has_tls_reg && !tls_emu) 58 __asm__("mrc p15, 0, %0, c13, c0, 2" : "=r" (reg)); 59 60 return reg; 61 } 62 #endif 63 #endif /* __ASMARM_TLS_H */ 64