root/include/asm-i386/segment.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __put_user
  2. __get_user
  3. get_user_byte
  4. get_user_word
  5. get_user_long
  6. put_user_byte
  7. put_user_word
  8. put_user_long
  9. __generic_memcpy_tofs
  10. __constant_memcpy_tofs
  11. __generic_memcpy_fromfs
  12. __constant_memcpy_fromfs
  13. get_fs
  14. get_ds
  15. set_fs

   1 #ifndef _ASM_SEGMENT_H
   2 #define _ASM_SEGMENT_H
   3 
   4 #define KERNEL_CS       0x10
   5 #define KERNEL_DS       0x18
   6 
   7 #define USER_CS         0x23
   8 #define USER_DS         0x2B
   9 
  10 #ifndef __ASSEMBLY__
  11 
  12 /*
  13  * Uh, these should become the main single-value transfer routines..
  14  * They automatically use the right size if we just have the right
  15  * pointer type..
  16  */
  17 #define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
  18 #define get_user(ptr) __get_user((ptr),sizeof(*(ptr)))
  19 
  20 /*
  21  * This is a silly but good way to make sure that
  22  * the __put_user function is indeed always optimized,
  23  * and that we use the correct sizes..
  24  */
  25 extern int bad_user_access_length(void);
  26 
  27 /*
  28  * dummy pointer type structure.. gcc won't try to do something strange
  29  * this way..
  30  */
  31 struct __segment_dummy { unsigned long a[100]; };
  32 #define __sd(x) ((struct __segment_dummy *) (x))
  33 
  34 static inline void __put_user(unsigned long x, void * y, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36         switch (size) {
  37                 case 1:
  38                         __asm__ ("movb %b1,%%fs:%0"
  39                                 :"=m" (*__sd(y))
  40                                 :"iq" ((unsigned char) x), "m" (*__sd(y)));
  41                         break;
  42                 case 2:
  43                         __asm__ ("movw %w1,%%fs:%0"
  44                                 :"=m" (*__sd(y))
  45                                 :"iq" ((unsigned short) x), "m" (*__sd(y)));
  46                         break;
  47                 case 4:
  48                         __asm__ ("movl %1,%%fs:%0"
  49                                 :"=m" (*__sd(y))
  50                                 :"ir" (x), "m" (*__sd(y)));
  51                         break;
  52                 default:
  53                         bad_user_access_length();
  54         }
  55 }
  56 
  57 static inline unsigned long __get_user(const void * y, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59         unsigned long result;
  60 
  61         switch (size) {
  62                 case 1:
  63                         __asm__ ("movb %%fs:%1,%b0"
  64                                 :"=q" (result)
  65                                 :"m" (*__sd(y)));
  66                         return (unsigned char) result;
  67                 case 2:
  68                         __asm__ ("movw %%fs:%1,%w0"
  69                                 :"=q" (result)
  70                                 :"m" (*__sd(y)));
  71                         return (unsigned short) result;
  72                 case 4:
  73                         __asm__ ("movl %%fs:%1,%0"
  74                                 :"=r" (result)
  75                                 :"m" (*__sd(y)));
  76                         return result;
  77                 default:
  78                         return bad_user_access_length();
  79         }
  80 }
  81 
  82 /*
  83  * These are depracated..
  84  */
  85 
  86 static inline unsigned char get_user_byte(const char * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         return __get_user(addr,1);
  89 }
  90 
  91 #define get_fs_byte(addr) get_user_byte((char *)(addr))
  92 
  93 static inline unsigned short get_user_word(const short *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95         return __get_user(addr, 2);
  96 }
  97 
  98 #define get_fs_word(addr) get_user_word((short *)(addr))
  99 
 100 static inline unsigned long get_user_long(const int *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         return __get_user(addr, 4);
 103 }
 104 
 105 #define get_fs_long(addr) get_user_long((int *)(addr))
 106 
 107 static inline void put_user_byte(char val,char *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         __put_user(val, addr, 1);
 110 }
 111 
 112 #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
 113 
 114 static inline void put_user_word(short val,short * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116         __put_user(val, addr, 2);
 117 }
 118 
 119 #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
 120 
 121 static inline void put_user_long(unsigned long val,int * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         __put_user(val, addr, 4);
 124 }
 125 
 126 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
 127 
 128 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130 __asm__("cld\n\t"
 131         "push %%es\n\t"
 132         "push %%fs\n\t"
 133         "pop %%es\n\t"
 134         "testb $1,%%cl\n\t"
 135         "je 1f\n\t"
 136         "movsb\n"
 137         "1:\ttestb $2,%%cl\n\t"
 138         "je 2f\n\t"
 139         "movsw\n"
 140         "2:\tshrl $2,%%ecx\n\t"
 141         "rep ; movsl\n\t"
 142         "pop %%es"
 143         : /* no outputs */
 144         :"c" (n),"D" ((long) to),"S" ((long) from)
 145         :"cx","di","si");
 146 }
 147 
 148 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 149 {
 150         switch (n) {
 151                 case 0:
 152                         return;
 153                 case 1:
 154                         put_user_byte(*(const char *) from, (char *) to);
 155                         return;
 156                 case 2:
 157                         put_user_word(*(const short *) from, (short *) to);
 158                         return;
 159                 case 3:
 160                         put_user_word(*(const short *) from, (short *) to);
 161                         put_user_byte(*(2+(const char *) from), 2+(char *) to);
 162                         return;
 163                 case 4:
 164                         put_user_long(*(const int *) from, (int *) to);
 165                         return;
 166         }
 167 #define COMMON(x) \
 168 __asm__("cld\n\t" \
 169         "push %%es\n\t" \
 170         "push %%fs\n\t" \
 171         "pop %%es\n\t" \
 172         "rep ; movsl\n\t" \
 173         x \
 174         "pop %%es" \
 175         : /* no outputs */ \
 176         :"c" (n/4),"D" ((long) to),"S" ((long) from) \
 177         :"cx","di","si")
 178 
 179         switch (n % 4) {
 180                 case 0:
 181                         COMMON("");
 182                         return;
 183                 case 1:
 184                         COMMON("movsb\n\t");
 185                         return;
 186                 case 2:
 187                         COMMON("movsw\n\t");
 188                         return;
 189                 case 3:
 190                         COMMON("movsw\n\tmovsb\n\t");
 191                         return;
 192         }
 193 #undef COMMON
 194 }
 195 
 196 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198 __asm__("cld\n\t"
 199         "testb $1,%%cl\n\t"
 200         "je 1f\n\t"
 201         "fs ; movsb\n"
 202         "1:\ttestb $2,%%cl\n\t"
 203         "je 2f\n\t"
 204         "fs ; movsw\n"
 205         "2:\tshrl $2,%%ecx\n\t"
 206         "rep ; fs ; movsl"
 207         : /* no outputs */
 208         :"c" (n),"D" ((long) to),"S" ((long) from)
 209         :"cx","di","si","memory");
 210 }
 211 
 212 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 213 {
 214         switch (n) {
 215                 case 0:
 216                         return;
 217                 case 1:
 218                         *(char *)to = get_user_byte((const char *) from);
 219                         return;
 220                 case 2:
 221                         *(short *)to = get_user_word((const short *) from);
 222                         return;
 223                 case 3:
 224                         *(short *) to = get_user_word((const short *) from);
 225                         *((char *) to + 2) = get_user_byte(2+(const char *) from);
 226                         return;
 227                 case 4:
 228                         *(int *) to = get_user_long((const int *) from);
 229                         return;
 230         }
 231 #define COMMON(x) \
 232 __asm__("cld\n\t" \
 233         "rep ; fs ; movsl\n\t" \
 234         x \
 235         : /* no outputs */ \
 236         :"c" (n/4),"D" ((long) to),"S" ((long) from) \
 237         :"cx","di","si","memory")
 238 
 239         switch (n % 4) {
 240                 case 0:
 241                         COMMON("");
 242                         return;
 243                 case 1:
 244                         COMMON("fs ; movsb");
 245                         return;
 246                 case 2:
 247                         COMMON("fs ; movsw");
 248                         return;
 249                 case 3:
 250                         COMMON("fs ; movsw\n\tfs ; movsb");
 251                         return;
 252         }
 253 #undef COMMON
 254 }
 255 
 256 #define memcpy_fromfs(to, from, n) \
 257 (__builtin_constant_p(n) ? \
 258  __constant_memcpy_fromfs((to),(from),(n)) : \
 259  __generic_memcpy_fromfs((to),(from),(n)))
 260 
 261 #define memcpy_tofs(to, from, n) \
 262 (__builtin_constant_p(n) ? \
 263  __constant_memcpy_tofs((to),(from),(n)) : \
 264  __generic_memcpy_tofs((to),(from),(n)))
 265 
 266 /*
 267  * Someone who knows GNU asm better than I should double check the following.
 268  * It seems to work, but I don't know if I'm doing something subtly wrong.
 269  * --- TYT, 11/24/91
 270  * [ nothing wrong here, Linus: I just changed the ax to be any reg ]
 271  */
 272 
 273 static inline unsigned long get_fs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 274 {
 275         unsigned long _v;
 276         __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
 277         return _v;
 278 }
 279 
 280 static inline unsigned long get_ds(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282         unsigned long _v;
 283         __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
 284         return _v;
 285 }
 286 
 287 static inline void set_fs(unsigned long val)
     /* [previous][next][first][last][top][bottom][index][help] */
 288 {
 289         __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
 290 }
 291 
 292 #endif /* __ASSEMBLY__ */
 293 
 294 #endif /* _ASM_SEGMENT_H */

/* [previous][next][first][last][top][bottom][index][help] */