diff options
author | GuanXuetao <gxt@mprc.pku.edu.cn> | 2011-02-26 05:49:26 -0500 |
---|---|---|
committer | GuanXuetao <gxt@mprc.pku.edu.cn> | 2011-03-16 21:19:13 -0400 |
commit | 77c93b2f2388b974253af4149aa025b4751f92ad (patch) | |
tree | 59b3c67518e2cae1f347a2c2bc738a234b349bb4 /arch/unicore32 | |
parent | 28bab059a23aac6bb129b307410e5b63e132a290 (diff) |
unicore32 additional architecture files: low-level lib: uaccess
This patch implements low-level uaccess libraries.
Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/unicore32')
-rw-r--r-- | arch/unicore32/include/asm/uaccess.h | 47 | ||||
-rw-r--r-- | arch/unicore32/lib/clear_user.S | 57 | ||||
-rw-r--r-- | arch/unicore32/lib/copy_from_user.S | 108 | ||||
-rw-r--r-- | arch/unicore32/lib/copy_page.S | 39 | ||||
-rw-r--r-- | arch/unicore32/lib/copy_template.S | 214 | ||||
-rw-r--r-- | arch/unicore32/lib/copy_to_user.S | 96 | ||||
-rw-r--r-- | arch/unicore32/lib/strncpy_from_user.S | 45 | ||||
-rw-r--r-- | arch/unicore32/lib/strnlen_user.S | 42 |
8 files changed, 648 insertions, 0 deletions
diff --git a/arch/unicore32/include/asm/uaccess.h b/arch/unicore32/include/asm/uaccess.h new file mode 100644 index 000000000000..2acda503a6d9 --- /dev/null +++ b/arch/unicore32/include/asm/uaccess.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/include/asm/uaccess.h | ||
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 | #ifndef __UNICORE_UACCESS_H__ | ||
13 | #define __UNICORE_UACCESS_H__ | ||
14 | |||
15 | #include <linux/thread_info.h> | ||
16 | #include <linux/errno.h> | ||
17 | |||
18 | #include <asm/memory.h> | ||
19 | #include <asm/system.h> | ||
20 | |||
21 | #define __copy_from_user __copy_from_user | ||
22 | #define __copy_to_user __copy_to_user | ||
23 | #define __strncpy_from_user __strncpy_from_user | ||
24 | #define __strnlen_user __strnlen_user | ||
25 | #define __clear_user __clear_user | ||
26 | |||
27 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) | ||
28 | #define __user_ok(addr, size) (((size) <= TASK_SIZE) \ | ||
29 | && ((addr) <= TASK_SIZE - (size))) | ||
30 | #define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size))) | ||
31 | |||
32 | extern unsigned long __must_check | ||
33 | __copy_from_user(void *to, const void __user *from, unsigned long n); | ||
34 | extern unsigned long __must_check | ||
35 | __copy_to_user(void __user *to, const void *from, unsigned long n); | ||
36 | extern unsigned long __must_check | ||
37 | __clear_user(void __user *addr, unsigned long n); | ||
38 | extern unsigned long __must_check | ||
39 | __strncpy_from_user(char *to, const char __user *from, unsigned long count); | ||
40 | extern unsigned long | ||
41 | __strnlen_user(const char __user *s, long n); | ||
42 | |||
43 | #include <asm-generic/uaccess.h> | ||
44 | |||
45 | extern int fixup_exception(struct pt_regs *regs); | ||
46 | |||
47 | #endif /* __UNICORE_UACCESS_H__ */ | ||
diff --git a/arch/unicore32/lib/clear_user.S b/arch/unicore32/lib/clear_user.S new file mode 100644 index 000000000000..20047f7224fd --- /dev/null +++ b/arch/unicore32/lib/clear_user.S | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/lib/clear_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 | #include <linux/linkage.h> | ||
13 | #include <asm/assembler.h> | ||
14 | |||
15 | .text | ||
16 | |||
17 | /* Prototype: int __clear_user(void *addr, size_t sz) | ||
18 | * Purpose : clear some user memory | ||
19 | * Params : addr - user memory address to clear | ||
20 | * : sz - number of bytes to clear | ||
21 | * Returns : number of bytes NOT cleared | ||
22 | */ | ||
23 | WEAK(__clear_user) | ||
24 | stm.w (lr), [sp-] | ||
25 | stm.w (r1), [sp-] | ||
26 | mov r2, #0 | ||
27 | csub.a r1, #4 | ||
28 | bsl 2f | ||
29 | and.a ip, r0, #3 | ||
30 | beq 1f | ||
31 | csub.a ip, #2 | ||
32 | strusr r2, r0, 1 | ||
33 | strusr r2, r0, 1, el | ||
34 | strusr r2, r0, 1, sl | ||
35 | rsub ip, ip, #4 | ||
36 | sub r1, r1, ip @ 7 6 5 4 3 2 1 | ||
37 | 1: sub.a r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 | ||
38 | strusr r2, r0, 4, ns, rept=2 | ||
39 | bns 1b | ||
40 | add.a r1, r1, #4 @ 3 2 1 0 -1 -2 -3 | ||
41 | strusr r2, r0, 4, ns | ||
42 | 2: cand.a r1, #2 @ 1x 1x 0x 0x 1x 1x 0x | ||
43 | strusr r2, r0, 1, ne, rept=2 | ||
44 | cand.a r1, #1 @ x1 x0 x1 x0 x1 x0 x1 | ||
45 | beq 3f | ||
46 | USER( stb.u r2, [r0]) | ||
47 | 3: mov r0, #0 | ||
48 | ldm.w (r1), [sp]+ | ||
49 | ldm.w (pc), [sp]+ | ||
50 | ENDPROC(__clear_user) | ||
51 | |||
52 | .pushsection .fixup,"ax" | ||
53 | .align 0 | ||
54 | 9001: ldm.w (r0), [sp]+ | ||
55 | ldm.w (pc), [sp]+ | ||
56 | .popsection | ||
57 | |||
diff --git a/arch/unicore32/lib/copy_from_user.S b/arch/unicore32/lib/copy_from_user.S new file mode 100644 index 000000000000..ab0767ea5dbd --- /dev/null +++ b/arch/unicore32/lib/copy_from_user.S | |||
@@ -0,0 +1,108 @@ | |||
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 | ||
41 | 100: 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 | ||
49 | 100: 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 | ||
73 | 201: stb.w \reg, [\ptr]+, #1 | ||
74 | 202: | ||
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 | |||
90 | ENTRY(__copy_from_user) | ||
91 | |||
92 | #include "copy_template.S" | ||
93 | |||
94 | ENDPROC(__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 | |||
diff --git a/arch/unicore32/lib/copy_page.S b/arch/unicore32/lib/copy_page.S new file mode 100644 index 000000000000..3a448d755ade --- /dev/null +++ b/arch/unicore32/lib/copy_page.S | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/lib/copy_page.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 | * ASM optimised string functions | ||
13 | */ | ||
14 | #include <linux/linkage.h> | ||
15 | #include <asm/assembler.h> | ||
16 | #include <generated/asm-offsets.h> | ||
17 | #include <asm/cache.h> | ||
18 | |||
19 | #define COPY_COUNT (PAGE_SZ/256) | ||
20 | |||
21 | .text | ||
22 | .align 5 | ||
23 | /* | ||
24 | * UniCore optimised copy_page routine | ||
25 | */ | ||
26 | ENTRY(copy_page) | ||
27 | stm.w (r17 - r19, lr), [sp-] | ||
28 | mov r17, r0 | ||
29 | mov r18, r1 | ||
30 | mov r19, #COPY_COUNT | ||
31 | 1: | ||
32 | .rept 4 | ||
33 | ldm.w (r0 - r15), [r18]+ | ||
34 | stm.w (r0 - r15), [r17]+ | ||
35 | .endr | ||
36 | sub.a r19, r19, #1 | ||
37 | bne 1b | ||
38 | ldm.w (r17 - r19, pc), [sp]+ | ||
39 | ENDPROC(copy_page) | ||
diff --git a/arch/unicore32/lib/copy_template.S b/arch/unicore32/lib/copy_template.S new file mode 100644 index 000000000000..524287fc0120 --- /dev/null +++ b/arch/unicore32/lib/copy_template.S | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/lib/copy_template.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 | /* | ||
14 | * Theory of operation | ||
15 | * ------------------- | ||
16 | * | ||
17 | * This file provides the core code for a forward memory copy used in | ||
18 | * the implementation of memcopy(), copy_to_user() and copy_from_user(). | ||
19 | * | ||
20 | * The including file must define the following accessor macros | ||
21 | * according to the need of the given function: | ||
22 | * | ||
23 | * ldr1w ptr reg abort | ||
24 | * | ||
25 | * This loads one word from 'ptr', stores it in 'reg' and increments | ||
26 | * 'ptr' to the next word. The 'abort' argument is used for fixup tables. | ||
27 | * | ||
28 | * ldr4w ptr reg1 reg2 reg3 reg4 abort | ||
29 | * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | ||
30 | * | ||
31 | * This loads four or eight words starting from 'ptr', stores them | ||
32 | * in provided registers and increments 'ptr' past those words. | ||
33 | * The'abort' argument is used for fixup tables. | ||
34 | * | ||
35 | * ldr1b ptr reg cond abort | ||
36 | * | ||
37 | * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte. | ||
38 | * It also must apply the condition code if provided, otherwise the | ||
39 | * "al" condition is assumed by default. | ||
40 | * | ||
41 | * str1w ptr reg abort | ||
42 | * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | ||
43 | * str1b ptr reg cond abort | ||
44 | * | ||
45 | * Same as their ldr* counterparts, but data is stored to 'ptr' location | ||
46 | * rather than being loaded. | ||
47 | * | ||
48 | * enter | ||
49 | * | ||
50 | * Preserve the provided registers on the stack plus any additional | ||
51 | * data as needed by the implementation including this code. Called | ||
52 | * upon code entry. | ||
53 | * | ||
54 | * exit | ||
55 | * | ||
56 | * Restore registers with the values previously saved with the | ||
57 | * 'preserv' macro. Called upon code termination. | ||
58 | */ | ||
59 | |||
60 | |||
61 | enter | ||
62 | |||
63 | sub.a r2, r2, #4 | ||
64 | bsl 8f | ||
65 | and.a ip, r0, #3 | ||
66 | bne 9f | ||
67 | and.a ip, r1, #3 | ||
68 | bne 10f | ||
69 | |||
70 | 1: sub.a r2, r2, #(28) | ||
71 | stm.w (r5 - r8), [sp-] | ||
72 | bsl 5f | ||
73 | |||
74 | 3: | ||
75 | 4: ldr8w r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f | ||
76 | sub.a r2, r2, #32 | ||
77 | str8w r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f | ||
78 | beg 3b | ||
79 | |||
80 | 5: and.a ip, r2, #28 | ||
81 | rsub ip, ip, #32 | ||
82 | beq 7f | ||
83 | add pc, pc, ip @ C is always clear here | ||
84 | nop | ||
85 | |||
86 | ldr1w r1, r3, abort=20f | ||
87 | ldr1w r1, r4, abort=20f | ||
88 | ldr1w r1, r5, abort=20f | ||
89 | ldr1w r1, r6, abort=20f | ||
90 | ldr1w r1, r7, abort=20f | ||
91 | ldr1w r1, r8, abort=20f | ||
92 | ldr1w r1, r11, abort=20f | ||
93 | |||
94 | add pc, pc, ip | ||
95 | nop | ||
96 | |||
97 | str1w r0, r3, abort=20f | ||
98 | str1w r0, r4, abort=20f | ||
99 | str1w r0, r5, abort=20f | ||
100 | str1w r0, r6, abort=20f | ||
101 | str1w r0, r7, abort=20f | ||
102 | str1w r0, r8, abort=20f | ||
103 | str1w r0, r11, abort=20f | ||
104 | |||
105 | 7: ldm.w (r5 - r8), [sp]+ | ||
106 | |||
107 | 8: mov.a r2, r2 << #31 | ||
108 | ldr1b r1, r3, ne, abort=21f | ||
109 | ldr1b r1, r4, ea, abort=21f | ||
110 | ldr1b r1, r10, ea, abort=21f | ||
111 | str1b r0, r3, ne, abort=21f | ||
112 | str1b r0, r4, ea, abort=21f | ||
113 | str1b r0, r10, ea, abort=21f | ||
114 | |||
115 | exit | ||
116 | |||
117 | 9: rsub ip, ip, #4 | ||
118 | csub.a ip, #2 | ||
119 | ldr1b r1, r3, sg, abort=21f | ||
120 | ldr1b r1, r4, eg, abort=21f | ||
121 | ldr1b r1, r11, abort=21f | ||
122 | str1b r0, r3, sg, abort=21f | ||
123 | str1b r0, r4, eg, abort=21f | ||
124 | sub.a r2, r2, ip | ||
125 | str1b r0, r11, abort=21f | ||
126 | bsl 8b | ||
127 | and.a ip, r1, #3 | ||
128 | beq 1b | ||
129 | |||
130 | 10: andn r1, r1, #3 | ||
131 | csub.a ip, #2 | ||
132 | ldr1w r1, r11, abort=21f | ||
133 | beq 17f | ||
134 | bsg 18f | ||
135 | |||
136 | |||
137 | .macro forward_copy_shift a b | ||
138 | |||
139 | sub.a r2, r2, #28 | ||
140 | bsl 14f | ||
141 | |||
142 | 11: stm.w (r5 - r9), [sp-] | ||
143 | |||
144 | 12: | ||
145 | ldr4w r1, r4, r5, r6, r7, abort=19f | ||
146 | mov r3, r11 pull #\a | ||
147 | sub.a r2, r2, #32 | ||
148 | ldr4w r1, r8, r9, r10, r11, abort=19f | ||
149 | or r3, r3, r4 push #\b | ||
150 | mov r4, r4 pull #\a | ||
151 | or r4, r4, r5 push #\b | ||
152 | mov r5, r5 pull #\a | ||
153 | or r5, r5, r6 push #\b | ||
154 | mov r6, r6 pull #\a | ||
155 | or r6, r6, r7 push #\b | ||
156 | mov r7, r7 pull #\a | ||
157 | or r7, r7, r8 push #\b | ||
158 | mov r8, r8 pull #\a | ||
159 | or r8, r8, r9 push #\b | ||
160 | mov r9, r9 pull #\a | ||
161 | or r9, r9, r10 push #\b | ||
162 | mov r10, r10 pull #\a | ||
163 | or r10, r10, r11 push #\b | ||
164 | str8w r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f | ||
165 | beg 12b | ||
166 | |||
167 | ldm.w (r5 - r9), [sp]+ | ||
168 | |||
169 | 14: and.a ip, r2, #28 | ||
170 | beq 16f | ||
171 | |||
172 | 15: mov r3, r11 pull #\a | ||
173 | ldr1w r1, r11, abort=21f | ||
174 | sub.a ip, ip, #4 | ||
175 | or r3, r3, r11 push #\b | ||
176 | str1w r0, r3, abort=21f | ||
177 | bsg 15b | ||
178 | |||
179 | 16: sub r1, r1, #(\b / 8) | ||
180 | b 8b | ||
181 | |||
182 | .endm | ||
183 | |||
184 | |||
185 | forward_copy_shift a=8 b=24 | ||
186 | |||
187 | 17: forward_copy_shift a=16 b=16 | ||
188 | |||
189 | 18: forward_copy_shift a=24 b=8 | ||
190 | |||
191 | |||
192 | /* | ||
193 | * Abort preamble and completion macros. | ||
194 | * If a fixup handler is required then those macros must surround it. | ||
195 | * It is assumed that the fixup code will handle the private part of | ||
196 | * the exit macro. | ||
197 | */ | ||
198 | |||
199 | .macro copy_abort_preamble | ||
200 | 19: ldm.w (r5 - r9), [sp]+ | ||
201 | b 21f | ||
202 | 299: .word 0 @ store lr | ||
203 | @ to avoid function call in fixup | ||
204 | 20: ldm.w (r5 - r8), [sp]+ | ||
205 | 21: | ||
206 | adr r1, 299b | ||
207 | stw lr, [r1] | ||
208 | .endm | ||
209 | |||
210 | .macro copy_abort_end | ||
211 | adr lr, 299b | ||
212 | ldw pc, [lr] | ||
213 | .endm | ||
214 | |||
diff --git a/arch/unicore32/lib/copy_to_user.S b/arch/unicore32/lib/copy_to_user.S new file mode 100644 index 000000000000..6e22151c840d --- /dev/null +++ b/arch/unicore32/lib/copy_to_user.S | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/lib/copy_to_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_to_user(void *to, const void *from, size_t n) | ||
20 | * | ||
21 | * Purpose: | ||
22 | * | ||
23 | * copy a block to user memory from kernel memory | ||
24 | * | ||
25 | * Params: | ||
26 | * | ||
27 | * to = user memory | ||
28 | * from = kernel 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 | ldw.w \reg, [\ptr]+, #4 | ||
38 | .endm | ||
39 | |||
40 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort | ||
41 | ldm.w (\reg1, \reg2, \reg3, \reg4), [\ptr]+ | ||
42 | .endm | ||
43 | |||
44 | .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | ||
45 | ldm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+ | ||
46 | .endm | ||
47 | |||
48 | .macro ldr1b ptr reg cond=al abort | ||
49 | notcond \cond, .+8 | ||
50 | ldb.w \reg, [\ptr]+, #1 | ||
51 | .endm | ||
52 | |||
53 | .macro str1w ptr reg abort | ||
54 | strusr \reg, \ptr, 4, abort=\abort | ||
55 | .endm | ||
56 | |||
57 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | ||
58 | 100: stm.w (\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8), [\ptr]+ | ||
59 | |||
60 | .pushsection __ex_table, "a" | ||
61 | .long 100b, \abort | ||
62 | .popsection | ||
63 | .endm | ||
64 | |||
65 | .macro str1b ptr reg cond=al abort | ||
66 | strusr \reg, \ptr, 1, \cond, abort=\abort | ||
67 | .endm | ||
68 | |||
69 | .macro enter | ||
70 | mov r3, #0 | ||
71 | stm.w (r0, r2, r3), [sp-] | ||
72 | .endm | ||
73 | |||
74 | .macro exit | ||
75 | add sp, sp, #8 | ||
76 | ldm.w (r0), [sp]+ | ||
77 | mov pc, lr | ||
78 | .endm | ||
79 | |||
80 | .text | ||
81 | |||
82 | WEAK(__copy_to_user) | ||
83 | |||
84 | #include "copy_template.S" | ||
85 | |||
86 | ENDPROC(__copy_to_user) | ||
87 | |||
88 | .pushsection .fixup,"ax" | ||
89 | .align 0 | ||
90 | copy_abort_preamble | ||
91 | ldm.w (r1, r2, r3), [sp]+ | ||
92 | sub r0, r0, r1 | ||
93 | rsub r0, r0, r2 | ||
94 | copy_abort_end | ||
95 | .popsection | ||
96 | |||
diff --git a/arch/unicore32/lib/strncpy_from_user.S b/arch/unicore32/lib/strncpy_from_user.S new file mode 100644 index 000000000000..ff6c304d5c7e --- /dev/null +++ b/arch/unicore32/lib/strncpy_from_user.S | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/lib/strncpy_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 | #include <linux/linkage.h> | ||
13 | #include <asm/assembler.h> | ||
14 | #include <asm/errno.h> | ||
15 | |||
16 | .text | ||
17 | .align 5 | ||
18 | |||
19 | /* | ||
20 | * Copy a string from user space to kernel space. | ||
21 | * r0 = dst, r1 = src, r2 = byte length | ||
22 | * returns the number of characters copied (strlen of copied string), | ||
23 | * -EFAULT on exception, or "len" if we fill the whole buffer | ||
24 | */ | ||
25 | ENTRY(__strncpy_from_user) | ||
26 | mov ip, r1 | ||
27 | 1: sub.a r2, r2, #1 | ||
28 | ldrusr r3, r1, 1, ns | ||
29 | bfs 2f | ||
30 | stb.w r3, [r0]+, #1 | ||
31 | cxor.a r3, #0 | ||
32 | bne 1b | ||
33 | sub r1, r1, #1 @ take NUL character out of count | ||
34 | 2: sub r0, r1, ip | ||
35 | mov pc, lr | ||
36 | ENDPROC(__strncpy_from_user) | ||
37 | |||
38 | .pushsection .fixup,"ax" | ||
39 | .align 0 | ||
40 | 9001: mov r3, #0 | ||
41 | stb r3, [r0+], #0 @ null terminate | ||
42 | mov r0, #-EFAULT | ||
43 | mov pc, lr | ||
44 | .popsection | ||
45 | |||
diff --git a/arch/unicore32/lib/strnlen_user.S b/arch/unicore32/lib/strnlen_user.S new file mode 100644 index 000000000000..75863030f21d --- /dev/null +++ b/arch/unicore32/lib/strnlen_user.S | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * linux/arch/unicore32/lib/strnlen_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 | #include <linux/linkage.h> | ||
13 | #include <asm/assembler.h> | ||
14 | #include <asm/errno.h> | ||
15 | |||
16 | .text | ||
17 | .align 5 | ||
18 | |||
19 | /* Prototype: unsigned long __strnlen_user(const char *str, long n) | ||
20 | * Purpose : get length of a string in user memory | ||
21 | * Params : str - address of string in user memory | ||
22 | * Returns : length of string *including terminator* | ||
23 | * or zero on exception, or n + 1 if too long | ||
24 | */ | ||
25 | ENTRY(__strnlen_user) | ||
26 | mov r2, r0 | ||
27 | 1: | ||
28 | ldrusr r3, r0, 1 | ||
29 | cxor.a r3, #0 | ||
30 | beq 2f | ||
31 | sub.a r1, r1, #1 | ||
32 | bne 1b | ||
33 | add r0, r0, #1 | ||
34 | 2: sub r0, r0, r2 | ||
35 | mov pc, lr | ||
36 | ENDPROC(__strnlen_user) | ||
37 | |||
38 | .pushsection .fixup,"ax" | ||
39 | .align 0 | ||
40 | 9001: mov r0, #0 | ||
41 | mov pc, lr | ||
42 | .popsection | ||