aboutsummaryrefslogtreecommitdiffstats
path: root/arch/unicore32
diff options
context:
space:
mode:
authorGuanXuetao <gxt@mprc.pku.edu.cn>2011-02-26 05:49:26 -0500
committerGuanXuetao <gxt@mprc.pku.edu.cn>2011-03-16 21:19:13 -0400
commit77c93b2f2388b974253af4149aa025b4751f92ad (patch)
tree59b3c67518e2cae1f347a2c2bc738a234b349bb4 /arch/unicore32
parent28bab059a23aac6bb129b307410e5b63e132a290 (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.h47
-rw-r--r--arch/unicore32/lib/clear_user.S57
-rw-r--r--arch/unicore32/lib/copy_from_user.S108
-rw-r--r--arch/unicore32/lib/copy_page.S39
-rw-r--r--arch/unicore32/lib/copy_template.S214
-rw-r--r--arch/unicore32/lib/copy_to_user.S96
-rw-r--r--arch/unicore32/lib/strncpy_from_user.S45
-rw-r--r--arch/unicore32/lib/strnlen_user.S42
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
32extern unsigned long __must_check
33__copy_from_user(void *to, const void __user *from, unsigned long n);
34extern unsigned long __must_check
35__copy_to_user(void __user *to, const void *from, unsigned long n);
36extern unsigned long __must_check
37__clear_user(void __user *addr, unsigned long n);
38extern unsigned long __must_check
39__strncpy_from_user(char *to, const char __user *from, unsigned long count);
40extern unsigned long
41__strnlen_user(const char __user *s, long n);
42
43#include <asm-generic/uaccess.h>
44
45extern 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 */
23WEAK(__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
371: 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
422: 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
46USER( stb.u r2, [r0])
473: mov r0, #0
48 ldm.w (r1), [sp]+
49 ldm.w (pc), [sp]+
50ENDPROC(__clear_user)
51
52 .pushsection .fixup,"ax"
53 .align 0
549001: 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
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
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 */
26ENTRY(copy_page)
27 stm.w (r17 - r19, lr), [sp-]
28 mov r17, r0
29 mov r18, r1
30 mov r19, #COPY_COUNT
311:
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]+
39ENDPROC(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
701: sub.a r2, r2, #(28)
71 stm.w (r5 - r8), [sp-]
72 bsl 5f
73
743:
754: 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
805: 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
1057: ldm.w (r5 - r8), [sp]+
106
1078: 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
1179: 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
13010: 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
14211: stm.w (r5 - r9), [sp-]
143
14412:
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
16914: and.a ip, r2, #28
170 beq 16f
171
17215: 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
17916: sub r1, r1, #(\b / 8)
180 b 8b
181
182 .endm
183
184
185 forward_copy_shift a=8 b=24
186
18717: forward_copy_shift a=16 b=16
188
18918: 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
20019: ldm.w (r5 - r9), [sp]+
201 b 21f
202299: .word 0 @ store lr
203 @ to avoid function call in fixup
20420: ldm.w (r5 - r8), [sp]+
20521:
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
58100: 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
82WEAK(__copy_to_user)
83
84#include "copy_template.S"
85
86ENDPROC(__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 */
25ENTRY(__strncpy_from_user)
26 mov ip, r1
271: 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
342: sub r0, r1, ip
35 mov pc, lr
36ENDPROC(__strncpy_from_user)
37
38 .pushsection .fixup,"ax"
39 .align 0
409001: 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 */
25ENTRY(__strnlen_user)
26 mov r2, r0
271:
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
342: sub r0, r0, r2
35 mov pc, lr
36ENDPROC(__strnlen_user)
37
38 .pushsection .fixup,"ax"
39 .align 0
409001: mov r0, #0
41 mov pc, lr
42 .popsection