Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[linux-2.6.git] / arch / hexagon / mm / copy_from_user.S
blob7fc94f3e66425b8d3020e808420cda7b9b78ba58
1 /*
2  * User memory copy functions for kernel
3  *
4  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 and
8  * only version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA.
19  */
22  * The right way to do this involves valignb
23  * The easy way to do this is only speed up src/dest similar alignment.
24  */
27  * Copy to/from user are the same, except that for packets with a load and
28  * a store, I don't know how to tell which kind of exception we got.
29  * Therefore, we duplicate the function, and handle faulting addresses
30  * differently for each function
31  */
34  * copy from user: loads can fault
35  */
36 #define src_sav r13
37 #define dst_sav r12
38 #define src_dst_sav r13:12
39 #define d_dbuf r15:14
40 #define w_dbuf r15
42 #define dst r0
43 #define src r1
44 #define bytes r2
45 #define loopcount r5
47 #define FUNCNAME __copy_from_user_hexagon
48 #include "copy_user_template.S"
50         /* LOAD FAULTS from COPY_FROM_USER */
52         /* Alignment loop.  r2 has been updated. Return it. */
53         .falign
54 1009:
55 2009:
56 4009:
57         {
58                 r0 = r2
59                 jumpr r31
60         }
61         /* Normal copy loops. Do epilog. Use src-src_sav to compute distance */
62         /* X - (A - B) == X + B - A */
63         .falign
64 8089:
65         {
66                 memd(dst) = d_dbuf
67                 r2 += sub(src_sav,src)
68         }
69         {
70                 r0 = r2
71                 jumpr r31
72         }
73         .falign
74 4089:
75         {
76                 memw(dst) = w_dbuf
77                 r2 += sub(src_sav,src)
78         }
79         {
80                 r0 = r2
81                 jumpr r31
82         }
83         .falign
84 2089:
85         {
86                 memh(dst) = w_dbuf
87                 r2 += sub(src_sav,src)
88         }
89         {
90                 r0 = r2
91                 jumpr r31
92         }
93         .falign
94 1089:
95         {
96                 memb(dst) = w_dbuf
97                 r2 += sub(src_sav,src)
98         }
99         {
100                 r0 = r2
101                 jumpr r31
102         }
104         /* COPY FROM USER: only loads can fail */
106         .section __ex_table,"a"
107         .long 1000b,1009b
108         .long 2000b,2009b
109         .long 4000b,4009b
110         .long 8080b,8089b
111         .long 4080b,4089b
112         .long 2080b,2089b
113         .long 1080b,1089b
114         .previous