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