1/*
2 * linux/arch/unicore32/lib/copy_from_user.S
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * Prototype:
18 *
19 *	size_t __copy_from_user(void *to, const void *from, size_t n)
20 *
21 * Purpose:
22 *
23 *	copy a block to kernel memory from user memory
24 *
25 * Params:
26 *
27 *	to = kernel memory
28 *	from = user memory
29 *	n = number of bytes to copy
30 *
31 * Return value:
32 *
33 *	Number of bytes NOT copied.
34 */
35
36	.macro ldr1w ptr reg abort
37	ldrusr	\reg, \ptr, 4, abort=\abort
38	.endm
39
40	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
41100:	ldm.w	(\reg1, \reg2, \reg3, \reg4), [\ptr]+
42	.pushsection __ex_table, "a"
43	.align	3
44	.long 100b, \abort
45	.popsection
46	.endm
47
48	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
49100:	ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
50	.pushsection __ex_table, "a"
51	.align	3
52	.long 100b, \abort
53	.popsection
54	.endm
55
56	.macro ldr1b ptr reg cond=al abort
57	ldrusr	\reg, \ptr, 1, \cond, abort=\abort
58	.endm
59
60	.macro str1w ptr reg abort
61	stw.w \reg, [\ptr]+, #4
62	.endm
63
64	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
65	stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+
66	.endm
67
68	.macro str1b ptr reg cond=al abort
69	.ifnc	\cond, al
70	b\cond	201f
71	b	202f
72	.endif
73201:	stb.w \reg, [\ptr]+, #1
74202:
75	.endm
76
77	.macro enter
78	mov	r3, #0
79	stm.w	(r0, r2, r3), [sp-]
80	.endm
81
82	.macro exit
83	add	sp, sp, #8
84	ldm.w	(r0), [sp]+
85	mov	pc, lr
86	.endm
87
88	.text
89
90ENTRY(__copy_from_user)
91
92#include "copy_template.S"
93
94ENDPROC(__copy_from_user)
95
96	.pushsection .fixup,"ax"
97	.align 0
98	copy_abort_preamble
99	ldm.w	(r1, r2), [sp]+
100	sub	r3, r0, r1
101	rsub	r2, r3, r2
102	stw	r2, [sp]
103	mov	r1, #0
104	b.l	memset
105	ldw.w	r0, [sp]+, #4
106	copy_abort_end
107	.popsection
108
109