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

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:
                     63:                        bad_user_access_length();
                     64:        }
                     65: }
                     66: 
1.1.1.2 ! root       67: static inline unsigned long __attribute__((always_inline)) __get_user(const void * y, int size)
1.1       root       68: {
                     69:        unsigned long result;
                     70: 
                     71:        switch (size) {
                     72:                case 1:
                     73:                        __asm__ ("movb %%fs:%1,%b0"
                     74:                                :"=q" (result)
                     75:                                :"m" (*__const_sd(y)));
                     76:                        return (unsigned char) result;
                     77:                case 2:
                     78:                        __asm__ ("movw %%fs:%1,%w0"
                     79:                                :"=r" (result)
                     80:                                :"m" (*__const_sd(y)));
                     81:                        return (unsigned short) result;
                     82:                case 4:
                     83:                        __asm__ ("movl %%fs:%1,%0"
                     84:                                :"=r" (result)
                     85:                                :"m" (*__const_sd(y)));
                     86:                        return result;
                     87:                default:
                     88:                        return bad_user_access_length();
                     89:        }
                     90: }
                     91: 
1.1.1.2 ! root       92: #if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
1.1       root       93: static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
                     94: {
                     95:     __asm__ volatile
1.1.1.2 ! root       96:        ("cld\n"
        !            97:        "push %%es\n"
        !            98:        "push %%fs\n"
        !            99:        "cmpl $3,%0\n"
        !           100:        "pop %%es\n"
        !           101:        "jbe 1f\n"
        !           102:        "movl %%edi,%%ecx\n"
        !           103:        "negl %%ecx\n"
        !           104:        "andl $3,%%ecx\n"
        !           105:        "subl %%ecx,%0\n"
        !           106:        "rep; movsb\n"
        !           107:        "movl %0,%%ecx\n"
        !           108:        "shrl $2,%%ecx\n"
        !           109:        "rep; movsl\n"
        !           110:        "andl $3,%0\n"
        !           111:        "1: movl %0,%%ecx\n"
        !           112:        "rep; movsb\n"
        !           113:        "pop %%es\n"
1.1       root      114:        :"=abd" (n)
                    115:        :"0" (n),"D" ((long) to),"S" ((long) from)
                    116:        :"cx","di","si");
                    117: }
                    118: 
                    119: static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
                    120: {
                    121:        switch (n) {
                    122:                case 0:
                    123:                        return;
                    124:                case 1:
                    125:                        __put_user(*(const char *) from, (char *) to, 1);
                    126:                        return;
                    127:                case 2:
                    128:                        __put_user(*(const short *) from, (short *) to, 2);
                    129:                        return;
                    130:                case 3:
                    131:                        __put_user(*(const short *) from, (short *) to, 2);
                    132:                        __put_user(*(2+(const char *) from), 2+(char *) to, 1);
                    133:                        return;
                    134:                case 4:
                    135:                        __put_user(*(const int *) from, (int *) to, 4);
                    136:                        return;
                    137:                case 8:
                    138:                        __put_user(*(const int *) from, (int *) to, 4);
                    139:                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
                    140:                        return;
                    141:                case 12:
                    142:                        __put_user(*(const int *) from, (int *) to, 4);
                    143:                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
                    144:                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
                    145:                        return;
                    146:                case 16:
                    147:                        __put_user(*(const int *) from, (int *) to, 4);
                    148:                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
                    149:                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
                    150:                        __put_user(*(3+(const int *) from), 3+(int *) to, 4);
                    151:                        return;
                    152:        }
                    153: #define COMMON(x) \
                    154: __asm__("cld\n\t" \
                    155:        "push %%es\n\t" \
                    156:        "push %%fs\n\t" \
                    157:        "pop %%es\n\t" \
                    158:        "rep ; movsl\n\t" \
                    159:        x \
                    160:        "pop %%es" \
                    161:        : /* no outputs */ \
                    162:        :"c" (n/4),"D" ((long) to),"S" ((long) from) \
                    163:        :"cx","di","si")
                    164: 
                    165:        switch (n % 4) {
                    166:                case 0:
                    167:                        COMMON("");
                    168:                        return;
                    169:                case 1:
                    170:                        COMMON("movsb\n\t");
                    171:                        return;
                    172:                case 2:
                    173:                        COMMON("movsw\n\t");
                    174:                        return;
                    175:                case 3:
                    176:                        COMMON("movsw\n\tmovsb\n\t");
                    177:                        return;
                    178:        }
                    179: #undef COMMON
                    180: }
                    181: 
                    182: static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
                    183: {
1.1.1.2 ! root      184:   __asm__ volatile
        !           185:     ("cld\n"
        !           186:      "cmpl $3,%0\n"
        !           187:      "jbe 1f\n"
        !           188:      "movl %%edi,%%ecx\n"
        !           189:      "negl %%ecx\n"
        !           190:      "andl $3,%%ecx\n"
        !           191:      "subl %%ecx,%0\n"
        !           192:      "fs; rep; movsb\n"
        !           193:      "movl %0,%%ecx\n"
        !           194:      "shrl $2,%%ecx\n"
        !           195:      "fs; rep; movsl\n"
        !           196:      "andl $3,%0\n"
        !           197:      "1:movl %0,%%ecx\n"
        !           198:      "fs; rep; movsb\n"
        !           199:      :"=abd" (n)
        !           200:      :"0" (n),"D" ((long) to),"S" ((long) from)
        !           201:      :"cx","di","si", "memory");
1.1       root      202: }
                    203: 
                    204: static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
                    205: {
                    206:        switch (n) {
                    207:                case 0:
                    208:                        return;
                    209:                case 1:
                    210:                        *(char *)to = __get_user((const char *) from, 1);
                    211:                        return;
                    212:                case 2:
                    213:                        *(short *)to = __get_user((const short *) from, 2);
                    214:                        return;
                    215:                case 3:
                    216:                        *(short *) to = __get_user((const short *) from, 2);
                    217:                        *((char *) to + 2) = __get_user(2+(const char *) from, 1);
                    218:                        return;
                    219:                case 4:
                    220:                        *(int *) to = __get_user((const int *) from, 4);
                    221:                        return;
                    222:                case 8:
                    223:                        *(int *) to = __get_user((const int *) from, 4);
                    224:                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
                    225:                        return;
                    226:                case 12:
                    227:                        *(int *) to = __get_user((const int *) from, 4);
                    228:                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
                    229:                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
                    230:                        return;
                    231:                case 16:
                    232:                        *(int *) to = __get_user((const int *) from, 4);
                    233:                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
                    234:                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
                    235:                        *(3+(int *) to) = __get_user(3+(const int *) from, 4);
                    236:                        return;
                    237:        }
                    238: #define COMMON(x) \
                    239: __asm__("cld\n\t" \
                    240:        "rep ; fs ; movsl\n\t" \
                    241:        x \
                    242:        : /* no outputs */ \
                    243:        :"c" (n/4),"D" ((long) to),"S" ((long) from) \
                    244:        :"cx","di","si","memory")
                    245: 
                    246:        switch (n % 4) {
                    247:                case 0:
                    248:                        COMMON("");
                    249:                        return;
                    250:                case 1:
                    251:                        COMMON("fs ; movsb");
                    252:                        return;
                    253:                case 2:
                    254:                        COMMON("fs ; movsw");
                    255:                        return;
                    256:                case 3:
                    257:                        COMMON("fs ; movsw\n\tfs ; movsb");
                    258:                        return;
                    259:        }
                    260: #undef COMMON
                    261: }
                    262: 
                    263: #define memcpy_fromfs(to, from, n) \
                    264: (__builtin_constant_p(n) ? \
                    265:  __constant_memcpy_fromfs((to),(from),(n)) : \
                    266:  __generic_memcpy_fromfs((to),(from),(n)))
                    267: 
                    268: #define memcpy_tofs(to, from, n) \
                    269: (__builtin_constant_p(n) ? \
                    270:  __constant_memcpy_tofs((to),(from),(n)) : \
                    271:  __generic_memcpy_tofs((to),(from),(n)))
                    272: 
