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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uC-libc/] [include/] [asm/] [segment.h] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#ifndef _OR1K_SEGMENT_H
2
#define _OR1K_SEGMENT_H
3
 
4
/* define constants */
5
/* Address spaces (FC0-FC2) */
6
#define USER_DATA     (1)
7
#ifndef USER_DS
8
#define USER_DS       (USER_DATA)
9
#endif
10
#define USER_PROGRAM  (2)
11
#define SUPER_DATA    (5)
12
#ifndef KERNEL_DS
13
#define KERNEL_DS     (SUPER_DATA)
14
#endif
15
#define SUPER_PROGRAM (6)
16
#define CPU_SPACE     (7)
17
 
18
#ifndef __ASSEMBLY__
19
 
20
/*
21
 * Uh, these should become the main single-value transfer routines..
22
 * They automatically use the right size if we just have the right
23
 * pointer type..
24
 */
25
#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
26
#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
27
 
28
/*
29
 * This is a silly but good way to make sure that
30
 * the __put_user function is indeed always optimized,
31
 * and that we use the correct sizes..
32
 */
33
extern int bad_user_access_length(void);
34
 
35
#define __ptr(x) ((unsigned long *)(x))
36
 
37
static inline void __put_user(unsigned long x, void * y, int size)
38
{
39
#if 0
40
        switch (size) {
41
                case 1:
42
                        __asm__ ("moveb %0,%1"
43
                                : /* no outputs */
44
                                :"d" (x),"m" (*__ptr(y)) : "memory");
45
                        break;
46
                case 2:
47
                        __asm__ ("movew %0,%1"
48
                                : /* no outputs */
49
                                :"d" (x),"m" (*__ptr(y)) : "memory");
50
                        break;
51
                case 4:
52
                        __asm__ ("movel %0,%1"
53
                                : /* no outputs */
54
                                :"d" (x),"m" (*__ptr(y)) : "memory");
55
                        break;
56
                default:
57
                        bad_user_access_length();
58
        }
59
#else
60
        switch (size) {
61
                case 1:
62
                        *(char *) y = x;
63
                        break;
64
                case 2:
65
                        *(short *) y = x;
66
                        break;
67
                case 4:
68
                        *(int *) y = x;
69
                        break;
70
                case 8:
71
                        *(long *) y = x;
72
                        break;
73
                default:
74
                        bad_user_access_length();
75
        }
76
#endif
77
}
78
 
79
static inline unsigned long __get_user(const void * y, int size)
80
{
81
#if 0
82
        unsigned long result;
83
 
84
        switch (size) {
85
                case 1:
86
                        __asm__ ("moveb %1,%0"
87
                                 :"=d" (result)
88
                                 :"m" (*__ptr(y)));
89
                        return (unsigned char) result;
90
                case 2:
91
                        __asm__ ("movew %1,%0"
92
                                 :"=d" (result)
93
                                 :"m" (*__ptr(y)));
94
                        return (unsigned short) result;
95
                case 4:
96
                        __asm__ ("movel %1,%0"
97
                                 :"=d" (result)
98
                                 :"m" (*__ptr(y)));
99
                        return result;
100
                default:
101
                        return bad_user_access_length();
102
        }
103
#else
104
        switch (size) {
105
                case 1:
106
                        return *(unsigned char *) y;
107
                case 2:
108
                        return *(unsigned short *) y;
109
                case 4:
110
                        return *(unsigned int *) y;
111
                case 8:
112
                        return *(unsigned long *) y;
113
                default:
114
                        return bad_user_access_length();
115
        }
116
#endif
117
}
118
#undef __ptr
119
 
120
/*
121
 * These are deprecated..
122
 *
123
 * Use "put_user()" and "get_user()" with the proper pointer types instead.
124
 */
125
 
126
#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
127
#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
128
#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
129
 
130
#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
131
#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
132
#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
133
 
134
#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
135
 
136
static inline unsigned char get_user_byte(const char * addr)
137
{
138
        return __get_user(addr,1);
139
}
140
 
141
static inline unsigned short get_user_word(const short *addr)
142
{
143
        return __get_user(addr,2);
144
}
145
 
146
static inline unsigned long get_user_long(const int *addr)
147
{
148
        return __get_user(addr,4);
149
}
150
 
151
static inline void put_user_byte(char val,char *addr)
152
{
153
        __put_user(val, addr, 1);
154
}
155
 
156
static inline void put_user_word(short val,short * addr)
157
{
158
        __put_user(val, addr, 2);
159
}
160
 
161
static inline void put_user_long(unsigned long val,int * addr)
162
{
163
        __put_user(val, addr, 4);
164
}
165
 
