OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-i386/] [segment.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.