FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/fusu.S
1 /* $NetBSD: fusu.S,v 1.10 2003/12/01 13:34:44 rearnsha Exp $ */
2
3 /*-
4 * Copyright (c) 1996-1998 Mark Brinicombe.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Mark Brinicombe
18 * 4. The name of the company nor the name of the author may be used to
19 * endorse or promote products derived from this software without specific
20 * prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36 #include <machine/asm.h>
37 #include <machine/asmacros.h>
38 #include <machine/armreg.h>
39 #include "assym.s"
40 __FBSDID("$FreeBSD: releng/10.0/sys/arm/arm/fusu.S 248361 2013-03-16 02:48:49Z andrew $");
41
42 #ifdef _ARM_ARCH_6
43 #define GET_PCB(tmp) \
44 mrc p15, 0, tmp, c13, c0, 4; \
45 add tmp, tmp, #(PC_CURPCB)
46 #else
47 .Lcurpcb:
48 .word _C_LABEL(__pcpu) + PC_CURPCB
49 #define GET_PCB(tmp) \
50 ldr tmp, .Lcurpcb
51 #endif
52
53 /*
54 * fuword(caddr_t uaddr);
55 * Fetch an int from the user's address space.
56 */
57
58 ENTRY_NP(casuword32)
59 ENTRY(casuword)
60 GET_PCB(r3)
61 ldr r3, [r3]
62
63 #ifdef DIAGNOSTIC
64 teq r3, #0x00000000
65 beq .Lfusupcbfault
66 #endif
67 stmfd sp!, {r4, r5}
68 adr r4, .Lcasuwordfault
69 str r4, [r3, #PCB_ONFAULT]
70 ldrt r5, [r0]
71 cmp r5, r1
72 movne r0, r5
73 streqt r2, [r0]
74 moveq r0, r1
75 ldmfd sp!, {r4, r5}
76 mov r1, #0x00000000
77 str r1, [r3, #PCB_ONFAULT]
78 RET
79 END(casuword32)
80 END(casuword)
81
82 /*
83 * Handle faults from casuword. Clean up and return -1.
84 */
85
86 .Lcasuwordfault:
87 mov r0, #0x00000000
88 str r0, [r3, #PCB_ONFAULT]
89 mvn r0, #0x00000000
90 ldmfd sp!, {r4, r5}
91 RET
92
93 /*
94 * fuword(caddr_t uaddr);
95 * Fetch an int from the user's address space.
96 */
97
98 ENTRY_NP(fuword32)
99 ENTRY(fuword)
100 GET_PCB(r2)
101 ldr r2, [r2]
102
103 #ifdef DIAGNOSTIC
104 teq r2, #0x00000000
105 beq .Lfusupcbfault
106 #endif
107
108 adr r1, .Lfusufault
109 str r1, [r2, #PCB_ONFAULT]
110
111 ldrt r3, [r0]
112
113 mov r1, #0x00000000
114 str r1, [r2, #PCB_ONFAULT]
115 mov r0, r3
116 RET
117 END(fuword32)
118 END(fuword)
119
120 /*
121 * fusword(caddr_t uaddr);
122 * Fetch a short from the user's address space.
123 */
124
125 ENTRY(fusword)
126 GET_PCB(r2)
127 ldr r2, [r2]
128
129 #ifdef DIAGNOSTIC
130 teq r2, #0x00000000
131 beq .Lfusupcbfault
132 #endif
133
134 adr r1, .Lfusufault
135 str r1, [r2, #PCB_ONFAULT]
136
137 ldrbt r3, [r0], #1
138 ldrbt ip, [r0]
139 #ifdef __ARMEB__
140 orr r0, ip, r3, asl #8
141 #else
142 orr r0, r3, ip, asl #8
143 #endif
144 mov r1, #0x00000000
145 str r1, [r2, #PCB_ONFAULT]
146 RET
147 END(fusword)
148
149 /*
150 * fuswintr(caddr_t uaddr);
151 * Fetch a short from the user's address space. Can be called during an
152 * interrupt.
153 */
154
155 ENTRY(fuswintr)
156 ldr r2, Lblock_userspace_access
157 ldr r2, [r2]
158 teq r2, #0
159 mvnne r0, #0x00000000
160 RETne
161
162 GET_PCB(r2)
163 ldr r2, [r2]
164
165 #ifdef DIAGNOSTIC
166 teq r2, #0x00000000
167 beq .Lfusupcbfault
168 #endif
169
170 adr r1, _C_LABEL(fusubailout)
171 str r1, [r2, #PCB_ONFAULT]
172
173 ldrbt r3, [r0], #1
174 ldrbt ip, [r0]
175 #ifdef __ARMEB__
176 orr r0, ip, r3, asl #8
177 #else
178 orr r0, r3, ip, asl #8
179 #endif
180
181 mov r1, #0x00000000
182 str r1, [r2, #PCB_ONFAULT]
183 RET
184 END(fuswintr)
185
186 Lblock_userspace_access:
187 .word _C_LABEL(block_userspace_access)
188
189 .data
190 .align 0
191 .global _C_LABEL(block_userspace_access)
192 _C_LABEL(block_userspace_access):
193 .word 0
194 .text
195
196 /*
197 * fubyte(caddr_t uaddr);
198 * Fetch a byte from the user's address space.
199 */
200
201 ENTRY(fubyte)
202 GET_PCB(r2)
203 ldr r2, [r2]
204
205 #ifdef DIAGNOSTIC
206 teq r2, #0x00000000
207 beq .Lfusupcbfault
208 #endif
209
210 adr r1, .Lfusufault
211 str r1, [r2, #PCB_ONFAULT]
212
213 ldrbt r3, [r0]
214
215 mov r1, #0x00000000
216 str r1, [r2, #PCB_ONFAULT]
217 mov r0, r3
218 RET
219 END(fubyte)
220
221 /*
222 * Handle faults from [fs]u*(). Clean up and return -1.
223 */
224
225 .Lfusufault:
226 mov r0, #0x00000000
227 str r0, [r2, #PCB_ONFAULT]
228 mvn r0, #0x00000000
229 RET
230
231 /*
232 * Handle faults from [fs]u*(). Clean up and return -1. This differs from
233 * fusufault() in that trap() will recognise it and return immediately rather
234 * than trying to page fault.
235 */
236
237 /* label must be global as fault.c references it */
238 .global _C_LABEL(fusubailout)
239 _C_LABEL(fusubailout):
240 mov r0, #0x00000000
241 str r0, [r2, #PCB_ONFAULT]
242 mvn r0, #0x00000000
243 RET
244
245 #ifdef DIAGNOSTIC
246 /*
247 * Handle earlier faults from [fs]u*(), due to no pcb
248 */
249
250 .Lfusupcbfault:
251 mov r1, r0
252 adr r0, fusupcbfaulttext
253 b _C_LABEL(panic)
254
255 fusupcbfaulttext:
256 .asciz "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
257 .align 0
258 #endif
259
260 /*
261 * suword(caddr_t uaddr, int x);
262 * Store an int in the user's address space.
263 */
264
265 ENTRY_NP(suword32)
266 ENTRY(suword)
267 GET_PCB(r2)
268 ldr r2, [r2]
269
270 #ifdef DIAGNOSTIC
271 teq r2, #0x00000000
272 beq .Lfusupcbfault
273 #endif
274
275 adr r3, .Lfusufault
276 str r3, [r2, #PCB_ONFAULT]
277
278 strt r1, [r0]
279
280 mov r0, #0x00000000
281 str r0, [r2, #PCB_ONFAULT]
282 RET
283 END(suword32)
284 END(suword)
285
286 /*
287 * suswintr(caddr_t uaddr, short x);
288 * Store a short in the user's address space. Can be called during an
289 * interrupt.
290 */
291
292 ENTRY(suswintr)
293 ldr r2, Lblock_userspace_access
294 ldr r2, [r2]
295 teq r2, #0
296 mvnne r0, #0x00000000
297 RETne
298
299 GET_PCB(r2)
300 ldr r2, [r2]
301
302 #ifdef DIAGNOSTIC
303 teq r2, #0x00000000
304 beq .Lfusupcbfault
305 #endif
306
307 adr r3, _C_LABEL(fusubailout)
308 str r3, [r2, #PCB_ONFAULT]
309
310 #ifdef __ARMEB__
311 mov ip, r1, lsr #8
312 strbt ip, [r0], #1
313 #else
314 strbt r1, [r0], #1
315 mov r1, r1, lsr #8
316 #endif
317 strbt r1, [r0]
318
319 mov r0, #0x00000000
320 str r0, [r2, #PCB_ONFAULT]
321 RET
322 END(suswintr)
323
324 /*
325 * susword(caddr_t uaddr, short x);
326 * Store a short in the user's address space.
327 */
328
329 ENTRY(susword)
330 GET_PCB(r2)
331 ldr r2, [r2]
332
333 #ifdef DIAGNOSTIC
334 teq r2, #0x00000000
335 beq .Lfusupcbfault
336 #endif
337
338 adr r3, .Lfusufault
339 str r3, [r2, #PCB_ONFAULT]
340
341 #ifdef __ARMEB__
342 mov ip, r1, lsr #8
343 strbt ip, [r0], #1
344 #else
345 strbt r1, [r0], #1
346 mov r1, r1, lsr #8
347 #endif
348 strbt r1, [r0]
349
350 mov r0, #0x00000000
351 str r0, [r2, #PCB_ONFAULT]
352 RET
353 END(susword)
354
355 /*
356 * subyte(caddr_t uaddr, char x);
357 * Store a byte in the user's address space.
358 */
359
360 ENTRY(subyte)
361 GET_PCB(r2)
362 ldr r2, [r2]
363
364
365 #ifdef DIAGNOSTIC
366 teq r2, #0x00000000
367 beq .Lfusupcbfault
368 #endif
369
370 adr r3, .Lfusufault
371 str r3, [r2, #PCB_ONFAULT]
372
373 strbt r1, [r0]
374 mov r0, #0x00000000
375 str r0, [r2, #PCB_ONFAULT]
376 RET
377 END(subyte)
378
Cache object: 871f31a9c3890f1d50b650050d999071
|