syscall.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. #include <types.h>
  30. #include <kern/errno.h>
  31. #include <kern/syscall.h>
  32. #include <lib.h>
  33. #include <mips/trapframe.h>
  34. #include <thread.h>
  35. #include <current.h>
  36. #include <syscall.h>
  37. /*
  38. * System call dispatcher.
  39. *
  40. * A pointer to the trapframe created during exception entry (in
  41. * exception.S) is passed in.
  42. *
  43. * The calling conventions for syscalls are as follows: Like ordinary
  44. * function calls, the first 4 32-bit arguments are passed in the 4
  45. * argument registers a0-a3. 64-bit arguments are passed in *aligned*
  46. * pairs of registers, that is, either a0/a1 or a2/a3. This means that
  47. * if the first argument is 32-bit and the second is 64-bit, a1 is
  48. * unused.
  49. *
  50. * This much is the same as the calling conventions for ordinary
  51. * function calls. In addition, the system call number is passed in
  52. * the v0 register.
  53. *
  54. * On successful return, the return value is passed back in the v0
  55. * register, or v0 and v1 if 64-bit. This is also like an ordinary
  56. * function call, and additionally the a3 register is also set to 0 to
  57. * indicate success.
  58. *
  59. * On an error return, the error code is passed back in the v0
  60. * register, and the a3 register is set to 1 to indicate failure.
  61. * (Userlevel code takes care of storing the error code in errno and
  62. * returning the value -1 from the actual userlevel syscall function.
  63. * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
  64. *
  65. * Upon syscall return the program counter stored in the trapframe
  66. * must be incremented by one instruction; otherwise the exception
  67. * return code will restart the "syscall" instruction and the system
  68. * call will repeat forever.
  69. *
  70. * If you run out of registers (which happens quickly with 64-bit
  71. * values) further arguments must be fetched from the user-level
  72. * stack, starting at sp+16 to skip over the slots for the
  73. * registerized values, with copyin().
  74. */
  75. void
  76. syscall(struct trapframe *tf)
  77. {
  78. int callno;
  79. int32_t retval;
  80. int err;
  81. KASSERT(curthread != NULL);
  82. KASSERT(curthread->t_curspl == 0);
  83. KASSERT(curthread->t_iplhigh_count == 0);
  84. callno = tf->tf_v0;
  85. /*
  86. * Initialize retval to 0. Many of the system calls don't
  87. * really return a value, just 0 for success and -1 on
  88. * error. Since retval is the value returned on success,
  89. * initialize it to 0 by default; thus it's not necessary to
  90. * deal with it except for calls that return other values,
  91. * like write.
  92. */
  93. retval = 0;
  94. switch (callno) {
  95. case SYS_reboot:
  96. err = sys_reboot(tf->tf_a0);
  97. break;
  98. case SYS___time:
  99. err = sys___time((userptr_t)tf->tf_a0,
  100. (userptr_t)tf->tf_a1);
  101. break;
  102. #ifdef UW
  103. case SYS_write:
  104. err = sys_write((int)tf->tf_a0,
  105. (userptr_t)tf->tf_a1,
  106. (int)tf->tf_a2,
  107. (int *)(&retval));
  108. break;
  109. case SYS__exit:
  110. sys__exit((int)tf->tf_a0);
  111. /* sys__exit does not return, execution should not get here */
  112. panic("unexpected return from sys__exit");
  113. break;
  114. case SYS_getpid:
  115. err = sys_getpid((pid_t *)&retval);
  116. break;
  117. case SYS_waitpid:
  118. err = sys_waitpid((pid_t)tf->tf_a0,
  119. (userptr_t)tf->tf_a1,
  120. (int)tf->tf_a2,
  121. (pid_t *)&retval);
  122. break;
  123. #endif // UW
  124. /* Add stuff here */
  125. default:
  126. kprintf("Unknown syscall %d\n", callno);
  127. err = ENOSYS;
  128. break;
  129. }
  130. if (err) {
  131. /*
  132. * Return the error code. This gets converted at
  133. * userlevel to a return value of -1 and the error
  134. * code in errno.
  135. */
  136. tf->tf_v0 = err;
  137. tf->tf_a3 = 1; /* signal an error */
  138. }
  139. else {
  140. /* Success. */
  141. tf->tf_v0 = retval;
  142. tf->tf_a3 = 0; /* signal no error */
  143. }
  144. /*
  145. * Now, advance the program counter, to avoid restarting
  146. * the syscall over and over again.
  147. */
  148. tf->tf_epc += 4;
  149. /* Make sure the syscall code didn't forget to lower spl */
  150. KASSERT(curthread->t_curspl == 0);
  151. /* ...or leak any spinlocks */
  152. KASSERT(curthread->t_iplhigh_count == 0);
  153. }
  154. /*
  155. * Enter user mode for a newly forked process.
  156. *
  157. * This function is provided as a reminder. You need to write
  158. * both it and the code that calls it.
  159. *
  160. * Thus, you can trash it and do things another way if you prefer.
  161. */
  162. void
  163. enter_forked_process(struct trapframe *tf)
  164. {
  165. (void)tf;
  166. }