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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-sparc64/] [uaccess.h] - Blame information for rev 1774

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

Line No. Rev Author Line
1 1276 phoenix
/* $Id: uaccess.h,v 1.1.1.1 2004-04-15 03:01:05 phoenix Exp $ */
2
#ifndef _ASM_UACCESS_H
3
#define _ASM_UACCESS_H
4
 
5
/*
6
 * User space memory access functions
7
 */
8
 
9
#ifdef __KERNEL__
10
#include <linux/sched.h>
11
#include <linux/string.h>
12
#include <asm/a.out.h>
13
#include <asm/asi.h>
14
#include <asm/system.h>
15
#include <asm/spitfire.h>
16
#endif
17
 
18
#ifndef __ASSEMBLY__
19
 
20
/*
21
 * Sparc64 is segmented, though more like the M68K than the I386.
22
 * We use the secondary ASI to address user memory, which references a
23
 * completely different VM map, thus there is zero chance of the user
24
 * doing something queer and tricking us into poking kernel memory.
25
 *
26
 * What is left here is basically what is needed for the other parts of
27
 * the kernel that expect to be able to manipulate, erum, "segments".
28
 * Or perhaps more properly, permissions.
29
 *
30
 * "For historical reasons, these macros are grossly misnamed." -Linus
31
 */
32
 
33
#define KERNEL_DS   ((mm_segment_t) { ASI_P })
34
#define USER_DS     ((mm_segment_t) { ASI_AIUS })       /* har har har */
35
 
36
#define VERIFY_READ     0
37
#define VERIFY_WRITE    1
38
 
39
#define get_fs() (current->thread.current_ds)
40
#define get_ds() (KERNEL_DS)
41
 
42
#define segment_eq(a,b)  ((a).seg == (b).seg)
43
 
44
#define set_fs(val)                                                             \
45
do {                                                                            \
46
        current->thread.current_ds = (val);                                     \
47
        __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg));        \
48
} while(0)
49
 
50
#define __user_ok(addr,size) 1
51
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
52
#define __access_ok(addr,size) 1
53
#define access_ok(type,addr,size) 1
54
 
55
extern inline int verify_area(int type, const void * addr, unsigned long size)
56
{
57
        return 0;
58
}
59
 
60
/*
61
 * The exception table consists of pairs of addresses: the first is the
62
 * address of an instruction that is allowed to fault, and the second is
63
 * the address at which the program should continue.  No registers are
64
 * modified, so it is entirely up to the continuation code to figure out
65
 * what to do.
66
 *
67
 * All the routines below use bits of fixup code that are out of line
68
 * with the main instruction path.  This means when everything is well,
69
 * we don't even have to jump over them.  Further, they do not intrude
70
 * on our cache or tlb entries.
71
 *
72
 * There is a special way how to put a range of potentially faulting
73
 * insns (like twenty ldd/std's with now intervening other instructions)
74
 * You specify address of first in insn and 0 in fixup and in the next
75
 * exception_table_entry you specify last potentially faulting insn + 1
76
 * and in fixup the routine which should handle the fault.
77
 * That fixup code will get
78
 * (faulting_insn_address - first_insn_in_the_range_address)/4
79
 * in %g2 (ie. index of the faulting instruction in the range).
80
 */
81
 
82
struct exception_table_entry
83
{
84
        unsigned insn, fixup;
85
};
86
 
87
/* Returns 0 if exception not found and fixup otherwise.  */
88
extern unsigned long search_exception_table(unsigned long, unsigned long *);
89
 
90
extern void __ret_efault(void);
91
 
92
/* Uh, these should become the main single-value transfer routines..
93
 * They automatically use the right size if we just have the right
94
 * pointer type..
95
 *
96
 * This gets kind of ugly. We want to return _two_ values in "get_user()"
97
 * and yet we don't want to do any pointers, because that is too much
98
 * of a performance impact. Thus we have a few rather ugly macros here,
99
 * and hide all the uglyness from the user.
100
 */
101
#define put_user(x,ptr) ({ \
102
unsigned long __pu_addr = (unsigned long)(ptr); \
103
__put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
104
 
105
#define get_user(x,ptr) ({ \
106
unsigned long __gu_addr = (unsigned long)(ptr); \
107
__get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
108
 
109
#define __put_user(x,ptr) put_user(x,ptr)
110
#define __get_user(x,ptr) get_user(x,ptr)
111
 
