Xen Ring Buffers
[akaros.git] / lib / syscall.c
1 // System call stubs.
2
3 #include <inc/syscall.h>
4 #include <inc/lib.h>
5
6 static inline uint32_t
7 syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
8 {
9         uint32_t ret;
10
11         // Generic system call: pass system call number in AX,
12         // up to five parameters in DX, CX, BX, DI, SI.
13         // Interrupt kernel with T_SYSCALL.
14         //
15         // The "volatile" tells the assembler not to optimize
16         // this instruction away just because we don't use the
17         // return value.
18         // 
19         // The last clause tells the assembler that this can
20         // potentially change the condition codes and arbitrary
21         // memory locations.
22
23         asm volatile("int %1\n"
24                 : "=a" (ret)
25                 : "i" (T_SYSCALL),
26                   "a" (num),
27                   "d" (a1),
28                   "c" (a2),
29                   "b" (a3),
30                   "D" (a4),
31                   "S" (a5)
32                 : "cc", "memory");
33         
34         return ret;
35 }
36
37 static inline error_t async_syscall(syscall_req_t *syscall)
38 {
39         static uint8_t next = 0; // should make sure this never goes too high
40         syscall_req_t* req = RING_GET_REQUEST(&sysfrontring, next++);   
41         memcpy(req, syscall, sizeof(syscall_req_t));
42         syscall_req_t* req = RING_GET_REQUEST(&sysfrontring, next++);   
43         memcpy(req, syscall, sizeof(syscall_req_t));
44         // need to actually update our sysfrontring.req_prod_pvt
45         sysfrontring.req_prod_pvt++;
46         RING_PUSH_REQUESTS(&sysfrontring);
47         return 0;
48 }
49
50 void sys_cputs_async(const char *s, size_t len)
51 {
52         // could just hardcode 4 0's, will eventually wrap this marshaller anyway
53         syscall_req_t syscall = {SYS_cputs, 0, {(uint32_t)s, len, [2 ... (NUM_SYS_ARGS-1)] 0} };
54         async_syscall(&syscall);
55 }
56
57 void
58 sys_cputs(const char *s, size_t len)
59 {
60         syscall(SYS_cputs, (uint32_t) s, len, 0, 0, 0);
61 }
62
63 int
64 sys_cgetc(void)
65 {
66         return syscall(SYS_cgetc, 0, 0, 0, 0, 0);
67 }
68
69 int
70 sys_env_destroy(envid_t envid)
71 {
72         return syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
73 }
74
75 envid_t
76 sys_getenvid(void)
77 {
78          return syscall(SYS_getenvid, 0, 0, 0, 0, 0);
79 }
80
81