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

Subversion Repositories or1k

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

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__ ("movesb %0,%1"
42
                                : /* no outputs */
43
                                :"r" (x),"m" (*__ptr(y)) : "memory");
44
                        break;
45
                case 2:
46
                        __asm__ ("movesw %0,%1"
47
                                : /* no outputs */
48
                                :"r" (x),"m" (*__ptr(y)) : "memory");
49
                        break;
50
                case 4:
51
                        __asm__ ("movesl %0,%1"
52
                                : /* no outputs */
53
                                :"r" (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__ ("movesb %1,%0"
67
                                 :"=r" (result)
68
                                 :"m" (*__ptr(y)));
69
                        return (unsigned char) result;
70
                case 2:
71
                        __asm__ ("movesw %1,%0"
72
                                 :"=r" (result)
73
                                 :"m" (*__ptr(y)));
74
                        return (unsigned short) result;
75
                case 4:
76
                        __asm__ ("movesl %1,%0"
77
                                 :"=r" (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
        unsigned long tmp;
137
        if (n == 0) return;
138
        tmp = n;
139
        n >>= 2;
140
        if (n != 0)
141
                __asm__ ("1:\t"
142
                         "movel %1@+,%/d0\n\t"
143
                         "movesl %/d0,%2@+\n\t"
144
                              "dbra %0,1b\n\t"
145
                              "clrw %0\n\t"
146
                              "subql #1,%0\n\t"
147
                         "bccs 1b\n\t"
148
                              : "=d" (n), "=a" (from), "=a" (to)
149
                         : "0" (n-1), "1" (from), "2" (to)
150
                         : "d0", "memory");
151
        if (tmp & 2)
152
                __asm__ ("movew %0@+,%/d0\n\t"
153
                         "movesw %/d0,%1@+\n\t"
154
                         : "=a" (from), "=a" (to)
155
                         : "0" (from), "1" (to)
156
                         : "d0", "memory");
157
        if (tmp & 1)
158
                __asm__ __volatile__ ("moveb %0@,%/d0\n\t"
159
                         "movesb %/d0,%1@\n\t"
160
                         : /* no outputs */
161
                         : "a" (from), "a" (to)
162
                              : "d0", "memory");
163
}
164
 
165
static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
166
{
167
        switch (n) {
168
                case 0:
169
                        return;
170
                case 1:
171
                        __put_user(*(const char *) from, (char *) to, 1);
172
                        return;
173
                case 2:
174
                        __put_user(*(const short *) from, (short *) to, 2);
175
                        return;
176
                case 3:
177
                        __put_user(*(const short *) from, (short *) to, 2);
178
                        __put_user(*(2+(const char *) from), 2+(char *) to, 1);
179
                        return;
180
                case 4:
181
                        __put_user(*(const int *) from, (int *) to, 4);
182
                        return;
183
                case 8:
184
                        __put_user(*(const int *) from, (int *) to, 4);
185
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
186
                        return;
187
                case 12:
188
                        __put_user(*(const int *) from, (int *) to, 4);
189
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
190
                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
191
                        return;
192
                case 16:
193
                        __put_user(*(const int *) from, (int *) to, 4);
194
                        __put_user(*(1+(const int *) from), 1+(int *) to, 4);
195
                        __put_user(*(2+(const int *) from), 2+(int *) to, 4);
196
                        __put_user(*(3+(const int *) from), 3+(int *) to, 4);
197
                        return;
198
        }
199
#define COMMON(x)                     \
200
__asm__ __volatile__ ("1:\n\t"        \
201
            "movel %1@+,%/d0\n\t"     \
202
            "movesl %/d0,%2@+\n\t"    \
203
            "dbra %0,1b\n\t"          \
204
            "clrw %0\n\t"             \
205
            "subql #1,%0\n\t"         \
206
            "bccs 1b\n\t"             \
207
            x                     \
208
            : "=d" (n), "=a" (from), "=a" (to)    \
209
            : "1" (from), "2" (to), "0" (n/4-1)   \
210
            : "d0", "memory");
211
 
212
  switch (n % 4) {
213
      case 0:
214
          COMMON("");
215
          return;
216
      case 1:
217
          COMMON("moveb %1@+,%/d0; movesb %/d0,%2@+");
218
          return;
219
      case 2:
220
          COMMON("movew %1@+,%/d0; movesw %/d0,%2@+");
221
          return;
222
      case 3:
223
          COMMON("movew %1@+,%/d0; movesw %/d0,%2@+\n\t"
224
                 "moveb %1@+,%/d0; movesb %/d0,%2@+");
225
          return;
226
  }
227
#undef COMMON
228
}
229
 
230
static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
231
{
232
        unsigned long tmp;
233
        if (n == 0) return;
234
        tmp = n;
235
        n >>= 2;
236
        if (n != 0)
237
                __asm__ ("1:\t"
238
                         "movesl %1@+,%/d0\n\t"
239
                         "movel %/d0,%2@+\n\t"
240
                              "dbra %0,1b\n\t"
241
                              "clrw %0\n\t"
242
                              "subql #1,%0\n\t"
243
                         "bccs 1b\n\t"
244
                              : "=d" (n), "=a" (from), "=a" (to)
245
                         : "0" (n-1), "1" (from), "2" (to)
246
                         : "d0", "memory");
247
        if (tmp & 2)
248
                __asm__ ("movesw %0@+,%/d0\n\t"
249
                         "movew %/d0,%1@+\n\t"
250
                         : "=a" (from), "=a" (to)
251
                         : "0" (from), "1" (to)
252
                         : "d0", "memory");
253
        if (tmp & 1)
254
                __asm__ __volatile__ ("movesb %0@,%/d0\n\t"
255
                         "moveb %/d0,%1@\n\t"
256
                         : /* no outputs */
257
                         : "a" (from), "a" (to)
258
                              : "d0", "memory");
259
}
260
 
261
static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
262
{
263
        switch (n) {
264
                case 0:
265
                        return;
266
                case 1:
267
                        *(char *)to = __get_user((const char *) from, 1);
268
                        return;
269
                case 2:
270
                        *(short *)to = __get_user((const short *) from, 2);
271
                        return;
272
                case 3:
273
                        *(short *) to = __get_user((const short *) from, 2);
274
                        *((char *) to + 2) = __get_user(2+(const char *) from, 1);
275
                        return;
276
                case 4:
277
                        *(int *) to = __get_user((const int *) from, 4);
278
                        return;
279
                case 8:
280
                        *(int *) to = __get_user((const int *) from, 4);
281
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
282
                        return;
283
                case 12:
284
                        *(int *) to = __get_user((const int *) from, 4);
285
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
286
                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
287
                        return;
288
                case 16:
289
                        *(int *) to = __get_user((const int *) from, 4);
290
                        *(1+(int *) to) = __get_user(1+(const int *) from, 4);
291
                        *(2+(int *) to) = __get_user(2+(const int *) from, 4);
292
                        *(3+(int *) to) = __get_user(3+(const int *) from, 4);
293
                        return;
294
        }
295
#define COMMON(x)                     \
296
__asm__ __volatile__ ("1:\n\t"        \
297
            "movesl %1@+,%/d0\n\t"    \
298
            "movel %/d0,%2@+\n\t"     \
299
            "dbra %0,1b\n\t"          \
300
            "clrw %0\n\t"             \
301
            "subql #1,%0\n\t"         \
302
            "bccs 1b\n\t"             \
303
            x                         \
304
            : "=d" (n), "=a" (from), "=a" (to)    \
305
            : "1" (from), "2" (to), "0" (n/4-1)   \
306
            : "d0", "memory");
307
 
308
  switch (n % 4) {
309
      case 0:
310
          COMMON("");
311
          return;
312
      case 1:
313
          COMMON("movesb %1@+,%/d0; moveb %/d0,%2@+");
314
          return;
315
      case 2:
316
          COMMON("movesw %1@+,%/d0; movew %/d0,%2@+");
317
          return;
318
      case 3:
319
          COMMON("movesw %1@+,%/d0; movew %/d0,%2@+\n\t"
320
                 "movesb %1@+,%/d0; moveb %/d0,%2@+");
321
          return;
322
  }
323
#undef COMMON
324
}
325
 
326
#define memcpy_fromfs(to, from, n) \
327
(__builtin_constant_p(n) ? \
328
 __constant_memcpy_fromfs((to),(from),(n)) : \
329
 __generic_memcpy_fromfs((to),(from),(n)))
330
 
331
#define memcpy_tofs(to, from, n) \
332
(__builtin_constant_p(n) ? \
333
 __constant_memcpy_tofs((to),(from),(n)) : \
334
 __generic_memcpy_tofs((to),(from),(n)))
335
 
336
/*
337
 * Get/set the SFC/DFC registers for MOVES instructions
338
 */
339
 
340
static inline unsigned long get_fs(void)
341
{
342
        unsigned long _v;
343
        __asm__ ("movec %/dfc,%0":"=r" (_v):);
344
 
345
        return _v;
346
}
347
 
348
static inline unsigned long get_ds(void)
349
{
350
    /* return the supervisor data space code */
351
    return KERNEL_DS;
352
}
353
 
354
static inline void set_fs(unsigned long val)
355
{
356
        __asm__ __volatile__ ("movec %0,%/sfc\n\t"
357
                              "movec %0,%/dfc\n\t"
358
                              : /* no outputs */ : "r" (val) : "memory");
359
}
360
 
361
#endif /* __ASSEMBLY__ */
362
 
363
#endif /* _M68K_SEGMENT_H */

powered by: WebSVN 2.1.0

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