sys_m68k.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * linux/arch/m68knommu/kernel/sys_m68k.c
  3. *
  4. * This file contains various random system calls that
  5. * have a non-standard calling sequence on the Linux/m68k
  6. * platform.
  7. */
  8. #include <linux/errno.h>
  9. #include <linux/sched.h>
  10. #include <linux/mm.h>
  11. #include <linux/smp.h>
  12. #include <linux/smp_lock.h>
  13. #include <linux/sem.h>
  14. #include <linux/msg.h>
  15. #include <linux/shm.h>
  16. #include <linux/stat.h>
  17. #include <linux/syscalls.h>
  18. #include <linux/mman.h>
  19. #include <linux/file.h>
  20. #include <linux/utsname.h>
  21. #include <asm/setup.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/cachectl.h>
  24. #include <asm/traps.h>
  25. #include <asm/ipc.h>
  26. #include <asm/cacheflush.h>
  27. #include <asm/unistd.h>
  28. /*
  29. * sys_pipe() is the normal C calling standard for creating
  30. * a pipe. It's not the way unix traditionally does this, though.
  31. */
  32. asmlinkage int sys_pipe(unsigned long * fildes)
  33. {
  34. int fd[2];
  35. int error;
  36. error = do_pipe(fd);
  37. if (!error) {
  38. if (copy_to_user(fildes, fd, 2*sizeof(int)))
  39. error = -EFAULT;
  40. }
  41. return error;
  42. }
  43. /* common code for old and new mmaps */
  44. static inline long do_mmap2(
  45. unsigned long addr, unsigned long len,
  46. unsigned long prot, unsigned long flags,
  47. unsigned long fd, unsigned long pgoff)
  48. {
  49. int error = -EBADF;
  50. struct file * file = NULL;
  51. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  52. if (!(flags & MAP_ANONYMOUS)) {
  53. file = fget(fd);
  54. if (!file)
  55. goto out;
  56. }
  57. down_write(&current->mm->mmap_sem);
  58. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  59. up_write(&current->mm->mmap_sem);
  60. if (file)
  61. fput(file);
  62. out:
  63. return error;
  64. }
  65. asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
  66. unsigned long prot, unsigned long flags,
  67. unsigned long fd, unsigned long pgoff)
  68. {
  69. return do_mmap2(addr, len, prot, flags, fd, pgoff);
  70. }
  71. /*
  72. * Perform the select(nd, in, out, ex, tv) and mmap() system
  73. * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
  74. * handle more than 4 system call parameters, so these system calls
  75. * used a memory block for parameter passing..
  76. */
  77. struct mmap_arg_struct {
  78. unsigned long addr;
  79. unsigned long len;
  80. unsigned long prot;
  81. unsigned long flags;
  82. unsigned long fd;
  83. unsigned long offset;
  84. };
  85. asmlinkage int old_mmap(struct mmap_arg_struct *arg)
  86. {
  87. struct mmap_arg_struct a;
  88. int error = -EFAULT;
  89. if (copy_from_user(&a, arg, sizeof(a)))
  90. goto out;
  91. error = -EINVAL;
  92. if (a.offset & ~PAGE_MASK)
  93. goto out;
  94. a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  95. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
  96. out:
  97. return error;
  98. }
  99. struct sel_arg_struct {
  100. unsigned long n;
  101. fd_set *inp, *outp, *exp;
  102. struct timeval *tvp;
  103. };
  104. asmlinkage int old_select(struct sel_arg_struct *arg)
  105. {
  106. struct sel_arg_struct a;
  107. if (copy_from_user(&a, arg, sizeof(a)))
  108. return -EFAULT;
  109. /* sys_select() does the appropriate kernel locking */
  110. return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
  111. }
  112. /*
  113. * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  114. *
  115. * This is really horribly ugly.
  116. */
  117. asmlinkage int sys_ipc (uint call, int first, int second,
  118. int third, void *ptr, long fifth)
  119. {
  120. int version;
  121. version = call >> 16; /* hack for backward compatibility */
  122. call &= 0xffff;
  123. if (call <= SEMCTL)
  124. switch (call) {
  125. case SEMOP:
  126. return sys_semop (first, (struct sembuf *)ptr, second);
  127. case SEMGET:
  128. return sys_semget (first, second, third);
  129. case SEMCTL: {
  130. union semun fourth;
  131. if (!ptr)
  132. return -EINVAL;
  133. if (get_user(fourth.__pad, (void **) ptr))
  134. return -EFAULT;
  135. return sys_semctl (first, second, third, fourth);
  136. }
  137. default:
  138. return -EINVAL;
  139. }
  140. if (call <= MSGCTL)
  141. switch (call) {
  142. case MSGSND:
  143. return sys_msgsnd (first, (struct msgbuf *) ptr,
  144. second, third);
  145. case MSGRCV:
  146. switch (version) {
  147. case 0: {
  148. struct ipc_kludge tmp;
  149. if (!ptr)
  150. return -EINVAL;
  151. if (copy_from_user (&tmp,
  152. (struct ipc_kludge *)ptr,
  153. sizeof (tmp)))
  154. return -EFAULT;
  155. return sys_msgrcv (first, tmp.msgp, second,
  156. tmp.msgtyp, third);
  157. }
  158. default:
  159. return sys_msgrcv (first,
  160. (struct msgbuf *) ptr,
  161. second, fifth, third);
  162. }
  163. case MSGGET:
  164. return sys_msgget ((key_t) first, second);
  165. case MSGCTL:
  166. return sys_msgctl (first, second,
  167. (struct msqid_ds *) ptr);
  168. default:
  169. return -EINVAL;
  170. }
  171. return -EINVAL;
  172. }
  173. /* sys_cacheflush -- flush (part of) the processor cache. */
  174. asmlinkage int
  175. sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
  176. {
  177. flush_cache_all();
  178. return(0);
  179. }
  180. asmlinkage int sys_getpagesize(void)
  181. {
  182. return PAGE_SIZE;
  183. }
  184. /*
  185. * Do a system call from kernel instead of calling sys_execve so we
  186. * end up with proper pt_regs.
  187. */
  188. int kernel_execve(const char *filename, char *const argv[], char *const envp[])
  189. {
  190. register long __res asm ("%d0") = __NR_execve;
  191. register long __a asm ("%d1") = (long)(filename);
  192. register long __b asm ("%d2") = (long)(argv);
  193. register long __c asm ("%d3") = (long)(envp);
  194. asm volatile ("trap #0" : "+d" (__res)
  195. : "d" (__a), "d" (__b), "d" (__c));
  196. return __res;
  197. }