linux/arch/arm/include/asm/tls.h
<<
>>
Prefs
   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__
  53static 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