112
struct __large_struct { unsigned long buf[100]; };
113
#define __m(x) ((struct __large_struct *)(x))
114
 
115
#define __put_user_nocheck(data,addr,size) ({ \
116
register int __pu_ret; \
117
switch (size) { \
118
case 1: __put_user_asm(data,b,addr,__pu_ret); break; \
119
case 2: __put_user_asm(data,h,addr,__pu_ret); break; \
120
case 4: __put_user_asm(data,w,addr,__pu_ret); break; \
121
case 8: __put_user_asm(data,x,addr,__pu_ret); break; \
122
default: __pu_ret = __put_user_bad(); break; \
123
} __pu_ret; })
124
 
125
#define __put_user_nocheck_ret(data,addr,size,retval) ({ \
126
register int __foo __asm__ ("l1"); \
127
switch (size) { \
128
case 1: __put_user_asm_ret(data,b,addr,retval,__foo); break; \
129
case 2: __put_user_asm_ret(data,h,addr,retval,__foo); break; \
130
case 4: __put_user_asm_ret(data,w,addr,retval,__foo); break; \
131
case 8: __put_user_asm_ret(data,x,addr,retval,__foo); break; \
132
default: if (__put_user_bad()) return retval; break; \
133
} })
134
 
135
#define __put_user_asm(x,size,addr,ret)                                 \
136
__asm__ __volatile__(                                                   \
137
        "/* Put user asm, inline. */\n"                                 \
138
"1:\t"  "st"#size "a %1, [%2] %%asi\n\t"                                \
139
        "clr    %0\n"                                                   \
140
"2:\n\n\t"                                                              \
141
        ".section .fixup,#alloc,#execinstr\n\t"                         \
142
        ".align 4\n"                                                    \
143
"3:\n\t"                                                                \
144
        "b      2b\n\t"                                                 \
145
        " mov   %3, %0\n\n\t"                                           \
146
        ".previous\n\t"                                                 \
147
        ".section __ex_table,#alloc\n\t"                                \
148
        ".align 4\n\t"                                                  \
149
        ".word  1b, 3b\n\t"                                             \
150
        ".previous\n\n\t"                                               \
151
       : "=r" (ret) : "r" (x), "r" (__m(addr)),                         \
152
         "i" (-EFAULT))
153
 
154
#define __put_user_asm_ret(x,size,addr,ret,foo)                         \
155
if (__builtin_constant_p(ret) && ret == -EFAULT)                        \
156
__asm__ __volatile__(                                                   \
157
        "/* Put user asm ret, inline. */\n"                             \
158
"1:\t"  "st"#size "a %1, [%2] %%asi\n\n\t"                              \
159
        ".section __ex_table,#alloc\n\t"                                \
160
        ".align 4\n\t"                                                  \
161
        ".word  1b, __ret_efault\n\n\t"                                 \
162
        ".previous\n\n\t"                                               \
163
       : "=r" (foo) : "r" (x), "r" (__m(addr)));                        \
164
else                                                                    \
165
__asm__ __volatile(                                                     \
166
        "/* Put user asm ret, inline. */\n"                             \
167
"1:\t"  "st"#size "a %1, [%2] %%asi\n\n\t"                              \
168
        ".section .fixup,#alloc,#execinstr\n\t"                         \
169
        ".align 4\n"                                                    \
170
"3:\n\t"                                                                \
171
        "ret\n\t"                                                       \
172
        " restore %%g0, %3, %%o0\n\n\t"                                 \
173
        ".previous\n\t"                                                 \
174
        ".section __ex_table,#alloc\n\t"                                \
175
        ".align 4\n\t"                                                  \
176
        ".word  1b, 3b\n\n\t"                                           \
177
        ".previous\n\n\t"                                               \
178
       : "=r" (foo) : "r" (x), "r" (__m(addr)),                         \
179
         "i" (ret))
180
 
181
extern int __put_user_bad(void);
182
 
183
#define __get_user_nocheck(data,addr,size,type) ({ \
184
register int __gu_ret; \
185
register unsigned long __gu_val; \
186
switch (size) { \
187
case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
188
case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
189
case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
190
case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
191
default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
192
} data = (type) __gu_val; __gu_ret; })
193
 
194
#define __get_user_nocheck_ret(data,addr,size,type,retval) ({ \
195
register unsigned long __gu_val __asm__ ("l1"); \
196
switch (size) { \
197
case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
198
case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
199
case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
200
case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
201
default: if (__get_user_bad()) return retval; \
202
} data = (type) __gu_val; })
203
 
