root/include/asm-mips/segment.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. get_user_byte
  2. get_user_word
  3. get_user_long
  4. get_user_dlong
  5. put_user_byte
  6. put_user_word
  7. put_user_long
  8. put_user_dlong
  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 /*
   2  * include/asm-mips/segment.h
   3  *
   4  * This file is subject to the terms and conditions of the GNU General Public
   5  * License.  See the file "COPYING" in the main directory of this archive
   6  * for more details.
   7  *
   8  * Copyright (C) 1994 by Ralf Baechle
   9  *
  10  */
  11 #ifndef __ASM_MIPS_SEGMENT_H
  12 #define __ASM_MIPS_SEGMENT_H
  13 
  14 /*
  15  * Memory segments (32bit kernel mode addresses)
  16  */
  17 #define KUSEG                   0x00000000
  18 #define KSEG0                   0x80000000
  19 #define KSEG1                   0xa0000000
  20 #define KSEG2                   0xc0000000
  21 #define KSEG3                   0xe0000000
  22 
  23 /*
  24  * returns the kernel segment base of a given address
  25  * Address space is a scarce resource on a R3000, so
  26  * emulate the Intel segment braindamage...
  27  */
  28 #define KSEGX(a)                (a & 0xe0000000)
  29 
  30 #define KERNEL_CS       KERNELBASE
  31 #define KERNEL_DS       KERNEL_CS
  32 
  33 #define USER_CS         0x00000000
  34 #define USER_DS         USER_CS
  35 
  36 #ifndef __ASSEMBLY__
  37 
  38 /*
  39  * This variable is defined in arch/mips/kernel/head.S.
  40  */
  41 extern unsigned long segment_fs;
  42 
  43 #define get_fs_byte(addr) get_user_byte((char *)(addr))
  44 static inline unsigned char get_user_byte(const char *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46         return *(const char *)(((unsigned long)addr)+segment_fs);
  47 }
  48 
  49 #define get_fs_word(addr) get_user_word((short *)(addr))
  50 static inline unsigned short get_user_word(const short *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52         return *(const short *)(((unsigned long)addr)+segment_fs);
  53 }
  54 
  55 #define get_fs_long(addr) get_user_long((int *)(addr))
  56 static inline unsigned long get_user_long(const int *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58         return *(const int *)(((unsigned long)addr)+segment_fs);
  59 }
  60 
  61 #define get_fs_dlong(addr) get_user_dlong((long long *)(addr))
  62 static inline unsigned long get_user_dlong(const long long *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64         return *(const long long *)(((unsigned long)addr)+segment_fs);
  65 }
  66 
  67 #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
  68 static inline void put_user_byte(char val,char *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70         *(char *)(((unsigned long)addr)+segment_fs) = val;
  71 }
  72 
  73 #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
  74 static inline void put_user_word(short val,short * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         *(short *)(((unsigned long)addr)+segment_fs) = val;
  77 }
  78 
  79 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
  80 static inline void put_user_long(unsigned long val,int * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82         *(int *)(((unsigned long)addr)+segment_fs) = val;
  83 }
  84 
  85 #define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr))
  86 static inline void put_user_dlong(unsigned long val,long long * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         *(long long *)(((unsigned long)addr)+segment_fs) = val;
  89 }
  90 
  91 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   __asm__(
  94         ".set\tnoreorder\n\t"
  95         ".set\tnoat\n"
  96         "1:\tlbu\t$1,(%2)\n\t"
  97         "addiu\t%2,%2,1\n\t"
  98         "sb\t$1,(%1)\n\t"
  99         "addiu\t%0,%0,-1\n\t"
 100         "bne\t$0,%0,1b\n\t"
 101         "addiu\t%1,%1,1\n\t"
 102         ".set\tat\n\t"
 103         ".set\treorder"
 104         : /* no outputs */
 105         :"r" (n),"r" (((long) to)| segment_fs),"r" ((long) from)
 106         :"$1");
 107 }
 108 
 109 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         /*
 112          * Use put_user_byte to avoid trouble with alignment.
 113          */
 114         switch (n) {
 115                 case 0:
 116                         return;
 117                 case 1:
 118                         put_user_byte(*(const char *) from, (char *) to);
 119                         return;
 120                 case 2:
 121                         put_user_byte(*(const char *) from, (char *) to);
 122                         put_user_byte(*(1+(const char *) from), 1+(char *) to);
 123                         return;
 124                 case 3:
 125                         put_user_byte(*((const char *) from), (char *) to);
 126                         put_user_byte(*(1+(const char *) from), 1+(char *) to);
 127                         put_user_byte(*(2+(const char *) from), 2+(char *) to);
 128                         return;
 129                 case 4:
 130                         put_user_byte(*((const char *) from), (char *) to);
 131                         put_user_byte(*(1+(const char *) from), 1+(char *) to);
 132                         put_user_byte(*(2+(const char *) from), 2+(char *) to);
 133                         put_user_byte(*(3+(const char *) from), 3+(char *) to);
 134                         return;
 135         }
 136 
 137         __generic_memcpy_tofs(to, from, n);
 138 
 139         return;
 140 }
 141 
 142 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144   __asm__(
 145         ".set\tnoreorder\n\t"
 146         ".set\tnoat\n"
 147         "1:\tlbu\t$1,(%2)\n\t"
 148         "addiu\t%2,%2,1\n\t"
 149         "sb\t$1,(%1)\n\t"
 150         "addiu\t%0,%0,-1\n\t"
 151         "bne\t$0,%0,1b\n\t"
 152         "addiu\t%1,%1,1\n\t"
 153         ".set\tat\n\t"
 154         ".set\treorder"
 155         : /* no outputs */
 156         :"r" (n),"r" ((long) to),"r" (((long) from | segment_fs))
 157         :"$1","memory");
 158 }
 159 
 160 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         /*
 163          * Use put_user_byte to avoid trouble with alignment.
 164          */
 165         switch (n) {
 166                 case 0:
 167                         return;
 168                 case 1:
 169                         *(char *)to = get_user_byte((const char *) from);
 170                         return;
 171                 case 2:
 172                         *(char *) to = get_user_byte((const char *) from);
 173                         *(char *) to = get_user_byte(1+(const char *) from);
 174                         return;
 175                 case 3:
 176                         *(char *) to = get_user_byte((const char *) from);
 177                         *(char *) to = get_user_byte(1+(const char *) from);
 178                         *(char *) to = get_user_byte(2+(const char *) from);
 179                         return;
 180                 case 4:
 181                         *(char *) to = get_user_byte((const char *) from);
 182                         *(char *) to = get_user_byte(1+(const char *) from);
 183                         *(char *) to = get_user_byte(2+(const char *) from);
 184                         *(char *) to = get_user_byte(3+(const char *) from);
 185                         return;
 186         }
 187 
 188         
 189         __generic_memcpy_fromfs(to, from, n);
 190         return;
 191 }
 192 
 193 #define memcpy_fromfs(to, from, n) \
 194 (__builtin_constant_p(n) ? \
 195  __constant_memcpy_fromfs((to),(from),(n)) : \
 196  __generic_memcpy_fromfs((to),(from),(n)))
 197 
 198 #define memcpy_tofs(to, from, n) \
 199 (__builtin_constant_p(n) ? \
 200  __constant_memcpy_tofs((to),(from),(n)) : \
 201  __generic_memcpy_tofs((to),(from),(n)))
 202 
 203 static inline unsigned long get_fs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205         return segment_fs;
 206 }
 207 
 208 static inline unsigned long get_ds(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210         return KERNEL_DS;
 211 }
 212 
 213 static inline void set_fs(unsigned long val)
     /* [previous][next][first][last][top][bottom][index][help] */
 214 {
 215         segment_fs = val;
 216 }
 217 
 218 #endif
 219 
 220 #endif /* __ASM_MIPS_SEGMENT_H */

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