Poor-mans async printf support for userspace
[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_t *syscall)
38 {
39         // testing just two syscalls at a time, and just put it at the beginning of
40         // the shared data page.  This is EXTREMELY GHETTO....
41         if ( ((syscall_t*)procdata)->args[0] ) // something there, presumably the first syscall
42                 memcpy(((void*)procdata) + sizeof(syscall_t), syscall, sizeof(syscall_t));
43         else // nothing there, this is the first one
44                 memcpy(procdata, syscall, sizeof(syscall_t));
45         return 0;
46 }
47
48 void sys_cputs_async(const char *s, size_t len)
49 {
50         // could just hardcode 4 0's, will eventually wrap this marshaller anyway
51         syscall_t syscall = {SYS_cputs, 0, {(uint32_t)s, len, [2 ... (NUM_SYS_ARGS-1)] 0} };
52         async_syscall(&syscall);
53 }
54
55 void
56 sys_cputs(const char *s, size_t len)
57 {
58         syscall(SYS_cputs, (uint32_t) s, len, 0, 0, 0);
59 }
60
61 int
62 sys_cgetc(void)
63 {
64         return syscall(SYS_cgetc, 0, 0, 0, 0, 0);
65 }
66
67 int
68 sys_env_destroy(envid_t envid)
69 {
70         return syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
71 }
72
73 envid_t
74 sys_getenvid(void)
75 {
76          return syscall(SYS_getenvid, 0, 0, 0, 0, 0);
77 }
78
79