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