Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/x86
[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) || defined(CONFIG_CHIP_M32104)
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 #elif defined(CONFIG_PLAT_M32104UT)
545         add3    r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
546         bnez    r2, check_end
547         ; read ICU status register of PLD
548         seth    r0, #high(PLD_ICUISTS)
549         or3     r0, r0, #low(PLD_ICUISTS)
550         lduh    r0, @r0
551         slli    r0, #21
552         srli    r0, #27                         ; ISN
553         addi    r0, #(M32104UT_PLD_IRQ_BASE)
554         bra     check_end
555         .fillinsn
556 check_end:
557 #endif  /* CONFIG_PLAT_M32104UT */
558         bl      do_IRQ
559 #endif  /* CONFIG_SMP */
560         ld      r14, @sp+
561         seth    r0, #shigh(M32R_ICU_IMASK_ADDR)
562         st      r14, @(low(M32R_ICU_IMASK_ADDR),r0)
563 #else
564 #error no chip configuration
565 #endif
566 ret_to_intr:
567         bra  ret_from_intr
568
569 /*
570  * Default EIT handler
571  */
572         ALIGN
573 int_msg:
574         .asciz  "Unknown interrupt\n"
575         .byte   0
576
577 ENTRY(default_eit_handler)
578         push    r0
579         mvfc    r0, psw
580         push    r1
581         push    r2
582         push    r3
583         push    r0
584         LDIMM   (r0, __KERNEL_DS)
585         mv      r0, r1
586         mv      r0, r2
587         LDIMM   (r0, int_msg)
588         bl      printk
589         pop     r0
590         pop     r3
591         pop     r2
592         pop     r1
593         mvtc    r0, psw
594         pop     r0
595 infinit:
596         bra     infinit
597
598 #ifdef CONFIG_MMU
599 /*
600  * Access Exception handler
601  */
602 ENTRY(ace_handler)
603         SWITCH_TO_KERNEL_STACK
604         SAVE_ALL
605
606         seth    r2, #shigh(MMU_REG_BASE)        /* Check status register */
607         ld      r4, @(low(MESTS_offset),r2)
608         st      r4, @(low(MESTS_offset),r2)
609         srl3    r1, r4, #4
610 #ifdef CONFIG_CHIP_M32700
611         and3    r1, r1, #0x0000ffff
612         ; WORKAROUND: ignore TME bit for the M32700(TS1).
613 #endif /* CONFIG_CHIP_M32700 */
614         beqz    r1, inst
615 oprand:
616         ld      r2, @(low(MDEVA_offset),r2)     ; set address
617         srli    r2, #12
618         slli    r2, #12
619         srli    r1, #1
620         bra     1f
621 inst:
622         and3    r1, r4, #2
623         srli    r1, #1
624         or3     r1, r1, #8
625         mvfc    r2, bpc                         ; set address
626         .fillinsn
627 1:
628         mvfc    r3, psw
629         mv      r0, sp
630         and3    r3, r3, 0x800
631         srli    r3, #9
632         or      r1, r3
633         /*
634          * do_page_fault():
635          *    r0 : struct pt_regs *regs
636          *    r1 : unsigned long error-code
637          *    r2 : unsigned long address
638          * error-code:
639          *    +------+------+------+------+
640          *    | bit3 | bit2 | bit1 | bit0 |
641          *    +------+------+------+------+
642          *    bit 3 == 0:means data,          1:means instruction
643          *    bit 2 == 0:means kernel,        1:means user-mode
644          *    bit 1 == 0:means read,          1:means write
645          *    bit 0 == 0:means no page found  1:means protection fault
646          *
647          */
648         bl      do_page_fault
649         bra     ret_from_intr
650 #endif  /* CONFIG_MMU */
651
652
653 ENTRY(alignment_check)
654 /* void alignment_check(int error_code) */
655         SWITCH_TO_KERNEL_STACK
656         SAVE_ALL
657         ldi     r1, #0x30                       ; error_code
658         mv      r0, sp                          ; pt_regs
659         bl      do_alignment_check
660 error_code:
661         bra     ret_from_exception
662
663 ENTRY(rie_handler)
664 /* void rie_handler(int error_code) */
665         SWITCH_TO_KERNEL_STACK
666         SAVE_ALL
667         ldi     r1, #0x20                       ; error_code
668         mv      r0, sp                          ; pt_regs
669         bl      do_rie_handler
670         bra     error_code
671
672 ENTRY(pie_handler)
673 /* void pie_handler(int error_code) */
674         SWITCH_TO_KERNEL_STACK
675         SAVE_ALL
676         ldi     r1, #0                          ; error_code ; FIXME
677         mv      r0, sp                          ; pt_regs
678         bl      do_pie_handler
679         bra     error_code
680
681 ENTRY(debug_trap)
682         .global withdraw_debug_trap
683         /* void debug_trap(void) */
684         SWITCH_TO_KERNEL_STACK
685         SAVE_ALL
686         mv      r0, sp                          ; pt_regs
687         bl      withdraw_debug_trap
688         ldi     r1, #0                          ; error_code
689         mv      r0, sp                          ; pt_regs
690         bl      do_debug_trap
691         bra     error_code
692
693 ENTRY(ill_trap)
694         /* void ill_trap(void) */
695         SWITCH_TO_KERNEL_STACK
696         SAVE_ALL
697         ldi     r1, #0                          ; error_code ; FIXME
698         mv      r0, sp                          ; pt_regs
699         bl      do_ill_trap
700         bra     error_code
701
702
703 /* Cache flushing handler */
704 ENTRY(cache_flushing_handler)
705         .global _flush_cache_all
706         /* void _flush_cache_all(void); */
707         SWITCH_TO_KERNEL_STACK
708         push    r0
709         push    r1
710         push    r2
711         push    r3
712         push    r4
713         push    r5
714         push    r6
715         push    r7
716         push    lr
717         bl      _flush_cache_all
718         pop     lr
719         pop     r7
720         pop     r6
721         pop     r5
722         pop     r4
723         pop     r3
724         pop     r2
725         pop     r1
726         pop     r0
727         rte
728
729 .data
730 ENTRY(sys_call_table)
731         .long sys_restart_syscall       /* 0  -  old "setup()" system call*/
732         .long sys_exit
733         .long sys_fork
734         .long sys_read
735         .long sys_write
736         .long sys_open                  /* 5 */
737         .long sys_close
738         .long sys_waitpid
739         .long sys_creat
740         .long sys_link
741         .long sys_unlink                /* 10 */
742         .long sys_execve
743         .long sys_chdir
744         .long sys_time
745         .long sys_mknod
746         .long sys_chmod                 /* 15 */
747         .long sys_ni_syscall            /* lchown16 syscall holder */
748         .long sys_ni_syscall            /* old break syscall holder */
749         .long sys_ni_syscall            /* old stat syscall holder */
750         .long sys_lseek
751         .long sys_getpid                /* 20 */
752         .long sys_mount
753         .long sys_oldumount
754         .long sys_ni_syscall            /* setuid16 syscall holder */
755         .long sys_ni_syscall            /* getuid16 syscall holder */
756         .long sys_stime                 /* 25 */
757         .long sys_ptrace
758         .long sys_alarm
759         .long sys_ni_syscall            /* old fstat syscall holder */
760         .long sys_pause
761         .long sys_utime                 /* 30 */
762         .long sys_ni_syscall            /* old stty syscall holder */
763         .long sys_cachectl              /* for M32R */ /* old gtty syscall holder */
764         .long sys_access
765         .long sys_ni_syscall            /* nice syscall holder */
766         .long sys_ni_syscall            /* 35  -  old ftime syscall holder */
767         .long sys_sync
768         .long sys_kill
769         .long sys_rename
770         .long sys_mkdir
771         .long sys_rmdir                 /* 40 */
772         .long sys_dup
773         .long sys_pipe
774         .long sys_times
775         .long sys_ni_syscall            /* old prof syscall holder */
776         .long sys_brk                   /* 45 */
777         .long sys_ni_syscall            /* setgid16 syscall holder */
778         .long sys_getgid                /* will be unused */
779         .long sys_ni_syscall            /* signal syscall holder */
780         .long sys_ni_syscall            /* geteuid16  syscall holder */
781         .long sys_ni_syscall            /* 50 - getegid16 syscall holder */
782         .long sys_acct
783         .long sys_umount                /* recycled never used phys() */
784         .long sys_ni_syscall            /* old lock syscall holder */
785         .long sys_ioctl
786         .long sys_fcntl                 /* 55 - will be unused */
787         .long sys_ni_syscall            /* mpx syscall holder */
788         .long sys_setpgid
789         .long sys_ni_syscall            /* old ulimit syscall holder */
790         .long sys_ni_syscall            /* sys_olduname */
791         .long sys_umask                 /* 60 */
792         .long sys_chroot
793         .long sys_ustat
794         .long sys_dup2
795         .long sys_getppid
796         .long sys_getpgrp               /* 65 */
797         .long sys_setsid
798         .long sys_ni_syscall            /* sigaction syscall holder */
799         .long sys_ni_syscall            /* sgetmask syscall holder */
800         .long sys_ni_syscall            /* ssetmask syscall holder */
801         .long sys_ni_syscall            /* 70 - setreuid16 syscall holder */
802         .long sys_ni_syscall            /* setregid16 syscall holder */
803         .long sys_ni_syscall            /* sigsuspend syscall holder */
804         .long sys_ni_syscall            /* sigpending syscall holder */
805         .long sys_sethostname
806         .long sys_setrlimit             /* 75 */
807         .long sys_getrlimit/*will be unused*/
808         .long sys_getrusage
809         .long sys_gettimeofday
810         .long sys_settimeofday
811         .long sys_ni_syscall            /* 80 - getgroups16 syscall holder */
812         .long sys_ni_syscall            /* setgroups16 syscall holder */
813         .long sys_ni_syscall            /* sys_oldselect */
814         .long sys_symlink
815         .long sys_ni_syscall            /* old lstat syscall holder */
816         .long sys_readlink              /* 85 */
817         .long sys_uselib
818         .long sys_swapon
819         .long sys_reboot
820         .long sys_ni_syscall            /* readdir syscall holder */
821         .long sys_ni_syscall            /* 90 - old_mmap syscall holder */
822         .long sys_munmap
823         .long sys_truncate
824         .long sys_ftruncate
825         .long sys_fchmod
826         .long sys_ni_syscall            /* 95 - fchwon16  syscall holder */
827         .long sys_getpriority
828         .long sys_setpriority
829         .long sys_ni_syscall            /* old profil syscall holder */
830         .long sys_statfs
831         .long sys_fstatfs               /* 100 */
832         .long sys_ni_syscall            /* ioperm syscall holder */
833         .long sys_socketcall
834         .long sys_syslog
835         .long sys_setitimer
836         .long sys_getitimer             /* 105 */
837         .long sys_newstat
838         .long sys_newlstat
839         .long sys_newfstat
840         .long sys_ni_syscall            /* old uname syscall holder */
841         .long sys_ni_syscall            /* 110  -  iopl syscall holder */
842         .long sys_vhangup
843         .long sys_ni_syscall            /* idle syscall holder */
844         .long sys_ni_syscall            /* vm86old syscall holder */
845         .long sys_wait4
846         .long sys_swapoff               /* 115 */
847         .long sys_sysinfo
848         .long sys_ipc
849         .long sys_fsync
850         .long sys_ni_syscall            /* sigreturn syscall holder */
851         .long sys_clone                 /* 120 */
852         .long sys_setdomainname
853         .long sys_newuname
854         .long sys_ni_syscall            /* modify_ldt syscall holder */
855         .long sys_adjtimex
856         .long sys_mprotect              /* 125 */
857         .long sys_ni_syscall            /* sigprocmask syscall holder */
858         .long sys_ni_syscall            /* create_module syscall holder */
859         .long sys_init_module
860         .long sys_delete_module
861         .long sys_ni_syscall            /* 130 - get_kernel_syms */
862         .long sys_quotactl
863         .long sys_getpgid
864         .long sys_fchdir
865         .long sys_bdflush
866         .long sys_sysfs                 /* 135 */
867         .long sys_personality
868         .long sys_ni_syscall            /* afs_syscall syscall holder */
869         .long sys_ni_syscall            /* setfsuid16 syscall holder */
870         .long sys_ni_syscall            /* setfsgid16 syscall holder */
871         .long sys_llseek                /* 140 */
872         .long sys_getdents
873         .long sys_select
874         .long sys_flock
875         .long sys_msync
876         .long sys_readv                 /* 145 */
877         .long sys_writev
878         .long sys_getsid
879         .long sys_fdatasync
880         .long sys_sysctl
881         .long sys_mlock                 /* 150 */
882         .long sys_munlock
883         .long sys_mlockall
884         .long sys_munlockall
885         .long sys_sched_setparam
886         .long sys_sched_getparam        /* 155 */
887         .long sys_sched_setscheduler
888         .long sys_sched_getscheduler
889         .long sys_sched_yield
890         .long sys_sched_get_priority_max
891         .long sys_sched_get_priority_min        /* 160 */
892         .long sys_sched_rr_get_interval
893         .long sys_nanosleep
894         .long sys_mremap
895         .long sys_ni_syscall            /* setresuid16 syscall holder */
896         .long sys_ni_syscall            /* 165 - getresuid16 syscall holder */
897         .long sys_tas                   /* vm86 syscall holder */
898         .long sys_ni_syscall            /* query_module syscall holder */
899         .long sys_poll
900         .long sys_nfsservctl
901         .long sys_setresgid             /* 170 */
902         .long sys_getresgid
903         .long sys_prctl
904         .long sys_rt_sigreturn
905         .long sys_rt_sigaction
906         .long sys_rt_sigprocmask        /* 175 */
907         .long sys_rt_sigpending
908         .long sys_rt_sigtimedwait
909         .long sys_rt_sigqueueinfo
910         .long sys_rt_sigsuspend
911         .long sys_pread64               /* 180 */
912         .long sys_pwrite64
913         .long sys_ni_syscall            /* chown16 syscall holder */
914         .long sys_getcwd
915         .long sys_capget
916         .long sys_capset                /* 185 */
917         .long sys_sigaltstack
918         .long sys_sendfile
919         .long sys_ni_syscall            /* streams1 */
920         .long sys_ni_syscall            /* streams2 */
921         .long sys_vfork                 /* 190 */
922         .long sys_getrlimit
923         .long sys_mmap2
924         .long sys_truncate64
925         .long sys_ftruncate64
926         .long sys_stat64                /* 195 */
927         .long sys_lstat64
928         .long sys_fstat64
929         .long sys_lchown
930         .long sys_getuid
931         .long sys_getgid                /* 200 */
932         .long sys_geteuid
933         .long sys_getegid
934         .long sys_setreuid
935         .long sys_setregid
936         .long sys_getgroups             /* 205 */
937         .long sys_setgroups
938         .long sys_fchown
939         .long sys_setresuid
940         .long sys_getresuid
941         .long sys_setresgid             /* 210 */
942         .long sys_getresgid
943         .long sys_chown
944         .long sys_setuid
945         .long sys_setgid
946         .long sys_setfsuid              /* 215 */
947         .long sys_setfsgid
948         .long sys_pivot_root
949         .long sys_mincore
950         .long sys_madvise
951         .long sys_getdents64            /* 220 */
952         .long sys_fcntl64
953         .long sys_ni_syscall            /* reserved for TUX */
954         .long sys_ni_syscall            /* Reserved for Security */
955         .long sys_gettid
956         .long sys_readahead             /* 225 */
957         .long sys_setxattr
958         .long sys_lsetxattr
959         .long sys_fsetxattr
960         .long sys_getxattr
961         .long sys_lgetxattr             /* 230 */
962         .long sys_fgetxattr
963         .long sys_listxattr
964         .long sys_llistxattr
965         .long sys_flistxattr
966         .long sys_removexattr           /* 235 */
967         .long sys_lremovexattr
968         .long sys_fremovexattr
969         .long sys_tkill
970         .long sys_sendfile64
971         .long sys_futex                 /* 240 */
972         .long sys_sched_setaffinity
973         .long sys_sched_getaffinity
974         .long sys_ni_syscall            /* reserved for "set_thread_area" system call */
975         .long sys_ni_syscall            /* reserved for "get_thread_area" system call */
976         .long sys_io_setup              /* 245 */
977         .long sys_io_destroy
978         .long sys_io_getevents
979         .long sys_io_submit
980         .long sys_io_cancel
981         .long sys_fadvise64             /* 250 */
982         .long sys_ni_syscall
983         .long sys_exit_group
984         .long sys_lookup_dcookie
985         .long sys_epoll_create
986         .long sys_epoll_ctl             /* 255 */
987         .long sys_epoll_wait
988         .long sys_remap_file_pages
989         .long sys_set_tid_address
990         .long sys_timer_create
991         .long sys_timer_settime         /* 260 */
992         .long sys_timer_gettime
993         .long sys_timer_getoverrun
994         .long sys_timer_delete
995         .long sys_clock_settime
996         .long sys_clock_gettime         /* 265 */
997         .long sys_clock_getres
998         .long sys_clock_nanosleep
999         .long sys_statfs64
1000         .long sys_fstatfs64
1001         .long sys_tgkill                /* 270 */
1002         .long sys_utimes
1003         .long sys_fadvise64_64
1004         .long sys_ni_syscall            /* Reserved for sys_vserver */
1005         .long sys_ni_syscall            /* Reserved for sys_mbind */
1006         .long sys_ni_syscall            /* Reserved for sys_get_mempolicy */
1007         .long sys_ni_syscall            /* Reserved for sys_set_mempolicy */
1008         .long sys_mq_open
1009         .long sys_mq_unlink
1010         .long sys_mq_timedsend
1011         .long sys_mq_timedreceive       /* 280 */
1012         .long sys_mq_notify
1013         .long sys_mq_getsetattr
1014         .long sys_ni_syscall            /* reserved for kexec */
1015         .long sys_waitid
1016
1017 syscall_table_size=(.-sys_call_table)
1018