Annotation of Gnu-Mach/linux/src/include/asm-i386/segment.h, revision 1.1.1.3

1.1       root        1: #ifndef _ASM_SEGMENT_H
                      2: #define _ASM_SEGMENT_H
                      3: 
1.1.1.2   root        4: #ifdef MACH
                      5: 
                      6: #include <machine/gdt.h>
                      7: #include <machine/ldt.h>
                      8: 
                      9: #else /* !MACH */
                     10: 
1.1       root       11: #define KERNEL_CS      0x10
                     12: #define KERNEL_DS      0x18
                     13: 
                     14: #define USER_CS                0x23
                     15: #define USER_DS                0x2B
                     16: 
1.1.1.2   root       17: #endif /* !MACH */
                     18: 
1.1       root       19: #ifndef __ASSEMBLY__
                     20: 
                     21: /*
                     22:  * Uh, these should become the main single-value transfer routines..
                     23:  * They automatically use the right size if we just have the right
                     24:  * pointer type..
                     25:  */
                     26: #define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
                     27: #define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
                     28: 
                     29: /*
                     30:  * This is a silly but good way to make sure that
                     31:  * the __put_user function is indeed always optimized,
                     32:  * and that we use the correct sizes..
                     33:  */
                     34: extern int bad_user_access_length(void);
                     35: 
                     36: /*
                     37:  * dummy pointer type structure.. gcc won't try to do something strange
                     38:  * this way..
                     39:  */
                     40: struct __segment_dummy { unsigned long a[100]; };
                     41: #define __sd(x) ((struct __segment_dummy *) (x))
                     42: #define __const_sd(x) ((const struct __segment_dummy *) (x))
                     43: 
1.1.1.2   root       44: static inline void __attribute__((always_inline)) __put_user(unsigned long x, void * y, int size)
1.1       root       45: {
                     46:        switch (size) {
                     47:                case 1:
                     48:                        __asm__ ("movb %b1,%%fs:%0"
                     49:                                :"=m" (*__sd(y))
                     50:                                :"iq" ((unsigned char) x), "m" (*__sd(y)));
                     51:                        break;
                     52:                case 2:
                     53:                        __asm__ ("movw %w1,%%fs:%0"
                     54:                                :"=m" (*__sd(y))
                     55:                                :"ir" ((unsigned short) x), "m" (*__sd(y)));
                     56:                        break;
                     57:                case 4:
                     58:                        __asm__ ("movl %1,%%fs:%0"
                     59:                                :"=m" (*__sd(y))
                     60:                                :"ir" (x), "m" (*__sd(y)));
                     61:                        break;
                     62:                default:
1.1.1.3 ! root       63: #ifdef __OPTIMIZE__
1.1       root       64:                        bad_user_access_length();
1.1.1.3 ! root       65: #else
        !            66:                        asm volatile("ud2");
        !            67: #endif
1.1       root       68:        }
                     69: }
                     70: 
1.1.1.2   root       71: static inline unsigned long __attribute__((always_inline)) __get_user(const void * y, int size)
1.1       root       72: {
                     73:        unsigned long result;
                     74: 
                     75:        switch (size) {
                     76:                case 1:
                     77:                        __asm__ ("movb %%fs:%1,%b0"
                     78:                                :"=q" (result)
                     79:                                :"m" (*__const_sd(y)));
                     80:                        return (unsigned char) result;
                     81:                case 2:
                     82:                        __asm__ ("movw %%fs:%1,%w0"
                     83:                                :"=r" (result)
                     84:                                :"m" (*__const_sd(y)));
                     85:                        return (unsigned short) result;
                     86:                case 4:
                     87:                        __asm__ ("movl %%fs:%1,%0"
                     88:                                :"=r" (result)
                     89:                                :"m" (*__const_sd(y)));
                     90:                        return result;
                     91:                default:
1.1.1.3 ! root       92: #ifdef __OPTIMIZE__
1.1       root       93:                        return bad_user_access_length();
1.1.1.3 ! root       94: #else
        !            95:                        asm volatile("ud2");
        !            96: #endif
1.1       root       97:        }
                     98: }
                     99: 
