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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-m68knommu/] [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 _M68K_SEGMENT_H
2
#define _M68K_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
        switch (size) {
40
                case 1:
41
                        __asm__ ("moveb %0,%1"
42
                                : /* no outputs */
43
                                :"d" (x),"m" (*__ptr(y)) : "memory");
44
                        break;
45
                case 2:
46
                        __asm__ ("movew %0,%1"
47
                                : /* no outputs */
48
                                :"d" (x),"m" (*__ptr(y)) : "memory");
49
                        break;
50
                case 4:
51
                        __asm__ ("movel %0,%1"
52
                                : /* no outputs */
53
                                :"d" (x),"m" (*__ptr(y)) : "memory");
54
                        break;
55
                default:
56
                        bad_user_access_length();
57
        }
58
}
59
 
60
static inline unsigned long __get_user(const void * y, int size)
61
{
62
        unsigned long result;
63
 
64
        switch (size) {
65
                case 1:
66
                        __asm__ ("moveb %1,%0"
67
                                 :"=d" (result)
68
                                 :"m" (*__ptr(y)));
69
                        return (unsigned char) result;
70
                case 2:
71
                        __asm__ ("movew %1,%0"
72
                                 :"=d" (result)
73
                                 :"m" (*__ptr(y)));
74
                        return (unsigned short) result;
75
                case 4:
76
                        __asm__ ("movel %1,%0"
77
                                 :"=d" (result)
78
                                 :"m" (*__ptr(y)));
79
                        return result;
80
                default:
81
                        return bad_user_access_length();
82
        }
83
}
84
#undef __ptr
85
 
86
/*
87
 * These are deprecated..
88
 *
89
 * Use "put_user()" and "get_user()" with the proper pointer types instead.
90
 */
91
 
92
#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
93
#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
94
#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
95
 
96
#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
97
#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
98
#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
99
 
100
#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
101
 
102
static inline unsigned char get_user_byte(const char * addr)
103
{
104
        return __get_user(addr,1);
105
}
106
 
107
static inline unsigned short get_user_word(const short *addr)
108
{
109
        return __get_user(addr,2);
110
}
111
 
112
static inline unsigned long get_user_long(const int *addr)
113
{
114
        return __get_user(addr,4);
115
}
116
 
117
static inline void put_user_byte(char val,char *addr)
118
{
119
        __put_user(val, addr, 1);
120
}
121
 
122
static inline void put_user_word(short val,short * addr)
123
{
124
        __put_user(val, addr, 2);
125
}
126
 
127
static inline void put_user_long(unsigned long val,int * addr)
128
{
129
        __put_user(val, addr, 4);
130
}
131
 
132
#endif
133
 
134
static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
135
{
136
        memcpy(to, from, n);
137
        /* Gah, idiots! */
138
#if 0
139
        unsigned long tmp;
140
        if (n == 0) return;
141
        tmp = n;
142
        n >>= 2;
143
        if (n != 0)
144
                __asm__ __volatile__ ("1:\t"
145
                         "movel %1@+,%/d0\n\t"
146
                         "movel %/d0,%2@+\n\t"     /* moves */
147
                         "dbra %0,1b\n\t"
148
                         "clrw %0\n\t"
149
                         "subql #1,%0\n\t"
150
                         "bccs 1b\n\t"
151
                         : "=d" (n), "=a" (from), "=a" (to)
152
                         : "0" (n-1), "1" (from), "2" (to)
153
                         : "d0", "memory");
154
        if (tmp & 2)
155
                __asm__ __volatile__ ("movew %0@+,%/d0\n\t"
156
                         "movew %/d0,%1@+\n\t" /* moves */
157
                         : "=a" (from), "=a" (to)
158
                         : "0" (from), "1" (to)
159
                         : "d0", "memory");
160
        if (tmp & 1)
161
                __asm__ __volatile__ ("moveb %0@,%/d0\n\t"
162
                         "moveb %/d0,%1@\n\t" /* moves */
163
                         : /* no outputs */
164
                         : "a" (from), "a" (to)
165
                         : "d0", "memory");
166
#endif
167
}
168
 
