xref: /openbmc/linux/arch/sh/include/asm/uaccess_32.h (revision 2d2b308a)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2f15cbe6fSPaul Mundt /*
3f15cbe6fSPaul Mundt  * User space memory access functions
4f15cbe6fSPaul Mundt  *
5f15cbe6fSPaul Mundt  * Copyright (C) 1999, 2002  Niibe Yutaka
6f15cbe6fSPaul Mundt  * Copyright (C) 2003 - 2008  Paul Mundt
7f15cbe6fSPaul Mundt  *
8f15cbe6fSPaul Mundt  *  Based on:
9f15cbe6fSPaul Mundt  *     MIPS implementation version 1.15 by
10f15cbe6fSPaul Mundt  *              Copyright (C) 1996, 1997, 1998 by Ralf Baechle
11f15cbe6fSPaul Mundt  *     and i386 version.
12f15cbe6fSPaul Mundt  */
13f15cbe6fSPaul Mundt #ifndef __ASM_SH_UACCESS_32_H
14f15cbe6fSPaul Mundt #define __ASM_SH_UACCESS_32_H
15f15cbe6fSPaul Mundt 
16f15cbe6fSPaul Mundt #define __get_user_size(x,ptr,size,retval)			\
17f15cbe6fSPaul Mundt do {								\
18f15cbe6fSPaul Mundt 	retval = 0;						\
19f15cbe6fSPaul Mundt 	switch (size) {						\
20f15cbe6fSPaul Mundt 	case 1:							\
21f15cbe6fSPaul Mundt 		__get_user_asm(x, ptr, retval, "b");		\
22f15cbe6fSPaul Mundt 		break;						\
23f15cbe6fSPaul Mundt 	case 2:							\
24f15cbe6fSPaul Mundt 		__get_user_asm(x, ptr, retval, "w");		\
25f15cbe6fSPaul Mundt 		break;						\
26f15cbe6fSPaul Mundt 	case 4:							\
27f15cbe6fSPaul Mundt 		__get_user_asm(x, ptr, retval, "l");		\
28f15cbe6fSPaul Mundt 		break;						\
292d2b308aSJohn Paul Adrian Glaubitz 	case 8:							\
302d2b308aSJohn Paul Adrian Glaubitz 		__get_user_u64(x, ptr, retval);			\
312d2b308aSJohn Paul Adrian Glaubitz 		break;						\
32f15cbe6fSPaul Mundt 	default:						\
33f15cbe6fSPaul Mundt 		__get_user_unknown();				\
34f15cbe6fSPaul Mundt 		break;						\
35f15cbe6fSPaul Mundt 	}							\
36f15cbe6fSPaul Mundt } while (0)
37f15cbe6fSPaul Mundt 
38f15cbe6fSPaul Mundt #ifdef CONFIG_MMU
39f15cbe6fSPaul Mundt #define __get_user_asm(x, addr, err, insn) \
40f15cbe6fSPaul Mundt ({ \
41f15cbe6fSPaul Mundt __asm__ __volatile__( \
42f15cbe6fSPaul Mundt 	"1:\n\t" \
43f15cbe6fSPaul Mundt 	"mov." insn "	%2, %1\n\t" \
44f15cbe6fSPaul Mundt 	"2:\n" \
45f15cbe6fSPaul Mundt 	".section	.fixup,\"ax\"\n" \
46f15cbe6fSPaul Mundt 	"3:\n\t" \
47f15cbe6fSPaul Mundt 	"mov	#0, %1\n\t" \
48f15cbe6fSPaul Mundt 	"mov.l	4f, %0\n\t" \
49f15cbe6fSPaul Mundt 	"jmp	@%0\n\t" \
50f15cbe6fSPaul Mundt 	" mov	%3, %0\n\t" \
51f15cbe6fSPaul Mundt 	".balign	4\n" \
52f15cbe6fSPaul Mundt 	"4:	.long	2b\n\t" \
53f15cbe6fSPaul Mundt 	".previous\n" \
54f15cbe6fSPaul Mundt 	".section	__ex_table,\"a\"\n\t" \
55f15cbe6fSPaul Mundt 	".long	1b, 3b\n\t" \
56f15cbe6fSPaul Mundt 	".previous" \
57f15cbe6fSPaul Mundt 	:"=&r" (err), "=&r" (x) \
58f15cbe6fSPaul Mundt 	:"m" (__m(addr)), "i" (-EFAULT), "0" (err)); })
59f15cbe6fSPaul Mundt #else
60f15cbe6fSPaul Mundt #define __get_user_asm(x, addr, err, insn)		\
61f15cbe6fSPaul Mundt do {							\
62f15cbe6fSPaul Mundt 	__asm__ __volatile__ (				\
63f15cbe6fSPaul Mundt 		"mov." insn "	%1, %0\n\t"		\
64f15cbe6fSPaul Mundt 		: "=&r" (x)				\
65f15cbe6fSPaul Mundt 		: "m" (__m(addr))			\
66f15cbe6fSPaul Mundt 	);						\
67f15cbe6fSPaul Mundt } while (0)
68f15cbe6fSPaul Mundt #endif /* CONFIG_MMU */
69f15cbe6fSPaul Mundt 
70f15cbe6fSPaul Mundt extern void __get_user_unknown(void);
71f15cbe6fSPaul Mundt 
722d2b308aSJohn Paul Adrian Glaubitz #if defined(CONFIG_CPU_LITTLE_ENDIAN)
732d2b308aSJohn Paul Adrian Glaubitz #define __get_user_u64(x, addr, err) \
742d2b308aSJohn Paul Adrian Glaubitz ({ \
752d2b308aSJohn Paul Adrian Glaubitz __asm__ __volatile__( \
762d2b308aSJohn Paul Adrian Glaubitz 	"1:\n\t" \
772d2b308aSJohn Paul Adrian Glaubitz 	"mov.l	%2,%R1\n\t" \
782d2b308aSJohn Paul Adrian Glaubitz 	"mov.l	%T2,%S1\n\t" \
792d2b308aSJohn Paul Adrian Glaubitz 	"2:\n" \
802d2b308aSJohn Paul Adrian Glaubitz 	".section	.fixup,\"ax\"\n" \
812d2b308aSJohn Paul Adrian Glaubitz 	"3:\n\t" \
822d2b308aSJohn Paul Adrian Glaubitz 	"mov  #0,%R1\n\t"   \
832d2b308aSJohn Paul Adrian Glaubitz 	"mov  #0,%S1\n\t"   \
842d2b308aSJohn Paul Adrian Glaubitz 	"mov.l	4f, %0\n\t" \
852d2b308aSJohn Paul Adrian Glaubitz 	"jmp	@%0\n\t" \
862d2b308aSJohn Paul Adrian Glaubitz 	" mov	%3, %0\n\t" \
872d2b308aSJohn Paul Adrian Glaubitz 	".balign	4\n" \
882d2b308aSJohn Paul Adrian Glaubitz 	"4:	.long	2b\n\t" \
892d2b308aSJohn Paul Adrian Glaubitz 	".previous\n" \
902d2b308aSJohn Paul Adrian Glaubitz 	".section	__ex_table,\"a\"\n\t" \
912d2b308aSJohn Paul Adrian Glaubitz 	".long	1b, 3b\n\t" \
922d2b308aSJohn Paul Adrian Glaubitz 	".long	1b + 2, 3b\n\t" \
932d2b308aSJohn Paul Adrian Glaubitz 	".previous" \
942d2b308aSJohn Paul Adrian Glaubitz 	:"=&r" (err), "=&r" (x) \
952d2b308aSJohn Paul Adrian Glaubitz 	:"m" (__m(addr)), "i" (-EFAULT), "0" (err)); })
962d2b308aSJohn Paul Adrian Glaubitz #else
972d2b308aSJohn Paul Adrian Glaubitz #define __get_user_u64(x, addr, err) \
982d2b308aSJohn Paul Adrian Glaubitz ({ \
992d2b308aSJohn Paul Adrian Glaubitz __asm__ __volatile__( \
1002d2b308aSJohn Paul Adrian Glaubitz 	"1:\n\t" \
1012d2b308aSJohn Paul Adrian Glaubitz 	"mov.l	%2,%S1\n\t" \
1022d2b308aSJohn Paul Adrian Glaubitz 	"mov.l	%T2,%R1\n\t" \
1032d2b308aSJohn Paul Adrian Glaubitz 	"2:\n" \
1042d2b308aSJohn Paul Adrian Glaubitz 	".section	.fixup,\"ax\"\n" \
1052d2b308aSJohn Paul Adrian Glaubitz 	"3:\n\t" \
1062d2b308aSJohn Paul Adrian Glaubitz 	"mov  #0,%S1\n\t"   \
1072d2b308aSJohn Paul Adrian Glaubitz 	"mov  #0,%R1\n\t"   \
1082d2b308aSJohn Paul Adrian Glaubitz 	"mov.l	4f, %0\n\t" \
1092d2b308aSJohn Paul Adrian Glaubitz 	"jmp	@%0\n\t" \
1102d2b308aSJohn Paul Adrian Glaubitz 	" mov	%3, %0\n\t" \
1112d2b308aSJohn Paul Adrian Glaubitz 	".balign	4\n" \
1122d2b308aSJohn Paul Adrian Glaubitz 	"4:	.long	2b\n\t" \
1132d2b308aSJohn Paul Adrian Glaubitz 	".previous\n" \
1142d2b308aSJohn Paul Adrian Glaubitz 	".section	__ex_table,\"a\"\n\t" \
1152d2b308aSJohn Paul Adrian Glaubitz 	".long	1b, 3b\n\t" \
1162d2b308aSJohn Paul Adrian Glaubitz 	".long	1b + 2, 3b\n\t" \
1172d2b308aSJohn Paul Adrian Glaubitz 	".previous" \
1182d2b308aSJohn Paul Adrian Glaubitz 	:"=&r" (err), "=&r" (x) \
1192d2b308aSJohn Paul Adrian Glaubitz 	:"m" (__m(addr)), "i" (-EFAULT), "0" (err)); })
1202d2b308aSJohn Paul Adrian Glaubitz #endif
1212d2b308aSJohn Paul Adrian Glaubitz 
122f15cbe6fSPaul Mundt #define __put_user_size(x,ptr,size,retval)		\
123f15cbe6fSPaul Mundt do {							\
124f15cbe6fSPaul Mundt 	retval = 0;					\
125f15cbe6fSPaul Mundt 	switch (size) {					\
126f15cbe6fSPaul Mundt 	case 1:						\
127f15cbe6fSPaul Mundt 		__put_user_asm(x, ptr, retval, "b");	\
128f15cbe6fSPaul Mundt 		break;					\
129f15cbe6fSPaul Mundt 	case 2:						\
130f15cbe6fSPaul Mundt 		__put_user_asm(x, ptr, retval, "w");	\
131f15cbe6fSPaul Mundt 		break;					\
132f15cbe6fSPaul Mundt 	case 4:						\
1336de9c648SOGAWA Hirofumi 		__put_user_asm(x, ptr, retval, "l");	\
134f15cbe6fSPaul Mundt 		break;					\
135f15cbe6fSPaul Mundt 	case 8:						\
136f15cbe6fSPaul Mundt 		__put_user_u64(x, ptr, retval);		\
137f15cbe6fSPaul Mundt 		break;					\
138f15cbe6fSPaul Mundt 	default:					\
139f15cbe6fSPaul Mundt 		__put_user_unknown();			\
140f15cbe6fSPaul Mundt 	}						\
141f15cbe6fSPaul Mundt } while (0)
142f15cbe6fSPaul Mundt 
143f15cbe6fSPaul Mundt #ifdef CONFIG_MMU
144f15cbe6fSPaul Mundt #define __put_user_asm(x, addr, err, insn)			\
145f15cbe6fSPaul Mundt do {								\
146f15cbe6fSPaul Mundt 	__asm__ __volatile__ (					\
147f15cbe6fSPaul Mundt 		"1:\n\t"					\
148f15cbe6fSPaul Mundt 		"mov." insn "	%1, %2\n\t"			\
149f15cbe6fSPaul Mundt 		"2:\n"						\
150f15cbe6fSPaul Mundt 		".section	.fixup,\"ax\"\n"		\
151f15cbe6fSPaul Mundt 		"3:\n\t"					\
152f15cbe6fSPaul Mundt 		"mov.l	4f, %0\n\t"				\
153f15cbe6fSPaul Mundt 		"jmp	@%0\n\t"				\
154f15cbe6fSPaul Mundt 		" mov	%3, %0\n\t"				\
155f15cbe6fSPaul Mundt 		".balign	4\n"				\
156f15cbe6fSPaul Mundt 		"4:	.long	2b\n\t"				\
157f15cbe6fSPaul Mundt 		".previous\n"					\
158f15cbe6fSPaul Mundt 		".section	__ex_table,\"a\"\n\t"		\
159f15cbe6fSPaul Mundt 		".long	1b, 3b\n\t"				\
160f15cbe6fSPaul Mundt 		".previous"					\
161f15cbe6fSPaul Mundt 		: "=&r" (err)					\
162f15cbe6fSPaul Mundt 		: "r" (x), "m" (__m(addr)), "i" (-EFAULT),	\
163f15cbe6fSPaul Mundt 		  "0" (err)					\
164f15cbe6fSPaul Mundt 		: "memory"					\
165f15cbe6fSPaul Mundt 	);							\
166f15cbe6fSPaul Mundt } while (0)
167f15cbe6fSPaul Mundt #else
168f15cbe6fSPaul Mundt #define __put_user_asm(x, addr, err, insn)		\
169f15cbe6fSPaul Mundt do {							\
170f15cbe6fSPaul Mundt 	__asm__ __volatile__ (				\
171f15cbe6fSPaul Mundt 		"mov." insn "	%0, %1\n\t"		\
172f15cbe6fSPaul Mundt 		: /* no outputs */			\
173f15cbe6fSPaul Mundt 		: "r" (x), "m" (__m(addr))		\
174f15cbe6fSPaul Mundt 		: "memory"				\
175f15cbe6fSPaul Mundt 	);						\
176f15cbe6fSPaul Mundt } while (0)
177f15cbe6fSPaul Mundt #endif /* CONFIG_MMU */
178f15cbe6fSPaul Mundt 
179f15cbe6fSPaul Mundt #if defined(CONFIG_CPU_LITTLE_ENDIAN)
180f15cbe6fSPaul Mundt #define __put_user_u64(val,addr,retval) \
181f15cbe6fSPaul Mundt ({ \
182f15cbe6fSPaul Mundt __asm__ __volatile__( \
183f15cbe6fSPaul Mundt 	"1:\n\t" \
184f15cbe6fSPaul Mundt 	"mov.l	%R1,%2\n\t" \
185f15cbe6fSPaul Mundt 	"mov.l	%S1,%T2\n\t" \
186f15cbe6fSPaul Mundt 	"2:\n" \
187f15cbe6fSPaul Mundt 	".section	.fixup,\"ax\"\n" \
188f15cbe6fSPaul Mundt 	"3:\n\t" \
189f15cbe6fSPaul Mundt 	"mov.l	4f,%0\n\t" \
190f15cbe6fSPaul Mundt 	"jmp	@%0\n\t" \
191f15cbe6fSPaul Mundt 	" mov	%3,%0\n\t" \
192f15cbe6fSPaul Mundt 	".balign	4\n" \
193f15cbe6fSPaul Mundt 	"4:	.long	2b\n\t" \
194f15cbe6fSPaul Mundt 	".previous\n" \
195f15cbe6fSPaul Mundt 	".section	__ex_table,\"a\"\n\t" \
196f15cbe6fSPaul Mundt 	".long	1b, 3b\n\t" \
197f15cbe6fSPaul Mundt 	".previous" \
198f15cbe6fSPaul Mundt 	: "=r" (retval) \
199f15cbe6fSPaul Mundt 	: "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \
200f15cbe6fSPaul Mundt         : "memory"); })
201f15cbe6fSPaul Mundt #else
202f15cbe6fSPaul Mundt #define __put_user_u64(val,addr,retval) \
203f15cbe6fSPaul Mundt ({ \
204f15cbe6fSPaul Mundt __asm__ __volatile__( \
205f15cbe6fSPaul Mundt 	"1:\n\t" \
206f15cbe6fSPaul Mundt 	"mov.l	%S1,%2\n\t" \
207f15cbe6fSPaul Mundt 	"mov.l	%R1,%T2\n\t" \
208f15cbe6fSPaul Mundt 	"2:\n" \
209f15cbe6fSPaul Mundt 	".section	.fixup,\"ax\"\n" \
210f15cbe6fSPaul Mundt 	"3:\n\t" \
211f15cbe6fSPaul Mundt 	"mov.l	4f,%0\n\t" \
212f15cbe6fSPaul Mundt 	"jmp	@%0\n\t" \
213f15cbe6fSPaul Mundt 	" mov	%3,%0\n\t" \
214f15cbe6fSPaul Mundt 	".balign	4\n" \
215f15cbe6fSPaul Mundt 	"4:	.long	2b\n\t" \
216f15cbe6fSPaul Mundt 	".previous\n" \
217f15cbe6fSPaul Mundt 	".section	__ex_table,\"a\"\n\t" \
218f15cbe6fSPaul Mundt 	".long	1b, 3b\n\t" \
219f15cbe6fSPaul Mundt 	".previous" \
220f15cbe6fSPaul Mundt 	: "=r" (retval) \
221f15cbe6fSPaul Mundt 	: "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \
222f15cbe6fSPaul Mundt         : "memory"); })
223f15cbe6fSPaul Mundt #endif
224f15cbe6fSPaul Mundt 
225f15cbe6fSPaul Mundt extern void __put_user_unknown(void);
226f15cbe6fSPaul Mundt 
227f15cbe6fSPaul Mundt #endif /* __ASM_SH_UACCESS_32_H */
228