Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[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 ENTRY(ill_trap)
685         /* void ill_trap(void) */
686         SWITCH_TO_KERNEL_STACK
687         SAVE_ALL
688         ldi     r1, #0                          ; error_code ; FIXME
689         mv      r0, sp                          ; pt_regs
690         bl      do_ill_trap
691         bra     error_code
692
693
694 /* Cache flushing handler */
695 ENTRY(cache_flushing_handler)
696         .global _flush_cache_all
697         /* void _flush_cache_all(void); */
698         SWITCH_TO_KERNEL_STACK
699         push    r0
700         push    r1
701         push    r2
702         push    r3
703         push    r4
704         push    r5
705         push    r6
706         push    r7
707         push    lr
708         bl      _flush_cache_all
709         pop     lr
710         pop     r7
711         pop     r6
712         pop     r5
713         pop     r4
714         pop     r3
715         pop     r2
716         pop     r1
717         pop     r0
718         rte
719
720 .data
721 ENTRY(sys_call_table)
722         .long sys_restart_syscall       /* 0  -  old "setup()" system call*/
723         .long sys_exit
724         .long sys_fork
725         .long sys_read
726         .long sys_write
727         .long sys_open                  /* 5 */
728         .long sys_close
729         .long sys_waitpid
730         .long sys_creat
731         .long sys_link
732         .long sys_unlink                /* 10 */
733         .long sys_execve
734         .long sys_chdir
735         .long sys_time
736         .long sys_mknod
737         .long sys_chmod                 /* 15 */
738         .long sys_ni_syscall            /* lchown16 syscall holder */
739         .long sys_ni_syscall            /* old break syscall holder */
740         .long sys_ni_syscall            /* old stat syscall holder */
741         .long sys_lseek
742         .long sys_getpid                /* 20 */
743         .long sys_mount
744         .long sys_oldumount
745         .long sys_ni_syscall            /* setuid16 syscall holder */
746         .long sys_ni_syscall            /* getuid16 syscall holder */
747         .long sys_stime                 /* 25 */
748         .long sys_ptrace
749         .long sys_alarm
750         .long sys_ni_syscall            /* old fstat syscall holder */
751         .long sys_pause
752         .long sys_utime                 /* 30 */
753         .long sys_ni_syscall            /* old stty syscall holder */
754         .long sys_cachectl              /* for M32R */ /* old gtty syscall holder */
755         .long sys_access
756         .long sys_ni_syscall            /* nice syscall holder */
757         .long sys_ni_syscall            /* 35  -  old ftime syscall holder */
758         .long sys_sync
759         .long sys_kill
760         .long sys_rename
761         .long sys_mkdir
762         .long sys_rmdir                 /* 40 */
763         .long sys_dup
764         .long sys_pipe
765         .long sys_times
766         .long sys_ni_syscall            /* old prof syscall holder */
767         .long sys_brk                   /* 45 */
768         .long sys_ni_syscall            /* setgid16 syscall holder */
769         .long sys_getgid                /* will be unused */
770         .long sys_ni_syscall            /* signal syscall holder */
771         .long sys_ni_syscall            /* geteuid16  syscall holder */
772         .long sys_ni_syscall            /* 50 - getegid16 syscall holder */
773         .long sys_acct
774         .long sys_umount                /* recycled never used phys() */
775         .long sys_ni_syscall            /* old lock syscall holder */
776         .long sys_ioctl
777         .long sys_fcntl                 /* 55 - will be unused */
778         .long sys_ni_syscall            /* mpx syscall holder */
779         .long sys_setpgid
780         .long sys_ni_syscall            /* old ulimit syscall holder */
781         .long sys_ni_syscall            /* sys_olduname */
782         .long sys_umask                 /* 60 */
783         .long sys_chroot
784         .long sys_ustat
785         .long sys_dup2
786         .long sys_getppid
787         .long sys_getpgrp               /* 65 */
788         .long sys_setsid
789         .long sys_ni_syscall            /* sigaction syscall holder */
790         .long sys_ni_syscall            /* sgetmask syscall holder */
791         .long sys_ni_syscall            /* ssetmask syscall holder */
792         .long sys_ni_syscall            /* 70 - setreuid16 syscall holder */
793         .long sys_ni_syscall            /* setregid16 syscall holder */
794         .long sys_ni_syscall            /* sigsuspend syscall holder */
795         .long sys_ni_syscall            /* sigpending syscall holder */
796         .long sys_sethostname
797         .long sys_setrlimit             /* 75 */
798         .long sys_getrlimit/*will be unused*/
799         .long sys_getrusage
800         .long sys_gettimeofday
801         .long sys_settimeofday
802         .long sys_ni_syscall            /* 80 - getgroups16 syscall holder */
803         .long sys_ni_syscall            /* setgroups16 syscall holder */
804         .long sys_ni_syscall            /* sys_oldselect */
805         .long sys_symlink
806         .long sys_ni_syscall            /* old lstat syscall holder */
807         .long sys_readlink              /* 85 */
808         .long sys_uselib
809         .long sys_swapon
810         .long sys_reboot
811         .long sys_ni_syscall            /* readdir syscall holder */
812         .long sys_ni_syscall            /* 90 - old_mmap syscall holder */
813         .long sys_munmap
814         .long sys_truncate
815         .long sys_ftruncate
816         .long sys_fchmod
817         .long sys_ni_syscall            /* 95 - fchwon16  syscall holder */
818         .long sys_getpriority
819         .long sys_setpriority
820         .long sys_ni_syscall            /* old profil syscall holder */
821         .long sys_statfs
822         .long sys_fstatfs               /* 100 */
823         .long sys_ni_syscall            /* ioperm syscall holder */
824         .long sys_socketcall
825         .long sys_syslog
826         .long sys_setitimer
827         .long sys_getitimer             /* 105 */
828         .long sys_newstat
829         .long sys_newlstat
830         .long sys_newfstat
831         .long sys_ni_syscall            /* old uname syscall holder */
832         .long sys_ni_syscall            /* 110  -  iopl syscall holder */
833         .long sys_vhangup
834         .long sys_ni_syscall            /* idle syscall holder */
835         .long sys_ni_syscall            /* vm86old syscall holder */
836         .long sys_wait4
837         .long sys_swapoff               /* 115 */
838         .long sys_sysinfo
839         .long sys_ipc
840         .long sys_fsync
841         .long sys_ni_syscall            /* sigreturn syscall holder */
842         .long sys_clone                 /* 120 */
843         .long sys_setdomainname
844         .long sys_newuname
845         .long sys_ni_syscall            /* modify_ldt syscall holder */
846         .long sys_adjtimex
847         .long sys_mprotect              /* 125 */
848         .long sys_ni_syscall            /* sigprocmask syscall holder */
849         .long sys_ni_syscall            /* create_module syscall holder */
850         .long sys_init_module
851         .long sys_delete_module
852         .long sys_ni_syscall            /* 130 - get_kernel_syms */
853         .long sys_quotactl
854         .long sys_getpgid
855         .long sys_fchdir
856         .long sys_bdflush
857         .long sys_sysfs                 /* 135 */
858         .long sys_personality
859         .long sys_ni_syscall            /* afs_syscall syscall holder */
860         .long sys_ni_syscall            /* setfsuid16 syscall holder */
861         .long sys_ni_syscall            /* setfsgid16 syscall holder */
862         .long sys_llseek                /* 140 */
863         .long sys_getdents
864         .long sys_select
865         .long sys_flock
866         .long sys_msync
867         .long sys_readv                 /* 145 */
868         .long sys_writev
869         .long sys_getsid
870         .long sys_fdatasync
871         .long sys_sysctl
872         .long sys_mlock                 /* 150 */
873         .long sys_munlock
874         .long sys_mlockall
875         .long sys_munlockall
876         .long sys_sched_setparam
877         .long sys_sched_getparam        /* 155 */
878         .long sys_sched_setscheduler
879         .long sys_sched_getscheduler
880         .long sys_sched_yield
881         .long sys_sched_get_priority_max
882         .long sys_sched_get_priority_min        /* 160 */
883         .long sys_sched_rr_get_interval
884         .long sys_nanosleep
885         .long sys_mremap
886         .long sys_ni_syscall            /* setresuid16 syscall holder */
887         .long sys_ni_syscall            /* 165 - getresuid16 syscall holder */
888         .long sys_tas                   /* vm86 syscall holder */
889         .long sys_ni_syscall            /* query_module syscall holder */
890         .long sys_poll
891         .long sys_nfsservctl
892         .long sys_setresgid             /* 170 */
893         .long sys_getresgid
894         .long sys_prctl
895         .long sys_rt_sigreturn
896         .long sys_rt_sigaction
897         .long sys_rt_sigprocmask        /* 175 */
898         .long sys_rt_sigpending
899         .long sys_rt_sigtimedwait
900         .long sys_rt_sigqueueinfo
901         .long sys_rt_sigsuspend
902         .long sys_pread64               /* 180 */
903         .long sys_pwrite64
904         .long sys_ni_syscall            /* chown16 syscall holder */
905         .long sys_getcwd
906         .long sys_capget
907         .long sys_capset                /* 185 */
908         .long sys_sigaltstack
909         .long sys_sendfile
910         .long sys_ni_syscall            /* streams1 */
911         .long sys_ni_syscall            /* streams2 */
912         .long sys_vfork                 /* 190 */
913         .long sys_getrlimit
914         .long sys_mmap2
915         .long sys_truncate64
916         .long sys_ftruncate64
917         .long sys_stat64                /* 195 */
918         .long sys_lstat64
919         .long sys_fstat64
920         .long sys_lchown
921         .long sys_getuid
922         .long sys_getgid                /* 200 */
923         .long sys_geteuid
924         .long sys_getegid
925         .long sys_setreuid
926         .long sys_setregid
927         .long sys_getgroups             /* 205 */
928         .long sys_setgroups
929         .long sys_fchown
930         .long sys_setresuid
931         .long sys_getresuid
932         .long sys_setresgid             /* 210 */
933         .long sys_getresgid
934         .long sys_chown
935         .long sys_setuid
936         .long sys_setgid
937         .long sys_setfsuid              /* 215 */
938         .long sys_setfsgid
939         .long sys_pivot_root
940         .long sys_mincore
941         .long sys_madvise
942         .long sys_getdents64            /* 220 */
943         .long sys_fcntl64
944         .long sys_ni_syscall            /* reserved for TUX */
945         .long sys_ni_syscall            /* Reserved for Security */
946         .long sys_gettid
947         .long sys_readahead             /* 225 */
948         .long sys_setxattr
949         .long sys_lsetxattr
950         .long sys_fsetxattr
951         .long sys_getxattr
952         .long sys_lgetxattr             /* 230 */
953         .long sys_fgetxattr
954         .long sys_listxattr
955         .long sys_llistxattr
956         .long sys_flistxattr
957         .long sys_removexattr           /* 235 */
958         .long sys_lremovexattr
959         .long sys_fremovexattr
960         .long sys_tkill
961         .long sys_sendfile64
962         .long sys_futex                 /* 240 */
963         .long sys_sched_setaffinity
964         .long sys_sched_getaffinity
965         .long sys_ni_syscall            /* reserved for "set_thread_area" system call */
966         .long sys_ni_syscall            /* reserved for "get_thread_area" system call */
967         .long sys_io_setup              /* 245 */
968         .long sys_io_destroy
969         .long sys_io_getevents
970         .long sys_io_submit
971         .long sys_io_cancel
972         .long sys_fadvise64             /* 250 */
973         .long sys_ni_syscall
974         .long sys_exit_group
975         .long sys_lookup_dcookie
976         .long sys_epoll_create
977         .long sys_epoll_ctl             /* 255 */
978         .long sys_epoll_wait
979         .long sys_remap_file_pages
980         .long sys_set_tid_address
981         .long sys_timer_create
982         .long sys_timer_settime         /* 260 */
983         .long sys_timer_gettime
984         .long sys_timer_getoverrun
985         .long sys_timer_delete
986         .long sys_clock_settime
987         .long sys_clock_gettime         /* 265 */
988         .long sys_clock_getres
989         .long sys_clock_nanosleep
990         .long sys_statfs64
991         .long sys_fstatfs64
992         .long sys_tgkill                /* 270 */
993         .long sys_utimes
994         .long sys_fadvise64_64
995         .long sys_ni_syscall            /* Reserved for sys_vserver */
996         .long sys_ni_syscall            /* Reserved for sys_mbind */
997         .long sys_ni_syscall            /* Reserved for sys_get_mempolicy */
998         .long sys_ni_syscall            /* Reserved for sys_set_mempolicy */
999         .long sys_mq_open
1000         .long sys_mq_unlink
1001         .long sys_mq_timedsend
1002         .long sys_mq_timedreceive       /* 280 */
1003         .long sys_mq_notify
1004         .long sys_mq_getsetattr
1005         .long sys_ni_syscall            /* reserved for kexec */
1006         .long sys_waitid
1007
1008 syscall_table_size=(.-sys_call_table)
1009