18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/module.h>
88c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciunsigned long __generic_copy_from_user(void *to, const void __user *from,
118c2ecf20Sopenharmony_ci				       unsigned long n)
128c2ecf20Sopenharmony_ci{
138c2ecf20Sopenharmony_ci	unsigned long tmp, res;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	asm volatile ("\n"
168c2ecf20Sopenharmony_ci		"	tst.l	%0\n"
178c2ecf20Sopenharmony_ci		"	jeq	2f\n"
188c2ecf20Sopenharmony_ci		"1:	"MOVES".l	(%1)+,%3\n"
198c2ecf20Sopenharmony_ci		"	move.l	%3,(%2)+\n"
208c2ecf20Sopenharmony_ci		"	subq.l	#1,%0\n"
218c2ecf20Sopenharmony_ci		"	jne	1b\n"
228c2ecf20Sopenharmony_ci		"2:	btst	#1,%5\n"
238c2ecf20Sopenharmony_ci		"	jeq	4f\n"
248c2ecf20Sopenharmony_ci		"3:	"MOVES".w	(%1)+,%3\n"
258c2ecf20Sopenharmony_ci		"	move.w	%3,(%2)+\n"
268c2ecf20Sopenharmony_ci		"4:	btst	#0,%5\n"
278c2ecf20Sopenharmony_ci		"	jeq	6f\n"
288c2ecf20Sopenharmony_ci		"5:	"MOVES".b	(%1)+,%3\n"
298c2ecf20Sopenharmony_ci		"	move.b  %3,(%2)+\n"
308c2ecf20Sopenharmony_ci		"6:\n"
318c2ecf20Sopenharmony_ci		"	.section .fixup,\"ax\"\n"
328c2ecf20Sopenharmony_ci		"	.even\n"
338c2ecf20Sopenharmony_ci		"10:	lsl.l	#2,%0\n"
348c2ecf20Sopenharmony_ci		"	btst	#1,%5\n"
358c2ecf20Sopenharmony_ci		"	jeq	8f\n"
368c2ecf20Sopenharmony_ci		"30:	addq.l	#2,%0\n"
378c2ecf20Sopenharmony_ci		"8:	btst	#0,%5\n"
388c2ecf20Sopenharmony_ci		"	jeq	6b\n"
398c2ecf20Sopenharmony_ci		"50:	addq.l	#1,%0\n"
408c2ecf20Sopenharmony_ci		"	jra	6b\n"
418c2ecf20Sopenharmony_ci		"	.previous\n"
428c2ecf20Sopenharmony_ci		"\n"
438c2ecf20Sopenharmony_ci		"	.section __ex_table,\"a\"\n"
448c2ecf20Sopenharmony_ci		"	.align	4\n"
458c2ecf20Sopenharmony_ci		"	.long	1b,10b\n"
468c2ecf20Sopenharmony_ci		"	.long	3b,30b\n"
478c2ecf20Sopenharmony_ci		"	.long	5b,50b\n"
488c2ecf20Sopenharmony_ci		"	.previous"
498c2ecf20Sopenharmony_ci		: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
508c2ecf20Sopenharmony_ci		: "0" (n / 4), "d" (n & 3));
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	return res;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__generic_copy_from_user);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciunsigned long __generic_copy_to_user(void __user *to, const void *from,
578c2ecf20Sopenharmony_ci				     unsigned long n)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	unsigned long tmp, res;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	asm volatile ("\n"
628c2ecf20Sopenharmony_ci		"	tst.l	%0\n"
638c2ecf20Sopenharmony_ci		"	jeq	4f\n"
648c2ecf20Sopenharmony_ci		"1:	move.l	(%1)+,%3\n"
658c2ecf20Sopenharmony_ci		"2:	"MOVES".l	%3,(%2)+\n"
668c2ecf20Sopenharmony_ci		"3:	subq.l	#1,%0\n"
678c2ecf20Sopenharmony_ci		"	jne	1b\n"
688c2ecf20Sopenharmony_ci		"4:	btst	#1,%5\n"
698c2ecf20Sopenharmony_ci		"	jeq	6f\n"
708c2ecf20Sopenharmony_ci		"	move.w	(%1)+,%3\n"
718c2ecf20Sopenharmony_ci		"5:	"MOVES".w	%3,(%2)+\n"
728c2ecf20Sopenharmony_ci		"6:	btst	#0,%5\n"
738c2ecf20Sopenharmony_ci		"	jeq	8f\n"
748c2ecf20Sopenharmony_ci		"	move.b	(%1)+,%3\n"
758c2ecf20Sopenharmony_ci		"7:	"MOVES".b  %3,(%2)+\n"
768c2ecf20Sopenharmony_ci		"8:\n"
778c2ecf20Sopenharmony_ci		"	.section .fixup,\"ax\"\n"
788c2ecf20Sopenharmony_ci		"	.even\n"
798c2ecf20Sopenharmony_ci		"20:	lsl.l	#2,%0\n"
808c2ecf20Sopenharmony_ci		"50:	add.l	%5,%0\n"
818c2ecf20Sopenharmony_ci		"	jra	8b\n"
828c2ecf20Sopenharmony_ci		"	.previous\n"
838c2ecf20Sopenharmony_ci		"\n"
848c2ecf20Sopenharmony_ci		"	.section __ex_table,\"a\"\n"
858c2ecf20Sopenharmony_ci		"	.align	4\n"
868c2ecf20Sopenharmony_ci		"	.long	2b,20b\n"
878c2ecf20Sopenharmony_ci		"	.long	3b,20b\n"
888c2ecf20Sopenharmony_ci		"	.long	5b,50b\n"
898c2ecf20Sopenharmony_ci		"	.long	6b,50b\n"
908c2ecf20Sopenharmony_ci		"	.long	7b,50b\n"
918c2ecf20Sopenharmony_ci		"	.long	8b,50b\n"
928c2ecf20Sopenharmony_ci		"	.previous"
938c2ecf20Sopenharmony_ci		: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
948c2ecf20Sopenharmony_ci		: "0" (n / 4), "d" (n & 3));
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	return res;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__generic_copy_to_user);
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci/*
1018c2ecf20Sopenharmony_ci * Zero Userspace
1028c2ecf20Sopenharmony_ci */
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ciunsigned long __clear_user(void __user *to, unsigned long n)
1058c2ecf20Sopenharmony_ci{
1068c2ecf20Sopenharmony_ci	unsigned long res;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	asm volatile ("\n"
1098c2ecf20Sopenharmony_ci		"	tst.l	%0\n"
1108c2ecf20Sopenharmony_ci		"	jeq	3f\n"
1118c2ecf20Sopenharmony_ci		"1:	"MOVES".l	%2,(%1)+\n"
1128c2ecf20Sopenharmony_ci		"2:	subq.l	#1,%0\n"
1138c2ecf20Sopenharmony_ci		"	jne	1b\n"
1148c2ecf20Sopenharmony_ci		"3:	btst	#1,%4\n"
1158c2ecf20Sopenharmony_ci		"	jeq	5f\n"
1168c2ecf20Sopenharmony_ci		"4:	"MOVES".w	%2,(%1)+\n"
1178c2ecf20Sopenharmony_ci		"5:	btst	#0,%4\n"
1188c2ecf20Sopenharmony_ci		"	jeq	7f\n"
1198c2ecf20Sopenharmony_ci		"6:	"MOVES".b	%2,(%1)\n"
1208c2ecf20Sopenharmony_ci		"7:\n"
1218c2ecf20Sopenharmony_ci		"	.section .fixup,\"ax\"\n"
1228c2ecf20Sopenharmony_ci		"	.even\n"
1238c2ecf20Sopenharmony_ci		"10:	lsl.l	#2,%0\n"
1248c2ecf20Sopenharmony_ci		"40:	add.l	%4,%0\n"
1258c2ecf20Sopenharmony_ci		"	jra	7b\n"
1268c2ecf20Sopenharmony_ci		"	.previous\n"
1278c2ecf20Sopenharmony_ci		"\n"
1288c2ecf20Sopenharmony_ci		"	.section __ex_table,\"a\"\n"
1298c2ecf20Sopenharmony_ci		"	.align	4\n"
1308c2ecf20Sopenharmony_ci		"	.long	1b,10b\n"
1318c2ecf20Sopenharmony_ci		"	.long	2b,10b\n"
1328c2ecf20Sopenharmony_ci		"	.long	4b,40b\n"
1338c2ecf20Sopenharmony_ci		"	.long	5b,40b\n"
1348c2ecf20Sopenharmony_ci		"	.long	6b,40b\n"
1358c2ecf20Sopenharmony_ci		"	.long	7b,40b\n"
1368c2ecf20Sopenharmony_ci		"	.previous"
1378c2ecf20Sopenharmony_ci		: "=d" (res), "+a" (to)
1388c2ecf20Sopenharmony_ci		: "d" (0), "0" (n / 4), "d" (n & 3));
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci    return res;
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__clear_user);
143