blob: a440d36ee6187e3557edc577eea2f0c6bc59f60a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
2 *
3 * linux/arch/sh/entry.S
4 *
5 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
6 * Copyright (C) 2003 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 */
13
14#include <linux/sys.h>
15#include <linux/linkage.h>
16#include <linux/config.h>
17#include <asm/asm-offsets.h>
18#include <asm/thread_info.h>
Paul Mundt091904a2006-02-01 03:06:01 -080019#include <asm/cpu/mmu_context.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <asm/unistd.h>
21
22#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
23#define sys_nfsservctl sys_ni_syscall
24#endif
25
26#if !defined(CONFIG_MMU)
27#define sys_madvise sys_ni_syscall
28#define sys_readahead sys_ni_syscall
29#define sys_mprotect sys_ni_syscall
30#define sys_msync sys_ni_syscall
31#define sys_mlock sys_ni_syscall
32#define sys_munlock sys_ni_syscall
33#define sys_mlockall sys_ni_syscall
34#define sys_munlockall sys_ni_syscall
35#define sys_mremap sys_ni_syscall
36#define sys_mincore sys_ni_syscall
37#define sys_remap_file_pages sys_ni_syscall
38#endif
39
40! NOTE:
41! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
42! to be jumped is too far, but it causes illegal slot exception.
43
44/*
45 * entry.S contains the system-call and fault low-level handling routines.
46 * This also contains the timer-interrupt handler, as well as all interrupts
47 * and faults that can result in a task-switch.
48 *
49 * NOTE: This code handles signal-recognition, which happens every time
50 * after a timer-interrupt and after each system call.
51 *
52 * NOTE: This code uses a convention that instructions in the delay slot
53 * of a transfer-control instruction are indented by an extra space, thus:
54 *
55 * jmp @k0 ! control-transfer instruction
56 * ldc k1, ssr ! delay slot
57 *
58 * Stack layout in 'ret_from_syscall':
59 * ptrace needs to have all regs on the stack.
60 * if the order here is changed, it needs to be
61 * updated in ptrace.c and ptrace.h
62 *
63 * r0
64 * ...
65 * r15 = stack pointer
66 * spc
67 * pr
68 * ssr
69 * gbr
70 * mach
71 * macl
72 * syscall #
73 *
74 */
75
76ENOSYS = 38
77EINVAL = 22
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079#if defined(CONFIG_KGDB_NMI)
80NMI_VEC = 0x1c0 ! Must catch early for debounce
81#endif
82
83/* Offsets to the stack */
84OFF_R0 = 0 /* Return value. New ABI also arg4 */
85OFF_R1 = 4 /* New ABI: arg5 */
86OFF_R2 = 8 /* New ABI: arg6 */
87OFF_R3 = 12 /* New ABI: syscall_nr */
88OFF_R4 = 16 /* New ABI: arg0 */
89OFF_R5 = 20 /* New ABI: arg1 */
90OFF_R6 = 24 /* New ABI: arg2 */
91OFF_R7 = 28 /* New ABI: arg3 */
92OFF_SP = (15*4)
93OFF_PC = (16*4)
94OFF_SR = (16*4+8)
95OFF_TRA = (16*4+6*4)
96
97
98#define k0 r0
99#define k1 r1
100#define k2 r2
101#define k3 r3
102#define k4 r4
103
104#define k_ex_code r2_bank /* r2_bank1 */
105#define g_imask r6 /* r6_bank1 */
106#define k_g_imask r6_bank /* r6_bank1 */
107#define current r7 /* r7_bank1 */
108
109/*
110 * Kernel mode register usage:
111 * k0 scratch
112 * k1 scratch
113 * k2 scratch (Exception code)
114 * k3 scratch (Return address)
115 * k4 scratch
116 * k5 reserved
117 * k6 Global Interrupt Mask (0--15 << 4)
118 * k7 CURRENT_THREAD_INFO (pointer to current thread info)
119 */
120
121!
122! TLB Miss / Initial Page write exception handling
123! _and_
124! TLB hits, but the access violate the protection.
125! It can be valid access, such as stack grow and/or C-O-W.
126!
127!
128! Find the pmd/pte entry and loadtlb
129! If it's not found, cause address error (SEGV)
130!
131! Although this could be written in assembly language (and it'd be faster),
132! this first version depends *much* on C implementation.
133!
134
135#define CLI() \
136 stc sr, r0; \
137 or #0xf0, r0; \
138 ldc r0, sr
139
140#define STI() \
141 mov.l __INV_IMASK, r11; \
142 stc sr, r10; \
143 and r11, r10; \
144 stc k_g_imask, r11; \
145 or r11, r10; \
146 ldc r10, sr
147
148#if defined(CONFIG_PREEMPT)
149# define preempt_stop() CLI()
150#else
151# define preempt_stop()
152# define resume_kernel restore_all
153#endif
154
155#if defined(CONFIG_MMU)
156 .align 2
157ENTRY(tlb_miss_load)
158 bra call_dpf
159 mov #0, r5
160
161 .align 2
162ENTRY(tlb_miss_store)
163 bra call_dpf
164 mov #1, r5
165
166 .align 2
167ENTRY(initial_page_write)
168 bra call_dpf
169 mov #1, r5
170
171 .align 2
172ENTRY(tlb_protection_violation_load)
173 bra call_dpf
174 mov #0, r5
175
176 .align 2
177ENTRY(tlb_protection_violation_store)
178 bra call_dpf
179 mov #1, r5
180
181call_dpf:
182 mov.l 1f, r0
183 mov r5, r8
184 mov.l @r0, r6
185 mov r6, r9
186 mov.l 2f, r0
187 sts pr, r10
188 jsr @r0
189 mov r15, r4
190 !
191 tst r0, r0
192 bf/s 0f
193 lds r10, pr
194 rts
195 nop
1960: STI()
197 mov.l 3f, r0
198 mov r9, r6
199 mov r8, r5
200 jmp @r0
201 mov r15, r4
202
203 .align 2
2041: .long MMU_TEA
2052: .long __do_page_fault
2063: .long do_page_fault
207
208 .align 2
209ENTRY(address_error_load)
210 bra call_dae
211 mov #0,r5 ! writeaccess = 0
212
213 .align 2
214ENTRY(address_error_store)
215 bra call_dae
216 mov #1,r5 ! writeaccess = 1
217
218 .align 2
219call_dae:
220 mov.l 1f, r0
221 mov.l @r0, r6 ! address
222 mov.l 2f, r0
223 jmp @r0
224 mov r15, r4 ! regs
225
226 .align 2
2271: .long MMU_TEA
2282: .long do_address_error
229#endif /* CONFIG_MMU */
230
231#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
232! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
233! If both are configured, handle the debug traps (breakpoints) in SW,
234! but still allow BIOS traps to FW.
235
236 .align 2
237debug_kernel:
238#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
239 /* Force BIOS call to FW (debug_trap put TRA in r8) */
240 mov r8,r0
241 shlr2 r0
242 cmp/eq #0x3f,r0
243 bt debug_kernel_fw
244#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
245
246debug_enter:
247#if defined(CONFIG_SH_KGDB)
248 /* Jump to kgdb, pass stacked regs as arg */
249debug_kernel_sw:
250 mov.l 3f, r0
251 jmp @r0
252 mov r15, r4
253 .align 2
2543: .long kgdb_handle_exception
255#endif /* CONFIG_SH_KGDB */
256
257#if defined(CONFIG_SH_STANDARD_BIOS)
258 /* Unwind the stack and jmp to the debug entry */
259debug_kernel_fw:
260 mov.l @r15+, r0
261 mov.l @r15+, r1
262 mov.l @r15+, r2
263 mov.l @r15+, r3
264 mov.l @r15+, r4
265 mov.l @r15+, r5
266 mov.l @r15+, r6
267 mov.l @r15+, r7
268 stc sr, r8
269 mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F
270 or r9, r8
271 ldc r8, sr ! here, change the register bank
272 mov.l @r15+, r8
273 mov.l @r15+, r9
274 mov.l @r15+, r10
275 mov.l @r15+, r11
276 mov.l @r15+, r12
277 mov.l @r15+, r13
278 mov.l @r15+, r14
279 mov.l @r15+, k0
280 ldc.l @r15+, spc
281 lds.l @r15+, pr
282 mov.l @r15+, k1
283 ldc.l @r15+, gbr
284 lds.l @r15+, mach
285 lds.l @r15+, macl
286 mov k0, r15
287 !
288 mov.l 2f, k0
289 mov.l @k0, k0
290 jmp @k0
291 ldc k1, ssr
292 .align 2
2931: .long 0x300000f0
2942: .long gdb_vbr_vector
295#endif /* CONFIG_SH_STANDARD_BIOS */
296
297#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
298
299
300 .align 2
301debug_trap:
302#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
303 mov #OFF_SR, r0
304 mov.l @(r0,r15), r0 ! get status register
305 shll r0
306 shll r0 ! kernel space?
307 bt/s debug_kernel
308#endif
309 mov.l @r15, r0 ! Restore R0 value
310 mov.l 1f, r8
311 jmp @r8
312 nop
313
314 .align 2
315ENTRY(exception_error)
316 !
317 STI()
318 mov.l 2f, r0
319 jmp @r0
320 nop
321
322!
323 .align 2
3241: .long break_point_trap_software
3252: .long do_exception_error
326
327 .align 2
328ret_from_exception:
329 preempt_stop()
330ret_from_irq:
331 !
332 mov #OFF_SR, r0
333 mov.l @(r0,r15), r0 ! get status register
334 shll r0
335 shll r0 ! kernel space?
336 bt/s resume_kernel ! Yes, it's from kernel, go back soon
337 GET_THREAD_INFO(r8)
338
339#ifdef CONFIG_PREEMPT
340 bra resume_userspace
341 nop
342ENTRY(resume_kernel)
343 mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
344 tst r0, r0
345 bf noresched
346need_resched:
347 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
348 tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
349 bt noresched
350
351 mov #OFF_SR, r0
352 mov.l @(r0,r15), r0 ! get status register
353 and #0xf0, r0 ! interrupts off (exception path)?
354 cmp/eq #0xf0, r0
355 bt noresched
356
357 mov.l 1f, r0
358 mov.l r0, @(TI_PRE_COUNT,r8)
359
360 STI()
361 mov.l 2f, r0
362 jsr @r0
363 nop
364 mov #0, r0
365 mov.l r0, @(TI_PRE_COUNT,r8)
366 CLI()
367
368 bra need_resched
369 nop
370noresched:
371 bra restore_all
372 nop
373
374 .align 2
3751: .long PREEMPT_ACTIVE
3762: .long schedule
377#endif
378
379ENTRY(resume_userspace)
380 ! r8: current_thread_info
381 CLI()
382 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
383 tst #_TIF_WORK_MASK, r0
384 bt/s restore_all
385 tst #_TIF_NEED_RESCHED, r0
386
387 .align 2
388work_pending:
389 ! r0: current_thread_info->flags
390 ! r8: current_thread_info
391 ! t: result of "tst #_TIF_NEED_RESCHED, r0"
392 bf/s work_resched
393 tst #_TIF_SIGPENDING, r0
394work_notifysig:
395 bt/s restore_all
396 mov r15, r4
397 mov #0, r5
398 mov.l 2f, r1
399 mova restore_all, r0
400 jmp @r1
401 lds r0, pr
402work_resched:
403#ifndef CONFIG_PREEMPT
404 ! gUSA handling
405 mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
406 mov r0, r1
407 shll r0
408 bf/s 1f
409 shll r0
410 bf/s 1f
411 mov #OFF_PC, r0
412 ! SP >= 0xc0000000 : gUSA mark
413 mov.l @(r0,r15), r2 ! get user space PC (program counter)
414 mov.l @(OFF_R0,r15), r3 ! end point
415 cmp/hs r3, r2 ! r2 >= r3?
416 bt 1f
417 add r3, r1 ! rewind point #2
418 mov.l r1, @(r0,r15) ! reset PC to rewind point #2
419 !
4201:
421#endif
422 mov.l 1f, r1
423 jsr @r1 ! schedule
424 nop
425 CLI()
426 !
427 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
428 tst #_TIF_WORK_MASK, r0
429 bt restore_all
430 bra work_pending
431 tst #_TIF_NEED_RESCHED, r0
432
433 .align 2
4341: .long schedule
4352: .long do_signal
436
437 .align 2
438syscall_exit_work:
439 ! r0: current_thread_info->flags
440 ! r8: current_thread_info
441 tst #_TIF_SYSCALL_TRACE, r0
442 bt/s work_pending
443 tst #_TIF_NEED_RESCHED, r0
444 STI()
445 ! XXX setup arguments...
446 mov.l 4f, r0 ! do_syscall_trace
447 jsr @r0
448 nop
449 bra resume_userspace
450 nop
451
452 .align 2
453syscall_trace_entry:
454 ! Yes it is traced.
455 ! XXX setup arguments...
456 mov.l 4f, r11 ! Call do_syscall_trace which notifies
457 jsr @r11 ! superior (will chomp R[0-7])
458 nop
459 ! Reload R0-R4 from kernel stack, where the
460 ! parent may have modified them using
461 ! ptrace(POKEUSR). (Note that R0-R2 are
462 ! used by the system call handler directly
463 ! from the kernel stack anyway, so don't need
464 ! to be reloaded here.) This allows the parent
465 ! to rewrite system calls and args on the fly.
466 mov.l @(OFF_R4,r15), r4 ! arg0
467 mov.l @(OFF_R5,r15), r5
468 mov.l @(OFF_R6,r15), r6
469 mov.l @(OFF_R7,r15), r7 ! arg3
470 mov.l @(OFF_R3,r15), r3 ! syscall_nr
471 ! Arrange for do_syscall_trace to be called
472 ! again as the system call returns.
473 mov.l 2f, r10 ! Number of syscalls
474 cmp/hs r10, r3
475 bf syscall_call
476 mov #-ENOSYS, r0
477 bra syscall_exit
478 mov.l r0, @(OFF_R0,r15) ! Return value
479
480/*
481 * Syscall interface:
482 *
483 * Syscall #: R3
484 * Arguments #0 to #3: R4--R7
485 * Arguments #4 to #6: R0, R1, R2
486 * TRA: (number of arguments + 0x10) x 4
487 *
488 * This code also handles delegating other traps to the BIOS/gdb stub
489 * according to:
490 *
491 * Trap number
492 * (TRA>>2) Purpose
493 * -------- -------
494 * 0x0-0xf old syscall ABI
495 * 0x10-0x1f new syscall ABI
496 * 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
497 *
498 * Note: When we're first called, the TRA value must be shifted
499 * right 2 bits in order to get the value that was used as the "trapa"
500 * argument.
501 */
502
503 .align 2
504 .globl ret_from_fork
505ret_from_fork:
506 mov.l 1f, r8
507 jsr @r8
508 mov r0, r4
509 bra syscall_exit
510 nop
511 .align 2
5121: .long schedule_tail
513 !
514ENTRY(system_call)
515 mov.l 1f, r9
516 mov.l @r9, r8 ! Read from TRA (Trap Address) Register
517 !
518 ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
519 mov #0x7f, r9
520 cmp/hi r9, r8
521 bt/s 0f
522 mov #OFF_TRA, r9
523 add r15, r9
524 !
525 mov.l r8, @r9 ! set TRA value to tra
526 STI()
527 ! Call the system call handler through the table.
528 ! First check for bad syscall number
529 mov r3, r9
530 mov.l 2f, r8 ! Number of syscalls
531 cmp/hs r8, r9
532 bf/s good_system_call
533 GET_THREAD_INFO(r8)
534syscall_badsys: ! Bad syscall number
535 mov #-ENOSYS, r0
536 bra resume_userspace
537 mov.l r0, @(OFF_R0,r15) ! Return value
538 !
5390:
540 bra debug_trap
541 nop
542 !
543good_system_call: ! Good syscall number
544 mov.l @(TI_FLAGS,r8), r8
545 mov #_TIF_SYSCALL_TRACE, r10
546 tst r10, r8
547 bf syscall_trace_entry
548 !
549syscall_call:
550 shll2 r9 ! x4
551 mov.l 3f, r8 ! Load the address of sys_call_table
552 add r8, r9
553 mov.l @r9, r8
554 jsr @r8 ! jump to specific syscall handler
555 nop
556 mov.l r0, @(OFF_R0,r15) ! save the return value
557 !
558syscall_exit:
559 CLI()
560 !
561 GET_THREAD_INFO(r8)
562 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
563 tst #_TIF_ALLWORK_MASK, r0
564 bf syscall_exit_work
565restore_all:
566 mov.l @r15+, r0
567 mov.l @r15+, r1
568 mov.l @r15+, r2
569 mov.l @r15+, r3
570 mov.l @r15+, r4
571 mov.l @r15+, r5
572 mov.l @r15+, r6
573 mov.l @r15+, r7
574 !
575 stc sr, r8
576 mov.l 7f, r9
577 or r9, r8 ! BL =1, RB=1
578 ldc r8, sr ! here, change the register bank
579 !
580 mov.l @r15+, r8
581 mov.l @r15+, r9
582 mov.l @r15+, r10
583 mov.l @r15+, r11
584 mov.l @r15+, r12
585 mov.l @r15+, r13
586 mov.l @r15+, r14
587 mov.l @r15+, k4 ! original stack pointer
588 ldc.l @r15+, spc
589 lds.l @r15+, pr
590 mov.l @r15+, k3 ! original SR
591 ldc.l @r15+, gbr
592 lds.l @r15+, mach
593 lds.l @r15+, macl
594 add #4, r15 ! Skip syscall number
595 !
596#ifdef CONFIG_SH_DSP
597 mov.l @r15+, k0 ! DSP mode marker
598 mov.l 5f, k1
599 cmp/eq k0, k1 ! Do we have a DSP stack frame?
600 bf skip_restore
601
602 stc sr, k0 ! Enable CPU DSP mode
603 or k1, k0 ! (within kernel it may be disabled)
604 ldc k0, sr
605 mov r2, k0 ! Backup r2
606
607 ! Restore DSP registers from stack
608 mov r15, r2
609 movs.l @r2+, a1
610 movs.l @r2+, a0g
611 movs.l @r2+, a1g
612 movs.l @r2+, m0
613 movs.l @r2+, m1
614 mov r2, r15
615
616 lds.l @r15+, a0
617 lds.l @r15+, x0
618 lds.l @r15+, x1
619 lds.l @r15+, y0
620 lds.l @r15+, y1
621 lds.l @r15+, dsr
622 ldc.l @r15+, rs
623 ldc.l @r15+, re
624 ldc.l @r15+, mod
625
626 mov k0, r2 ! Restore r2
627skip_restore:
628#endif
629 !
630 ! Calculate new SR value
631 mov k3, k2 ! original SR value
632 mov.l 9f, k1
633 and k1, k2 ! Mask orignal SR value
634 !
635 mov k3, k0 ! Calculate IMASK-bits
636 shlr2 k0
637 and #0x3c, k0
638 cmp/eq #0x3c, k0
639 bt/s 6f
640 shll2 k0
641 mov g_imask, k0
642 !
6436: or k0, k2 ! Set the IMASK-bits
644 ldc k2, ssr
645 !
646#if defined(CONFIG_KGDB_NMI)
647 ! Clear in_nmi
648 mov.l 4f, k0
649 mov #0, k1
650 mov.b k1, @k0
651#endif
652 mov.l @r15+, k2 ! restore EXPEVT
653 mov k4, r15
654 rte
655 nop
656
657 .align 2
6581: .long TRA
6592: .long NR_syscalls
6603: .long sys_call_table
6614: .long do_syscall_trace
6625: .long 0x00001000 ! DSP
6637: .long 0x30000000
6649:
665__INV_IMASK:
666 .long 0xffffff0f ! ~(IMASK)
667
668! Exception Vector Base
669!
670! Should be aligned page boundary.
671!
672 .balign 4096,0,4096
673ENTRY(vbr_base)
674 .long 0
675!
676 .balign 256,0,256
677general_exception:
678 mov.l 1f, k2
679 mov.l 2f, k3
680 bra handle_exception
681 mov.l @k2, k2
682 .align 2
6831: .long EXPEVT
6842: .long ret_from_exception
685!
686!
687 .balign 1024,0,1024
688tlb_miss:
689 mov.l 1f, k2
690 mov.l 4f, k3
691 bra handle_exception
692 mov.l @k2, k2
693!
694 .balign 512,0,512
695interrupt:
696 mov.l 2f, k2
697 mov.l 3f, k3
698#if defined(CONFIG_KGDB_NMI)
699 ! Debounce (filter nested NMI)
700 mov.l @k2, k0
701 mov.l 5f, k1
702 cmp/eq k1, k0
703 bf 0f
704 mov.l 6f, k1
705 tas.b @k1
706 bt 0f
707 rte
708 nop
709 .align 2
7105: .long NMI_VEC
7116: .long in_nmi
7120:
713#endif /* defined(CONFIG_KGDB_NMI) */
714 bra handle_exception
715 mov.l @k2, k2
716
717 .align 2
7181: .long EXPEVT
7192: .long INTEVT
7203: .long ret_from_irq
7214: .long ret_from_exception
722
723!
724!
725 .align 2
726handle_exception:
727 ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
728 ! save all registers onto stack.
729 !
730 stc ssr, k0 ! Is it from kernel space?
731 shll k0 ! Check MD bit (bit30) by shifting it into...
732 shll k0 ! ...the T bit
733 bt/s 1f ! It's a kernel to kernel transition.
734 mov r15, k0 ! save original stack to k0
735 /* User space to kernel */
736 mov #0x20, k1
737 shll8 k1 ! k1 := 8192 (== THREAD_SIZE)
738 add current, k1
739 mov k1, r15 ! change to kernel stack
740 !
7411: mov #-1, k4
742 mov.l 2f, k1
743 !
744#ifdef CONFIG_SH_DSP
745 mov.l r2, @-r15 ! Save r2, we need another reg
746 stc sr, k4
747 mov.l 1f, r2
748 tst r2, k4 ! Check if in DSP mode
749 mov.l @r15+, r2 ! Restore r2 now
750 bt/s skip_save
751 mov #0, k4 ! Set marker for no stack frame
752
753 mov r2, k4 ! Backup r2 (in k4) for later
754
755 ! Save DSP registers on stack
756 stc.l mod, @-r15
757 stc.l re, @-r15
758 stc.l rs, @-r15
759 sts.l dsr, @-r15
760 sts.l y1, @-r15
761 sts.l y0, @-r15
762 sts.l x1, @-r15
763 sts.l x0, @-r15
764 sts.l a0, @-r15
765
766 ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
767
768 ! FIXME: Make sure that this is still the case with newer toolchains,
769 ! as we're not at all interested in supporting ancient toolchains at
770 ! this point. -- PFM.
771
772 mov r15, r2
773 .word 0xf653 ! movs.l a1, @-r2
774 .word 0xf6f3 ! movs.l a0g, @-r2
775 .word 0xf6d3 ! movs.l a1g, @-r2
776 .word 0xf6c3 ! movs.l m0, @-r2
777 .word 0xf6e3 ! movs.l m1, @-r2
778 mov r2, r15
779
780 mov k4, r2 ! Restore r2
781 mov.l 1f, k4 ! Force DSP stack frame
782skip_save:
783 mov.l k4, @-r15 ! Push DSP mode marker onto stack
784#endif
785 ! Save the user registers on the stack.
786 mov.l k2, @-r15 ! EXPEVT
787 mov.l k4, @-r15 ! set TRA (default: -1)
788 !
789 sts.l macl, @-r15
790 sts.l mach, @-r15
791 stc.l gbr, @-r15
792 stc.l ssr, @-r15
793 sts.l pr, @-r15
794 stc.l spc, @-r15
795 !
796 lds k3, pr ! Set the return address to pr
797 !
798 mov.l k0, @-r15 ! save orignal stack
799 mov.l r14, @-r15
800 mov.l r13, @-r15
801 mov.l r12, @-r15
802 mov.l r11, @-r15
803 mov.l r10, @-r15
804 mov.l r9, @-r15
805 mov.l r8, @-r15
806 !
807 stc sr, r8 ! Back to normal register bank, and
808 or k1, r8 ! Block all interrupts
809 mov.l 3f, k1
810 and k1, r8 ! ...
811 ldc r8, sr ! ...changed here.
812 !
813 mov.l r7, @-r15
814 mov.l r6, @-r15
815 mov.l r5, @-r15
816 mov.l r4, @-r15
817 mov.l r3, @-r15
818 mov.l r2, @-r15
819 mov.l r1, @-r15
820 mov.l r0, @-r15
821 ! Then, dispatch to the handler, according to the exception code.
822 stc k_ex_code, r8
823 shlr2 r8
824 shlr r8
825 mov.l 4f, r9
826 add r8, r9
827 mov.l @r9, r9
828 jmp @r9
829 nop
830
831 .align 2
8321: .long 0x00001000 ! DSP=1
8332: .long 0x000080f0 ! FD=1, IMASK=15
8343: .long 0xcfffffff ! RB=0, BL=0
8354: .long exception_handling_table
836
837 .align 2
838ENTRY(exception_none)
839 rts
840 nop
841
842 .data
843ENTRY(sys_call_table)
844 .long sys_ni_syscall /* 0 - old "setup()" system call*/
845 .long sys_exit
846 .long sys_fork
847 .long sys_read
848 .long sys_write
849 .long sys_open /* 5 */
850 .long sys_close
851 .long sys_waitpid
852 .long sys_creat
853 .long sys_link
854 .long sys_unlink /* 10 */
855 .long sys_execve
856 .long sys_chdir
857 .long sys_time
858 .long sys_mknod
859 .long sys_chmod /* 15 */
860 .long sys_lchown16
861 .long sys_ni_syscall /* old break syscall holder */
862 .long sys_stat
863 .long sys_lseek
864 .long sys_getpid /* 20 */
865 .long sys_mount
866 .long sys_oldumount
867 .long sys_setuid16
868 .long sys_getuid16
869 .long sys_stime /* 25 */
870 .long sys_ptrace
871 .long sys_alarm
872 .long sys_fstat
873 .long sys_pause
874 .long sys_utime /* 30 */
875 .long sys_ni_syscall /* old stty syscall holder */
876 .long sys_ni_syscall /* old gtty syscall holder */
877 .long sys_access
878 .long sys_nice
879 .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
880 .long sys_sync
881 .long sys_kill
882 .long sys_rename
883 .long sys_mkdir
884 .long sys_rmdir /* 40 */
885 .long sys_dup
886 .long sys_pipe
887 .long sys_times
888 .long sys_ni_syscall /* old prof syscall holder */
889 .long sys_brk /* 45 */
890 .long sys_setgid16
891 .long sys_getgid16
892 .long sys_signal
893 .long sys_geteuid16
894 .long sys_getegid16 /* 50 */
895 .long sys_acct
896 .long sys_umount /* recycled never used phys() */
897 .long sys_ni_syscall /* old lock syscall holder */
898 .long sys_ioctl
899 .long sys_fcntl /* 55 */
900 .long sys_ni_syscall /* old mpx syscall holder */
901 .long sys_setpgid
902 .long sys_ni_syscall /* old ulimit syscall holder */
903 .long sys_ni_syscall /* sys_olduname */
904 .long sys_umask /* 60 */
905 .long sys_chroot
906 .long sys_ustat
907 .long sys_dup2
908 .long sys_getppid
909 .long sys_getpgrp /* 65 */
910 .long sys_setsid
911 .long sys_sigaction
912 .long sys_sgetmask
913 .long sys_ssetmask
914 .long sys_setreuid16 /* 70 */
915 .long sys_setregid16
916 .long sys_sigsuspend
917 .long sys_sigpending
918 .long sys_sethostname
919 .long sys_setrlimit /* 75 */
920 .long sys_old_getrlimit
921 .long sys_getrusage
922 .long sys_gettimeofday
923 .long sys_settimeofday
924 .long sys_getgroups16 /* 80 */
925 .long sys_setgroups16
926 .long sys_ni_syscall /* sys_oldselect */
927 .long sys_symlink
928 .long sys_lstat
929 .long sys_readlink /* 85 */
930 .long sys_uselib
931 .long sys_swapon
932 .long sys_reboot
933 .long old_readdir
934 .long old_mmap /* 90 */
935 .long sys_munmap
936 .long sys_truncate
937 .long sys_ftruncate
938 .long sys_fchmod
939 .long sys_fchown16 /* 95 */
940 .long sys_getpriority
941 .long sys_setpriority
942 .long sys_ni_syscall /* old profil syscall holder */
943 .long sys_statfs
944 .long sys_fstatfs /* 100 */
945 .long sys_ni_syscall /* ioperm */
946 .long sys_socketcall
947 .long sys_syslog
948 .long sys_setitimer
949 .long sys_getitimer /* 105 */
950 .long sys_newstat
951 .long sys_newlstat
952 .long sys_newfstat
953 .long sys_uname
954 .long sys_ni_syscall /* 110 */ /* iopl */
955 .long sys_vhangup
956 .long sys_ni_syscall /* idle */
957 .long sys_ni_syscall /* vm86old */
958 .long sys_wait4
959 .long sys_swapoff /* 115 */
960 .long sys_sysinfo
961 .long sys_ipc
962 .long sys_fsync
963 .long sys_sigreturn
964 .long sys_clone /* 120 */
965 .long sys_setdomainname
966 .long sys_newuname
967 .long sys_ni_syscall /* sys_modify_ldt */
968 .long sys_adjtimex
969 .long sys_mprotect /* 125 */
970 .long sys_sigprocmask
971 .long sys_ni_syscall /* old "create_module" */
972 .long sys_init_module
973 .long sys_delete_module
974 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
975 .long sys_quotactl
976 .long sys_getpgid
977 .long sys_fchdir
978 .long sys_bdflush
979 .long sys_sysfs /* 135 */
980 .long sys_personality
981 .long sys_ni_syscall /* for afs_syscall */
982 .long sys_setfsuid16
983 .long sys_setfsgid16
984 .long sys_llseek /* 140 */
985 .long sys_getdents
986 .long sys_select
987 .long sys_flock
988 .long sys_msync
989 .long sys_readv /* 145 */
990 .long sys_writev
991 .long sys_getsid
992 .long sys_fdatasync
993 .long sys_sysctl
994 .long sys_mlock /* 150 */
995 .long sys_munlock
996 .long sys_mlockall
997 .long sys_munlockall
998 .long sys_sched_setparam
999 .long sys_sched_getparam /* 155 */
1000 .long sys_sched_setscheduler
1001 .long sys_sched_getscheduler
1002 .long sys_sched_yield
1003 .long sys_sched_get_priority_max
1004 .long sys_sched_get_priority_min /* 160 */
1005 .long sys_sched_rr_get_interval
1006 .long sys_nanosleep
1007 .long sys_mremap
1008 .long sys_setresuid16
1009 .long sys_getresuid16 /* 165 */
1010 .long sys_ni_syscall /* vm86 */
1011 .long sys_ni_syscall /* old "query_module" */
1012 .long sys_poll
1013 .long sys_nfsservctl
1014 .long sys_setresgid16 /* 170 */
1015 .long sys_getresgid16
1016 .long sys_prctl
1017 .long sys_rt_sigreturn
1018 .long sys_rt_sigaction
1019 .long sys_rt_sigprocmask /* 175 */
1020 .long sys_rt_sigpending
1021 .long sys_rt_sigtimedwait
1022 .long sys_rt_sigqueueinfo
1023 .long sys_rt_sigsuspend
1024 .long sys_pread_wrapper /* 180 */
1025 .long sys_pwrite_wrapper
1026 .long sys_chown16
1027 .long sys_getcwd
1028 .long sys_capget
1029 .long sys_capset /* 185 */
1030 .long sys_sigaltstack
1031 .long sys_sendfile
1032 .long sys_ni_syscall /* streams1 */
1033 .long sys_ni_syscall /* streams2 */
1034 .long sys_vfork /* 190 */
1035 .long sys_getrlimit
1036 .long sys_mmap2
1037 .long sys_truncate64
1038 .long sys_ftruncate64
1039 .long sys_stat64 /* 195 */
1040 .long sys_lstat64
1041 .long sys_fstat64
1042 .long sys_lchown
1043 .long sys_getuid
1044 .long sys_getgid /* 200 */
1045 .long sys_geteuid
1046 .long sys_getegid
1047 .long sys_setreuid
1048 .long sys_setregid
1049 .long sys_getgroups /* 205 */
1050 .long sys_setgroups
1051 .long sys_fchown
1052 .long sys_setresuid
1053 .long sys_getresuid
1054 .long sys_setresgid /* 210 */
1055 .long sys_getresgid
1056 .long sys_chown
1057 .long sys_setuid
1058 .long sys_setgid
1059 .long sys_setfsuid /* 215 */
1060 .long sys_setfsgid
1061 .long sys_pivot_root
1062 .long sys_mincore
1063 .long sys_madvise
1064 .long sys_getdents64 /* 220 */
1065 .long sys_fcntl64
1066 .long sys_ni_syscall /* reserved for TUX */
1067 .long sys_ni_syscall /* Reserved for Security */
1068 .long sys_gettid
1069 .long sys_readahead /* 225 */
1070 .long sys_setxattr
1071 .long sys_lsetxattr
1072 .long sys_fsetxattr
1073 .long sys_getxattr
1074 .long sys_lgetxattr /* 230 */
1075 .long sys_fgetxattr
1076 .long sys_listxattr
1077 .long sys_llistxattr
1078 .long sys_flistxattr
1079 .long sys_removexattr /* 235 */
1080 .long sys_lremovexattr
1081 .long sys_fremovexattr
1082 .long sys_tkill
1083 .long sys_sendfile64
1084 .long sys_futex /* 240 */
1085 .long sys_sched_setaffinity
1086 .long sys_sched_getaffinity
1087 .long sys_ni_syscall
1088 .long sys_ni_syscall
1089 .long sys_io_setup /* 245 */
1090 .long sys_io_destroy
1091 .long sys_io_getevents
1092 .long sys_io_submit
1093 .long sys_io_cancel
1094 .long sys_fadvise64 /* 250 */
1095 .long sys_ni_syscall
1096 .long sys_exit_group
1097 .long sys_lookup_dcookie
1098 .long sys_epoll_create
1099 .long sys_epoll_ctl /* 255 */
1100 .long sys_epoll_wait
1101 .long sys_remap_file_pages
1102 .long sys_set_tid_address
1103 .long sys_timer_create
1104 .long sys_timer_settime /* 260 */
1105 .long sys_timer_gettime
1106 .long sys_timer_getoverrun
1107 .long sys_timer_delete
1108 .long sys_clock_settime
1109 .long sys_clock_gettime /* 265 */
1110 .long sys_clock_getres
1111 .long sys_clock_nanosleep
1112 .long sys_statfs64
1113 .long sys_fstatfs64
1114 .long sys_tgkill /* 270 */
1115 .long sys_utimes
1116 .long sys_fadvise64_64_wrapper
1117 .long sys_ni_syscall /* Reserved for vserver */
1118 .long sys_ni_syscall /* Reserved for mbind */
1119 .long sys_ni_syscall /* 275 - get_mempolicy */
1120 .long sys_ni_syscall /* set_mempolicy */
1121 .long sys_mq_open
1122 .long sys_mq_unlink
1123 .long sys_mq_timedsend
1124 .long sys_mq_timedreceive /* 280 */
1125 .long sys_mq_notify
1126 .long sys_mq_getsetattr
1127 .long sys_ni_syscall /* Reserved for kexec */
1128 .long sys_waitid
1129 .long sys_add_key /* 285 */
1130 .long sys_request_key
1131 .long sys_keyctl
Robert Lovef2926b72005-08-18 11:24:13 -07001132 .long sys_ioprio_set
1133 .long sys_ioprio_get
1134 .long sys_inotify_init /* 290 */
1135 .long sys_inotify_add_watch
1136 .long sys_inotify_rm_watch
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138/* End of entry.S */