Merge ../linux-2.6
[linux-2.6] / arch / m32r / kernel / entry.S
1 /*
2  *  linux/arch/m32r/kernel/entry.S
3  *
4  *  Copyright (c) 2001, 2002  Hirokazu Takata, Hitoshi Yamamoto, H. Kondo
5  *  Copyright (c) 2003  Hitoshi Yamamoto
6  *  Copyright (c) 2004  Hirokazu Takata <takata at linux-m32r.org>
7  *
8  *  Taken from i386 version.
9  *    Copyright (C) 1991, 1992  Linus Torvalds
10  */
11
12 /*
13  * entry.S contains the system-call and fault low-level handling routines.
14  * This also contains the timer-interrupt handler, as well as all interrupts
15  * and faults that can result in a task-switch.
16  *
17  * NOTE: This code handles signal-recognition, which happens every time
18  * after a timer-interrupt and after each system call.
19  *
20  * Stack layout in 'ret_from_system_call':
21  *      ptrace needs to have all regs on the stack.
22  *      if the order here is changed, it needs to be
23  *      updated in fork.c:copy_thread, signal.c:do_signal,
24  *      ptrace.c and ptrace.h
25  *
26  * M32Rx/M32R2                          M32R
27  *       @(sp)      - r4                ditto
28  *       @(0x04,sp) - r5                ditto
29  *       @(0x08,sp) - r6                ditto
30  *       @(0x0c,sp) - *pt_regs          ditto
31  *       @(0x10,sp) - r0                ditto
32  *       @(0x14,sp) - r1                ditto
33  *       @(0x18,sp) - r2                ditto
34  *       @(0x1c,sp) - r3                ditto
35  *       @(0x20,sp) - r7                ditto
36  *       @(0x24,sp) - r8                ditto
37  *       @(0x28,sp) - r9                ditto
38  *       @(0x2c,sp) - r10               ditto
39  *       @(0x30,sp) - r11               ditto
40  *       @(0x34,sp) - r12               ditto
41  *       @(0x38,sp) - syscall_nr        ditto
42  *       @(0x3c,sp) - acc0h             @(0x3c,sp) - acch
43  *       @(0x40,sp) - acc0l             @(0x40,sp) - accl
44  *       @(0x44,sp) - acc1h             @(0x44,sp) - dummy_acc1h
45  *       @(0x48,sp) - acc1l             @(0x48,sp) - dummy_acc1l
46  *       @(0x4c,sp) - psw               ditto
47  *       @(0x50,sp) - bpc               ditto
48  *       @(0x54,sp) - bbpsw             ditto
49  *       @(0x58,sp) - bbpc              ditto
50  *       @(0x5c,sp) - spu (cr3)         ditto
51  *       @(0x60,sp) - fp (r13)          ditto
52  *       @(0x64,sp) - lr (r14)          ditto
53  *       @(0x68,sp) - spi (cr2)         ditto
54  *       @(0x6c,sp) - orig_r0           ditto
55  */
56
57 #include <linux/config.h>
58 #include <linux/linkage.h>
59 #include <asm/irq.h>
60 #include <asm/unistd.h>
61 #include <asm/assembler.h>
62 #include <asm/thread_info.h>
63 #include <asm/errno.h>
64 #include <asm/segment.h>
65 #include <asm/smp.h>
66 #include <asm/page.h>
67 #include <asm/m32r.h>
68 #include <asm/mmu_context.h>
69
70 #if !defined(CONFIG_MMU)
71 #define sys_madvise             sys_ni_syscall
72 #define sys_readahead           sys_ni_syscall
73 #define sys_mprotect            sys_ni_syscall
74 #define sys_msync               sys_ni_syscall
75 #define sys_mlock               sys_ni_syscall
76 #define sys_munlock             sys_ni_syscall
77 #define sys_mlockall            sys_ni_syscall
78 #define sys_munlockall          sys_ni_syscall
79 #define sys_mremap              sys_ni_syscall
80 #define sys_mincore             sys_ni_syscall
81 #define sys_remap_file_pages    sys_ni_syscall
82 #endif /* CONFIG_MMU */
83
84 #define R4(reg)                 @reg
85 #define R5(reg)                 @(0x04,reg)
86 #define R6(reg)                 @(0x08,reg)
87 #define PTREGS(reg)             @(0x0C,reg)
88 #define R0(reg)                 @(0x10,reg)
89 #define R1(reg)                 @(0x14,reg)
90 #define R2(reg)                 @(0x18,reg)
91 #define R3(reg)                 @(0x1C,reg)
92 #define R7(reg)                 @(0x20,reg)
93 #define R8(reg)                 @(0x24,reg)
94 #define R9(reg)                 @(0x28,reg)
95 #define R10(reg)                @(0x2C,reg)
96 #define R11(reg)                @(0x30,reg)
97 #define R12(reg)                @(0x34,reg)
98 #define SYSCALL_NR(reg)         @(0x38,reg)
99 #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
100 #define ACC0H(reg)              @(0x3C,reg)
101 #define ACC0L(reg)              @(0x40,reg)
102 #define ACC1H(reg)              @(0x44,reg)
103 #define ACC1L(reg)              @(0x48,reg)
104 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
105 #define ACCH(reg)               @(0x3C,reg)
106 #define ACCL(reg)               @(0x40,reg)
107 #else
108 #error unknown isa configuration
109 #endif
110 #define PSW(reg)                @(0x4C,reg)
111 #define BPC(reg)                @(0x50,reg)
112 #define BBPSW(reg)              @(0x54,reg)
113 #define BBPC(reg)               @(0x58,reg)
114 #define SPU(reg)                @(0x5C,reg)
115 #define FP(reg)                 @(0x60,reg)  /* FP = R13 */
116 #define LR(reg)                 @(0x64,reg)
117 #define SP(reg)                 @(0x68,reg)
118 #define ORIG_R0(reg)            @(0x6C,reg)
119
120 CF_MASK         = 0x00000001
121 TF_MASK         = 0x00000100
122 IF_MASK         = 0x00000200
123 DF_MASK         = 0x00000400
124 NT_MASK         = 0x00004000
125 VM_MASK         = 0x00020000
126
127 #ifdef CONFIG_PREEMPT
128 #define preempt_stop(x)         CLI(x)
129 #else
130 #define preempt_stop(x)
131 #define resume_kernel           restore_all
132 #endif
133
134 ENTRY(ret_from_fork)
135         pop     r0
136         bl      schedule_tail
137         GET_THREAD_INFO(r8)
138         bra     syscall_exit
139
140 /*
141  * Return to user mode is not as complex as all this looks,
142  * but we want the default path for a system call return to
143  * go as quickly as possible which is why some of this is
144  * less clear than it otherwise should be.
145  */
146
147         ; userspace resumption stub bypassing syscall exit tracing
148         ALIGN
149 ret_from_exception:
150         preempt_stop(r4)
151 ret_from_intr:
152         ld      r4, PSW(sp)
153 #ifdef CONFIG_ISA_M32R2
154         and3    r4, r4, #0x8800         ; check BSM and BPM bits
155 #else
156         and3    r4, r4, #0x8000         ; check BSM bit
157 #endif
158         beqz    r4, resume_kernel
159 ENTRY(resume_userspace)
160         CLI(r4)                         ; make sure we don't miss an interrupt
161                                         ; setting need_resched or sigpending
162                                         ; between sampling and the iret
163         GET_THREAD_INFO(r8)
164         ld      r9, @(TI_FLAGS, r8)
165         and3    r4, r9, #_TIF_WORK_MASK ; is there any work to be done on
166                                         ; int/exception return?
167         bnez    r4, work_pending
168         bra     restore_all
169
170 #ifdef CONFIG_PREEMPT
171 ENTRY(resume_kernel)
172         GET_THREAD_INFO(r8)
173         ld      r9, @(TI_PRE_COUNT, r8) ; non-zero preempt_count ?
174         bnez    r9, restore_all
175 need_resched:
176         ld      r9, @(TI_FLAGS, r8)     ; need_resched set ?
177         and3    r4, r9, #_TIF_NEED_RESCHED
178         beqz    r4, restore_all
179         ld      r4, PSW(sp)             ; interrupts off (exception path) ?
180         and3    r4, r4, #0x4000
181         beqz    r4, restore_all
182         LDIMM   (r4, PREEMPT_ACTIVE)
183         st      r4, @(TI_PRE_COUNT, r8)
184         STI(r4)
185         bl      schedule
186         ldi     r4, #0
187         st      r4, @(TI_PRE_COUNT, r8)
188         CLI(r4)
189         bra     need_resched
190 #endif
191
192         ; system call handler stub
193 ENTRY(system_call)
194         SWITCH_TO_KERNEL_STACK
195         SAVE_ALL
196         STI(r4)                         ; Enable interrupt
197         st      sp, PTREGS(sp)          ; implicit pt_regs parameter
198         cmpui   r7, #NR_syscalls
199         bnc     syscall_badsys
200         st      r7, SYSCALL_NR(sp)      ; syscall_nr
201                                         ; system call tracing in operation
202         GET_THREAD_INFO(r8)
203         ld      r9, @(TI_FLAGS, r8)
204         and3    r4, r9, #_TIF_SYSCALL_TRACE
205         bnez    r4, syscall_trace_entry
206 syscall_call:
207         slli    r7, #2                  ; table jump for the system call
208         LDIMM   (r4, sys_call_table)
209         add     r7, r4
210         ld      r7, @r7
211         jl      r7                      ; execute system call
212         st      r0, R0(sp)              ; save the return value
213 syscall_exit:
214         CLI(r4)                         ; make sure we don't miss an interrupt
215                                         ; setting need_resched or sigpending
216                                         ; between sampling and the iret
217         ld      r9, @(TI_FLAGS, r8)
218         and3    r4, r9, #_TIF_ALLWORK_MASK      ; current->work
219         bnez    r4, syscall_exit_work
220 restore_all:
221         RESTORE_ALL
222
223         # perform work that needs to be done immediately before resumption
224         # r9 : flags
225         ALIGN
226 work_pending:
227         and3    r4, r9, #_TIF_NEED_RESCHED
228         beqz    r4, work_notifysig
229 work_resched:
230         bl      schedule
231         CLI(r4)                         ; make sure we don't miss an interrupt
232                                         ; setting need_resched or sigpending
233                                         ; between sampling and the iret
234         ld      r9, @(TI_FLAGS, r8)
235         and3    r4, r9, #_TIF_WORK_MASK ; is there any work to be done other
236                                         ; than syscall tracing?
237         beqz    r4, restore_all
238         and3    r4, r4, #_TIF_NEED_RESCHED
239         bnez    r4, work_resched
240
241 work_notifysig:                         ; deal with pending signals and
242                                         ; notify-resume requests
243         mv      r0, sp                  ; arg1 : struct pt_regs *regs
244         ldi     r1, #0                  ; arg2 : sigset_t *oldset
245         mv      r2, r9                  ; arg3 : __u32 thread_info_flags
246         bl      do_notify_resume
247         bra     restore_all
248
249         ; perform syscall exit tracing
250         ALIGN
251 syscall_trace_entry:
252         ldi     r4, #-ENOSYS
253         st      r4, R0(sp)
254         bl      do_syscall_trace
255         ld      r0, ORIG_R0(sp)
256         ld      r1, R1(sp)
257         ld      r2, R2(sp)
258         ld      r3, R3(sp)
259         ld      r4, R4(sp)
260         ld      r5, R5(sp)
261         ld      r6, R6(sp)
262         ld      r7, SYSCALL_NR(sp)
263         cmpui   r7, #NR_syscalls
264         bc      syscall_call
265         bra     syscall_exit
266
267         ; perform syscall exit tracing
268         ALIGN
269 syscall_exit_work:
270         ld      r9, @(TI_FLAGS, r8)
271         and3    r4, r9, #_TIF_SYSCALL_TRACE
272         beqz    r4, work_pending
273         STI(r4)                         ; could let do_syscall_trace() call
274                                         ; schedule() instead
275         bl      do_syscall_trace
276         bra     resume_userspace
277
278         ALIGN
279 syscall_fault:
280         SAVE_ALL
281         GET_THREAD_INFO(r8)
282         ldi     r4, #-EFAULT
283         st      r4, R0(sp)
284         bra     resume_userspace
285
286         ALIGN
287 syscall_badsys:
288         ldi     r4, #-ENOSYS
289         st      r4, R0(sp)
290         bra     resume_userspace
291
292         .global eit_vector
293
294         .equ ei_vec_table, eit_vector + 0x0200
295
296 /*
297  * EI handler routine
298  */
299 ENTRY(ei_handler)
300 #if defined(CONFIG_CHIP_M32700)
301         SWITCH_TO_KERNEL_STACK
302         ; WORKAROUND: force to clear SM bit and use the kernel stack (SPI).
303 #endif
304         SAVE_ALL
305         mv      r1, sp                  ; arg1(regs)
306 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
307         || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
308         || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
309
310 ;    GET_ICU_STATUS;
311         seth    r0, #shigh(M32R_ICU_ISTS_ADDR)
312         ld      r0, @(low(M32R_ICU_ISTS_ADDR),r0)
313         push    r0
314 #if defined(CONFIG_SMP)
315         /*
316          * If IRQ == 0      --> Nothing to do,  Not write IMASK
317          * If IRQ == IPI    --> Do IPI handler, Not write IMASK
318          * If IRQ != 0, IPI --> Do do_IRQ(),    Write IMASK
319          */
320         slli    r0, #4
321         srli    r0, #24                 ; r0(irq_num<<2)
322         ;; IRQ exist check
323 #if defined(CONFIG_CHIP_M32700)
324         /* WORKAROUND: IMASK bug M32700-TS1, TS2 chip. */
325         beqz    r0, 3f                  ; if (!irq_num) goto exit
326 #else
327         beqz    r0, 1f                  ; if (!irq_num) goto exit
328 #endif  /* WORKAROUND */
329         ;; IPI check
330         cmpi    r0, #(M32R_IRQ_IPI0<<2) ; ISN < IPI0 check
331         bc      2f
332         cmpi    r0, #((M32R_IRQ_IPI7+1)<<2)     ; ISN > IPI7 check
333         bnc     2f
334         LDIMM   (r2, ei_vec_table)
335         add     r2, r0
336         ld      r2, @r2
337         beqz    r2, 1f                  ; if (no IPI handler) goto exit
338         mv      r0, r1                  ; arg0(regs)
339         jl      r2
340         .fillinsn
341 1:
342         addi    sp, #4
343         bra     ret_to_intr
344 #if defined(CONFIG_CHIP_M32700)
345         /* WORKAROUND: IMASK bug M32700-TS1, TS2 chip. */
346         .fillinsn
347 3:
348         ld24    r14, #0x00070000
349         seth    r0, #shigh(M32R_ICU_IMASK_ADDR)
350         st      r14, @(low(M32R_ICU_IMASK_ADDR), r0)
351         addi    sp, #4
352         bra     ret_to_intr
353 #endif  /* WORKAROUND */
354         ;; do_IRQ
355         .fillinsn
356 2:
357         srli    r0, #2
358 #if defined(CONFIG_PLAT_USRV)
359         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
360         bnez    r2, 9f
361         ; read ICU status register of PLD
362         seth    r0, #high(PLD_ICUISTS)
363         or3     r0, r0, #low(PLD_ICUISTS)
364         lduh    r0, @r0
365         slli    r0, #21
366         srli    r0, #27                         ; ISN
367         addi    r0, #(M32700UT_PLD_IRQ_BASE)
368         .fillinsn
369 9:
370 #elif defined(CONFIG_PLAT_M32700UT)
371         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
372         bnez    r2, check_int0
373         ; read ICU status register of PLD
374         seth    r0, #high(PLD_ICUISTS)
375         or3     r0, r0, #low(PLD_ICUISTS)
376         lduh    r0, @r0
377         slli    r0, #21
378         srli    r0, #27                         ; ISN
379         addi    r0, #(M32700UT_PLD_IRQ_BASE)
380         bra     check_end
381         .fillinsn
382 check_int0:
383         add3    r2, r0, #-(M32R_IRQ_INT0)       ; INT0# interrupt
384         bnez    r2, check_int2
385         ; read ICU status of LAN-board
386         seth    r0, #high(M32700UT_LAN_ICUISTS)
387         or3     r0, r0, #low(M32700UT_LAN_ICUISTS)
388         lduh    r0, @r0
389         slli    r0, #21
390         srli    r0, #27                         ; ISN
391         add3    r0, r0, #(M32700UT_LAN_PLD_IRQ_BASE)
392         bra     check_end
393         .fillinsn
394 check_int2:
395         add3    r2, r0, #-(M32R_IRQ_INT2)       ; INT2# interrupt
396         bnez    r2, check_end
397         ; read ICU status of LCD-board
398         seth    r0, #high(M32700UT_LCD_ICUISTS)
399         or3     r0, r0, #low(M32700UT_LCD_ICUISTS)
400         lduh    r0, @r0
401         slli    r0, #21
402         srli    r0, #27                         ; ISN
403         add3    r0, r0, #(M32700UT_LCD_PLD_IRQ_BASE)
404         bra     check_end
405         .fillinsn
406 check_end:
407 #elif defined(CONFIG_PLAT_OPSPUT)
408         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
409         bnez    r2, check_int0
410         ; read ICU status register of PLD
411         seth    r0, #high(PLD_ICUISTS)
412         or3     r0, r0, #low(PLD_ICUISTS)
413         lduh    r0, @r0
414         slli    r0, #21
415         srli    r0, #27                         ; ISN
416         addi    r0, #(OPSPUT_PLD_IRQ_BASE)
417         bra     check_end
418         .fillinsn
419 check_int0:
420         add3    r2, r0, #-(M32R_IRQ_INT0)       ; INT0# interrupt
421         bnez    r2, check_int2
422         ; read ICU status of LAN-board
423         seth    r0, #high(OPSPUT_LAN_ICUISTS)
424         or3     r0, r0, #low(OPSPUT_LAN_ICUISTS)
425         lduh    r0, @r0
426         slli    r0, #21
427         srli    r0, #27                         ; ISN
428         add3    r0, r0, #(OPSPUT_LAN_PLD_IRQ_BASE)
429         bra     check_end
430         .fillinsn
431 check_int2:
432         add3    r2, r0, #-(M32R_IRQ_INT2)       ; INT2# interrupt
433         bnez    r2, check_end
434         ; read ICU status of LCD-board
435         seth    r0, #high(OPSPUT_LCD_ICUISTS)
436         or3     r0, r0, #low(OPSPUT_LCD_ICUISTS)
437         lduh    r0, @r0
438         slli    r0, #21
439         srli    r0, #27                         ; ISN
440         add3    r0, r0, #(OPSPUT_LCD_PLD_IRQ_BASE)
441         bra     check_end
442         .fillinsn
443 check_end:
444 #endif  /* CONFIG_PLAT_OPSPUT */
445         bl      do_IRQ                  ; r0(irq), r1(regs)
446 #else  /* not CONFIG_SMP */
447         srli    r0, #22                 ; r0(irq)
448 #if defined(CONFIG_PLAT_USRV)
449         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
450         bnez    r2, 1f
451         ; read ICU status register of PLD
452         seth    r0, #high(PLD_ICUISTS)
453         or3     r0, r0, #low(PLD_ICUISTS)
454         lduh    r0, @r0
455         slli    r0, #21
456         srli    r0, #27                         ; ISN
457         addi    r0, #(M32700UT_PLD_IRQ_BASE)
458         .fillinsn
459 1:
460 #elif defined(CONFIG_PLAT_M32700UT)
461         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
462         bnez    r2, check_int0
463         ; read ICU status register of PLD
464         seth    r0, #high(PLD_ICUISTS)
465         or3     r0, r0, #low(PLD_ICUISTS)
466         lduh    r0, @r0
467         slli    r0, #21
468         srli    r0, #27                         ; ISN
469         addi    r0, #(M32700UT_PLD_IRQ_BASE)
470         bra     check_end
471         .fillinsn
472 check_int0:
473         add3    r2, r0, #-(M32R_IRQ_INT0)       ; INT0# interrupt
474         bnez    r2, check_int2
475         ; read ICU status of LAN-board
476         seth    r0, #high(M32700UT_LAN_ICUISTS)
477         or3     r0, r0, #low(M32700UT_LAN_ICUISTS)
478         lduh    r0, @r0
479         slli    r0, #21
480         srli    r0, #27                         ; ISN
481         add3    r0, r0, #(M32700UT_LAN_PLD_IRQ_BASE)
482         bra     check_end
483         .fillinsn
484 check_int2:
485         add3    r2, r0, #-(M32R_IRQ_INT2)       ; INT2# interrupt
486         bnez    r2, check_end
487         ; read ICU status of LCD-board
488         seth    r0, #high(M32700UT_LCD_ICUISTS)
489         or3     r0, r0, #low(M32700UT_LCD_ICUISTS)
490         lduh    r0, @r0
491         slli    r0, #21
492         srli    r0, #27                         ; ISN
493         add3    r0, r0, #(M32700UT_LCD_PLD_IRQ_BASE)
494         bra     check_end
495         .fillinsn
496 check_end:
497 #elif defined(CONFIG_PLAT_OPSPUT)
498         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
499         bnez    r2, check_int0
500         ; read ICU status register of PLD
501         seth    r0, #high(PLD_ICUISTS)
502         or3     r0, r0, #low(PLD_ICUISTS)
503         lduh    r0, @r0
504         slli    r0, #21
505         srli    r0, #27                         ; ISN
506         addi    r0, #(OPSPUT_PLD_IRQ_BASE)
507         bra     check_end
508         .fillinsn
509 check_int0:
510         add3    r2, r0, #-(M32R_IRQ_INT0)       ; INT0# interrupt
511         bnez    r2, check_int2
512         ; read ICU status of LAN-board
513         seth    r0, #high(OPSPUT_LAN_ICUISTS)
514         or3     r0, r0, #low(OPSPUT_LAN_ICUISTS)
515         lduh    r0, @r0
516         slli    r0, #21
517         srli    r0, #27                         ; ISN
518         add3    r0, r0, #(OPSPUT_LAN_PLD_IRQ_BASE)
519         bra     check_end
520         .fillinsn
521 check_int2:
522         add3    r2, r0, #-(M32R_IRQ_INT2)       ; INT2# interrupt
523         bnez    r2, check_end
524         ; read ICU status of LCD-board
525         seth    r0, #high(OPSPUT_LCD_ICUISTS)
526         or3     r0, r0, #low(OPSPUT_LCD_ICUISTS)
527         lduh    r0, @r0
528         slli    r0, #21
529         srli    r0, #27                         ; ISN
530         add3    r0, r0, #(OPSPUT_LCD_PLD_IRQ_BASE)
531         bra     check_end
532         .fillinsn
533 check_end:
534 #elif defined(CONFIG_PLAT_M32104UT)
535         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
536         bnez    r2, check_end
537         ; read ICU status register of PLD
538         seth    r0, #high(PLD_ICUISTS)
539         or3     r0, r0, #low(PLD_ICUISTS)
540         lduh    r0, @r0
541         slli    r0, #21
542         srli    r0, #27                         ; ISN
543         addi    r0, #(M32104UT_PLD_IRQ_BASE)
544         bra     check_end
545         .fillinsn
546 check_end:
547 #endif  /* CONFIG_PLAT_M32104UT */
548         bl      do_IRQ
549 #endif  /* CONFIG_SMP */
550         pop     r14
551         seth    r0, #shigh(M32R_ICU_IMASK_ADDR)
552         st      r14, @(low(M32R_ICU_IMASK_ADDR),r0)
553 #else
554 #error no chip configuration
555 #endif
556 ret_to_intr:
557         bra  ret_from_intr
558
559 /*
560  * Default EIT handler
561  */
562         ALIGN
563 int_msg:
564         .asciz  "Unknown interrupt\n"
565         .byte   0
566
567 ENTRY(default_eit_handler)
568         push    r0
569         mvfc    r0, psw
570         push    r1
571         push    r2
572         push    r3
573         push    r0
574         LDIMM   (r0, __KERNEL_DS)
575         mv      r0, r1
576         mv      r0, r2
577         LDIMM   (r0, int_msg)
578         bl      printk
579         pop     r0
580         pop     r3
581         pop     r2
582         pop     r1
583         mvtc    r0, psw
584         pop     r0
585 infinit:
586         bra     infinit
587
588 #ifdef CONFIG_MMU
589 /*
590  * Access Exception handler
591  */
592 ENTRY(ace_handler)
593         SWITCH_TO_KERNEL_STACK
594         SAVE_ALL
595
596         seth    r2, #shigh(MMU_REG_BASE)        /* Check status register */
597         ld      r4, @(low(MESTS_offset),r2)
598         st      r4, @(low(MESTS_offset),r2)
599         srl3    r1, r4, #4
600 #ifdef CONFIG_CHIP_M32700
601         and3    r1, r1, #0x0000ffff
602         ; WORKAROUND: ignore TME bit for the M32700(TS1).
603 #endif /* CONFIG_CHIP_M32700 */
604         beqz    r1, inst
605 oprand:
606         ld      r2, @(low(MDEVA_offset),r2)     ; set address
607         srli    r2, #12
608         slli    r2, #12
609         srli    r1, #1
610         bra     1f
611 inst:
612         and3    r1, r4, #2
613         srli    r1, #1
614         or3     r1, r1, #8
615         mvfc    r2, bpc                         ; set address
616         .fillinsn
617 1:
618         mvfc    r3, psw
619         mv      r0, sp
620         and3    r3, r3, 0x800
621         srli    r3, #9
622         or      r1, r3
623         /*
624          * do_page_fault():
625          *    r0 : struct pt_regs *regs
626          *    r1 : unsigned long error-code
627          *    r2 : unsigned long address
628          * error-code:
629          *    +------+------+------+------+
630          *    | bit3 | bit2 | bit1 | bit0 |
631          *    +------+------+------+------+
632          *    bit 3 == 0:means data,          1:means instruction
633          *    bit 2 == 0:means kernel,        1:means user-mode
634          *    bit 1 == 0:means read,          1:means write
635          *    bit 0 == 0:means no page found  1:means protection fault
636          *
637          */
638         bl      do_page_fault
639         bra     ret_from_intr
640 #endif  /* CONFIG_MMU */
641
642
643 ENTRY(alignment_check)
644 /* void alignment_check(int error_code) */
645         SWITCH_TO_KERNEL_STACK
646         SAVE_ALL
647         ldi     r1, #0x30                       ; error_code
648         mv      r0, sp                          ; pt_regs
649         bl      do_alignment_check
650 error_code:
651         bra     ret_from_exception
652
653 ENTRY(rie_handler)
654 /* void rie_handler(int error_code) */
655         SWITCH_TO_KERNEL_STACK
656         SAVE_ALL
657         ldi     r1, #0x20                       ; error_code
658         mv      r0, sp                          ; pt_regs
659         bl      do_rie_handler
660         bra     error_code
661
662 ENTRY(pie_handler)
663 /* void pie_handler(int error_code) */
664         SWITCH_TO_KERNEL_STACK
665         SAVE_ALL
666         ldi     r1, #0                          ; error_code ; FIXME
667         mv      r0, sp                          ; pt_regs
668         bl      do_pie_handler
669         bra     error_code
670
671 ENTRY(debug_trap)
672         .global withdraw_debug_trap
673         /* void debug_trap(void) */
674         SWITCH_TO_KERNEL_STACK
675         SAVE_ALL
676         mv      r0, sp                          ; pt_regs
677         bl      withdraw_debug_trap
678         ldi     r1, #0                          ; error_code
679         mv      r0, sp                          ; pt_regs
680         bl      do_debug_trap
681         bra     error_code
682
683 ENTRY(ill_trap)
684         /* void ill_trap(void) */
685         SWITCH_TO_KERNEL_STACK
686         SAVE_ALL
687         ldi     r1, #0                          ; error_code ; FIXME
688         mv      r0, sp                          ; pt_regs
689         bl      do_ill_trap
690         bra     error_code
691
692
693 /* Cache flushing handler */
694 ENTRY(cache_flushing_handler)
695         .global _flush_cache_all
696         /* void _flush_cache_all(void); */
697         SWITCH_TO_KERNEL_STACK
698         push    r0
699         push    r1
700         push    r2
701         push    r3
702         push    r4
703         push    r5
704         push    r6
705         push    r7
706         push    lr
707         bl      _flush_cache_all
708         pop     lr
709         pop     r7
710         pop     r6
711         pop     r5
712         pop     r4
713         pop     r3
714         pop     r2
715         pop     r1
716         pop     r0
717         rte
718
719 .data
720 ENTRY(sys_call_table)
721         .long sys_restart_syscall       /* 0  -  old "setup()" system call*/
722         .long sys_exit
723         .long sys_fork
724         .long sys_read
725         .long sys_write
726         .long sys_open                  /* 5 */
727         .long sys_close
728         .long sys_waitpid
729         .long sys_creat
730         .long sys_link
731         .long sys_unlink                /* 10 */
732         .long sys_execve
733         .long sys_chdir
734         .long sys_time
735         .long sys_mknod
736         .long sys_chmod                 /* 15 */
737         .long sys_ni_syscall            /* lchown16 syscall holder */
738         .long sys_ni_syscall            /* old break syscall holder */
739         .long sys_ni_syscall            /* old stat syscall holder */
740         .long sys_lseek
741         .long sys_getpid                /* 20 */
742         .long sys_mount
743         .long sys_oldumount
744         .long sys_ni_syscall            /* setuid16 syscall holder */
745         .long sys_ni_syscall            /* getuid16 syscall holder */
746         .long sys_stime                 /* 25 */
747         .long sys_ptrace
748         .long sys_alarm
749         .long sys_ni_syscall            /* old fstat syscall holder */
750         .long sys_pause
751         .long sys_utime                 /* 30 */
752         .long sys_ni_syscall            /* old stty syscall holder */
753         .long sys_cachectl              /* for M32R */ /* old gtty syscall holder */
754         .long sys_access
755         .long sys_ni_syscall            /* nice syscall holder */
756         .long sys_ni_syscall            /* 35  -  old ftime syscall holder */
757         .long sys_sync
758         .long sys_kill
759         .long sys_rename
760         .long sys_mkdir
761         .long sys_rmdir                 /* 40 */
762         .long sys_dup
763         .long sys_pipe
764         .long sys_times
765         .long sys_ni_syscall            /* old prof syscall holder */
766         .long sys_brk                   /* 45 */
767         .long sys_ni_syscall            /* setgid16 syscall holder */
768         .long sys_getgid                /* will be unused */
769         .long sys_ni_syscall            /* signal syscall holder */
770         .long sys_ni_syscall            /* geteuid16  syscall holder */
771         .long sys_ni_syscall            /* 50 - getegid16 syscall holder */
772         .long sys_acct
773         .long sys_umount                /* recycled never used phys() */
774         .long sys_ni_syscall            /* old lock syscall holder */
775         .long sys_ioctl
776         .long sys_fcntl                 /* 55 - will be unused */
777         .long sys_ni_syscall            /* mpx syscall holder */
778         .long sys_setpgid
779         .long sys_ni_syscall            /* old ulimit syscall holder */
780         .long sys_ni_syscall            /* sys_olduname */
781         .long sys_umask                 /* 60 */
782         .long sys_chroot
783         .long sys_ustat
784         .long sys_dup2
785         .long sys_getppid
786         .long sys_getpgrp               /* 65 */
787         .long sys_setsid
788         .long sys_ni_syscall            /* sigaction syscall holder */
789         .long sys_ni_syscall            /* sgetmask syscall holder */
790         .long sys_ni_syscall            /* ssetmask syscall holder */
791         .long sys_ni_syscall            /* 70 - setreuid16 syscall holder */
792         .long sys_ni_syscall            /* setregid16 syscall holder */
793         .long sys_ni_syscall            /* sigsuspend syscall holder */
794         .long sys_ni_syscall            /* sigpending syscall holder */
795         .long sys_sethostname
796         .long sys_setrlimit             /* 75 */
797         .long sys_getrlimit/*will be unused*/
798         .long sys_getrusage
799         .long sys_gettimeofday
800         .long sys_settimeofday
801         .long sys_ni_syscall            /* 80 - getgroups16 syscall holder */
802         .long sys_ni_syscall            /* setgroups16 syscall holder */
803         .long sys_ni_syscall            /* sys_oldselect */
804         .long sys_symlink
805         .long sys_ni_syscall            /* old lstat syscall holder */
806         .long sys_readlink              /* 85 */
807         .long sys_uselib
808         .long sys_swapon
809         .long sys_reboot
810         .long sys_ni_syscall            /* readdir syscall holder */
811         .long sys_ni_syscall            /* 90 - old_mmap syscall holder */
812         .long sys_munmap
813         .long sys_truncate
814         .long sys_ftruncate
815         .long sys_fchmod
816         .long sys_ni_syscall            /* 95 - fchwon16  syscall holder */
817         .long sys_getpriority
818         .long sys_setpriority
819         .long sys_ni_syscall            /* old profil syscall holder */
820         .long sys_statfs
821         .long sys_fstatfs               /* 100 */
822         .long sys_ni_syscall            /* ioperm syscall holder */
823         .long sys_socketcall
824         .long sys_syslog
825         .long sys_setitimer
826         .long sys_getitimer             /* 105 */
827         .long sys_newstat
828         .long sys_newlstat
829         .long sys_newfstat
830         .long sys_ni_syscall            /* old uname syscall holder */
831         .long sys_ni_syscall            /* 110  -  iopl syscall holder */
832         .long sys_vhangup
833         .long sys_ni_syscall            /* idle syscall holder */
834         .long sys_ni_syscall            /* vm86old syscall holder */
835         .long sys_wait4
836         .long sys_swapoff               /* 115 */
837         .long sys_sysinfo
838         .long sys_ipc
839         .long sys_fsync
840         .long sys_ni_syscall            /* sigreturn syscall holder */
841         .long sys_clone                 /* 120 */
842         .long sys_setdomainname
843         .long sys_newuname
844         .long sys_ni_syscall            /* modify_ldt syscall holder */
845         .long sys_adjtimex
846         .long sys_mprotect              /* 125 */
847         .long sys_ni_syscall            /* sigprocmask syscall holder */
848         .long sys_ni_syscall            /* create_module syscall holder */
849         .long sys_init_module
850         .long sys_delete_module
851         .long sys_ni_syscall            /* 130 - get_kernel_syms */
852         .long sys_quotactl
853         .long sys_getpgid
854         .long sys_fchdir
855         .long sys_bdflush
856         .long sys_sysfs                 /* 135 */
857         .long sys_personality
858         .long sys_ni_syscall            /* afs_syscall syscall holder */
859         .long sys_ni_syscall            /* setfsuid16 syscall holder */
860         .long sys_ni_syscall            /* setfsgid16 syscall holder */
861         .long sys_llseek                /* 140 */
862         .long sys_getdents
863         .long sys_select
864         .long sys_flock
865         .long sys_msync
866         .long sys_readv                 /* 145 */
867         .long sys_writev
868         .long sys_getsid
869         .long sys_fdatasync
870         .long sys_sysctl
871         .long sys_mlock                 /* 150 */
872         .long sys_munlock
873         .long sys_mlockall
874         .long sys_munlockall
875         .long sys_sched_setparam
876         .long sys_sched_getparam        /* 155 */
877         .long sys_sched_setscheduler
878         .long sys_sched_getscheduler
879         .long sys_sched_yield
880         .long sys_sched_get_priority_max
881         .long sys_sched_get_priority_min        /* 160 */
882         .long sys_sched_rr_get_interval
883         .long sys_nanosleep
884         .long sys_mremap
885         .long sys_ni_syscall            /* setresuid16 syscall holder */
886         .long sys_ni_syscall            /* 165 - getresuid16 syscall holder */
887         .long sys_tas                   /* vm86 syscall holder */
888         .long sys_ni_syscall            /* query_module syscall holder */
889         .long sys_poll
890         .long sys_nfsservctl
891         .long sys_setresgid             /* 170 */
892         .long sys_getresgid
893         .long sys_prctl
894         .long sys_rt_sigreturn
895         .long sys_rt_sigaction
896         .long sys_rt_sigprocmask        /* 175 */
897         .long sys_rt_sigpending
898         .long sys_rt_sigtimedwait
899         .long sys_rt_sigqueueinfo
900         .long sys_rt_sigsuspend
901         .long sys_pread64               /* 180 */
902         .long sys_pwrite64
903         .long sys_ni_syscall            /* chown16 syscall holder */
904         .long sys_getcwd
905         .long sys_capget
906         .long sys_capset                /* 185 */
907         .long sys_sigaltstack
908         .long sys_sendfile
909         .long sys_ni_syscall            /* streams1 */
910         .long sys_ni_syscall            /* streams2 */
911         .long sys_vfork                 /* 190 */
912         .long sys_getrlimit
913         .long sys_mmap2
914         .long sys_truncate64
915         .long sys_ftruncate64
916         .long sys_stat64                /* 195 */
917         .long sys_lstat64
918         .long sys_fstat64
919         .long sys_lchown
920         .long sys_getuid
921         .long sys_getgid                /* 200 */
922         .long sys_geteuid
923         .long sys_getegid
924         .long sys_setreuid
925         .long sys_setregid
926         .long sys_getgroups             /* 205 */
927         .long sys_setgroups
928         .long sys_fchown
929         .long sys_setresuid
930         .long sys_getresuid
931         .long sys_setresgid             /* 210 */
932         .long sys_getresgid
933         .long sys_chown
934         .long sys_setuid
935         .long sys_setgid
936         .long sys_setfsuid              /* 215 */
937         .long sys_setfsgid
938         .long sys_pivot_root
939         .long sys_mincore
940         .long sys_madvise
941         .long sys_getdents64            /* 220 */
942         .long sys_fcntl64
943         .long sys_ni_syscall            /* reserved for TUX */
944         .long sys_ni_syscall            /* Reserved for Security */
945         .long sys_gettid
946         .long sys_readahead             /* 225 */
947         .long sys_setxattr
948         .long sys_lsetxattr
949         .long sys_fsetxattr
950         .long sys_getxattr
951         .long sys_lgetxattr             /* 230 */
952         .long sys_fgetxattr
953         .long sys_listxattr
954         .long sys_llistxattr
955         .long sys_flistxattr
956         .long sys_removexattr           /* 235 */
957         .long sys_lremovexattr
958         .long sys_fremovexattr
959         .long sys_tkill
960         .long sys_sendfile64
961         .long sys_futex                 /* 240 */
962         .long sys_sched_setaffinity
963         .long sys_sched_getaffinity
964         .long sys_ni_syscall            /* reserved for "set_thread_area" system call */
965         .long sys_ni_syscall            /* reserved for "get_thread_area" system call */
966         .long sys_io_setup              /* 245 */
967         .long sys_io_destroy
968         .long sys_io_getevents
969         .long sys_io_submit
970         .long sys_io_cancel
971         .long sys_fadvise64             /* 250 */
972         .long sys_ni_syscall
973         .long sys_exit_group
974         .long sys_lookup_dcookie
975         .long sys_epoll_create
976         .long sys_epoll_ctl             /* 255 */
977         .long sys_epoll_wait
978         .long sys_remap_file_pages
979         .long sys_set_tid_address
980         .long sys_timer_create
981         .long sys_timer_settime         /* 260 */
982         .long sys_timer_gettime
983         .long sys_timer_getoverrun
984         .long sys_timer_delete
985         .long sys_clock_settime
986         .long sys_clock_gettime         /* 265 */
987         .long sys_clock_getres
988         .long sys_clock_nanosleep
989         .long sys_statfs64
990         .long sys_fstatfs64
991         .long sys_tgkill                /* 270 */
992         .long sys_utimes
993         .long sys_fadvise64_64
994         .long sys_ni_syscall            /* Reserved for sys_vserver */
995         .long sys_ni_syscall            /* Reserved for sys_mbind */
996         .long sys_ni_syscall            /* Reserved for sys_get_mempolicy */
997         .long sys_ni_syscall            /* Reserved for sys_set_mempolicy */
998         .long sys_mq_open
999         .long sys_mq_unlink
1000         .long sys_mq_timedsend
1001         .long sys_mq_timedreceive       /* 280 */
1002         .long sys_mq_notify
1003         .long sys_mq_getsetattr
1004         .long sys_ni_syscall            /* reserved for kexec */
1005         .long sys_waitid
1006
1007 syscall_table_size=(.-sys_call_table)