Linux 6.9-rc1
[linux-2.6-microblaze.git] / arch / csky / include / asm / uaccess.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef __ASM_CSKY_UACCESS_H
4 #define __ASM_CSKY_UACCESS_H
5
6 /*
7  * __put_user_fn
8  */
9 extern int __put_user_bad(void);
10
11 #define __put_user_asm_b(x, ptr, err)                   \
12 do {                                                    \
13         int errcode;                                    \
14         __asm__ __volatile__(                           \
15         "1:     stb   %1, (%2,0)        \n"             \
16         "       br    3f                \n"             \
17         "2:     mov   %0, %3            \n"             \
18         "       br    3f                \n"             \
19         ".section __ex_table, \"a\"     \n"             \
20         ".align   2                     \n"             \
21         ".long    1b,2b                 \n"             \
22         ".previous                      \n"             \
23         "3:                             \n"             \
24         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
25         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
26         : "memory");                                    \
27 } while (0)
28
29 #define __put_user_asm_h(x, ptr, err)                   \
30 do {                                                    \
31         int errcode;                                    \
32         __asm__ __volatile__(                           \
33         "1:     sth   %1, (%2,0)        \n"             \
34         "       br    3f                \n"             \
35         "2:     mov   %0, %3            \n"             \
36         "       br    3f                \n"             \
37         ".section __ex_table, \"a\"     \n"             \
38         ".align   2                     \n"             \
39         ".long    1b,2b                 \n"             \
40         ".previous                      \n"             \
41         "3:                             \n"             \
42         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
43         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
44         : "memory");                                    \
45 } while (0)
46
47 #define __put_user_asm_w(x, ptr, err)                   \
48 do {                                                    \
49         int errcode;                                    \
50         __asm__ __volatile__(                           \
51         "1:     stw   %1, (%2,0)        \n"             \
52         "       br    3f                \n"             \
53         "2:     mov   %0, %3            \n"             \
54         "       br    3f                \n"             \
55         ".section __ex_table,\"a\"      \n"             \
56         ".align   2                     \n"             \
57         ".long    1b, 2b                \n"             \
58         ".previous                      \n"             \
59         "3:                             \n"             \
60         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
61         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
62         : "memory");                                    \
63 } while (0)
64
65 #define __put_user_asm_64(x, ptr, err)                  \
66 do {                                                    \
67         int tmp;                                        \
68         int errcode;                                    \
69                                                         \
70         __asm__ __volatile__(                           \
71         "     ldw     %3, (%1, 0)     \n"               \
72         "1:   stw     %3, (%2, 0)     \n"               \
73         "     ldw     %3, (%1, 4)     \n"               \
74         "2:   stw     %3, (%2, 4)     \n"               \
75         "     br      4f              \n"               \
76         "3:   mov     %0, %4          \n"               \
77         "     br      4f              \n"               \
78         ".section __ex_table, \"a\"   \n"               \
79         ".align   2                   \n"               \
80         ".long    1b, 3b              \n"               \
81         ".long    2b, 3b              \n"               \
82         ".previous                    \n"               \
83         "4:                           \n"               \
84         : "=r"(err), "=r"(x), "=r"(ptr),                \
85           "=r"(tmp), "=r"(errcode)                      \
86         : "0"(err), "1"(x), "2"(ptr), "3"(0),           \
87           "4"(-EFAULT)                                  \
88         : "memory");                                    \
89 } while (0)
90
91 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
92 {
93         int retval = 0;
94         u32 tmp;
95
96         switch (size) {
97         case 1:
98                 tmp = *(u8 *)x;
99                 __put_user_asm_b(tmp, ptr, retval);
100                 break;
101         case 2:
102                 tmp = *(u16 *)x;
103                 __put_user_asm_h(tmp, ptr, retval);
104                 break;
105         case 4:
106                 tmp = *(u32 *)x;
107                 __put_user_asm_w(tmp, ptr, retval);
108                 break;
109         case 8:
110                 __put_user_asm_64(x, (u64 *)ptr, retval);
111                 break;
112         }
113
114         return retval;
115 }
116 #define __put_user_fn __put_user_fn
117
118 /*
119  * __get_user_fn
120  */
121 extern int __get_user_bad(void);
122
123 #define __get_user_asm_common(x, ptr, ins, err)         \
124 do {                                                    \
125         int errcode;                                    \
126         __asm__ __volatile__(                           \
127         "1:   " ins " %1, (%4, 0)       \n"             \
128         "       br    3f                \n"             \
129         "2:     mov   %0, %2            \n"             \
130         "       movi  %1, 0             \n"             \
131         "       br    3f                \n"             \
132         ".section __ex_table,\"a\"      \n"             \
133         ".align   2                     \n"             \
134         ".long    1b, 2b                \n"             \
135         ".previous                      \n"             \
136         "3:                             \n"             \
137         : "=r"(err), "=r"(x), "=r"(errcode)             \
138         : "0"(0), "r"(ptr), "2"(-EFAULT)                \
139         : "memory");                                    \
140 } while (0)
141
142 #define __get_user_asm_64(x, ptr, err)                  \
143 do {                                                    \
144         int tmp;                                        \
145         int errcode;                                    \
146                                                         \
147         __asm__ __volatile__(                           \
148         "1:   ldw     %3, (%2, 0)     \n"               \
149         "     stw     %3, (%1, 0)     \n"               \
150         "2:   ldw     %3, (%2, 4)     \n"               \
151         "     stw     %3, (%1, 4)     \n"               \
152         "     br      4f              \n"               \
153         "3:   mov     %0, %4          \n"               \
154         "     br      4f              \n"               \
155         ".section __ex_table, \"a\"   \n"               \
156         ".align   2                   \n"               \
157         ".long    1b, 3b              \n"               \
158         ".long    2b, 3b              \n"               \
159         ".previous                    \n"               \
160         "4:                           \n"               \
161         : "=r"(err), "=r"(x), "=r"(ptr),                \
162           "=r"(tmp), "=r"(errcode)                      \
163         : "0"(err), "1"(x), "2"(ptr), "3"(0),           \
164           "4"(-EFAULT)                                  \
165         : "memory");                                    \
166 } while (0)
167
168 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
169 {
170         int retval;
171         u32 tmp;
172
173         switch (size) {
174         case 1:
175                 __get_user_asm_common(tmp, ptr, "ldb", retval);
176                 *(u8 *)x = (u8)tmp;
177                 break;
178         case 2:
179                 __get_user_asm_common(tmp, ptr, "ldh", retval);
180                 *(u16 *)x = (u16)tmp;
181                 break;
182         case 4:
183                 __get_user_asm_common(tmp, ptr, "ldw", retval);
184                 *(u32 *)x = (u32)tmp;
185                 break;
186         case 8:
187                 __get_user_asm_64(x, ptr, retval);
188                 break;
189         }
190
191         return retval;
192 }
193 #define __get_user_fn __get_user_fn
194
195 unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n);
196 unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
197
198 unsigned long __clear_user(void __user *to, unsigned long n);
199 #define __clear_user __clear_user
200
201 #include <asm-generic/uaccess.h>
202
203 #endif /* __ASM_CSKY_UACCESS_H */