169
static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
170
{
171
        memcpy(to, from, n);
172
#if 0
173
        switch (n) {
174
                case 0:
175
                        return;
176
                case 1:
177
                        __put_user(*(const char *) from, (char *) to, 1);
178
                        return;
179
                case 2:
180
                        __put_user(*(const short *) from, (short *) to, 2);
181
                        return;
182
                case 3:
183
                        __put_user(*(const short *) from, (short *) to, 2);
184
                        __put_user(*(2+(const char *) from), 2+(char *) to, 1);
185
                        return;
186
                case 4:
187
                        __put_user(*(const int *) from, (int *) to, 4);
188
                        return;
189
                case 8:
190
                        __put_user(*(const int *) from, (int *) to, 4);
191
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
192
                        return;
193
                case 12:
194
                        __put_user(*(const int *) from, (int *) to, 4);
195
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
196
                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
197
                        return;
198
                case 16:
199
                        __put_user(*(const int *) from, (int *) to, 4);
200
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
201
                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
202
                        __put_user(*(3+(const int *) from), 3+(int *) to, 4);
203
                        return;
204
        }
205
 
206
        /* moves */
207
#define COMMON(x)                     \
208
__asm__ __volatile__ ("1:\n\t"        \
209
            "movel %1@+,%/d0\n\t"     \
210
            "movel %/d0,%2@+\n\t"    \
211
            "dbra %0,1b\n\t"          \
212
            "clrw %0\n\t"             \
213
            "subql #1,%0\n\t"         \
214
            "bccs 1b\n\t"             \
215
            x                     \
216
            : "=d" (n), "=a" (from), "=a" (to)    \
217
            : "1" (from), "2" (to), "0" (n/4-1)   \
218
            : "d0", "memory");
219
 
220
  switch (n % 4) {
221
      case 0:
222
          COMMON("");
223
          return;
224
      case 1:
225
          COMMON("moveb %1@+,%/d0; moveb %/d0,%2@+"); /* moves */
226
          return;
227
      case 2:
228
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+"); /* moves */
229
          return;
230
      case 3:
231
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+\n\t" /* moves */
232
                 "moveb %1@+,%/d0; moveb %/d0,%2@+");   /* moves */
233
          return;
234
  }
235
#undef COMMON
236
#endif
237
}
238
 
239
static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
240
{
241
        memcpy(to, from, n);
242
        /* Gah, idiots! */
243
#if 0
244
        unsigned long tmp;
245
        if (n == 0) return;
246
        tmp = n;
247
        n >>= 2;
248
        if (n != 0)
249
                __asm__ __volatile__ ("1:\t"
250
                         "movel %1@+,%/d0\n\t" /* moves */
251
                         "movel %/d0,%2@+\n\t"
252
                         "dbra %0,1b\n\t"
253
                         "clrw %0\n\t"
254
                         "subql #1,%0\n\t"
255
                         "bccs 1b\n\t"
256
                         : "=d" (n), "=a" (from), "=a" (to)
257
                         : "0" (n-1), "1" (from), "2" (to)
258
                         : "d0", "memory");
259
        if (tmp & 2)
260
                __asm__ __volatile__ ("movew %0@+,%/d0\n\t" /* moves */
261
                         "movew %/d0,%1@+\n\t"
262
                         : "=a" (from), "=a" (to)
263
                         : "0" (from), "1" (to)
264
                         : "d0", "memory");
265
        if (tmp & 1)
266
                __asm__ __volatile__ ("moveb %0@,%/d0\n\t" /* moves */
267
                         "moveb %/d0,%1@\n\t"
268
                         : /* no outputs */
269
                         : "a" (from), "a" (to)
270
                         : "d0", "memory");
271
#endif
272
}
273
 
