root/include/asm-m68k/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 _M68K_SEGMENT_H
   2 #define _M68K_SEGMENT_H
   3 
   4 /* define constants */
   5 /* Address spaces (FC0-FC2) */
   6 #define USER_DATA     (1)
   7 #ifndef USER_DS
   8 #define USER_DS       (USER_DATA)
   9 #endif
  10 #define USER_PROGRAM  (2)
  11 #define SUPER_DATA    (5)
  12 #ifndef KERNEL_DS
  13 #define KERNEL_DS     (SUPER_DATA)
  14 #endif
  15 #define SUPER_PROGRAM (6)
  16 #define CPU_SPACE     (7)
  17 
  18 #ifndef __ASSEMBLY__
  19 
  20 /*
  21  * Uh, these should become the main single-value transfer routines..
  22  * They automatically use the right size if we just have the right
  23  * pointer type..
  24  */
  25 #define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
  26 #define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
  27 
  28 /*
  29  * This is a silly but good way to make sure that
  30  * the __put_user function is indeed always optimized,
  31  * and that we use the correct sizes..
  32  */
  33 extern int bad_user_access_length(void);
  34 
  35 #define __ptr(x) ((unsigned long *)(x))
  36 
  37 static inline void __put_user(unsigned long x, void * y, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  38 {
  39         switch (size) {
  40                 case 1:
  41                         __asm__ ("movesb %0,%1"
  42                                 : /* no outputs */
  43                                 :"r" (x),"m" (*__ptr(y)) : "memory");
  44                         break;
  45                 case 2:
  46                         __asm__ ("movesw %0,%1"
  47                                 : /* no outputs */
  48                                 :"r" (x),"m" (*__ptr(y)) : "memory");
  49                         break;
  50                 case 4:
  51                         __asm__ ("movesl %0,%1"
  52                                 : /* no outputs */
  53                                 :"r" (x),"m" (*__ptr(y)) : "memory");
  54                         break;
  55                 default:
  56                         bad_user_access_length();
  57         }
  58 }
  59 
  60 static inline unsigned long __get_user(const void * y, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62         unsigned long result;
  63 
  64         switch (size) {
  65                 case 1:
  66                         __asm__ ("movesb %1,%0"
  67                                  :"=r" (result)
  68                                  :"m" (*__ptr(y)));
  69                         return (unsigned char) result;
  70                 case 2:
  71                         __asm__ ("movesw %1,%0"
  72                                  :"=r" (result)
  73                                  :"m" (*__ptr(y)));
  74                         return (unsigned short) result;
  75                 case 4:
  76                         __asm__ ("movesl %1,%0"
  77                                  :"=r" (result)
  78                                  :"m" (*__ptr(y)));
  79                         return result;
  80                 default:
  81                         return bad_user_access_length();
  82         }
  83 }
  84 #undef __ptr
  85 
  86 /*
  87  * These are deprecated..
  88  *
  89  * Use "put_user()" and "get_user()" with the proper pointer types instead.
  90  */
  91 
  92 #define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
  93 #define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
  94 #define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
  95 
  96 #define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
  97 #define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
  98 #define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
  99 
 100 #ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
 101 
 102 static inline unsigned char get_user_byte(const char * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         return __get_user(addr,1);
 105 }
 106 
 107 static inline unsigned short get_user_word(const short *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         return __get_user(addr,2);
 110 }
 111 
 112 static inline unsigned long get_user_long(const int *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 113 {
 114         return __get_user(addr,4);
 115 }
 116 
 117 static inline void put_user_byte(char val,char *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119         __put_user(val, addr, 1);
 120 }
 121 
 122 static inline void put_user_word(short val,short * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124         __put_user(val, addr, 2);
 125 }
 126 
 127 static inline void put_user_long(unsigned long val,int * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         __put_user(val, addr, 4);
 130 }
 131 
 132 #endif
 133 
 134 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 135 {
 136         unsigned long tmp;
 137         if (n == 0) return;
 138         tmp = n;
 139         n >>= 2;
 140         if (n != 0)
 141                 __asm__ ("1:\t"
 142                          "movel %1@+,%/d0\n\t"
 143                          "movesl %/d0,%2@+\n\t"
 144                               "dbra %0,1b\n\t"
 145                               "clrw %0\n\t"
 146                               "subql #1,%0\n\t"
 147                          "bccs 1b\n\t"
 148                               : "=d" (n), "=a" (from), "=a" (to)
 149                          : "0" (n-1), "1" (from), "2" (to)
 150                          : "d0", "memory");
 151         if (tmp & 2)
 152                 __asm__ ("movew %0@+,%/d0\n\t"
 153                          "movesw %/d0,%1@+\n\t"
 154                          : "=a" (from), "=a" (to)
 155                          : "0" (from), "1" (to)
 156                          : "d0", "memory");
 157         if (tmp & 1)
 158                 __asm__ ("moveb %0@,%/d0\n\t"
 159                          "movesb %/d0,%1@\n\t"
 160                          : /* no outputs */
 161                          : "a" (from), "a" (to)
 162                               : "d0", "memory");
 163 }
 164 
 165 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         switch (n) {
 168                 case 0:
 169                         return;
 170                 case 1:
 171                         __put_user(*(const char *) from, (char *) to, 1);
 172                         return;
 173                 case 2:
 174                         __put_user(*(const short *) from, (short *) to, 2);
 175                         return;
 176                 case 3:
 177                         __put_user(*(const short *) from, (short *) to, 2);
 178                         __put_user(*(2+(const char *) from), 2+(char *) to, 1);
 179                         return;
 180                 case 4:
 181                         __put_user(*(const int *) from, (int *) to, 4);
 182                         return;
 183                 case 8:
 184                         __put_user(*(const int *) from, (int *) to, 4);
 185                         __put_user(*(1+(const int *) from), 1+(int *) to, 4);
 186                         return;
 187                 case 12:
 188                         __put_user(*(const int *) from, (int *) to, 4);
 189                         __put_user(*(1+(const int *) from), 1+(int *) to, 4);
 190                         __put_user(*(2+(const int *) from), 2+(int *) to, 4);
 191                         return;
 192                 case 16:
 193                         __put_user(*(const int *) from, (int *) to, 4);
 194                         __put_user(*(1+(const int *) from), 1+(int *) to, 4);
 195                         __put_user(*(2+(const int *) from), 2+(int *) to, 4);
 196                         __put_user(*(3+(const int *) from), 3+(int *) to, 4);
 197                         return;
 198         }
 199 #define COMMON(x)                     \
 200 __asm__ __volatile__ ("1:\n\t"        \
 201             "movel %1@+,%/d0\n\t"     \
 202             "movesl %/d0,%2@+\n\t"    \
 203             "dbra %0,1b\n\t"          \
 204             "clrw %0\n\t"             \
 205             "subql #1,%0\n\t"         \
 206             "bccs 1b\n\t"             \
 207             x                     \
 208             : "=d" (n), "=a" (from), "=a" (to)    \
 209             : "1" (from), "2" (to), "0" (n/4-1)   \
 210             : "d0", "memory");
 211 
 212   switch (n % 4) {
 213       case 0:
 214           COMMON("");
 215           return;
 216       case 1:
 217           COMMON("moveb %1@+,%/d0; movesb %/d0,%2@+");
 218           return;
 219       case 2:
 220           COMMON("movew %1@+,%/d0; movesw %/d0,%2@+");
 221           return;
 222       case 3:
 223           COMMON("movew %1@+,%/d0; movesw %/d0,%2@+\n\t"
 224                  "moveb %1@+,%/d0; movesb %/d0,%2@+");
 225           return;
 226   }
 227 #undef COMMON
 228 }
 229 
 230 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232         unsigned long tmp;
 233         if (n == 0) return;
 234         tmp = n;
 235         n >>= 2;
 236         if (n != 0)
 237                 __asm__ ("1:\t"
 238                          "movesl %1@+,%/d0\n\t"
 239                          "movel %/d0,%2@+\n\t"
 240                               "dbra %0,1b\n\t"
 241                               "clrw %0\n\t"
 242                               "subql #1,%0\n\t"
 243                          "bccs 1b\n\t"
 244                               : "=d" (n), "=a" (from), "=a" (to)
 245                          : "0" (n-1), "1" (from), "2" (to)
 246                          : "d0", "memory");
 247         if (tmp & 2)
 248                 __asm__ ("movesw %0@+,%/d0\n\t"
 249                          "movew %/d0,%1@+\n\t"
 250                          : "=a" (from), "=a" (to)
 251                          : "0" (from), "1" (to)
 252                          : "d0", "memory");
 253         if (tmp & 1)
 254                 __asm__ ("movesb %0@,%/d0\n\t"
 255                          "moveb %/d0,%1@\n\t"
 256                          : /* no outputs */
 257                          : "a" (from), "a" (to)
 258                               : "d0", "memory");
 259 }
 260 
 261 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 262 {
 263         switch (n) {
 264                 case 0:
 265                         return;
 266                 case 1:
 267                         *(char *)to = __get_user((const char *) from, 1);
 268                         return;
 269                 case 2:
 270                         *(short *)to = __get_user((const short *) from, 2);
 271                         return;
 272                 case 3:
 273                         *(short *) to = __get_user((const short *) from, 2);
 274                         *((char *) to + 2) = __get_user(2+(const char *) from, 1);
 275                         return;
 276                 case 4:
 277                         *(int *) to = __get_user((const int *) from, 4);
 278                         return;
 279                 case 8:
 280                         *(int *) to = __get_user((const int *) from, 4);
 281                         *(1+(int *) to) = __get_user(1+(const int *) from, 4);
 282                         return;
 283                 case 12:
 284                         *(int *) to = __get_user((const int *) from, 4);
 285                         *(1+(int *) to) = __get_user(1+(const int *) from, 4);
 286                         *(2+(int *) to) = __get_user(2+(const int *) from, 4);
 287                         return;
 288                 case 16:
 289                         *(int *) to = __get_user((const int *) from, 4);
 290                         *(1+(int *) to) = __get_user(1+(const int *) from, 4);
 291                         *(2+(int *) to) = __get_user(2+(const int *) from, 4);
 292                         *(3+(int *) to) = __get_user(3+(const int *) from, 4);
 293                         return;
 294         }
 295 #define COMMON(x)                     \
 296 __asm__ __volatile__ ("1:\n\t"        \
 297             "movesl %1@+,%/d0\n\t"    \
 298             "movel %/d0,%2@+\n\t"     \
 299             "dbra %0,1b\n\t"          \
 300             "clrw %0\n\t"             \
 301             "subql #1,%0\n\t"         \
 302             "bccs 1b\n\t"             \
 303             x                         \
 304             : "=d" (n), "=a" (from), "=a" (to)    \
 305             : "1" (from), "2" (to), "0" (n/4-1)   \
 306             : "d0", "memory");
 307 
 308   switch (n % 4) {
 309       case 0:
 310           COMMON("");
 311           return;
 312       case 1:
 313           COMMON("movesb %1@+,%/d0; moveb %/d0,%2@+");
 314           return;
 315       case 2:
 316           COMMON("movesw %1@+,%/d0; movew %/d0,%2@+");
 317           return;
 318       case 3:
 319           COMMON("movesw %1@+,%/d0; movew %/d0,%2@+\n\t"
 320                  "movesb %1@+,%/d0; moveb %/d0,%2@+");
 321           return;
 322   }
 323 #undef COMMON
 324 }
 325 
 326 #define memcpy_fromfs(to, from, n) \
 327 (__builtin_constant_p(n) ? \
 328  __constant_memcpy_fromfs((to),(from),(n)) : \
 329  __generic_memcpy_fromfs((to),(from),(n)))
 330 
 331 #define memcpy_tofs(to, from, n) \
 332 (__builtin_constant_p(n) ? \
 333  __constant_memcpy_tofs((to),(from),(n)) : \
 334  __generic_memcpy_tofs((to),(from),(n)))
 335 
 336 /*
 337  * Get/set the SFC/DFC registers for MOVES instructions
 338  */
 339 
 340 static inline unsigned long get_fs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342         unsigned long _v;
 343         __asm__ ("movec %/dfc,%0":"=r" (_v):);
 344 
 345         return _v;
 346 }
 347 
 348 static inline unsigned long get_ds(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 349 {
 350     /* return the supervisor data space code */
 351     return KERNEL_DS;
 352 }
 353 
 354 static inline void set_fs(unsigned long val)
     /* [previous][next][first][last][top][bottom][index][help] */
 355 {
 356         __asm__ __volatile__ ("movec %0,%/sfc\n\t"
 357                               "movec %0,%/dfc\n\t"
 358                               : /* no outputs */ : "r" (val) : "memory");
 359 }
 360 
 361 #endif /* __ASSEMBLY__ */
 362 
 363 #endif /* _M68K_SEGMENT_H */

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