1.1.1.2 ! root      273: 
        !           274: #else /* code for gcc-2.95.x and newer follows */
        !           275: 
        !           276: static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
        !           277: {
        !           278:   char *d = (char *)to;
        !           279:   const char *s = (const char *)from;
        !           280:   while (n-- > 0) {
        !           281:     *d++ = __get_user(s++, 1);
        !           282:   }
        !           283: }
        !           284: 
        !           285: static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
        !           286: {
        !           287:   char *d = (char *)to;
        !           288:   const char *s = (const char *)from;
        !           289:   while (n-- > 0) {
        !           290:     __put_user(*s++, d++, 1);
        !           291:   }
        !           292: }
        !           293: 
        !           294: #endif /* not gcc-2.95 */
        !           295: 
1.1       root      296: /*
                    297:  * These are deprecated..
                    298:  *
                    299:  * Use "put_user()" and "get_user()" with the proper pointer types instead.
                    300:  */
                    301: 
                    302: #define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
                    303: #define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
                    304: #define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
                    305: 
                    306: #define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
                    307: #define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
                    308: #define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
                    309: 
                    310: #ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
                    311: 
                    312: static inline unsigned short get_user_word(const short *addr)
                    313: {
                    314:        return __get_user(addr, 2);
                    315: }
                    316: 
                    317: static inline unsigned char get_user_byte(const char * addr)
                    318: {
                    319:        return __get_user(addr,1);
                    320: }
                    321: 
                    322: static inline unsigned long get_user_long(const int *addr)
                    323: {
                    324:        return __get_user(addr, 4);
                    325: }
                    326: 
                    327: static inline void put_user_byte(char val,char *addr)
                    328: {
                    329:        __put_user(val, addr, 1);
                    330: }
                    331: 
                    332: static inline void put_user_word(short val,short * addr)
                    333: {
                    334:        __put_user(val, addr, 2);
                    335: }
                    336: 
                    337: static inline void put_user_long(unsigned long val,int * addr)
                    338: {
                    339:        __put_user(val, addr, 4);
                    340: }
                    341: 
                    342: #endif
                    343: 
                    344: /*
                    345:  * Someone who knows GNU asm better than I should double check the following.
                    346:  * It seems to work, but I don't know if I'm doing something subtly wrong.
                    347:  * --- TYT, 11/24/91
                    348:  * [ nothing wrong here, Linus: I just changed the ax to be any reg ]
                    349:  */
                    350: 
                    351: static inline unsigned long get_fs(void)
                    352: {
                    353:        unsigned long _v;
                    354:        __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
                    355:        return _v;
                    356: }
                    357: 
                    358: static inline unsigned long get_ds(void)
                    359: {
                    360:        unsigned long _v;
                    361:        __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
                    362:        return _v;
                    363: }
                    364: 
                    365: static inline void set_fs(unsigned long val)
                    366: {
                    367:        __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
                    368: }
                    369: 
                    370: #endif /* __ASSEMBLY__ */
                    371: 
                    372: #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.