Implemented the bodies of the serial read/write syscalls on both user/kernel...
[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 uint32_t
11 syscall_sysenter(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
12 {
13         uint32_t ret;
14     asm volatile(
15             //"pushl %%ecx\n\t"
16             //"pushl %%edx\n\t"
17             "pushl %%ebp\n\t"
18                         "pushl %%esi\n\t"
19             "movl %%esp, %%ebp\n\t"
20             "leal after_sysenter, %%esi\n\t"
21             "sysenter\n\t"
22             "after_sysenter:\n\t"
23                         "popl %%esi\n\t"
24             "popl %%ebp\n\t"
25             //"popl %%edx\n\t"
26             //"popl %%ecx"
27             :"=a" (ret)
28             : "a" (num),
29                 "d" (a1),
30                 "c" (a2),
31                 "b" (a3),
32                 "D" (a4)
33         : "cc", "memory", "%esp");
34         return ret;
35 }
36
37 static inline uint32_t syscall_trap(int num, uint32_t a1, uint32_t a2, 
38                                     uint32_t a3, uint32_t a4, uint32_t a5)
39 {
40         uint32_t ret;
41
42         // Generic system call: pass system call number in AX,
43         // up to five parameters in DX, CX, BX, DI, SI.
44         // Interrupt kernel with T_SYSCALL.
45         //
46         // The "volatile" tells the assembler not to optimize
47         // this instruction away just because we don't use the
48         // return value.
49         //
50         // The last clause tells the assembler that this can
51         // potentially change the condition codes and arbitrary
52         // memory locations.
53
54         asm volatile("int %1\n"
55                 : "=a" (ret)
56                 : "i" (T_SYSCALL),
57                   "a" (num),
58                   "d" (a1),
59                   "c" (a2),
60                   "b" (a3),
61                   "D" (a4),
62                   "S" (a5)
63                 : "cc", "memory");
64
65         return ret;
66 }
67
68 static inline uint32_t syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3,
69                                uint32_t a4, uint32_t a5)
70 {
71         #ifndef SYSCALL_TRAP
72                 return syscall_sysenter(num, a1, a2, a3, a4, a5);
73         #else
74                 return syscall_trap(num, a1, a2, a3, a4, a5);
75         #endif
76 }
77
78 void sys_env_destroy(envid_t envid)
79 {
80         syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
81         while(1); //Should never get here...
82 }
83
84 envid_t sys_getenvid(void)
85 {
86          return syscall(SYS_getenvid, 0, 0, 0, 0, 0);
87 }
88
89 uint32_t sys_getcpuid(void)
90 {
91          return syscall(SYS_getcpuid, 0, 0, 0, 0, 0);
92 }
93
94 error_t sys_cputs(const char *s, size_t len)
95 {
96     return syscall(SYS_cputs, (uint32_t) s,  len, 0, 0, 0);
97 }
98
99 //Write a buffer over the serial port
100 error_t sys_serial_write(void* buf, uint16_t len) 
101 {
102         return syscall(SYS_serial_write, (uint32_t)buf, len, 0, 0, 0);
103 }
104
105 //Read a buffer over the serial port
106 uint16_t sys_serial_read(void* buf, uint16_t len) 
107 {
108         return syscall(SYS_serial_read, (uint32_t)buf, len, 0, 0, 0);
109 }