1 #ifndef __M68KNOMMU_UACCESS_H
2 #define __M68KNOMMU_UACCESS_H
5 * User space memory access functions
7 #include <linux/sched.h>
9 #include <linux/string.h>
11 #include <asm/segment.h>
14 #define VERIFY_WRITE 1
16 /* We let the MMU do all checking */
17 extern inline int access_ok(int type
, const void * addr
, unsigned long size
)
19 #define RANGE_CHECK_OK(addr, size, lower, upper) \
20 (((addr) >= (lower)) && (((addr) + (size)) < (upper)))
22 #ifdef CONFIG_COLDFIRE
23 extern unsigned long _ramend
;
24 return(RANGE_CHECK_OK((unsigned long) addr
, size
, 0L, _ramend
) ||
25 (is_in_rom((unsigned long) addr
) &&
26 is_in_rom((unsigned long) addr
+ size
)));
28 /* DAVIDM - this could be restricted a lot more */
29 return(RANGE_CHECK_OK((unsigned long)addr
, size
, 0, 0x10f00000));
33 extern inline int verify_area(int type
, const void * addr
, unsigned long size
)
35 return access_ok(type
,addr
,size
)?0:-EFAULT
;
39 * The exception table consists of pairs of addresses: the first is the
40 * address of an instruction that is allowed to fault, and the second is
41 * the address at which the program should continue. No registers are
42 * modified, so it is entirely up to the continuation code to figure out
45 * All the routines below use bits of fixup code that are out of line
46 * with the main instruction path. This means when everything is well,
47 * we don't even have to jump over them. Further, they do not intrude
48 * on our cache or tlb entries.
51 struct exception_table_entry
53 unsigned long insn
, fixup
;
56 /* Returns 0 if exception not found and fixup otherwise. */
57 extern unsigned long search_exception_table(unsigned long);
61 * These are the main single-value transfer routines. They automatically
62 * use the right size if we just have the right pointer type.
65 #define put_user(x, ptr) \
68 typeof(*(ptr)) __pu_val = (x); \
69 switch (sizeof (*(ptr))) { \
71 __put_user_asm(__pu_err, __pu_val, ptr, b); \
74 __put_user_asm(__pu_err, __pu_val, ptr, w); \
77 __put_user_asm(__pu_err, __pu_val, ptr, l); \
80 memcpy(ptr, &__pu_val, sizeof (*(ptr))); \
83 __pu_err = __put_user_bad(); \
88 #define __put_user(x, ptr) put_user(x, ptr)
90 extern int __put_user_bad(void);
93 * Tell gcc we read from memory instead of writing: this is because
94 * we do not write to any memory gcc knows about, so there are no
98 #define __ptr(x) ((unsigned long *)(x))
100 #define __put_user_asm(err,x,ptr,bwl) \
101 __asm__ ("move" #bwl " %0,%1" \
103 :"d" (x),"m" (*__ptr(ptr)) : "memory")
105 #define get_user(x, ptr) \
108 typeof(*(ptr)) __gu_val = 0; \
109 switch (sizeof(*(ptr))) { \
111 __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \
114 __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \
117 __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \
120 memcpy(&__gu_val, ptr, sizeof (*(ptr))); \
124 __gu_err = __get_user_bad(); \
130 #define __get_user(x, ptr) get_user(x, ptr)
132 extern int __get_user_bad(void);
134 #define __get_user_asm(err,x,ptr,bwl,reg) \
135 __asm__ ("move" #bwl " %1,%0" \
139 #define copy_from_user(to, from, n) (memcpy(to, from, n), 0)
140 #define copy_to_user(to, from, n) (memcpy(to, from, n), 0)
142 #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
143 #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
145 #define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
147 #define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
150 * Copy a null terminated string from userspace.
154 strncpy_from_user(char *dst
, const char *src
, long count
)
157 strncpy(dst
, src
, count
);
158 for (tmp
= dst
; *tmp
&& count
> 0; tmp
++, count
--)
160 return(tmp
- dst
); /* DAVIDM should we count a NUL ? check getname */
164 * Return the size of a string (including the ending 0)
166 * Return 0 on exception, a value greater than N if too long
168 static inline long strnlen_user(const char *src
, long n
)
170 return(strlen(src
) + 1); /* DAVIDM make safer */
173 #define strlen_user(str) strnlen_user(str, 32767)
179 static inline unsigned long
180 clear_user(void *to
, unsigned long n
)
186 #endif /* _M68KNOMMU_UACCESS_H */