1 /*
2  * Copyright (C) 2006 Atmark Techno, Inc.
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License. See the file "COPYING" in the main directory of this archive
6  * for more details.
7  */
8 
9 #ifndef _ASM_MICROBLAZE_UACCESS_H
10 #define _ASM_MICROBLAZE_UACCESS_H
11 
12 #ifdef __KERNEL__
13 #ifndef __ASSEMBLY__
14 
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/sched.h> /* RLIMIT_FSIZE */
18 #include <linux/mm.h>
19 
20 #include <asm/mmu.h>
21 #include <asm/page.h>
22 #include <asm/pgtable.h>
23 #include <asm/segment.h>
24 #include <linux/string.h>
25 
26 #define VERIFY_READ	0
27 #define VERIFY_WRITE	1
28 
29 extern int ___range_ok(unsigned long addr, unsigned long size);
30 
31 #define __range_ok(addr, size) \
32 		___range_ok((unsigned long)(addr), (unsigned long)(size))
33 
34 #define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
35 #define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
36 
37 extern inline int bad_user_access_length(void)
38 {
39 	return 0;
40 }
41 /* FIXME this is function for optimalization -> memcpy */
42 #define __get_user(var, ptr)					\
43 	({							\
44 		int __gu_err = 0;				\
45 		switch (sizeof(*(ptr))) {			\
46 		case 1:						\
47 		case 2:						\
48 		case 4:						\
49 			(var) = *(ptr);				\
50 			break;					\
51 		case 8:						\
52 			memcpy((void *) &(var), (ptr), 8);	\
53 			break;					\
54 		default:					\
55 			(var) = 0;				\
56 			__gu_err = __get_user_bad();		\
57 			break;					\
58 		}						\
59 		__gu_err;					\
60 	})
61 
62 #define __get_user_bad()	(bad_user_access_length(), (-EFAULT))
63 
64 #define __put_user(var, ptr)					\
65 	({							\
66 		int __pu_err = 0;				\
67 		switch (sizeof(*(ptr))) {			\
68 		case 1:						\
69 		case 2:						\
70 		case 4:						\
71 			*(ptr) = (var);				\
72 			break;					\
73 		case 8: {					\
74 			typeof(*(ptr)) __pu_val = var;		\
75 			memcpy(ptr, &__pu_val, sizeof(__pu_val));\
76 			}					\
77 			break;					\
78 		default:					\
79 			__pu_err = __put_user_bad();		\
80 			break;					\
81 		}							\
82 		__pu_err;						\
83 	})
84 
85 #define __put_user_bad()	(bad_user_access_length(), (-EFAULT))
86 
87 #define put_user(x, ptr)	__put_user(x, ptr)
88 #define get_user(x, ptr)	__get_user(x, ptr)
89 
90 #define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
91 #define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
92 
93 #define __copy_to_user(to, from, n)		(copy_to_user(to, from, n))
94 #define __copy_from_user(to, from, n)		(copy_from_user(to, from, n))
95 #define __copy_to_user_inatomic(to, from, n)	(__copy_to_user(to, from, n))
96 #define __copy_from_user_inatomic(to, from, n)	(__copy_from_user(to, from, n))
97 
98 #define __clear_user(addr, n)	(memset((void *)addr, 0, n), 0)
99 
100 static inline unsigned long clear_user(void *addr, unsigned long size)
101 {
102 	if (access_ok(VERIFY_WRITE, addr, size))
103 		size = __clear_user(addr, size);
104 	return size;
105 }
106 
107 /* Returns 0 if exception not found and fixup otherwise. */
108 extern unsigned long search_exception_table(unsigned long);
109 
110 
111 extern long strncpy_from_user(char *dst, const char __user *src, long count);
112 extern long strnlen_user(const char __user *src, long count);
113 extern long __strncpy_from_user(char *dst, const char __user *src, long count);
114 
115 /*
116  * The exception table consists of pairs of addresses: the first is the
117  * address of an instruction that is allowed to fault, and the second is
118  * the address at which the program should continue. No registers are
119  * modified, so it is entirely up to the continuation code to figure out
120  * what to do.
121  *
122  * All the routines below use bits of fixup code that are out of line
123  * with the main instruction path. This means when everything is well,
124  * we don't even have to jump over them. Further, they do not intrude
125  * on our cache or tlb entries.
126  */
127 struct exception_table_entry {
128 	unsigned long insn, fixup;
129 };
130 
131 #endif  /* __ASSEMBLY__ */
132 #endif /* __KERNEL__ */
133 
134 #endif /* _ASM_MICROBLAZE_UACCESS_H */
135