1.1.1.2   root      100: #if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
1.1       root      101: static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
                    102: {
                    103:     __asm__ volatile
1.1.1.2   root      104:        ("cld\n"
                    105:        "push %%es\n"
                    106:        "push %%fs\n"
                    107:        "cmpl $3,%0\n"
                    108:        "pop %%es\n"
                    109:        "jbe 1f\n"
                    110:        "movl %%edi,%%ecx\n"
                    111:        "negl %%ecx\n"
                    112:        "andl $3,%%ecx\n"
                    113:        "subl %%ecx,%0\n"
                    114:        "rep; movsb\n"
                    115:        "movl %0,%%ecx\n"
                    116:        "shrl $2,%%ecx\n"
                    117:        "rep; movsl\n"
                    118:        "andl $3,%0\n"
                    119:        "1: movl %0,%%ecx\n"
                    120:        "rep; movsb\n"
                    121:        "pop %%es\n"
1.1       root      122:        :"=abd" (n)
                    123:        :"0" (n),"D" ((long) to),"S" ((long) from)
                    124:        :"cx","di","si");
                    125: }
                    126: 
                    127: static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
                    128: {
                    129:        switch (n) {
                    130:                case 0:
                    131:                        return;
                    132:                case 1:
                    133:                        __put_user(*(const char *) from, (char *) to, 1);
                    134:                        return;
                    135:                case 2:
                    136:                        __put_user(*(const short *) from, (short *) to, 2);
                    137:                        return;
                    138:                case 3:
                    139:                        __put_user(*(const short *) from, (short *) to, 2);
                    140:                        __put_user(*(2+(const char *) from), 2+(char *) to, 1);
                    141:                        return;
                    142:                case 4:
                    143:                        __put_user(*(const int *) from, (int *) to, 4);
                    144:                        return;
                    145:                case 8:
                    146:                        __put_user(*(const int *) from, (int *) to, 4);
                    147:                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
                    148:                        return;
                    149:                case 12:
                    150:                        __put_user(*(const int *) from, (int *) to, 4);
                    151:                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
                    152:                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
                    153:                        return;
                    154:                case 16:
                    155:                        __put_user(*(const int *) from, (int *) to, 4);
                    156:                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
                    157:                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
                    158:                        __put_user(*(3+(const int *) from), 3+(int *) to, 4);
                    159:                        return;
                    160:        }
                    161: #define COMMON(x) \
                    162: __asm__("cld\n\t" \
                    163:        "push %%es\n\t" \
                    164:        "push %%fs\n\t" \
                    165:        "pop %%es\n\t" \
                    166:        "rep ; movsl\n\t" \
                    167:        x \
                    168:        "pop %%es" \
                    169:        : /* no outputs */ \
                    170:        :"c" (n/4),"D" ((long) to),"S" ((long) from) \
                    171:        :"cx","di","si")
                    172: 
                    173:        switch (n % 4) {
                    174:                case 0:
                    175:                        COMMON("");
                    176:                        return;
                    177:                case 1:
                    178:                        COMMON("movsb\n\t");
                    179:                        return;
                    180:                case 2:
                    181:                        COMMON("movsw\n\t");
                    182:                        return;
                    183:                case 3:
                    184:                        COMMON("movsw\n\tmovsb\n\t");
                    185:                        return;
                    186:        }
                    187: #undef COMMON
                    188: }
                    189: 
                    190: static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
                    191: {
1.1.1.2   root      192:   __asm__ volatile
                    193:     ("cld\n"
                    194:      "cmpl $3,%0\n"
                    195:      "jbe 1f\n"
                    196:      "movl %%edi,%%ecx\n"
                    197:      "negl %%ecx\n"
                    198:      "andl $3,%%ecx\n"
                    199:      "subl %%ecx,%0\n"
                    200:      "fs; rep; movsb\n"
                    201:      "movl %0,%%ecx\n"
                    202:      "shrl $2,%%ecx\n"
                    203:      "fs; rep; movsl\n"
                    204:      "andl $3,%0\n"
                    205:      "1:movl %0,%%ecx\n"
                    206:      "fs; rep; movsb\n"
                    207:      :"=abd" (n)
                    208:      :"0" (n),"D" ((long) to),"S" ((long) from)
                    209:      :"cx","di","si", "memory");
1.1       root      210: }
                    211: 
                    212: static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
                    213: {
                    214:        switch (n) {
                    215:                case 0:
                    216:                        return;
                    217:                case 1:
                    218:                        *(char *)to = __get_user((const char *) from, 1);
                    219:                        return;
                    220:                case 2:
                    221:                        *(short *)to = __get_user((const short *) from, 2);
                    222:                        return;
                    223:                case 3:
                    224:                        *(short *) to = __get_user((const short *) from, 2);
                    225:                        *((char *) to + 2) = __get_user(2+(const char *) from, 1);
                    226:                        return;
                    227:                case 4:
                    228:                        *(int *) to = __get_user((const int *) from, 4);
                    229:                        return;
                    230:                case 8:
                    231:                        *(int *) to = __get_user((const int *) from, 4);
                    232:                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
                    233:                        return;
                    234:                case 12:
                    235:                        *(int *) to = __get_user((const int *) from, 4);
                    236:                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
                    237:                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
                    238:                        return;
                    239:                case 16:
                    240:                        *(int *) to = __get_user((const int *) from, 4);
                    241:                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
                    242:                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
                    243:                        *(3+(int *) to) = __get_user(3+(const int *) from, 4);
                    244:                        return;
                    245:        }
                    246: #define COMMON(x) \
                    247: __asm__("cld\n\t" \
                    248:        "rep ; fs ; movsl\n\t" \
                    249:        x \
                    250:        : /* no outputs */ \
                    251:        :"c" (n/4),"D" ((long) to),"S" ((long) from) \
                    252:        :"cx","di","si","memory")
                    253: 
                    254:        switch (n % 4) {
                    255:                case 0:
                    256:                        COMMON("");
                    257:                        return;
                    258:                case 1:
                    259:                        COMMON("fs ; movsb");
                    260:                        return;
                    261:                case 2:
                    262:                        COMMON("fs ; movsw");
                    263:                        return;
                    264:                case 3:
                    265:                        COMMON("fs ; movsw\n\tfs ; movsb");
                    266:                        return;
                    267:        }
                    268: #undef COMMON
                    269: }
                    270: 
                    271: #define memcpy_fromfs(to, from, n) \
                    272: (__builtin_constant_p(n) ? \
                    273:  __constant_memcpy_fromfs((to),(from),(n)) : \
                    274:  __generic_memcpy_fromfs((to),(from),(n)))
                    275: 
                    276: #define memcpy_tofs(to, from, n) \
                    277: (__builtin_constant_p(n) ? \
                    278:  __constant_memcpy_tofs((to),(from),(n)) : \
                    279:  __generic_memcpy_tofs((to),(from),(n)))
                    280: 