204
#define __get_user_asm(x,size,addr,ret)                                 \
205
__asm__ __volatile__(                                                   \
206
        "/* Get user asm, inline. */\n"                                 \
207
"1:\t"  "ld"#size "a [%2] %%asi, %1\n\t"                                \
208
        "clr    %0\n"                                                   \
209
"2:\n\n\t"                                                              \
210
        ".section .fixup,#alloc,#execinstr\n\t"                         \
211
        ".align 4\n"                                                    \
212
"3:\n\t"                                                                \
213
        "clr    %1\n\t"                                                 \
214
        "b      2b\n\t"                                                 \
215
        " mov   %3, %0\n\n\t"                                           \
216
        ".previous\n\t"                                                 \
217
        ".section __ex_table,#alloc\n\t"                                \
218
        ".align 4\n\t"                                                  \
219
        ".word  1b, 3b\n\n\t"                                           \
220
        ".previous\n\t"                                                 \
221
       : "=r" (ret), "=r" (x) : "r" (__m(addr)),                        \
222
         "i" (-EFAULT))
223
 
224
#define __get_user_asm_ret(x,size,addr,retval)                          \
225
if (__builtin_constant_p(retval) && retval == -EFAULT)                  \
226
__asm__ __volatile__(                                                   \
227
        "/* Get user asm ret, inline. */\n"                             \
228
"1:\t"  "ld"#size "a [%1] %%asi, %0\n\n\t"                              \
229
        ".section __ex_table,#alloc\n\t"                                \
230
        ".align 4\n\t"                                                  \
231
        ".word  1b,__ret_efault\n\n\t"                                  \
232
        ".previous\n\t"                                                 \
233
       : "=r" (x) : "r" (__m(addr)));                                   \
234
else                                                                    \
235
__asm__ __volatile__(                                                   \
236
        "/* Get user asm ret, inline. */\n"                             \
237
"1:\t"  "ld"#size "a [%1] %%asi, %0\n\n\t"                              \
238
        ".section .fixup,#alloc,#execinstr\n\t"                         \
239
        ".align 4\n"                                                    \
240
"3:\n\t"                                                                \
241
        "ret\n\t"                                                       \
242
        " restore %%g0, %2, %%o0\n\n\t"                                 \
243
        ".previous\n\t"                                                 \
244
        ".section __ex_table,#alloc\n\t"                                \
245
        ".align 4\n\t"                                                  \
246
        ".word  1b, 3b\n\n\t"                                           \
247
        ".previous\n\t"                                                 \
248
       : "=r" (x) : "r" (__m(addr)), "i" (retval))
249
 
250
extern int __get_user_bad(void);
251
 
252
extern __kernel_size_t __copy_from_user(void *to, const void *from,
253
                                        __kernel_size_t size);
254
 
255
extern __kernel_size_t __copy_to_user(void *to, const void *from,
256
                                      __kernel_size_t size);
257
 
258
extern __kernel_size_t __copy_in_user(void *to, const void *from,
259
                                      __kernel_size_t size);
260
 
261
#define copy_from_user(to,from,n)               \
262
        __copy_from_user((void *)(to),  \
263
                    (void *)(from), (__kernel_size_t)(n))
264
 
265
#define copy_to_user(to,from,n) \
266
        __copy_to_user((void *)(to), \
267
        (void *) (from), (__kernel_size_t)(n))
268
 
269
#define copy_in_user(to,from,n) \
270
        __copy_in_user((void *)(to), \
271
        (void *) (from), (__kernel_size_t)(n))
272
 
273
extern __inline__ __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
274
{
275
        extern __kernel_size_t __bzero_noasi(void *addr, __kernel_size_t size);
276
 
277
        return __bzero_noasi(addr, size);
278
}
279
 
280
#define clear_user(addr,n) \
281
        __clear_user((void *)(addr), (__kernel_size_t)(n))
282
 
283
extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
284
 
285
#define strncpy_from_user(dest,src,count) \
286
        __strncpy_from_user((unsigned long)(dest), (unsigned long)(src), (int)(count))
287
 
288
extern int __strlen_user(const char *);
289
extern int __strnlen_user(const char *, long len);
290
 
291
#define strlen_user __strlen_user
292
#define strnlen_user __strnlen_user
293
 
294
#endif  /* __ASSEMBLY__ */
295
 
296
#endif /* _ASM_UACCESS_H */

powered by: WebSVN 2.1.0

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