diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/dev/include/asm-i386/segment.h | 380 | ||||
-rw-r--r-- | linux/src/include/asm-i386/segment.h | 117 |
2 files changed, 79 insertions, 418 deletions
diff --git a/linux/dev/include/asm-i386/segment.h b/linux/dev/include/asm-i386/segment.h deleted file mode 100644 index 300ba53..0000000 --- a/linux/dev/include/asm-i386/segment.h +++ /dev/null @@ -1,380 +0,0 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H - -#ifdef MACH - -#ifdef MACH_HYP -#define KERNEL_CS 0x09 -#define KERNEL_DS 0x11 -#else /* MACH_HYP */ -#define KERNEL_CS 0x08 -#define KERNEL_DS 0x10 -#endif /* MACH_HYP */ - -#define USER_CS 0x17 -#define USER_DS 0x1F - -#else /* !MACH */ - -#define KERNEL_CS 0x10 -#define KERNEL_DS 0x18 - -#define USER_CS 0x23 -#define USER_DS 0x2B - -#endif /* !MACH */ - -#ifndef __ASSEMBLY__ - -/* - * Uh, these should become the main single-value transfer routines.. - * They automatically use the right size if we just have the right - * pointer type.. - */ -#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) -#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))) - -/* - * This is a silly but good way to make sure that - * the __put_user function is indeed always optimized, - * and that we use the correct sizes.. - */ -extern int bad_user_access_length(void); - -/* - * dummy pointer type structure.. gcc won't try to do something strange - * this way.. - */ -struct __segment_dummy { unsigned long a[100]; }; -#define __sd(x) ((struct __segment_dummy *) (x)) -#define __const_sd(x) ((const struct __segment_dummy *) (x)) - -static inline void __attribute__((always_inline)) __put_user(unsigned long x, void * y, int size) -{ - switch (size) { - case 1: - __asm__ ("movb %b1,%%fs:%0" - :"=m" (*__sd(y)) - :"iq" ((unsigned char) x), "m" (*__sd(y))); - break; - case 2: - __asm__ ("movw %w1,%%fs:%0" - :"=m" (*__sd(y)) - :"ir" ((unsigned short) x), "m" (*__sd(y))); - break; - case 4: - __asm__ ("movl %1,%%fs:%0" - :"=m" (*__sd(y)) - :"ir" (x), "m" (*__sd(y))); - break; - default: - bad_user_access_length(); - } -} - -static inline unsigned long __attribute__((always_inline)) __get_user(const void * y, int size) -{ - unsigned long result; - - switch (size) { - case 1: - __asm__ ("movb %%fs:%1,%b0" - :"=q" (result) - :"m" (*__const_sd(y))); - return (unsigned char) result; - case 2: - __asm__ ("movw %%fs:%1,%w0" - :"=r" (result) - :"m" (*__const_sd(y))); - return (unsigned short) result; - case 4: - __asm__ ("movl %%fs:%1,%0" - :"=r" (result) - :"m" (*__const_sd(y))); - return result; - default: - return bad_user_access_length(); - } -} - -#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) -static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - __asm__ volatile - ("cld\n" - "push %%es\n" - "push %%fs\n" - "cmpl $3,%0\n" - "pop %%es\n" - "jbe 1f\n" - "movl %%edi,%%ecx\n" - "negl %%ecx\n" - "andl $3,%%ecx\n" - "subl %%ecx,%0\n" - "rep; movsb\n" - "movl %0,%%ecx\n" - "shrl $2,%%ecx\n" - "rep; movsl\n" - "andl $3,%0\n" - "1: movl %0,%%ecx\n" - "rep; movsb\n" - "pop %%es\n" - :"=abd" (n) - :"0" (n),"D" ((long) to),"S" ((long) from) - :"cx","di","si"); -} - -static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - switch (n) { - case 0: - return; - case 1: - __put_user(*(const char *) from, (char *) to, 1); - return; - case 2: - __put_user(*(const short *) from, (short *) to, 2); - return; - case 3: - __put_user(*(const short *) from, (short *) to, 2); - __put_user(*(2+(const char *) from), 2+(char *) to, 1); - return; - case 4: - __put_user(*(const int *) from, (int *) to, 4); - return; - case 8: - __put_user(*(const int *) from, (int *) to, 4); - __put_user(*(1+(const int *) from), 1+(int *) to, 4); - return; - case 12: - __put_user(*(const int *) from, (int *) to, 4); - __put_user(*(1+(const int *) from), 1+(int *) to, 4); - __put_user(*(2+(const int *) from), 2+(int *) to, 4); - return; - case 16: - __put_user(*(const int *) from, (int *) to, 4); - __put_user(*(1+(const int *) from), 1+(int *) to, 4); - __put_user(*(2+(const int *) from), 2+(int *) to, 4); - __put_user(*(3+(const int *) from), 3+(int *) to, 4); - return; - } -#define COMMON(x) \ -__asm__("cld\n\t" \ - "push %%es\n\t" \ - "push %%fs\n\t" \ - "pop %%es\n\t" \ - "rep ; movsl\n\t" \ - x \ - "pop %%es" \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("movsb\n\t"); - return; - case 2: - COMMON("movsw\n\t"); - return; - case 3: - COMMON("movsw\n\tmovsb\n\t"); - return; - } -#undef COMMON -} - -static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - __asm__ volatile - ("cld\n" - "cmpl $3,%0\n" - "jbe 1f\n" - "movl %%edi,%%ecx\n" - "negl %%ecx\n" - "andl $3,%%ecx\n" - "subl %%ecx,%0\n" - "fs; rep; movsb\n" - "movl %0,%%ecx\n" - "shrl $2,%%ecx\n" - "fs; rep; movsl\n" - "andl $3,%0\n" - "1:movl %0,%%ecx\n" - "fs; rep; movsb\n" - :"=abd" (n) - :"0" (n),"D" ((long) to),"S" ((long) from) - :"cx","di","si", "memory"); -} - -static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - switch (n) { - case 0: - return; - case 1: - *(char *)to = __get_user((const char *) from, 1); - return; - case 2: - *(short *)to = __get_user((const short *) from, 2); - return; - case 3: - *(short *) to = __get_user((const short *) from, 2); - *((char *) to + 2) = __get_user(2+(const char *) from, 1); - return; - case 4: - *(int *) to = __get_user((const int *) from, 4); - return; - case 8: - *(int *) to = __get_user((const int *) from, 4); - *(1+(int *) to) = __get_user(1+(const int *) from, 4); - return; - case 12: - *(int *) to = __get_user((const int *) from, 4); - *(1+(int *) to) = __get_user(1+(const int *) from, 4); - *(2+(int *) to) = __get_user(2+(const int *) from, 4); - return; - case 16: - *(int *) to = __get_user((const int *) from, 4); - *(1+(int *) to) = __get_user(1+(const int *) from, 4); - *(2+(int *) to) = __get_user(2+(const int *) from, 4); - *(3+(int *) to) = __get_user(3+(const int *) from, 4); - return; - } -#define COMMON(x) \ -__asm__("cld\n\t" \ - "rep ; fs ; movsl\n\t" \ - x \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si","memory") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("fs ; movsb"); - return; - case 2: - COMMON("fs ; movsw"); - return; - case 3: - COMMON("fs ; movsw\n\tfs ; movsb"); - return; - } -#undef COMMON -} - -#define memcpy_fromfs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_fromfs((to),(from),(n)) : \ - __generic_memcpy_fromfs((to),(from),(n))) - -#define memcpy_tofs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_tofs((to),(from),(n)) : \ - __generic_memcpy_tofs((to),(from),(n))) - - -#else /* code for gcc-2.95.x and newer follows */ - -static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - char *d = (char *)to; - const char *s = (const char *)from; - while (n-- > 0) { - *d++ = __get_user(s++, 1); - } -} - -static inline void memcpy_tofs(void * to, const void * from, unsigned long n) -{ - char *d = (char *)to; - const char *s = (const char *)from; - while (n-- > 0) { - __put_user(*s++, d++, 1); - } -} - -#endif /* not gcc-2.95 */ - -/* - * These are deprecated.. - * - * Use "put_user()" and "get_user()" with the proper pointer types instead. - */ - -#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1) -#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2) -#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4) - -#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1) -#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2) -#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4) - -#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE - -static inline unsigned short get_user_word(const short *addr) -{ - return __get_user(addr, 2); -} - -static inline unsigned char get_user_byte(const char * addr) -{ - return __get_user(addr,1); -} - -static inline unsigned long get_user_long(const int *addr) -{ - return __get_user(addr, 4); -} - -static inline void put_user_byte(char val,char *addr) -{ - __put_user(val, addr, 1); -} - -static inline void put_user_word(short val,short * addr) -{ - __put_user(val, addr, 2); -} - -static inline void put_user_long(unsigned long val,int * addr) -{ - __put_user(val, addr, 4); -} - -#endif - -/* - * Someone who knows GNU asm better than I should double check the following. - * It seems to work, but I don't know if I'm doing something subtly wrong. - * --- TYT, 11/24/91 - * [ nothing wrong here, Linus: I just changed the ax to be any reg ] - */ - -static inline unsigned long get_fs(void) -{ - unsigned long _v; - __asm__("mov %%fs,%w0":"=r" (_v):"0" (0)); - return _v; -} - -static inline unsigned long get_ds(void) -{ - unsigned long _v; - __asm__("mov %%ds,%w0":"=r" (_v):"0" (0)); - return _v; -} - -static inline void set_fs(unsigned long val) -{ - __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val)); -} - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_SEGMENT_H */ diff --git a/linux/src/include/asm-i386/segment.h b/linux/src/include/asm-i386/segment.h index 6052ad4..300ba53 100644 --- a/linux/src/include/asm-i386/segment.h +++ b/linux/src/include/asm-i386/segment.h @@ -1,12 +1,29 @@ #ifndef _ASM_SEGMENT_H #define _ASM_SEGMENT_H +#ifdef MACH + +#ifdef MACH_HYP +#define KERNEL_CS 0x09 +#define KERNEL_DS 0x11 +#else /* MACH_HYP */ +#define KERNEL_CS 0x08 +#define KERNEL_DS 0x10 +#endif /* MACH_HYP */ + +#define USER_CS 0x17 +#define USER_DS 0x1F + +#else /* !MACH */ + #define KERNEL_CS 0x10 #define KERNEL_DS 0x18 #define USER_CS 0x23 #define USER_DS 0x2B +#endif /* !MACH */ + #ifndef __ASSEMBLY__ /* @@ -32,7 +49,7 @@ struct __segment_dummy { unsigned long a[100]; }; #define __sd(x) ((struct __segment_dummy *) (x)) #define __const_sd(x) ((const struct __segment_dummy *) (x)) -static inline void __put_user(unsigned long x, void * y, int size) +static inline void __attribute__((always_inline)) __put_user(unsigned long x, void * y, int size) { switch (size) { case 1: @@ -55,7 +72,7 @@ static inline void __put_user(unsigned long x, void * y, int size) } } -static inline unsigned long __get_user(const void * y, int size) +static inline unsigned long __attribute__((always_inline)) __get_user(const void * y, int size) { unsigned long result; @@ -80,27 +97,28 @@ static inline unsigned long __get_user(const void * y, int size) } } +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) { __asm__ volatile - (" cld - push %%es - push %%fs - cmpl $3,%0 - pop %%es - jbe 1f - movl %%edi,%%ecx - negl %%ecx - andl $3,%%ecx - subl %%ecx,%0 - rep; movsb - movl %0,%%ecx - shrl $2,%%ecx - rep; movsl - andl $3,%0 - 1: movl %0,%%ecx - rep; movsb - pop %%es" + ("cld\n" + "push %%es\n" + "push %%fs\n" + "cmpl $3,%0\n" + "pop %%es\n" + "jbe 1f\n" + "movl %%edi,%%ecx\n" + "negl %%ecx\n" + "andl $3,%%ecx\n" + "subl %%ecx,%0\n" + "rep; movsb\n" + "movl %0,%%ecx\n" + "shrl $2,%%ecx\n" + "rep; movsl\n" + "andl $3,%0\n" + "1: movl %0,%%ecx\n" + "rep; movsb\n" + "pop %%es\n" :"=abd" (n) :"0" (n),"D" ((long) to),"S" ((long) from) :"cx","di","si"); @@ -171,24 +189,24 @@ __asm__("cld\n\t" \ static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) { - __asm__ volatile - (" cld - cmpl $3,%0 - jbe 1f - movl %%edi,%%ecx - negl %%ecx - andl $3,%%ecx - subl %%ecx,%0 - fs; rep; movsb - movl %0,%%ecx - shrl $2,%%ecx - fs; rep; movsl - andl $3,%0 - 1: movl %0,%%ecx - fs; rep; movsb" - :"=abd" (n) - :"0" (n),"D" ((long) to),"S" ((long) from) - :"cx","di","si", "memory"); + __asm__ volatile + ("cld\n" + "cmpl $3,%0\n" + "jbe 1f\n" + "movl %%edi,%%ecx\n" + "negl %%ecx\n" + "andl $3,%%ecx\n" + "subl %%ecx,%0\n" + "fs; rep; movsb\n" + "movl %0,%%ecx\n" + "shrl $2,%%ecx\n" + "fs; rep; movsl\n" + "andl $3,%0\n" + "1:movl %0,%%ecx\n" + "fs; rep; movsb\n" + :"=abd" (n) + :"0" (n),"D" ((long) to),"S" ((long) from) + :"cx","di","si", "memory"); } static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) @@ -260,6 +278,29 @@ __asm__("cld\n\t" \ __constant_memcpy_tofs((to),(from),(n)) : \ __generic_memcpy_tofs((to),(from),(n))) + +#else /* code for gcc-2.95.x and newer follows */ + +static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) +{ + char *d = (char *)to; + const char *s = (const char *)from; + while (n-- > 0) { + *d++ = __get_user(s++, 1); + } +} + +static inline void memcpy_tofs(void * to, const void * from, unsigned long n) +{ + char *d = (char *)to; + const char *s = (const char *)from; + while (n-- > 0) { + __put_user(*s++, d++, 1); + } +} + +#endif /* not gcc-2.95 */ + /* * These are deprecated.. * |