Annotation of Gnu-Mach/linux/dev/include/asm-i386/segment.h, revision 1.1.1.2

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