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