Pull ar-k0-usage into release branch
[linux-2.6] / include / asm-arm26 / uaccess-asm.h
1 /*
2  *  linux/include/asm-arm/proc-armo/uaccess.h
3  *
4  *  Copyright (C) 1996 Russell King
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 as
8  * published by the Free Software Foundation.
9  */
10
11 /*
12  * The fs functions are implemented on the ARM2 and ARM3 architectures
13  * manually.
14  * Use *_user functions to access user memory with faulting behaving
15  *   as though the user is accessing the memory.
16  * Use set_fs(get_ds()) and then the *_user functions to allow them to
17  *   access kernel memory.
18  */
19
20 /*
21  * These are the values used to represent the user `fs' and the kernel `ds'
22  * FIXME - the KERNEL_DS should end at 0x03000000 but we want to access ROM at
23  * 0x03400000. ideally we want to forbid access to the IO space inbetween.
24  */
25 #define KERNEL_DS       0x03FFFFFF
26 #define USER_DS         0x02000000
27
28 extern uaccess_t uaccess_user, uaccess_kernel;
29
30 static inline void set_fs (mm_segment_t fs)
31 {
32         current_thread_info()->addr_limit = fs;
33         current->thread.uaccess = (fs == USER_DS ? &uaccess_user : &uaccess_kernel);
34 }
35
36 #define __range_ok(addr,size) ({                                        \
37         unsigned long flag, sum;                                        \
38         __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \
39                 : "=&r" (flag), "=&r" (sum)                             \
40                 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit)      \
41                 : "cc");                                                \
42         flag; })
43
44 #define __addr_ok(addr) ({                                              \
45         unsigned long flag;                                             \
46         __asm__ __volatile__("cmp %2, %0; movlo %0, #0"                 \
47                 : "=&r" (flag)                                          \
48                 : "0" (current_thread_info()->addr_limit), "r" (addr)   \
49                 : "cc");                                                \
50         (flag == 0); })
51
52 #define __put_user_asm_byte(x,addr,err)                                 \
53         __asm__ __volatile__(                                           \
54         "       mov     r0, %1\n"                                       \
55         "       mov     r1, %2\n"                                       \
56         "       mov     r2, %0\n"                                       \
57         "       mov     lr, pc\n"                                       \
58         "       mov     pc, %3\n"                                       \
59         "       mov     %0, r2\n"                                       \
60         : "=r" (err)                                                    \
61         : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \
62           "0" (err)                                                     \
63         : "r0", "r1", "r2", "lr")
64
65 #define __put_user_asm_half(x,addr,err)                                 \
66         __asm__ __volatile__(                                           \
67         "       mov     r0, %1\n"                                       \
68         "       mov     r1, %2\n"                                       \
69         "       mov     r2, %0\n"                                       \
70         "       mov     lr, pc\n"                                       \
71         "       mov     pc, %3\n"                                       \
72         "       mov     %0, r2\n"                                       \
73         : "=r" (err)                                                    \
74         : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \
75           "0" (err)                                                     \
76         : "r0", "r1", "r2", "lr")
77
78 #define __put_user_asm_word(x,addr,err)                                 \
79         __asm__ __volatile__(                                           \
80         "       mov     r0, %1\n"                                       \
81         "       mov     r1, %2\n"                                       \
82         "       mov     r2, %0\n"                                       \
83         "       mov     lr, pc\n"                                       \
84         "       mov     pc, %3\n"                                       \
85         "       mov     %0, r2\n"                                       \
86         : "=r" (err)                                                    \
87         : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \
88           "0" (err)                                                     \
89         : "r0", "r1", "r2", "lr")
90
91 #define __put_user_asm_dword(x,addr,err)                                 \
92         __asm__ __volatile__(                                           \
93         "       mov     r0, %1\n"                                       \
94         "       mov     r1, %2\n"                                       \
95         "       mov     r2, %0\n"                                       \
96         "       mov     lr, pc\n"                                       \
97         "       mov     pc, %3\n"                                       \
98         "       mov     %0, r2\n"                                       \
99         : "=r" (err)                                                    \
100         : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_dword), \
101           "0" (err)                                                     \
102         : "r0", "r1", "r2", "lr")
103
104 #define __get_user_asm_byte(x,addr,err)                                 \
105         __asm__ __volatile__(                                           \
106         "       mov     r0, %2\n"                                       \
107         "       mov     r1, %0\n"                                       \
108         "       mov     lr, pc\n"                                       \
109         "       mov     pc, %3\n"                                       \
110         "       mov     %0, r1\n"                                       \
111         "       mov     %1, r0\n"                                       \
112         : "=r" (err), "=r" (x)                                          \
113         : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err)        \
114         : "r0", "r1", "r2", "lr")
115
116 #define __get_user_asm_half(x,addr,err)                                 \
117         __asm__ __volatile__(                                           \
118         "       mov     r0, %2\n"                                       \
119         "       mov     r1, %0\n"                                       \
120         "       mov     lr, pc\n"                                       \
121         "       mov     pc, %3\n"                                       \
122         "       mov     %0, r1\n"                                       \
123         "       mov     %1, r0\n"                                       \
124         : "=r" (err), "=r" (x)                                          \
125         : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err)        \
126         : "r0", "r1", "r2", "lr")
127
128 #define __get_user_asm_word(x,addr,err)                                 \
129         __asm__ __volatile__(                                           \
130         "       mov     r0, %2\n"                                       \
131         "       mov     r1, %0\n"                                       \
132         "       mov     lr, pc\n"                                       \
133         "       mov     pc, %3\n"                                       \
134         "       mov     %0, r1\n"                                       \
135         "       mov     %1, r0\n"                                       \
136         : "=r" (err), "=r" (x)                                          \
137         : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err)        \
138         : "r0", "r1", "r2", "lr")
139
140 #define __do_copy_from_user(to,from,n)                                  \
141         (n) = current->thread.uaccess->copy_from_user((to),(from),(n))
142
143 #define __do_copy_to_user(to,from,n)                                    \
144         (n) = current->thread.uaccess->copy_to_user((to),(from),(n))
145
146 #define __do_clear_user(addr,sz)                                        \
147         (sz) = current->thread.uaccess->clear_user((addr),(sz))
148
149 #define __do_strncpy_from_user(dst,src,count,res)                       \
150         (res) = current->thread.uaccess->strncpy_from_user(dst,src,count)
151
152 #define __do_strnlen_user(s,n,res)                                      \
153         (res) = current->thread.uaccess->strnlen_user(s,n)