All pastes #298120 Raw Edit

Mine

public c v1 · immutable
#298120 ·published 2006-12-31 16:14 UTC
rendered paste body
/* * System call handler. * * A pointer to the trapframe created during exception entry (in * exception.S) is passed in. * * The calling conventions for syscalls are as follows: Like ordinary * function calls, the first 4 32-bit arguments are passed in the 4 * argument registers a0-a3. In addition, the system call number is * passed in the v0 register. * * On successful return, the return value is passed back in the v0 * register, like an ordinary function call, and the a3 register is * also set to 0 to indicate success. * * On an error return, the error code is passed back in the v0 * register, and the a3 register is set to 1 to indicate failure. * (Userlevel code takes care of storing the error code in errno and * returning the value -1 from the actual userlevel syscall function. * See src/lib/libc/syscalls.S and related files.) * * Upon syscall return the program counter stored in the trapframe * must be incremented by one instruction; otherwise the exception * return code will restart the "syscall" instruction and the system * call will repeat forever. * * Since none of the OS/161 system calls have more than 4 arguments, * there should be no need to fetch additional arguments from the * user-level stack. * * Watch out: if you make system calls that have 64-bit quantities as * arguments, they will get passed in pairs of registers, and not * necessarily in the way you expect. We recommend you don't do it. * (In fact, we recommend you don't use 64-bit quantities at all. See * arch/mips/include/types.h.) */voidmips_syscall(struct trapframe *tf){        int callno;        int32_t retval;        int err;        assert(curspl==0);        callno = tf->tf_v0;        /*         * Initialize retval to 0. Many of the system calls don't         * really return a value, just 0 for success and -1 on         * error. Since retval is the value returned on success,         * initialize it to 0 by default; thus it's not necessary to         * deal with it except for calls that return other values,         * like write.         */        retval = 0;        switch (callno) {            case SYS_reboot:                err = sys_reboot(tf->tf_a0);                break;            /* Add stuff here */            default:                kprintf("Unknown syscall %d\n", callno);                err = ENOSYS;                break;        }        if (err) {                /*                 * Return the error code. This gets converted at                 * userlevel to a return value of -1 and the error                 * code in errno.                 */                tf->tf_v0 = err;                tf->tf_a3 = 1;      /* signal an error */        }        else {                /* Success. */                tf->tf_v0 = retval;                tf->tf_a3 = 0;      /* signal no error */        }        /*         * Now, advance the program counter, to avoid restarting         * the syscall over and over again.         */        tf->tf_epc += 4;        /* Make sure the syscall code didn't forget to lower spl */        assert(curspl==0);}