Cleaned up the return values for all system calls.
[akaros.git] / user / parlib / src / syscall.c
1 // System call stubs.
2 #ifdef __DEPUTY__
3 #pragma nodeputy
4 #endif
5
6 #include <arch/x86.h>
7 #include <parlib.h>
8
9 // TODO: modify to take only four parameters
10 static intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
11                                  intreg_t a2, intreg_t a3,
12                                  intreg_t a4, intreg_t a5)
13 {
14         intreg_t ret;
15     asm volatile(
16             //"pushl %%ecx\n\t"
17             //"pushl %%edx\n\t"
18             "pushl %%ebp\n\t"
19                         "pushl %%esi\n\t"
20             "movl %%esp, %%ebp\n\t"
21             "leal after_sysenter, %%esi\n\t"
22             "sysenter\n\t"
23             "after_sysenter:\n\t"
24                         "popl %%esi\n\t"
25             "popl %%ebp\n\t"
26             //"popl %%edx\n\t"
27             //"popl %%ecx"
28             :"=a" (ret)
29             : "a" (num),
30                 "d" (a1),
31                 "c" (a2),
32                 "b" (a3),
33                 "D" (a4)
34         : "cc", "memory", "%esp");
35         return ret;
36 }
37
38 static intreg_t syscall_trap(uint16_t num, intreg_t a1,
39                              intreg_t a2, intreg_t a3,
40                              intreg_t a4, intreg_t a5)
41 {
42         intreg_t ret;
43
44         // Generic system call: pass system call number in AX,
45         // up to five parameters in DX, CX, BX, DI, SI.
46         // Interrupt kernel with T_SYSCALL.
47         //
48         // The "volatile" tells the assembler not to optimize
49         // this instruction away just because we don't use the
50         // return value.
51         //
52         // The last clause tells the assembler that this can
53         // potentially change the condition codes and arbitrary
54         // memory locations.
55
56         asm volatile("int %1\n"
57                 : "=a" (ret)
58                 : "i" (T_SYSCALL),
59                   "a" (num),
60                   "d" (a1),
61                   "c" (a2),
62                   "b" (a3),
63                   "D" (a4),
64                   "S" (a5)
65                 : "cc", "memory");
66
67         return ret;
68 }
69
70 static intreg_t syscall(uint16_t num, intreg_t a1,
71                         intreg_t a2, intreg_t a3,
72                         intreg_t a4, intreg_t a5)
73 {
74         #ifndef SYSCALL_TRAP
75                 return syscall_sysenter(num, a1, a2, a3, a4, a5);
76         #else
77                 return syscall_trap(num, a1, a2, a3, a4, a5);
78         #endif
79 }
80
81 void sys_env_destroy(envid_t envid)
82 {
83         syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
84         while(1); //Should never get here...
85 }
86
87 envid_t sys_getenvid(void)
88 {
89          return syscall(SYS_getenvid, 0, 0, 0, 0, 0);
90 }
91
92 envid_t sys_getcpuid(void)
93 {
94          return syscall(SYS_getcpuid, 0, 0, 0, 0, 0);
95 }
96
97 ssize_t sys_cputs(const uint8_t *s, size_t len)
98 {
99     return syscall(SYS_cputs, (intreg_t) s,  len, 0, 0, 0);
100 }
101
102 uint16_t sys_cgetc(void)
103 {
104     return syscall(SYS_cgetc, 0, 0, 0, 0, 0);
105 }
106
107 //Write a buffer over the serial port
108 ssize_t sys_serial_write(void* buf, size_t len) 
109 {
110         return syscall(SYS_serial_write, (intreg_t)buf, len, 0, 0, 0);
111 }
112
113 //Read a buffer over the serial port
114 ssize_t sys_serial_read(void* buf, size_t len) 
115 {
116         return syscall(SYS_serial_read, (intreg_t)buf, len, 0, 0, 0);
117 }