11da177e4SLinus Torvalds/* 21da177e4SLinus Torvalds * arch/alpha/kernel/entry.S 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Kernel entry-points. 51da177e4SLinus Torvalds */ 61da177e4SLinus Torvalds 7e2d5df93SSam Ravnborg#include <asm/asm-offsets.h> 81da177e4SLinus Torvalds#include <asm/thread_info.h> 91da177e4SLinus Torvalds#include <asm/pal.h> 101da177e4SLinus Torvalds#include <asm/errno.h> 111da177e4SLinus Torvalds#include <asm/unistd.h> 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds .text 141da177e4SLinus Torvalds .set noat 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds/* Stack offsets. */ 171da177e4SLinus Torvalds#define SP_OFF 184 181da177e4SLinus Torvalds#define SWITCH_STACK_SIZE 320 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds/* 211da177e4SLinus Torvalds * This defines the normal kernel pt-regs layout. 221da177e4SLinus Torvalds * 231da177e4SLinus Torvalds * regs 9-15 preserved by C code 241da177e4SLinus Torvalds * regs 16-18 saved by PAL-code 251da177e4SLinus Torvalds * regs 29-30 saved and set up by PAL-code 261da177e4SLinus Torvalds * JRP - Save regs 16-18 in a special area of the stack, so that 271da177e4SLinus Torvalds * the palcode-provided values are available to the signal handler. 281da177e4SLinus Torvalds */ 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds#define SAVE_ALL \ 311da177e4SLinus Torvalds subq $sp, SP_OFF, $sp; \ 321da177e4SLinus Torvalds stq $0, 0($sp); \ 331da177e4SLinus Torvalds stq $1, 8($sp); \ 341da177e4SLinus Torvalds stq $2, 16($sp); \ 351da177e4SLinus Torvalds stq $3, 24($sp); \ 361da177e4SLinus Torvalds stq $4, 32($sp); \ 371da177e4SLinus Torvalds stq $28, 144($sp); \ 381da177e4SLinus Torvalds lda $2, alpha_mv; \ 391da177e4SLinus Torvalds stq $5, 40($sp); \ 401da177e4SLinus Torvalds stq $6, 48($sp); \ 411da177e4SLinus Torvalds stq $7, 56($sp); \ 421da177e4SLinus Torvalds stq $8, 64($sp); \ 431da177e4SLinus Torvalds stq $19, 72($sp); \ 441da177e4SLinus Torvalds stq $20, 80($sp); \ 451da177e4SLinus Torvalds stq $21, 88($sp); \ 461da177e4SLinus Torvalds ldq $2, HAE_CACHE($2); \ 471da177e4SLinus Torvalds stq $22, 96($sp); \ 481da177e4SLinus Torvalds stq $23, 104($sp); \ 491da177e4SLinus Torvalds stq $24, 112($sp); \ 501da177e4SLinus Torvalds stq $25, 120($sp); \ 511da177e4SLinus Torvalds stq $26, 128($sp); \ 521da177e4SLinus Torvalds stq $27, 136($sp); \ 531da177e4SLinus Torvalds stq $2, 152($sp); \ 541da177e4SLinus Torvalds stq $16, 160($sp); \ 551da177e4SLinus Torvalds stq $17, 168($sp); \ 561da177e4SLinus Torvalds stq $18, 176($sp) 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds#define RESTORE_ALL \ 591da177e4SLinus Torvalds lda $19, alpha_mv; \ 601da177e4SLinus Torvalds ldq $0, 0($sp); \ 611da177e4SLinus Torvalds ldq $1, 8($sp); \ 621da177e4SLinus Torvalds ldq $2, 16($sp); \ 631da177e4SLinus Torvalds ldq $3, 24($sp); \ 641da177e4SLinus Torvalds ldq $21, 152($sp); \ 651da177e4SLinus Torvalds ldq $20, HAE_CACHE($19); \ 661da177e4SLinus Torvalds ldq $4, 32($sp); \ 671da177e4SLinus Torvalds ldq $5, 40($sp); \ 681da177e4SLinus Torvalds ldq $6, 48($sp); \ 691da177e4SLinus Torvalds ldq $7, 56($sp); \ 701da177e4SLinus Torvalds subq $20, $21, $20; \ 711da177e4SLinus Torvalds ldq $8, 64($sp); \ 721da177e4SLinus Torvalds beq $20, 99f; \ 731da177e4SLinus Torvalds ldq $20, HAE_REG($19); \ 741da177e4SLinus Torvalds stq $21, HAE_CACHE($19); \ 751da177e4SLinus Torvalds stq $21, 0($20); \ 761da177e4SLinus Torvalds99:; \ 771da177e4SLinus Torvalds ldq $19, 72($sp); \ 781da177e4SLinus Torvalds ldq $20, 80($sp); \ 791da177e4SLinus Torvalds ldq $21, 88($sp); \ 801da177e4SLinus Torvalds ldq $22, 96($sp); \ 811da177e4SLinus Torvalds ldq $23, 104($sp); \ 821da177e4SLinus Torvalds ldq $24, 112($sp); \ 831da177e4SLinus Torvalds ldq $25, 120($sp); \ 841da177e4SLinus Torvalds ldq $26, 128($sp); \ 851da177e4SLinus Torvalds ldq $27, 136($sp); \ 861da177e4SLinus Torvalds ldq $28, 144($sp); \ 871da177e4SLinus Torvalds addq $sp, SP_OFF, $sp 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds/* 901da177e4SLinus Torvalds * Non-syscall kernel entry points. 911da177e4SLinus Torvalds */ 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds .align 4 941da177e4SLinus Torvalds .globl entInt 951da177e4SLinus Torvalds .ent entInt 961da177e4SLinus TorvaldsentInt: 971da177e4SLinus Torvalds SAVE_ALL 981da177e4SLinus Torvalds lda $8, 0x3fff 991da177e4SLinus Torvalds lda $26, ret_from_sys_call 1001da177e4SLinus Torvalds bic $sp, $8, $8 1011da177e4SLinus Torvalds mov $sp, $19 1021da177e4SLinus Torvalds jsr $31, do_entInt 1031da177e4SLinus Torvalds.end entInt 1041da177e4SLinus Torvalds 1051da177e4SLinus Torvalds .align 4 1061da177e4SLinus Torvalds .globl entArith 1071da177e4SLinus Torvalds .ent entArith 1081da177e4SLinus TorvaldsentArith: 1091da177e4SLinus Torvalds SAVE_ALL 1101da177e4SLinus Torvalds lda $8, 0x3fff 1111da177e4SLinus Torvalds lda $26, ret_from_sys_call 1121da177e4SLinus Torvalds bic $sp, $8, $8 1131da177e4SLinus Torvalds mov $sp, $18 1141da177e4SLinus Torvalds jsr $31, do_entArith 1151da177e4SLinus Torvalds.end entArith 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds .align 4 1181da177e4SLinus Torvalds .globl entMM 1191da177e4SLinus Torvalds .ent entMM 1201da177e4SLinus TorvaldsentMM: 1211da177e4SLinus Torvalds SAVE_ALL 1221da177e4SLinus Torvalds/* save $9 - $15 so the inline exception code can manipulate them. */ 1231da177e4SLinus Torvalds subq $sp, 56, $sp 1241da177e4SLinus Torvalds stq $9, 0($sp) 1251da177e4SLinus Torvalds stq $10, 8($sp) 1261da177e4SLinus Torvalds stq $11, 16($sp) 1271da177e4SLinus Torvalds stq $12, 24($sp) 1281da177e4SLinus Torvalds stq $13, 32($sp) 1291da177e4SLinus Torvalds stq $14, 40($sp) 1301da177e4SLinus Torvalds stq $15, 48($sp) 1311da177e4SLinus Torvalds addq $sp, 56, $19 1321da177e4SLinus Torvalds/* handle the fault */ 1331da177e4SLinus Torvalds lda $8, 0x3fff 1341da177e4SLinus Torvalds bic $sp, $8, $8 1351da177e4SLinus Torvalds jsr $26, do_page_fault 1361da177e4SLinus Torvalds/* reload the registers after the exception code played. */ 1371da177e4SLinus Torvalds ldq $9, 0($sp) 1381da177e4SLinus Torvalds ldq $10, 8($sp) 1391da177e4SLinus Torvalds ldq $11, 16($sp) 1401da177e4SLinus Torvalds ldq $12, 24($sp) 1411da177e4SLinus Torvalds ldq $13, 32($sp) 1421da177e4SLinus Torvalds ldq $14, 40($sp) 1431da177e4SLinus Torvalds ldq $15, 48($sp) 1441da177e4SLinus Torvalds addq $sp, 56, $sp 1451da177e4SLinus Torvalds/* finish up the syscall as normal. */ 1461da177e4SLinus Torvalds br ret_from_sys_call 1471da177e4SLinus Torvalds.end entMM 1481da177e4SLinus Torvalds 1491da177e4SLinus Torvalds .align 4 1501da177e4SLinus Torvalds .globl entIF 1511da177e4SLinus Torvalds .ent entIF 1521da177e4SLinus TorvaldsentIF: 1531da177e4SLinus Torvalds SAVE_ALL 1541da177e4SLinus Torvalds lda $8, 0x3fff 1551da177e4SLinus Torvalds lda $26, ret_from_sys_call 1561da177e4SLinus Torvalds bic $sp, $8, $8 1571da177e4SLinus Torvalds mov $sp, $17 1581da177e4SLinus Torvalds jsr $31, do_entIF 1591da177e4SLinus Torvalds.end entIF 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds .align 4 1621da177e4SLinus Torvalds .globl entUna 1631da177e4SLinus Torvalds .ent entUna 1641da177e4SLinus TorvaldsentUna: 1651da177e4SLinus Torvalds lda $sp, -256($sp) 1661da177e4SLinus Torvalds stq $0, 0($sp) 1671da177e4SLinus Torvalds ldq $0, 256($sp) /* get PS */ 1681da177e4SLinus Torvalds stq $1, 8($sp) 1691da177e4SLinus Torvalds stq $2, 16($sp) 1701da177e4SLinus Torvalds stq $3, 24($sp) 1711da177e4SLinus Torvalds and $0, 8, $0 /* user mode? */ 1721da177e4SLinus Torvalds stq $4, 32($sp) 1731da177e4SLinus Torvalds bne $0, entUnaUser /* yup -> do user-level unaligned fault */ 1741da177e4SLinus Torvalds stq $5, 40($sp) 1751da177e4SLinus Torvalds stq $6, 48($sp) 1761da177e4SLinus Torvalds stq $7, 56($sp) 1771da177e4SLinus Torvalds stq $8, 64($sp) 1781da177e4SLinus Torvalds stq $9, 72($sp) 1791da177e4SLinus Torvalds stq $10, 80($sp) 1801da177e4SLinus Torvalds stq $11, 88($sp) 1811da177e4SLinus Torvalds stq $12, 96($sp) 1821da177e4SLinus Torvalds stq $13, 104($sp) 1831da177e4SLinus Torvalds stq $14, 112($sp) 1841da177e4SLinus Torvalds stq $15, 120($sp) 1851da177e4SLinus Torvalds /* 16-18 PAL-saved */ 1861da177e4SLinus Torvalds stq $19, 152($sp) 1871da177e4SLinus Torvalds stq $20, 160($sp) 1881da177e4SLinus Torvalds stq $21, 168($sp) 1891da177e4SLinus Torvalds stq $22, 176($sp) 1901da177e4SLinus Torvalds stq $23, 184($sp) 1911da177e4SLinus Torvalds stq $24, 192($sp) 1921da177e4SLinus Torvalds stq $25, 200($sp) 1931da177e4SLinus Torvalds stq $26, 208($sp) 1941da177e4SLinus Torvalds stq $27, 216($sp) 1951da177e4SLinus Torvalds stq $28, 224($sp) 196d70ddac1SRichard Henderson mov $sp, $19 1971da177e4SLinus Torvalds stq $gp, 232($sp) 1981da177e4SLinus Torvalds lda $8, 0x3fff 1991da177e4SLinus Torvalds stq $31, 248($sp) 2001da177e4SLinus Torvalds bic $sp, $8, $8 2011da177e4SLinus Torvalds jsr $26, do_entUna 2021da177e4SLinus Torvalds ldq $0, 0($sp) 2031da177e4SLinus Torvalds ldq $1, 8($sp) 2041da177e4SLinus Torvalds ldq $2, 16($sp) 2051da177e4SLinus Torvalds ldq $3, 24($sp) 2061da177e4SLinus Torvalds ldq $4, 32($sp) 2071da177e4SLinus Torvalds ldq $5, 40($sp) 2081da177e4SLinus Torvalds ldq $6, 48($sp) 2091da177e4SLinus Torvalds ldq $7, 56($sp) 2101da177e4SLinus Torvalds ldq $8, 64($sp) 2111da177e4SLinus Torvalds ldq $9, 72($sp) 2121da177e4SLinus Torvalds ldq $10, 80($sp) 2131da177e4SLinus Torvalds ldq $11, 88($sp) 2141da177e4SLinus Torvalds ldq $12, 96($sp) 2151da177e4SLinus Torvalds ldq $13, 104($sp) 2161da177e4SLinus Torvalds ldq $14, 112($sp) 2171da177e4SLinus Torvalds ldq $15, 120($sp) 2181da177e4SLinus Torvalds /* 16-18 PAL-saved */ 2191da177e4SLinus Torvalds ldq $19, 152($sp) 2201da177e4SLinus Torvalds ldq $20, 160($sp) 2211da177e4SLinus Torvalds ldq $21, 168($sp) 2221da177e4SLinus Torvalds ldq $22, 176($sp) 2231da177e4SLinus Torvalds ldq $23, 184($sp) 2241da177e4SLinus Torvalds ldq $24, 192($sp) 2251da177e4SLinus Torvalds ldq $25, 200($sp) 2261da177e4SLinus Torvalds ldq $26, 208($sp) 2271da177e4SLinus Torvalds ldq $27, 216($sp) 2281da177e4SLinus Torvalds ldq $28, 224($sp) 2291da177e4SLinus Torvalds ldq $gp, 232($sp) 2301da177e4SLinus Torvalds lda $sp, 256($sp) 2311da177e4SLinus Torvalds call_pal PAL_rti 2321da177e4SLinus Torvalds.end entUna 2331da177e4SLinus Torvalds 2341da177e4SLinus Torvalds .align 4 2351da177e4SLinus Torvalds .ent entUnaUser 2361da177e4SLinus TorvaldsentUnaUser: 2371da177e4SLinus Torvalds ldq $0, 0($sp) /* restore original $0 */ 2381da177e4SLinus Torvalds lda $sp, 256($sp) /* pop entUna's stack frame */ 2391da177e4SLinus Torvalds SAVE_ALL /* setup normal kernel stack */ 2401da177e4SLinus Torvalds lda $sp, -56($sp) 2411da177e4SLinus Torvalds stq $9, 0($sp) 2421da177e4SLinus Torvalds stq $10, 8($sp) 2431da177e4SLinus Torvalds stq $11, 16($sp) 2441da177e4SLinus Torvalds stq $12, 24($sp) 2451da177e4SLinus Torvalds stq $13, 32($sp) 2461da177e4SLinus Torvalds stq $14, 40($sp) 2471da177e4SLinus Torvalds stq $15, 48($sp) 2481da177e4SLinus Torvalds lda $8, 0x3fff 2491da177e4SLinus Torvalds addq $sp, 56, $19 2501da177e4SLinus Torvalds bic $sp, $8, $8 2511da177e4SLinus Torvalds jsr $26, do_entUnaUser 2521da177e4SLinus Torvalds ldq $9, 0($sp) 2531da177e4SLinus Torvalds ldq $10, 8($sp) 2541da177e4SLinus Torvalds ldq $11, 16($sp) 2551da177e4SLinus Torvalds ldq $12, 24($sp) 2561da177e4SLinus Torvalds ldq $13, 32($sp) 2571da177e4SLinus Torvalds ldq $14, 40($sp) 2581da177e4SLinus Torvalds ldq $15, 48($sp) 2591da177e4SLinus Torvalds lda $sp, 56($sp) 2601da177e4SLinus Torvalds br ret_from_sys_call 2611da177e4SLinus Torvalds.end entUnaUser 2621da177e4SLinus Torvalds 2631da177e4SLinus Torvalds .align 4 2641da177e4SLinus Torvalds .globl entDbg 2651da177e4SLinus Torvalds .ent entDbg 2661da177e4SLinus TorvaldsentDbg: 2671da177e4SLinus Torvalds SAVE_ALL 2681da177e4SLinus Torvalds lda $8, 0x3fff 2691da177e4SLinus Torvalds lda $26, ret_from_sys_call 2701da177e4SLinus Torvalds bic $sp, $8, $8 2711da177e4SLinus Torvalds mov $sp, $16 2721da177e4SLinus Torvalds jsr $31, do_entDbg 2731da177e4SLinus Torvalds.end entDbg 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds/* 2761da177e4SLinus Torvalds * The system call entry point is special. Most importantly, it looks 2771da177e4SLinus Torvalds * like a function call to userspace as far as clobbered registers. We 2781da177e4SLinus Torvalds * do preserve the argument registers (for syscall restarts) and $26 2791da177e4SLinus Torvalds * (for leaf syscall functions). 2801da177e4SLinus Torvalds * 2811da177e4SLinus Torvalds * So much for theory. We don't take advantage of this yet. 2821da177e4SLinus Torvalds * 2831da177e4SLinus Torvalds * Note that a0-a2 are not saved by PALcode as with the other entry points. 2841da177e4SLinus Torvalds */ 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds .align 4 2871da177e4SLinus Torvalds .globl entSys 2881da177e4SLinus Torvalds .globl ret_from_sys_call 2891da177e4SLinus Torvalds .ent entSys 2901da177e4SLinus TorvaldsentSys: 2911da177e4SLinus Torvalds SAVE_ALL 2921da177e4SLinus Torvalds lda $8, 0x3fff 2931da177e4SLinus Torvalds bic $sp, $8, $8 2941da177e4SLinus Torvalds lda $4, NR_SYSCALLS($31) 2951da177e4SLinus Torvalds stq $16, SP_OFF+24($sp) 2961da177e4SLinus Torvalds lda $5, sys_call_table 2971da177e4SLinus Torvalds lda $27, sys_ni_syscall 2981da177e4SLinus Torvalds cmpult $0, $4, $4 2991da177e4SLinus Torvalds ldl $3, TI_FLAGS($8) 3001da177e4SLinus Torvalds stq $17, SP_OFF+32($sp) 3011da177e4SLinus Torvalds s8addq $0, $5, $5 3021da177e4SLinus Torvalds stq $18, SP_OFF+40($sp) 3031da177e4SLinus Torvalds blbs $3, strace 3041da177e4SLinus Torvalds beq $4, 1f 3051da177e4SLinus Torvalds ldq $27, 0($5) 3061da177e4SLinus Torvalds1: jsr $26, ($27), alpha_ni_syscall 3071da177e4SLinus Torvalds ldgp $gp, 0($26) 3081da177e4SLinus Torvalds blt $0, $syscall_error /* the call failed */ 3091da177e4SLinus Torvalds stq $0, 0($sp) 3101da177e4SLinus Torvalds stq $31, 72($sp) /* a3=0 => no error */ 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds .align 4 3131da177e4SLinus Torvaldsret_from_sys_call: 3141da177e4SLinus Torvalds cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ 3151da177e4SLinus Torvalds ldq $0, SP_OFF($sp) 3161da177e4SLinus Torvalds and $0, 8, $0 31777edffb6SAl Viro beq $0, ret_to_kernel 318494486a1SAl Viroret_to_user: 3191da177e4SLinus Torvalds /* Make sure need_resched and sigpending don't change between 3201da177e4SLinus Torvalds sampling and the rti. */ 3211da177e4SLinus Torvalds lda $16, 7 3221da177e4SLinus Torvalds call_pal PAL_swpipl 3231da177e4SLinus Torvalds ldl $5, TI_FLAGS($8) 3241da177e4SLinus Torvalds and $5, _TIF_WORK_MASK, $2 325494486a1SAl Viro bne $2, work_pending 3261da177e4SLinus Torvaldsrestore_all: 3271da177e4SLinus Torvalds RESTORE_ALL 3281da177e4SLinus Torvalds call_pal PAL_rti 3291da177e4SLinus Torvalds 33077edffb6SAl Viroret_to_kernel: 33177edffb6SAl Viro lda $16, 7 33277edffb6SAl Viro call_pal PAL_swpipl 33377edffb6SAl Viro br restore_all 33477edffb6SAl Viro 3351da177e4SLinus Torvalds .align 3 3361da177e4SLinus Torvalds$syscall_error: 3371da177e4SLinus Torvalds /* 3381da177e4SLinus Torvalds * Some system calls (e.g., ptrace) can return arbitrary 3391da177e4SLinus Torvalds * values which might normally be mistaken as error numbers. 3401da177e4SLinus Torvalds * Those functions must zero $0 (v0) directly in the stack 3411da177e4SLinus Torvalds * frame to indicate that a negative return value wasn't an 3421da177e4SLinus Torvalds * error number.. 3431da177e4SLinus Torvalds */ 3441da177e4SLinus Torvalds ldq $19, 0($sp) /* old syscall nr (zero if success) */ 3451da177e4SLinus Torvalds beq $19, $ret_success 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds ldq $20, 72($sp) /* .. and this a3 */ 3481da177e4SLinus Torvalds subq $31, $0, $0 /* with error in v0 */ 3491da177e4SLinus Torvalds addq $31, 1, $1 /* set a3 for errno return */ 3501da177e4SLinus Torvalds stq $0, 0($sp) 3511da177e4SLinus Torvalds mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 3521da177e4SLinus Torvalds stq $1, 72($sp) /* a3 for return */ 3531da177e4SLinus Torvalds br ret_from_sys_call 3541da177e4SLinus Torvalds 3551da177e4SLinus Torvalds$ret_success: 3561da177e4SLinus Torvalds stq $0, 0($sp) 3571da177e4SLinus Torvalds stq $31, 72($sp) /* a3=0 => no error */ 3581da177e4SLinus Torvalds br ret_from_sys_call 3591da177e4SLinus Torvalds.end entSys 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds/* 3621da177e4SLinus Torvalds * Do all cleanup when returning from all interrupts and system calls. 3631da177e4SLinus Torvalds * 3641da177e4SLinus Torvalds * Arguments: 3651da177e4SLinus Torvalds * $5: TI_FLAGS. 3661da177e4SLinus Torvalds * $8: current. 3671da177e4SLinus Torvalds * $19: The old syscall number, or zero if this is not a return 3681da177e4SLinus Torvalds * from a syscall that errored and is possibly restartable. 369494486a1SAl Viro * $20: The old a3 value 3701da177e4SLinus Torvalds */ 3711da177e4SLinus Torvalds 3721da177e4SLinus Torvalds .align 4 3731da177e4SLinus Torvalds .ent work_pending 3741da177e4SLinus Torvaldswork_pending: 3751da177e4SLinus Torvalds and $5, _TIF_NEED_RESCHED, $2 3761da177e4SLinus Torvalds beq $2, $work_notifysig 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvalds$work_resched: 3791da177e4SLinus Torvalds subq $sp, 16, $sp 3801da177e4SLinus Torvalds stq $19, 0($sp) /* save syscall nr */ 3811da177e4SLinus Torvalds stq $20, 8($sp) /* and error indication (a3) */ 3821da177e4SLinus Torvalds jsr $26, schedule 3831da177e4SLinus Torvalds ldq $19, 0($sp) 3841da177e4SLinus Torvalds ldq $20, 8($sp) 3851da177e4SLinus Torvalds addq $sp, 16, $sp 3861da177e4SLinus Torvalds /* Make sure need_resched and sigpending don't change between 3871da177e4SLinus Torvalds sampling and the rti. */ 3881da177e4SLinus Torvalds lda $16, 7 3891da177e4SLinus Torvalds call_pal PAL_swpipl 3901da177e4SLinus Torvalds ldl $5, TI_FLAGS($8) 3911da177e4SLinus Torvalds and $5, _TIF_WORK_MASK, $2 3921da177e4SLinus Torvalds beq $2, restore_all 3931da177e4SLinus Torvalds and $5, _TIF_NEED_RESCHED, $2 3941da177e4SLinus Torvalds bne $2, $work_resched 3951da177e4SLinus Torvalds 3961da177e4SLinus Torvalds$work_notifysig: 397b927b3e2SRichard Henderson mov $sp, $16 398494486a1SAl Viro bsr $1, do_switch_stack 399b927b3e2SRichard Henderson mov $sp, $17 400b927b3e2SRichard Henderson mov $5, $18 401494486a1SAl Viro mov $19, $9 /* save old syscall number */ 402494486a1SAl Viro mov $20, $10 /* save old a3 */ 403494486a1SAl Viro and $5, _TIF_SIGPENDING, $2 404494486a1SAl Viro cmovne $2, 0, $9 /* we don't want double syscall restarts */ 4051da177e4SLinus Torvalds jsr $26, do_notify_resume 406494486a1SAl Viro mov $9, $19 407494486a1SAl Viro mov $10, $20 4081da177e4SLinus Torvalds bsr $1, undo_switch_stack 409494486a1SAl Viro br ret_to_user 4101da177e4SLinus Torvalds.end work_pending 4111da177e4SLinus Torvalds 4121da177e4SLinus Torvalds/* 4131da177e4SLinus Torvalds * PTRACE syscall handler 4141da177e4SLinus Torvalds */ 4151da177e4SLinus Torvalds 4161da177e4SLinus Torvalds .align 4 4171da177e4SLinus Torvalds .ent strace 4181da177e4SLinus Torvaldsstrace: 4191da177e4SLinus Torvalds /* set up signal stack, call syscall_trace */ 4201da177e4SLinus Torvalds bsr $1, do_switch_stack 4211da177e4SLinus Torvalds jsr $26, syscall_trace 4221da177e4SLinus Torvalds bsr $1, undo_switch_stack 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds /* get the system call number and the arguments back.. */ 4251da177e4SLinus Torvalds ldq $0, 0($sp) 4261da177e4SLinus Torvalds ldq $16, SP_OFF+24($sp) 4271da177e4SLinus Torvalds ldq $17, SP_OFF+32($sp) 4281da177e4SLinus Torvalds ldq $18, SP_OFF+40($sp) 4291da177e4SLinus Torvalds ldq $19, 72($sp) 4301da177e4SLinus Torvalds ldq $20, 80($sp) 4311da177e4SLinus Torvalds ldq $21, 88($sp) 4321da177e4SLinus Torvalds 4331da177e4SLinus Torvalds /* get the system call pointer.. */ 4341da177e4SLinus Torvalds lda $1, NR_SYSCALLS($31) 4351da177e4SLinus Torvalds lda $2, sys_call_table 4361da177e4SLinus Torvalds lda $27, alpha_ni_syscall 4371da177e4SLinus Torvalds cmpult $0, $1, $1 4381da177e4SLinus Torvalds s8addq $0, $2, $2 4391da177e4SLinus Torvalds beq $1, 1f 4401da177e4SLinus Torvalds ldq $27, 0($2) 4411da177e4SLinus Torvalds1: jsr $26, ($27), sys_gettimeofday 44253293638SAl Viroret_from_straced: 4431da177e4SLinus Torvalds ldgp $gp, 0($26) 4441da177e4SLinus Torvalds 4451da177e4SLinus Torvalds /* check return.. */ 4461da177e4SLinus Torvalds blt $0, $strace_error /* the call failed */ 4471da177e4SLinus Torvalds stq $31, 72($sp) /* a3=0 => no error */ 4481da177e4SLinus Torvalds$strace_success: 4491da177e4SLinus Torvalds stq $0, 0($sp) /* save return value */ 4501da177e4SLinus Torvalds 4511da177e4SLinus Torvalds bsr $1, do_switch_stack 4521da177e4SLinus Torvalds jsr $26, syscall_trace 4531da177e4SLinus Torvalds bsr $1, undo_switch_stack 4541da177e4SLinus Torvalds br $31, ret_from_sys_call 4551da177e4SLinus Torvalds 4561da177e4SLinus Torvalds .align 3 4571da177e4SLinus Torvalds$strace_error: 4581da177e4SLinus Torvalds ldq $19, 0($sp) /* old syscall nr (zero if success) */ 4591da177e4SLinus Torvalds beq $19, $strace_success 4601da177e4SLinus Torvalds ldq $20, 72($sp) /* .. and this a3 */ 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds subq $31, $0, $0 /* with error in v0 */ 4631da177e4SLinus Torvalds addq $31, 1, $1 /* set a3 for errno return */ 4641da177e4SLinus Torvalds stq $0, 0($sp) 4651da177e4SLinus Torvalds stq $1, 72($sp) /* a3 for return */ 4661da177e4SLinus Torvalds 4671da177e4SLinus Torvalds bsr $1, do_switch_stack 4681da177e4SLinus Torvalds mov $19, $9 /* save old syscall number */ 4691da177e4SLinus Torvalds mov $20, $10 /* save old a3 */ 4701da177e4SLinus Torvalds jsr $26, syscall_trace 4711da177e4SLinus Torvalds mov $9, $19 4721da177e4SLinus Torvalds mov $10, $20 4731da177e4SLinus Torvalds bsr $1, undo_switch_stack 4741da177e4SLinus Torvalds 4751da177e4SLinus Torvalds mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 4761da177e4SLinus Torvalds br ret_from_sys_call 4771da177e4SLinus Torvalds.end strace 4781da177e4SLinus Torvalds 4791da177e4SLinus Torvalds/* 4801da177e4SLinus Torvalds * Save and restore the switch stack -- aka the balance of the user context. 4811da177e4SLinus Torvalds */ 4821da177e4SLinus Torvalds 4831da177e4SLinus Torvalds .align 4 4841da177e4SLinus Torvalds .ent do_switch_stack 4851da177e4SLinus Torvaldsdo_switch_stack: 4861da177e4SLinus Torvalds lda $sp, -SWITCH_STACK_SIZE($sp) 4871da177e4SLinus Torvalds stq $9, 0($sp) 4881da177e4SLinus Torvalds stq $10, 8($sp) 4891da177e4SLinus Torvalds stq $11, 16($sp) 4901da177e4SLinus Torvalds stq $12, 24($sp) 4911da177e4SLinus Torvalds stq $13, 32($sp) 4921da177e4SLinus Torvalds stq $14, 40($sp) 4931da177e4SLinus Torvalds stq $15, 48($sp) 4941da177e4SLinus Torvalds stq $26, 56($sp) 4951da177e4SLinus Torvalds stt $f0, 64($sp) 4961da177e4SLinus Torvalds stt $f1, 72($sp) 4971da177e4SLinus Torvalds stt $f2, 80($sp) 4981da177e4SLinus Torvalds stt $f3, 88($sp) 4991da177e4SLinus Torvalds stt $f4, 96($sp) 5001da177e4SLinus Torvalds stt $f5, 104($sp) 5011da177e4SLinus Torvalds stt $f6, 112($sp) 5021da177e4SLinus Torvalds stt $f7, 120($sp) 5031da177e4SLinus Torvalds stt $f8, 128($sp) 5041da177e4SLinus Torvalds stt $f9, 136($sp) 5051da177e4SLinus Torvalds stt $f10, 144($sp) 5061da177e4SLinus Torvalds stt $f11, 152($sp) 5071da177e4SLinus Torvalds stt $f12, 160($sp) 5081da177e4SLinus Torvalds stt $f13, 168($sp) 5091da177e4SLinus Torvalds stt $f14, 176($sp) 5101da177e4SLinus Torvalds stt $f15, 184($sp) 5111da177e4SLinus Torvalds stt $f16, 192($sp) 5121da177e4SLinus Torvalds stt $f17, 200($sp) 5131da177e4SLinus Torvalds stt $f18, 208($sp) 5141da177e4SLinus Torvalds stt $f19, 216($sp) 5151da177e4SLinus Torvalds stt $f20, 224($sp) 5161da177e4SLinus Torvalds stt $f21, 232($sp) 5171da177e4SLinus Torvalds stt $f22, 240($sp) 5181da177e4SLinus Torvalds stt $f23, 248($sp) 5191da177e4SLinus Torvalds stt $f24, 256($sp) 5201da177e4SLinus Torvalds stt $f25, 264($sp) 5211da177e4SLinus Torvalds stt $f26, 272($sp) 5221da177e4SLinus Torvalds stt $f27, 280($sp) 5231da177e4SLinus Torvalds mf_fpcr $f0 # get fpcr 5241da177e4SLinus Torvalds stt $f28, 288($sp) 5251da177e4SLinus Torvalds stt $f29, 296($sp) 5261da177e4SLinus Torvalds stt $f30, 304($sp) 5271da177e4SLinus Torvalds stt $f0, 312($sp) # save fpcr in slot of $f31 5281da177e4SLinus Torvalds ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state. 5291da177e4SLinus Torvalds ret $31, ($1), 1 5301da177e4SLinus Torvalds.end do_switch_stack 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvalds .align 4 5331da177e4SLinus Torvalds .ent undo_switch_stack 5341da177e4SLinus Torvaldsundo_switch_stack: 5351da177e4SLinus Torvalds ldq $9, 0($sp) 5361da177e4SLinus Torvalds ldq $10, 8($sp) 5371da177e4SLinus Torvalds ldq $11, 16($sp) 5381da177e4SLinus Torvalds ldq $12, 24($sp) 5391da177e4SLinus Torvalds ldq $13, 32($sp) 5401da177e4SLinus Torvalds ldq $14, 40($sp) 5411da177e4SLinus Torvalds ldq $15, 48($sp) 5421da177e4SLinus Torvalds ldq $26, 56($sp) 5431da177e4SLinus Torvalds ldt $f30, 312($sp) # get saved fpcr 5441da177e4SLinus Torvalds ldt $f0, 64($sp) 5451da177e4SLinus Torvalds ldt $f1, 72($sp) 5461da177e4SLinus Torvalds ldt $f2, 80($sp) 5471da177e4SLinus Torvalds ldt $f3, 88($sp) 5481da177e4SLinus Torvalds mt_fpcr $f30 # install saved fpcr 5491da177e4SLinus Torvalds ldt $f4, 96($sp) 5501da177e4SLinus Torvalds ldt $f5, 104($sp) 5511da177e4SLinus Torvalds ldt $f6, 112($sp) 5521da177e4SLinus Torvalds ldt $f7, 120($sp) 5531da177e4SLinus Torvalds ldt $f8, 128($sp) 5541da177e4SLinus Torvalds ldt $f9, 136($sp) 5551da177e4SLinus Torvalds ldt $f10, 144($sp) 5561da177e4SLinus Torvalds ldt $f11, 152($sp) 5571da177e4SLinus Torvalds ldt $f12, 160($sp) 5581da177e4SLinus Torvalds ldt $f13, 168($sp) 5591da177e4SLinus Torvalds ldt $f14, 176($sp) 5601da177e4SLinus Torvalds ldt $f15, 184($sp) 5611da177e4SLinus Torvalds ldt $f16, 192($sp) 5621da177e4SLinus Torvalds ldt $f17, 200($sp) 5631da177e4SLinus Torvalds ldt $f18, 208($sp) 5641da177e4SLinus Torvalds ldt $f19, 216($sp) 5651da177e4SLinus Torvalds ldt $f20, 224($sp) 5661da177e4SLinus Torvalds ldt $f21, 232($sp) 5671da177e4SLinus Torvalds ldt $f22, 240($sp) 5681da177e4SLinus Torvalds ldt $f23, 248($sp) 5691da177e4SLinus Torvalds ldt $f24, 256($sp) 5701da177e4SLinus Torvalds ldt $f25, 264($sp) 5711da177e4SLinus Torvalds ldt $f26, 272($sp) 5721da177e4SLinus Torvalds ldt $f27, 280($sp) 5731da177e4SLinus Torvalds ldt $f28, 288($sp) 5741da177e4SLinus Torvalds ldt $f29, 296($sp) 5751da177e4SLinus Torvalds ldt $f30, 304($sp) 5761da177e4SLinus Torvalds lda $sp, SWITCH_STACK_SIZE($sp) 5771da177e4SLinus Torvalds ret $31, ($1), 1 5781da177e4SLinus Torvalds.end undo_switch_stack 5791da177e4SLinus Torvalds 5801da177e4SLinus Torvalds/* 5811da177e4SLinus Torvalds * The meat of the context switch code. 5821da177e4SLinus Torvalds */ 5831da177e4SLinus Torvalds 5841da177e4SLinus Torvalds .align 4 5851da177e4SLinus Torvalds .globl alpha_switch_to 5861da177e4SLinus Torvalds .ent alpha_switch_to 5871da177e4SLinus Torvaldsalpha_switch_to: 5881da177e4SLinus Torvalds .prologue 0 5891da177e4SLinus Torvalds bsr $1, do_switch_stack 5901da177e4SLinus Torvalds call_pal PAL_swpctx 5911da177e4SLinus Torvalds lda $8, 0x3fff 5921da177e4SLinus Torvalds bsr $1, undo_switch_stack 5931da177e4SLinus Torvalds bic $sp, $8, $8 5941da177e4SLinus Torvalds mov $17, $0 5951da177e4SLinus Torvalds ret 5961da177e4SLinus Torvalds.end alpha_switch_to 5971da177e4SLinus Torvalds 5981da177e4SLinus Torvalds/* 5991da177e4SLinus Torvalds * New processes begin life here. 6001da177e4SLinus Torvalds */ 6011da177e4SLinus Torvalds 6021da177e4SLinus Torvalds .globl ret_from_fork 6031da177e4SLinus Torvalds .align 4 6041da177e4SLinus Torvalds .ent ret_from_fork 6051da177e4SLinus Torvaldsret_from_fork: 6061da177e4SLinus Torvalds lda $26, ret_from_sys_call 6071da177e4SLinus Torvalds mov $17, $16 6081da177e4SLinus Torvalds jmp $31, schedule_tail 6091da177e4SLinus Torvalds.end ret_from_fork 6101da177e4SLinus Torvalds 6111da177e4SLinus Torvalds/* 612cba1ec7eSAl Viro * ... and new kernel threads - here 6131da177e4SLinus Torvalds */ 6141da177e4SLinus Torvalds .align 4 615cba1ec7eSAl Viro .globl ret_from_kernel_thread 616cba1ec7eSAl Viro .ent ret_from_kernel_thread 617cba1ec7eSAl Viroret_from_kernel_thread: 618cba1ec7eSAl Viro mov $17, $16 619cba1ec7eSAl Viro jsr $26, schedule_tail 620cba1ec7eSAl Viro mov $9, $27 621cba1ec7eSAl Viro mov $10, $16 622cba1ec7eSAl Viro jsr $26, ($9) 6231da177e4SLinus Torvalds ldgp $gp, 0($26) 6241da177e4SLinus Torvalds mov $0, $16 6251da177e4SLinus Torvalds mov $31, $26 6261da177e4SLinus Torvalds jmp $31, sys_exit 627cba1ec7eSAl Viro.end ret_from_kernel_thread 6281da177e4SLinus Torvalds 6291da177e4SLinus Torvalds 6301da177e4SLinus Torvalds/* 6311da177e4SLinus Torvalds * Special system calls. Most of these are special in that they either 6321da177e4SLinus Torvalds * have to play switch_stack games or in some way use the pt_regs struct. 6331da177e4SLinus Torvalds */ 6341da177e4SLinus Torvalds .align 4 6351da177e4SLinus Torvalds .globl sys_fork 6361da177e4SLinus Torvalds .ent sys_fork 6371da177e4SLinus Torvaldssys_fork: 6381da177e4SLinus Torvalds .prologue 0 6391da177e4SLinus Torvalds mov $sp, $21 6401da177e4SLinus Torvalds bsr $1, do_switch_stack 6411da177e4SLinus Torvalds bis $31, SIGCHLD, $16 6421da177e4SLinus Torvalds mov $31, $17 6431da177e4SLinus Torvalds mov $31, $18 6441da177e4SLinus Torvalds mov $31, $19 6451da177e4SLinus Torvalds mov $31, $20 6461da177e4SLinus Torvalds jsr $26, alpha_clone 6471da177e4SLinus Torvalds bsr $1, undo_switch_stack 6481da177e4SLinus Torvalds ret 6491da177e4SLinus Torvalds.end sys_fork 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds .align 4 6521da177e4SLinus Torvalds .globl sys_clone 6531da177e4SLinus Torvalds .ent sys_clone 6541da177e4SLinus Torvaldssys_clone: 6551da177e4SLinus Torvalds .prologue 0 6561da177e4SLinus Torvalds mov $sp, $21 6571da177e4SLinus Torvalds bsr $1, do_switch_stack 6581da177e4SLinus Torvalds /* $16, $17, $18, $19, $20 come from the user. */ 6591da177e4SLinus Torvalds jsr $26, alpha_clone 6601da177e4SLinus Torvalds bsr $1, undo_switch_stack 6611da177e4SLinus Torvalds ret 6621da177e4SLinus Torvalds.end sys_clone 6631da177e4SLinus Torvalds 6641da177e4SLinus Torvalds .align 4 6651da177e4SLinus Torvalds .globl sys_vfork 6661da177e4SLinus Torvalds .ent sys_vfork 6671da177e4SLinus Torvaldssys_vfork: 6681da177e4SLinus Torvalds .prologue 0 6691da177e4SLinus Torvalds mov $sp, $16 6701da177e4SLinus Torvalds bsr $1, do_switch_stack 6711da177e4SLinus Torvalds jsr $26, alpha_vfork 6721da177e4SLinus Torvalds bsr $1, undo_switch_stack 6731da177e4SLinus Torvalds ret 6741da177e4SLinus Torvalds.end sys_vfork 6751da177e4SLinus Torvalds 6761da177e4SLinus Torvalds .align 4 6771da177e4SLinus Torvalds .globl sys_sigreturn 6781da177e4SLinus Torvalds .ent sys_sigreturn 6791da177e4SLinus Torvaldssys_sigreturn: 6801da177e4SLinus Torvalds .prologue 0 68153293638SAl Viro lda $9, ret_from_straced 68253293638SAl Viro cmpult $26, $9, $9 6831da177e4SLinus Torvalds mov $sp, $17 6841da177e4SLinus Torvalds lda $18, -SWITCH_STACK_SIZE($sp) 6851da177e4SLinus Torvalds lda $sp, -SWITCH_STACK_SIZE($sp) 6861da177e4SLinus Torvalds jsr $26, do_sigreturn 68753293638SAl Viro bne $9, 1f 68853293638SAl Viro jsr $26, syscall_trace 68953293638SAl Viro1: br $1, undo_switch_stack 6901da177e4SLinus Torvalds br ret_from_sys_call 6911da177e4SLinus Torvalds.end sys_sigreturn 6921da177e4SLinus Torvalds 6931da177e4SLinus Torvalds .align 4 6941da177e4SLinus Torvalds .globl sys_rt_sigreturn 6951da177e4SLinus Torvalds .ent sys_rt_sigreturn 6961da177e4SLinus Torvaldssys_rt_sigreturn: 6971da177e4SLinus Torvalds .prologue 0 69853293638SAl Viro lda $9, ret_from_straced 69953293638SAl Viro cmpult $26, $9, $9 7001da177e4SLinus Torvalds mov $sp, $17 7011da177e4SLinus Torvalds lda $18, -SWITCH_STACK_SIZE($sp) 7021da177e4SLinus Torvalds lda $sp, -SWITCH_STACK_SIZE($sp) 7031da177e4SLinus Torvalds jsr $26, do_rt_sigreturn 70453293638SAl Viro bne $9, 1f 70553293638SAl Viro jsr $26, syscall_trace 70653293638SAl Viro1: br $1, undo_switch_stack 7071da177e4SLinus Torvalds br ret_from_sys_call 7081da177e4SLinus Torvalds.end sys_rt_sigreturn 7091da177e4SLinus Torvalds 7101da177e4SLinus Torvalds .align 4 7111da177e4SLinus Torvalds .globl alpha_ni_syscall 7121da177e4SLinus Torvalds .ent alpha_ni_syscall 7131da177e4SLinus Torvaldsalpha_ni_syscall: 7141da177e4SLinus Torvalds .prologue 0 7151da177e4SLinus Torvalds /* Special because it also implements overflow handling via 7161da177e4SLinus Torvalds syscall number 0. And if you recall, zero is a special 7171da177e4SLinus Torvalds trigger for "not an error". Store large non-zero there. */ 7181da177e4SLinus Torvalds lda $0, -ENOSYS 7191da177e4SLinus Torvalds unop 7201da177e4SLinus Torvalds stq $0, 0($sp) 7211da177e4SLinus Torvalds ret 7221da177e4SLinus Torvalds.end alpha_ni_syscall 723