1.1.1.2   root      281: 
                    282: #else /* code for gcc-2.95.x and newer follows */
                    283: 
                    284: static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
                    285: {
                    286:   char *d = (char *)to;
                    287:   const char *s = (const char *)from;
                    288:   while (n-- > 0) {
                    289:     *d++ = __get_user(s++, 1);
                    290:   }
                    291: }
                    292: 
                    293: static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
                    294: {
                    295:   char *d = (char *)to;
                    296:   const char *s = (const char *)from;
                    297:   while (n-- > 0) {
                    298:     __put_user(*s++, d++, 1);
                    299:   }
                    300: }
                    301: 
                    302: #endif /* not gcc-2.95 */
                    303: 
1.1       root      304: /*
                    305:  * These are deprecated..
                    306:  *
                    307:  * Use "put_user()" and "get_user()" with the proper pointer types instead.
                    308:  */
                    309: 
                    310: #define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
                    311: #define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
                    312: #define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
                    313: 
                    314: #define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
                    315: #define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
                    316: #define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
                    317: 
                    318: #ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
                    319: 
                    320: static inline unsigned short get_user_word(const short *addr)
                    321: {
                    322:        return __get_user(addr, 2);
                    323: }
                    324: 
                    325: static inline unsigned char get_user_byte(const char * addr)
                    326: {
                    327:        return __get_user(addr,1);
                    328: }
                    329: 
                    330: static inline unsigned long get_user_long(const int *addr)
                    331: {
                    332:        return __get_user(addr, 4);
                    333: }
                    334: 
                    335: static inline void put_user_byte(char val,char *addr)
                    336: {
                    337:        __put_user(val, addr, 1);
                    338: }
                    339: 
                    340: static inline void put_user_word(short val,short * addr)
                    341: {
                    342:        __put_user(val, addr, 2);
                    343: }
                    344: 
                    345: static inline void put_user_long(unsigned long val,int * addr)
                    346: {
                    347:        __put_user(val, addr, 4);
                    348: }
                    349: 
                    350: #endif
                    351: 
                    352: /*
                    353:  * Someone who knows GNU asm better than I should double check the following.
                    354:  * It seems to work, but I don't know if I'm doing something subtly wrong.
                    355:  * --- TYT, 11/24/91
                    356:  * [ nothing wrong here, Linus: I just changed the ax to be any reg ]
                    357:  */
                    358: 
                    359: static inline unsigned long get_fs(void)
                    360: {
                    361:        unsigned long _v;
                    362:        __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
                    363:        return _v;
                    364: }
                    365: 
                    366: static inline unsigned long get_ds(void)
                    367: {
                    368:        unsigned long _v;
                    369:        __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
                    370:        return _v;
                    371: }
                    372: 
                    373: static inline void set_fs(unsigned long val)
                    374: {
                    375:        __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
                    376: }
                    377: 
                    378: #endif /* __ASSEMBLY__ */
                    379: 
                    380: #endif /* _ASM_SEGMENT_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.