at v2.6.17 1138 lines 25 kB view raw
1/* $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> 19#include <asm/cpu/mmu_context.h> 20#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 79#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 1132 .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 1137 1138/* End of entry.S */