Merge branch 'master' into net-dev
[akaros.git] / user / parlib / src / syscall_i386.c
1 // System call stubs.
2 #ifdef __DEPUTY__
3 #pragma nodeputy
4 #endif
5
6 #include <arch/types.h>
7 #include <arch/arch.h>
8
9 // TODO: fix sysenter to take all 5 params
10 static inline 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 ("  pushl %%ebp;        "
16                       "  pushl %%esi;        "
17                       "  movl %%esp, %%ebp;  "
18                       "  leal 1f, %%esi;     "
19                       "  sysenter;           "
20                       "1:                    "
21                       "  popl %%esi;         "
22                       "  popl %%ebp;         "
23                       : "=a" (ret)
24                       : "a" (num),
25                         "d" (a1),
26                         "c" (a2),
27                         "b" (a3),
28                         "D" (a4)
29                       : "cc", "memory");
30         return ret;
31 }
32
33 static inline intreg_t syscall_trap(uint16_t num, intreg_t a1,
34                              intreg_t a2, intreg_t a3,
35                              intreg_t a4, intreg_t a5)
36 {
37         uint32_t ret;
38
39         // Generic system call: pass system call number in AX,
40         // up to five parameters in DX, CX, BX, DI, SI.
41         // Interrupt kernel with T_SYSCALL.
42         //
43         // The "volatile" tells the assembler not to optimize
44         // this instruction away just because we don't use the
45         // return value.
46         //
47         // The last clause tells the assembler that this can
48         // potentially change the condition codes and arbitrary
49         // memory locations.
50
51         asm volatile("int %1"
52                      : "=a" (ret)
53                      : "i" (T_SYSCALL),
54                        "a" (num),
55                        "d" (a1),
56                        "c" (a2),
57                        "b" (a3),
58                        "D" (a4),
59                        "S" (a5)
60                      : "cc", "memory");
61         return ret;
62 }
63
64 intreg_t syscall(uint16_t num, intreg_t a1,
65                 intreg_t a2, intreg_t a3,
66                 intreg_t a4, intreg_t a5)
67 {
68         #ifndef SYSCALL_TRAP
69                 return syscall_sysenter(num, a1, a2, a3, a4, a5);
70         #else
71                 return syscall_trap(num, a1, a2, a3, a4, a5);
72         #endif
73 }