1#ifndef __V850_UACCESS_H__
2#define __V850_UACCESS_H__
3
4/*
5 * User space memory access functions
6 */
7
8#include <linux/errno.h>
9#include <linux/string.h>
10
11#include <asm/segment.h>
12#include <asm/machdep.h>
13
14#define VERIFY_READ	0
15#define VERIFY_WRITE	1
16
17static inline int access_ok (int type, const void *addr, unsigned long size)
18{
19	unsigned long val = (unsigned long)addr;
20	return val >= (0x80 + NUM_CPU_IRQS*16) && val < 0xFFFFF000;
21}
22
23/*
24 * The exception table consists of pairs of addresses: the first is the
25 * address of an instruction that is allowed to fault, and the second is
26 * the address at which the program should continue.  No registers are
27 * modified, so it is entirely up to the continuation code to figure out
28 * what to do.
29 *
30 * All the routines below use bits of fixup code that are out of line
31 * with the main instruction path.  This means when everything is well,
32 * we don't even have to jump over them.  Further, they do not intrude
33 * on our cache or tlb entries.
34 */
35
36struct exception_table_entry
37{
38	unsigned long insn, fixup;
39};
40
41/* Returns 0 if exception not found and fixup otherwise.  */
42extern unsigned long search_exception_table (unsigned long);
43
44
45/*
46 * These are the main single-value transfer routines.  They automatically
47 * use the right size if we just have the right pointer type.
48 */
49
50extern int bad_user_access_length (void);
51
52#define __get_user(var, ptr)						      \
53  ({									      \
54	  int __gu_err = 0;						      \
55	  typeof(*(ptr)) __gu_val = 0;					      \
56	  switch (sizeof (*(ptr))) {					      \
57	  case 1:							      \
58	  case 2:							      \
59	  case 4:							      \
60		  __gu_val = *(ptr);					      \
61		  break;						      \
62	  case 8:							      \
63		  memcpy(&__gu_val, ptr, sizeof(__gu_val));		      \
64		  break;						      \
65	  default:							      \
66		  __gu_val = 0;						      \
67		  __gu_err = __get_user_bad ();				      \
68		  break;						      \
69	  }								      \
70	  (var) = __gu_val;						      \
71	  __gu_err;							      \
72  })
73#define __get_user_bad()	(bad_user_access_length (), (-EFAULT))
74
75#define __put_user(var, ptr)						      \
76  ({									      \
77	  int __pu_err = 0;						      \
78	  switch (sizeof (*(ptr))) {					      \
79	  case 1:							      \
80	  case 2:							      \
81	  case 4:							      \
82		  *(ptr) = (var);					      \
83		  break;						      \
84	  case 8: {							      \
85	  	  typeof(*(ptr)) __pu_val = 0;				      \
86		  memcpy(ptr, &__pu_val, sizeof(__pu_val));		      \
87		  }							      \
88		  break;						      \
89	  default:							      \
90		  __pu_err = __put_user_bad ();				      \
91		  break;						      \
92	  }								      \
93	  __pu_err;							      \
94  })
95#define __put_user_bad()	(bad_user_access_length (), (-EFAULT))
96
97#define put_user(x, ptr)	__put_user(x, ptr)
98#define get_user(x, ptr)	__get_user(x, ptr)
99
100#define __copy_from_user(to, from, n)	(memcpy (to, from, n), 0)
101#define __copy_to_user(to, from, n)	(memcpy(to, from, n), 0)
102
103#define __copy_to_user_inatomic __copy_to_user
104#define __copy_from_user_inatomic __copy_from_user
105
106#define copy_from_user(to, from, n)	__copy_from_user (to, from, n)
107#define copy_to_user(to, from, n) 	__copy_to_user(to, from, n)
108
109#define copy_to_user_ret(to,from,n,retval) \
110  ({ if (copy_to_user (to,from,n)) return retval; })
111
112#define copy_from_user_ret(to,from,n,retval) \
113  ({ if (copy_from_user (to,from,n)) return retval; })
114
115/*
116 * Copy a null terminated string from userspace.
117 */
118
119static inline long
120strncpy_from_user (char *dst, const char *src, long count)
121{
122	char *tmp;
123	strncpy (dst, src, count);
124	for (tmp = dst; *tmp && count > 0; tmp++, count--)
125		;
126	return tmp - dst;
127}
128
129/*
130 * Return the size of a string (including the ending 0)
131 *
132 * Return 0 on exception, a value greater than N if too long
133 */
134static inline long strnlen_user (const char *src, long n)
135{
136	return strlen (src) + 1;
137}
138
139#define strlen_user(str)	strnlen_user (str, 32767)
140
141/*
142 * Zero Userspace
143 */
144
145static inline unsigned long
146clear_user (void *to, unsigned long n)
147{
148	memset (to, 0, n);
149	return 0;
150}
151
152#endif /* __V850_UACCESS_H__ */
153