166
#endif
167
 
168
static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
169
{
170
        memcpy(to, from, n);
171
        /* Gah, idiots! */
172
#if 0
173
        unsigned long tmp;
174
        if (n == 0) return;
175
        tmp = n;
176
        n >>= 2;
177
        if (n != 0)
178
                __asm__ __volatile__ ("1:\t"
179
                         "movel %1@+,%/d0\n\t"
180
                         "movel %/d0,%2@+\n\t"     /* moves */
181
                         "dbra %0,1b\n\t"
182
                         "clrw %0\n\t"
183
                         "subql #1,%0\n\t"
184
                         "bccs 1b\n\t"
185
                         : "=d" (n), "=a" (from), "=a" (to)
186
                         : "0" (n-1), "1" (from), "2" (to)
187
                         : "d0", "memory");
188
        if (tmp & 2)
189
                __asm__ __volatile__ ("movew %0@+,%/d0\n\t"
190
                         "movew %/d0,%1@+\n\t" /* moves */
191
                         : "=a" (from), "=a" (to)
192
                         : "0" (from), "1" (to)
193
                         : "d0", "memory");
194
        if (tmp & 1)
195
                __asm__ __volatile__ ("moveb %0@,%/d0\n\t"
196
                         "moveb %/d0,%1@\n\t" /* moves */
197
                         : /* no outputs */
198
                         : "a" (from), "a" (to)
199
                         : "d0", "memory");
200
#endif
201
}
202
 
203
static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
204
{
205
        memcpy(to, from, n);
206
#if 0
207
        switch (n) {
208
                case 0:
209
                        return;
210
                case 1:
211
                        __put_user(*(const char *) from, (char *) to, 1);
212
                        return;
213
                case 2:
214
                        __put_user(*(const short *) from, (short *) to, 2);
215
                        return;
216
                case 3:
217
                        __put_user(*(const short *) from, (short *) to, 2);
218
                        __put_user(*(2+(const char *) from), 2+(char *) to, 1);
219
                        return;
220
                case 4:
221
                        __put_user(*(const int *) from, (int *) to, 4);
222
                        return;
223
                case 8:
224
                        __put_user(*(const int *) from, (int *) to, 4);
225
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
226
                        return;
227
                case 12:
228
                        __put_user(*(const int *) from, (int *) to, 4);
229
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
230
                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
231
                        return;
232
                case 16:
233
                        __put_user(*(const int *) from, (int *) to, 4);
234
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
235
                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
236
                        __put_user(*(3+(const int *) from), 3+(int *) to, 4);
237
                        return;
238
        }
239
 
240
        /* moves */
241
#define COMMON(x)                     \
242
__asm__ __volatile__ ("1:\n\t"        \
243
            "movel %1@+,%/d0\n\t"     \
244
            "movel %/d0,%2@+\n\t"    \
245
            "dbra %0,1b\n\t"          \
246
            "clrw %0\n\t"             \
247
            "subql #1,%0\n\t"         \
248
            "bccs 1b\n\t"             \
249
            x                     \
250
            : "=d" (n), "=a" (from), "=a" (to)    \
251
            : "1" (from), "2" (to), "0" (n/4-1)   \
252
            : "d0", "memory");
253
 
254
  switch (n % 4) {
255
      case 0:
256
          COMMON("");
257
          return;
258
      case 1:
259
          COMMON("moveb %1@+,%/d0; moveb %/d0,%2@+"); /* moves */
260
          return;
261
      case 2:
262
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+"); /* moves */
263
          return;
264
      case 3:
265
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+\n\t" /* moves */
266
                 "moveb %1@+,%/d0; moveb %/d0,%2@+");   /* moves */
267
          return;
268
  }
269
#undef COMMON
270
#endif
271
}
272
 
273
static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
274
{
275
        memcpy(to, from, n);
276
        /* Gah, idiots! */
277
#if 0
278
        unsigned long tmp;
279
        if (n == 0) return;
280
        tmp = n;
281
        n >>= 2;
282
        if (n != 0)
283
                __asm__ __volatile__ ("1:\t"
284
                         "movel %1@+,%/d0\n\t" /* moves */
285
                         "movel %/d0,%2@+\n\t"
286
                         "dbra %0,1b\n\t"
287
                         "clrw %0\n\t"
288
                         "subql #1,%0\n\t"
289
                         "bccs 1b\n\t"
290
                         : "=d" (n), "=a" (from), "=a" (to)
291
                         : "0" (n-1), "1" (from), "2" (to)
292
                         : "d0", "memory");
293
        if (tmp & 2)
294
                __asm__ __volatile__ ("movew %0@+,%/d0\n\t" /* moves */
295
                         "movew %/d0,%1@+\n\t"
296
                         : "=a" (from), "=a" (to)
297
                         : "0" (from), "1" (to)
298
                         : "d0", "memory");
299
        if (tmp & 1)
300
                __asm__ __volatile__ ("moveb %0@,%/d0\n\t" /* moves */
301
                         "moveb %/d0,%1@\n\t"
302
                         : /* no outputs */
303
                         : "a" (from), "a" (to)
304
                         : "d0", "memory");
305
#endif
306
}
307
 
