Fixed bug in sysenter/sysexit
[akaros.git] / kern / arch / i686 / ros / syscall.h
1 #ifndef _ROS_ARCH_SYSCALL_H
2 #define _ROS_ARCH_SYSCALL_H
3
4 #define T_SYSCALL       0x80
5
6 #ifndef ROS_KERNEL
7
8 #include <sys/types.h>
9 #include <stdint.h>
10 #include <ros/common.h>
11
12 // TODO: fix sysenter to take all 5 params
13 static inline intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
14                                  intreg_t a2, intreg_t a3,
15                                  intreg_t a4, intreg_t a5)
16 {
17         // The kernel clobbers ecx and edx => put them in clobber list.
18         // ebx is handled specially because of a glibc register
19         // allocation problem (not enough registers).
20         intreg_t ret;
21         asm volatile ("  pushl %%ebp;        "
22                       "  pushl %%esi;        "
23                       "  pushl %%ebx;        "
24                       "  pushl %%ecx;        "
25                       "  pushl %%edx;        "
26                       "  movl %%esp, %%ebp;  "
27                       "  movl %4, %%ebx;     "
28                       "  leal 1f, %%esi;     "
29                       "  sysenter;           "
30                       "1:                    "
31                       "  popl %%edx;         "
32                       "  popl %%ecx;         "
33                       "  popl %%ebx;         "
34                       "  popl %%esi;         "
35                       "  popl %%ebp;         "
36                       : "=a" (ret)
37                       : "a" (num),
38                         "d" (a1),
39                         "c" (a2),
40                         "r" (a3),
41                         "D" (a4)
42                       : "cc", "memory");
43         return ret;
44 }
45
46 static inline intreg_t syscall_trap(uint16_t num, intreg_t a1,
47                              intreg_t a2, intreg_t a3,
48                              intreg_t a4, intreg_t a5)
49 {
50         uint32_t ret;
51
52         // Generic system call: pass system call number in AX,
53         // up to five parameters in DX, CX, BX, DI, SI.
54         // Interrupt kernel with T_SYSCALL.
55         //
56         // The "volatile" tells the assembler not to optimize
57         // this instruction away just because we don't use the
58         // return value.
59         //
60         // The last clause tells the assembler that this can
61         // potentially change the condition codes and arbitrary
62         // memory locations.
63
64         asm volatile("int %1"
65                      : "=a" (ret)
66                      : "i" (T_SYSCALL),
67                        "a" (num),
68                        "d" (a1),
69                        "c" (a2),
70                        "b" (a3),
71                        "D" (a4),
72                        "S" (a5)
73                      : "cc", "memory");
74         return ret;
75 }
76
77 static inline long __attribute__((always_inline))
78 __ros_syscall(long _num, long _a0, long _a1, long _a2, long _a3, long _a4)
79 {
80         #ifndef SYSCALL_TRAP
81                 return syscall_sysenter(_num, _a0, _a1, _a2, _a3, _a4);
82         #else
83                 return syscall_trap(_num, _a0, _a1, _a2, _a3, _a4);
84         #endif
85 }
86
87 #endif
88
89 #endif
90