Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[cascardo/linux.git] / arch / arm / lib / copy_to_user.S
1 /*
2  *  linux/arch/arm/lib/copy_to_user.S
3  *
4  *  Author:     Nicolas Pitre
5  *  Created:    Sep 29, 2005
6  *  Copyright:  MontaVista Software, Inc.
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 #include <asm/unwind.h>
16 #include <asm/export.h>
17
18 /*
19  * Prototype:
20  *
21  *      size_t arm_copy_to_user(void *to, const void *from, size_t n)
22  *
23  * Purpose:
24  *
25  *      copy a block to user memory from kernel memory
26  *
27  * Params:
28  *
29  *      to = user memory
30  *      from = kernel memory
31  *      n = number of bytes to copy
32  *
33  * Return value:
34  *
35  *      Number of bytes NOT copied.
36  */
37
38 #define LDR1W_SHIFT     0
39 #ifndef CONFIG_THUMB2_KERNEL
40 #define STR1W_SHIFT     0
41 #else
42 #define STR1W_SHIFT     1
43 #endif
44
45         .macro ldr1w ptr reg abort
46         W(ldr) \reg, [\ptr], #4
47         .endm
48
49         .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
50         ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
51         .endm
52
53         .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
54         ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
55         .endm
56
57         .macro ldr1b ptr reg cond=al abort
58         ldr\cond\()b \reg, [\ptr], #1
59         .endm
60
61         .macro str1w ptr reg abort
62         strusr  \reg, \ptr, 4, abort=\abort
63         .endm
64
65         .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
66         str1w \ptr, \reg1, \abort
67         str1w \ptr, \reg2, \abort
68         str1w \ptr, \reg3, \abort
69         str1w \ptr, \reg4, \abort
70         str1w \ptr, \reg5, \abort
71         str1w \ptr, \reg6, \abort
72         str1w \ptr, \reg7, \abort
73         str1w \ptr, \reg8, \abort
74         .endm
75
76         .macro str1b ptr reg cond=al abort
77         strusr  \reg, \ptr, 1, \cond, abort=\abort
78         .endm
79
80         .macro enter reg1 reg2
81         mov     r3, #0
82         stmdb   sp!, {r0, r2, r3, \reg1, \reg2}
83         .endm
84
85         .macro usave reg1 reg2
86         UNWIND( .save {r0, r2, r3, \reg1, \reg2}        )
87         .endm
88
89         .macro exit reg1 reg2
90         add     sp, sp, #8
91         ldmfd   sp!, {r0, \reg1, \reg2}
92         .endm
93
94         .text
95
96 ENTRY(__copy_to_user_std)
97 WEAK(arm_copy_to_user)
98
99 #include "copy_template.S"
100
101 ENDPROC(arm_copy_to_user)
102 ENDPROC(__copy_to_user_std)
103 #ifndef CONFIG_UACCESS_WITH_MEMCPY
104 EXPORT_SYMBOL(arm_copy_to_user)
105 #endif
106
107         .pushsection .text.fixup,"ax"
108         .align 0
109         copy_abort_preamble
110         ldmfd   sp!, {r1, r2, r3}
111         sub     r0, r0, r1
112         rsb     r0, r0, r2
113         copy_abort_end
114         .popsection
115