274
static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
275
{
276
        memcpy(to, from, n);
277
#if 0
278
        switch (n) {
279
                case 0:
280
                        return;
281
                case 1:
282
                        *(char *)to = __get_user((const char *) from, 1);
283
                        return;
284
                case 2:
285
                        *(short *)to = __get_user((const short *) from, 2);
286
                        return;
287
                case 3:
288
                        *(short *) to = __get_user((const short *) from, 2);
289
                        *((char *) to + 2) = __get_user(2+(const char *) from, 1);
290
                        return;
291
                case 4:
292
                        *(int *) to = __get_user((const int *) from, 4);
293
                        return;
294
                case 8:
295
                        *(int *) to = __get_user((const int *) from, 4);
296
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
297
                        return;
298
                case 12:
299
                        *(int *) to = __get_user((const int *) from, 4);
300
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
301
                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
302
                        return;
303
                case 16:
304
                        *(int *) to = __get_user((const int *) from, 4);
305
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
306
                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
307
                        *(3+(int *) to) = __get_user(3+(const int *) from, 4);
308
                        return;
309
        }
310
        /*moves*/
311
#define COMMON(x)                     \
312
__asm__ __volatile__ ("1:\n\t"        \
313
            "movel %1@+,%/d0\n\t"    \
314
            "movel %/d0,%2@+\n\t"     \
315
            "dbra %0,1b\n\t"          \
316
            "clrw %0\n\t"             \
317
            "subql #1,%0\n\t"         \
318
            "bccs 1b\n\t"             \
319
            x                         \
320
            : "=d" (n), "=a" (from), "=a" (to)    \
321
            : "1" (from), "2" (to), "0" (n/4-1)   \
322
            : "d0", "memory");
323
 
324
  switch (n % 4) {
325
      case 0:
326
          COMMON("");
327
          return;
328
      case 1:
329
          COMMON("moveb %1@+,%/d0; moveb %/d0,%2@+"); /* moves */
330
          return;
331
      case 2:
332
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+"); /* moves */
333
          return;
334
      case 3:
335
          COMMON("movew %1@+,%/d0; movew %/d0,%2@+\n\t" /* moves */
336
                 "moveb %1@+,%/d0; moveb %/d0,%2@+"); /* moves */
337
          return;
338
  }
339
#undef COMMON
340
#endif
341
}
342
 
343
#define memcpy_fromfs(to, from, n) \
344
(__builtin_constant_p(n) ? \
345
 __constant_memcpy_fromfs((to),(from),(n)) : \
346
 __generic_memcpy_fromfs((to),(from),(n)))
347
 
348
#define memcpy_tofs(to, from, n) \
349
(__builtin_constant_p(n) ? \
350
 __constant_memcpy_tofs((to),(from),(n)) : \
351
 __generic_memcpy_tofs((to),(from),(n)))
352
 
353
/*
354
 * Get/set the SFC/DFC registers for MOVES instructions
355
 */
356
 
357
static inline unsigned long get_fs(void)
358
{
359
#ifdef NO_MM
360
        return USER_DS;
361
#else
362
        unsigned long _v;
363
        __asm__ ("movec %/dfc,%0":"=r" (_v):);
364
 
365
        return _v;
366
#endif
367
}
368
 
369
static inline unsigned long get_ds(void)
370
{
371
    /* return the supervisor data space code */
372
    return KERNEL_DS;
373
}
374
 
375
static inline void set_fs(unsigned long val)
376
{
377
#ifndef NO_MM
378
        __asm__ __volatile__ ("movec %0,%/sfc\n\t"
379
                              "movec %0,%/dfc\n\t"
380
                              : /* no outputs */ : "r" (val) : "memory");
381
#endif
382
}
383
 
384
#endif /* __ASSEMBLY__ */
385
 
386
#endif /* _M68K_SEGMENT_H */

powered by: WebSVN 2.1.0

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