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