308
static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
309
{
310
        memcpy(to, from, n);
311
#if 0
312
        switch (n) {
313
                case 0:
314
                        return;
315
                case 1:
316
                        *(char *)to = __get_user((const char *) from, 1);
317
                        return;
318
                case 2:
319
                        *(short *)to = __get_user((const short *) from, 2);
320
                        return;
321
                case 3:
322
                        *(short *) to = __get_user((const short *) from, 2);
323
                        *((char *) to + 2) = __get_user(2+(const char *) from, 1);
324
                        return;
325
                case 4:
326
                        *(int *) to = __get_user((const int *) from, 4);
327
                        return;
328
                case 8:
329
                        *(int *) to = __get_user((const int *) from, 4);
330
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
331
                        return;
332
                case 12:
333
                        *(int *) to = __get_user((const int *) from, 4);
334
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
335
                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
336
                        return;
337
                case 16:
338
                        *(int *) to = __get_user((const int *) from, 4);
339
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
340
                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
341
                        *(3+(int *) to) = __get_user(3+(const int *) from, 4);
342
                        return;
343
        }
344
        /*moves*/
345
#define COMMON(x)                     \
346
__asm__ __volatile__ ("1:\n\t"        \
347
            "movel %1@+,%/d0\n\t"    \
348
            "movel %/d0,%2@+\n\t"     \
349
            "dbra %0,1b\n\t"          \
350
            "clrw %0\n\t"             \
351
            "subql #1,%0\n\t"         \
352
            "bccs 1b\n\t"             \
353
            x                         \
354
            : "=d" (n), "=a" (from), "=a" (to)    \
355
            : "1" (from), "2" (to), "0" (n/4-1)   \
356
            : "d0", "memory");
357
 
358
  switch (n % 4) {
359
      case 0:
360
          COMMON("");
361
          return;
362
      case 1:
363
          COMMON("moveb %1@+,%/d0; moveb %/d0,%2@+"); /* moves */
364
          return;
365
      case 2:
366
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+"); /* moves */
367
          return;
368
      case 3:
369
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+\n\t" /* moves */
370
                 "moveb %1@+,%/d0; moveb %/d0,%2@+"); /* moves */
371
          return;
372
  }
373
#undef COMMON
374
#endif
375
}
376
#if 0
377
#define memcpy_fromfs(to, from, n) \
378
(__builtin_constant_p(n) ? \
379
 __constant_memcpy_fromfs((to),(from),(n)) : \
380
 __generic_memcpy_fromfs((to),(from),(n)))
381
 
382
#define memcpy_tofs(to, from, n) \
383
(__builtin_constant_p(n) ? \
384
 __constant_memcpy_tofs((to),(from),(n)) : \
385
 __generic_memcpy_tofs((to),(from),(n)))
386
#else
387
#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr))
388
 
389
#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n))
390
 
391
#define memcpy_tofs(to, from, n) memcpy((to),(from),(n)) 
392
#endif
393
 
394
/*
395
 * Get/set the SFC/DFC registers for MOVES instructions
396
 */
397
 
398
static inline unsigned long get_fs(void)
399
{
400
#ifdef NO_MM
401
        return USER_DS;
402
#else
403
        unsigned long _v;
404
        __asm__ ("movec %/dfc,%0":"=r" (_v):);
405
 
406
        return _v;
407
#endif
408
}
409
 
410
static inline unsigned long get_ds(void)
411
{
412
    /* return the supervisor data space code */
413
    return KERNEL_DS;
414
}
415
 
416
static inline void set_fs(unsigned long val)
417
{
418
#ifndef NO_MM
419
        __asm__ __volatile__ ("movec %0,%/sfc\n\t"
420
                              "movec %0,%/dfc\n\t"
421
                              : /* no outputs */ : "r" (val) : "memory");
422
#endif
423
}
424
 
425
#endif /* __ASSEMBLY__ */
426
 
427
#endif /* _OR1K_SEGMENT_H */

powered by: WebSVN 2.1.0

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