Commit | Line | Data |
---|---|---|
1da177e4 LT |
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) |