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

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