1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/err.h>
27#include <linux/init.h>
28#include <linux/linkage.h>
29
30#include <asm/asmmacro.h>
31#include <asm/thread_info.h>
32#include <asm/unistd.h>
33
34
35
36
37.macro disable_irq
38 mfcr r8, cr0
39 srli r8, r8, 1
40 slli r8, r8, 1
41 mtcr r8, cr0
42 nop
43 nop
44 nop
45 nop
46 nop
47.endm
48
49
50
51
52.macro enable_irq
53 mfcr r8, cr0
54 ori r8, 1
55 mtcr r8, cr0
56 nop
57 nop
58 nop
59 nop
60 nop
61.endm
62
63__INIT
64ENTRY(debug_exception_vector)
65 nop!
66 nop!
67 nop!
68 nop!
69 nop!
70 nop!
71 nop!
72 nop!
73
74ENTRY(general_exception_vector)
75 j general_exception
76 nop!
77 nop!
78 nop!
79 nop!
80 nop!
81 nop!
82
83ENTRY(interrupt_exception_vector)
84 j interrupt_exception
85 nop!
86 nop!
87 nop!
88 nop!
89 nop!
90 nop!
91
92 .section ".text", "ax"
93 .align 2;
94general_exception:
95 mfcr r31, cr2
96 nop
97 la r30, exception_handlers
98 andi r31, 0x1f
99 slli r31, r31, 2
100 add r30, r30, r31
101 lw r30, [r30]
102 br r30
103
104interrupt_exception:
105 SAVE_ALL
106 mfcr r4, cr2
107 nop
108 lw r16, [r28, TI_REGS]
109 sw r0, [r28, TI_REGS]
110 la r3, ret_from_irq
111 srli r4, r4, 18
112 mv r5, r0
113 j do_IRQ
114
115ENTRY(handle_nmi)
116 SAVE_ALL
117 mv r4, r0
118 la r8, nmi_exception_handler
119 brl r8
120 j restore_all
121
122ENTRY(handle_adelinsn)
123 SAVE_ALL
124 mfcr r8, cr6
125 nop
126 nop
127 sw r8, [r0, PT_EMA]
128 mv r4, r0
129 la r8, do_adelinsn
130 brl r8
131 mv r4, r0
132 j ret_from_exception
133 nop
134
135ENTRY(handle_ibe)
136 SAVE_ALL
137 mv r4, r0
138 la r8, do_be
139 brl r8
140 mv r4, r0
141 j ret_from_exception
142 nop
143
144ENTRY(handle_pel)
145 SAVE_ALL
146 mv r4, r0
147 la r8, do_pel
148 brl r8
149 mv r4, r0
150 j ret_from_exception
151 nop
152
153ENTRY(handle_ccu)
154 SAVE_ALL
155 mv r4, r0
156 la r8, do_ccu
157 brl r8
158 mv r4, r0
159 j ret_from_exception
160 nop
161
162ENTRY(handle_ri)
163 SAVE_ALL
164 mv r4, r0
165 la r8, do_ri
166 brl r8
167 mv r4, r0
168 j ret_from_exception
169 nop
170
171ENTRY(handle_tr)
172 SAVE_ALL
173 mv r4, r0
174 la r8, do_tr
175 brl r8
176 mv r4, r0
177 j ret_from_exception
178 nop
179
180ENTRY(handle_adedata)
181 SAVE_ALL
182 mfcr r8, cr6
183 nop
184 nop
185 sw r8, [r0, PT_EMA]
186 mv r4, r0
187 la r8, do_adedata
188 brl r8
189 mv r4, r0
190 j ret_from_exception
191 nop
192
193ENTRY(handle_cee)
194 SAVE_ALL
195 mv r4, r0
196 la r8, do_cee
197 brl r8
198 mv r4, r0
199 j ret_from_exception
200 nop
201
202ENTRY(handle_cpe)
203 SAVE_ALL
204 mv r4, r0
205 la r8, do_cpe
206 brl r8
207 mv r4, r0
208 j ret_from_exception
209 nop
210
211ENTRY(handle_dbe)
212 SAVE_ALL
213 mv r4, r0
214 la r8, do_be
215 brl r8
216 mv r4, r0
217 j ret_from_exception
218 nop
219
220ENTRY(handle_reserved)
221 SAVE_ALL
222 mv r4, r0
223 la r8, do_reserved
224 brl r8
225 mv r4, r0
226 j ret_from_exception
227 nop
228
229#ifndef CONFIG_PREEMPT
230#define resume_kernel restore_all
231#else
232#define __ret_from_irq ret_from_exception
233#endif
234
235 .align 2
236#ifndef CONFIG_PREEMPT
237ENTRY(ret_from_exception)
238 disable_irq
239 nop
240 j __ret_from_irq
241 nop
242#endif
243
244ENTRY(ret_from_irq)
245 sw r16, [r28, TI_REGS]
246
247ENTRY(__ret_from_irq)
248 lw r8, [r0, PT_PSR]
249 andri.c r8, r8, KU_USER
250 beq resume_kernel
251
252resume_userspace:
253 disable_irq
254 lw r6, [r28, TI_FLAGS]
255 li r8, _TIF_WORK_MASK
256 and.c r8, r8, r6
257 bne work_pending
258 nop
259 j restore_all
260 nop
261
262#ifdef CONFIG_PREEMPT
263resume_kernel:
264 disable_irq
265 lw r8, [r28, TI_PRE_COUNT]
266 cmpz.c r8
267 bne restore_all
268need_resched:
269 lw r8, [r28, TI_FLAGS]
270 andri.c r9, r8, _TIF_NEED_RESCHED
271 beq restore_all
272 lw r8, [r28, PT_PSR]
273 andri.c r8, r8, 1
274 beq restore_all
275 bl preempt_schedule_irq
276 nop
277 j need_resched
278 nop
279#endif
280
281ENTRY(ret_from_kernel_thread)
282 bl schedule_tail
283 nop
284 mv r4, r13
285 brl r12
286 j syscall_exit
287
288ENTRY(ret_from_fork)
289 bl schedule_tail
290
291ENTRY(syscall_exit)
292 nop
293 disable_irq
294 lw r6, [r28, TI_FLAGS]
295 li r8, _TIF_WORK_MASK
296 and.c r8, r6, r8
297 bne syscall_exit_work
298
299ENTRY(restore_all)
300 RESTORE_ALL_AND_RET
301
302work_pending:
303 andri.c r8, r6, _TIF_NEED_RESCHED
304 beq work_notifysig
305work_resched:
306 bl schedule
307 nop
308 disable_irq
309 lw r6, [r28, TI_FLAGS]
310 li r8, _TIF_WORK_MASK
311 and.c r8, r6, r8
312
313 beq restore_all
314 andri.c r8, r6, _TIF_NEED_RESCHED
315 bne work_resched
316
317work_notifysig:
318 mv r4, r0
319 li r5, 0
320 bl do_notify_resume
321 nop
322 j resume_userspace
323 nop
324
325ENTRY(syscall_exit_work)
326 li r8, _TIF_SYSCALL_TRACE
327 and.c r8, r8, r6
328 beq work_pending
329 nop
330 enable_irq
331 mv r4, r0
332 li r5, 1
333 bl do_syscall_trace
334 nop
335 b resume_userspace
336 nop
337
338.macro save_context reg
339 sw r12, [\reg, THREAD_REG12];
340 sw r13, [\reg, THREAD_REG13];
341 sw r14, [\reg, THREAD_REG14];
342 sw r15, [\reg, THREAD_REG15];
343 sw r16, [\reg, THREAD_REG16];
344 sw r17, [\reg, THREAD_REG17];
345 sw r18, [\reg, THREAD_REG18];
346 sw r19, [\reg, THREAD_REG19];
347 sw r20, [\reg, THREAD_REG20];
348 sw r21, [\reg, THREAD_REG21];
349 sw r29, [\reg, THREAD_REG29];
350 sw r2, [\reg, THREAD_REG2];
351 sw r0, [\reg, THREAD_REG0]
352.endm
353
354.macro restore_context reg
355 lw r12, [\reg, THREAD_REG12];
356 lw r13, [\reg, THREAD_REG13];
357 lw r14, [\reg, THREAD_REG14];
358 lw r15, [\reg, THREAD_REG15];
359 lw r16, [\reg, THREAD_REG16];
360 lw r17, [\reg, THREAD_REG17];
361 lw r18, [\reg, THREAD_REG18];
362 lw r19, [\reg, THREAD_REG19];
363 lw r20, [\reg, THREAD_REG20];
364 lw r21, [\reg, THREAD_REG21];
365 lw r29, [\reg, THREAD_REG29];
366 lw r0, [\reg, THREAD_REG0];
367 lw r2, [\reg, THREAD_REG2];
368 lw r3, [\reg, THREAD_REG3]
369.endm
370
371
372
373
374
375ENTRY(resume)
376 mfcr r9, cr0
377 nop
378 nop
379 sw r9, [r4, THREAD_PSR]
380 save_context r4
381 sw r3, [r4, THREAD_REG3]
382
383 mv r28, r6
384 restore_context r5
385 mv r8, r6
386 addi r8, KERNEL_STACK_SIZE
387 subi r8, 32
388 la r9, kernelsp;
389 sw r8, [r9];
390
391 mfcr r9, cr0
392 ldis r7, 0x00ff
393 nop
394 and r9, r9, r7
395 lw r6, [r5, THREAD_PSR]
396 not r7, r7
397 and r6, r6, r7
398 or r6, r6, r9
399 mtcr r6, cr0
400 nop; nop; nop; nop; nop
401 br r3
402
403ENTRY(handle_sys)
404 SAVE_ALL
405 sw r8, [r0, 16]
406 sw r9, [r0, 20]
407 enable_irq
408
409 sw r4, [r0, PT_ORIG_R4]
410 sw r7, [r0, PT_ORIG_R7]
411 sw r27, [r0, PT_IS_SYSCALL]
412
413 lw r9, [r0, PT_EPC]
414 addi r9, 4
415 sw r9, [r0, PT_EPC]
416
417 cmpi.c r27, __NR_syscalls
418 bcs illegal_syscall
419
420 slli r8, r27, 2
421 la r11, sys_call_table
422 add r11, r11, r8
423 lw r10, [r11]
424
425 cmpz.c r10
426 beq illegal_syscall
427
428 lw r8, [r28, TI_FLAGS]
429 li r9, _TIF_SYSCALL_TRACE
430 and.c r8, r8, r9
431 bne syscall_trace_entry
432
433 brl r10
434
435 cmpi.c r4, 0
436 blt 1f
437 ldi r8, 0
438 sw r8, [r0, PT_R7]
439 b 2f
4401:
441 cmpi.c r4, -MAX_ERRNO - 1
442 ble 2f
443 ldi r8, 0x1;
444 sw r8, [r0, PT_R7]
445 neg r4, r4
4462:
447 sw r4, [r0, PT_R4]
448
449syscall_return:
450 disable_irq
451 lw r6, [r28, TI_FLAGS]
452 li r8, _TIF_WORK_MASK
453 and.c r8, r6, r8
454 bne syscall_return_work
455 j restore_all
456
457syscall_return_work:
458 j syscall_exit_work
459
460syscall_trace_entry:
461 mv r16, r10
462 mv r4, r0
463 li r5, 0
464 bl do_syscall_trace
465
466 mv r8, r16
467 lw r4, [r0, PT_R4]
468 lw r5, [r0, PT_R5]
469 lw r6, [r0, PT_R6]
470 lw r7, [r0, PT_R7]
471 brl r8
472
473 li r8, -MAX_ERRNO - 1
474 sw r8, [r0, PT_R7]
475
476 neg r4, r4
477 sw r4, [r0, PT_R0]
478
4791: sw r4, [r0, PT_R2]
480 j syscall_exit
481
482illegal_syscall:
483 ldi r4, -ENOSYS
484 sw r4, [r0, PT_ORIG_R4]
485 sw r4, [r0, PT_R4]
486 ldi r9, 1
487 sw r9, [r0, PT_R7]
488 j syscall_return
489
490ENTRY(sys_rt_sigreturn)
491 mv r4, r0
492 la r8, score_rt_sigreturn
493 br r8
494