Added ability to load an arbitrary binary from an ethernet server and launch it
[akaros.git] / user / parlib / src / syscall.c
index 495e74b..e0f6c5b 100644 (file)
@@ -3,42 +3,40 @@
 #pragma nodeputy
 #endif
 
-#include <inc/syscall.h>
-#include <inc/lib.h>
-#include <inc/x86.h>
+#include <arch/x86.h>
+#include <parlib.h>
 
 // TODO: modify to take only four parameters
-static uint32_t
-syscall_sysenter(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
+static intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
+                                 intreg_t a2, intreg_t a3,
+                                 intreg_t a4, intreg_t a5)
 {
-       uint32_t ret;
-    asm volatile(
-            //"pushl %%ecx\n\t"
-            //"pushl %%edx\n\t"
-            "pushl %%ebp\n\t"
-                       "pushl %%esi\n\t"
-            "movl %%esp, %%ebp\n\t"
-            "leal after_sysenter, %%esi\n\t"
-            "sysenter\n\t"
-            "after_sysenter:\n\t"
-                       "popl %%esi\n\t"
-            "popl %%ebp\n\t"
-            //"popl %%edx\n\t"
-            //"popl %%ecx"
-            :"=a" (ret)
-            : "a" (num),
-                "d" (a1),
-                "c" (a2),
-                "b" (a3),
-                "D" (a4)
-        : "cc", "memory", "%esp");
+       intreg_t ret;
+       asm volatile(
+           "pushl %%ebp\n\t"
+           "pushl %%esi\n\t"
+           "movl %%esp, %%ebp\n\t"
+           "leal after_sysenter, %%esi\n\t"
+           "sysenter\n\t"
+           "after_sysenter:\n\t"
+           "\tpopl %%esi\n"
+           "\tpopl %%ebp\n"
+           :"=a" (ret)
+           : "a" (num),
+             "d" (a1),
+             "c" (a2),
+             "b" (a3),
+             "D" (a4)
+           : "cc", "memory", "%esp");
        return ret;
 }
-static inline uint32_t
-syscall_trap(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
-{
-       uint32_t ret;
 
+static intreg_t syscall_trap(uint16_t num, intreg_t a1,
+                             intreg_t a2, intreg_t a3,
+                             intreg_t a4, intreg_t a5)
+{
+       intreg_t ret;
+       
        // Generic system call: pass system call number in AX,
        // up to five parameters in DX, CX, BX, DI, SI.
        // Interrupt kernel with T_SYSCALL.
@@ -65,120 +63,69 @@ syscall_trap(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32
        return ret;
 }
 
-static inline uint32_t
-syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
+static intreg_t syscall(uint16_t num, intreg_t a1,
+                        intreg_t a2, intreg_t a3,
+                        intreg_t a4, intreg_t a5)
 {
        #ifndef SYSCALL_TRAP
-       return syscall_sysenter(num, a1, a2, a3, a4, a5);
+               return syscall_sysenter(num, a1, a2, a3, a4, a5);
        #else
-       return syscall_trap(num, a1, a2, a3, a4, a5);
+               return syscall_trap(num, a1, a2, a3, a4, a5);
        #endif
 }
 
-static error_t async_syscall(syscall_req_t* req, syscall_desc_t* desc)
-{
-       // Note that this assumes one global frontring (TODO)
-       // abort if there is no room for our request.  ring size is currently 64.
-       // we could spin til it's free, but that could deadlock if this same thread
-       // is supposed to consume the requests it is waiting on later.
-       if (RING_FULL(&sysfrontring))
-               return E_BUSY;
-       // req_prod_pvt comes in as the previously produced item.  need to
-       // increment to the next available spot, which is the one we'll work on.
-       // at some point, we need to listen for the responses.
-       desc->idx = ++(sysfrontring.req_prod_pvt);
-       desc->sysfr = &sysfrontring;
-       syscall_req_t* r = RING_GET_REQUEST(&sysfrontring, desc->idx);
-       memcpy(r, req, sizeof(syscall_req_t));
-       // push our updates to sysfrontring.req_prod_pvt
-       RING_PUSH_REQUESTS(&sysfrontring);
-       //cprintf("DEBUG: sring->req_prod: %d, sring->rsp_prod: %d\n", \
-               sysfrontring.sring->req_prod, sysfrontring.sring->rsp_prod);
-       return 0;
-}
-
-// consider a timeout too
-error_t waiton_syscall(syscall_desc_t* desc, syscall_rsp_t* rsp)
+void sys_env_destroy(envid_t envid)
 {
-       // Make sure we were given a desc with a non-NULL frontring.  This could
-       // happen if someone forgot to check the error code on the paired syscall.
-       if (!desc->sysfr)
-               return E_FAIL;
-       // this forces us to call wait in the order in which the syscalls are made.
-       if (desc->idx != desc->sysfr->rsp_cons + 1)
-               return E_DEADLOCK;
-       while (!(RING_HAS_UNCONSUMED_RESPONSES(desc->sysfr)))
-               cpu_relax();
-       memcpy(rsp, RING_GET_RESPONSE(desc->sysfr, desc->idx), sizeof(*rsp));
-       desc->sysfr->rsp_cons++;
-    // run a cleanup function for this desc, if available
-    if (desc->cleanup)
-       desc->cleanup(desc->data);
-       return 0;
+       syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
+       while(1); //Should never get here...
 }
 
-error_t sys_null_async(syscall_desc_t* desc)
+envid_t sys_getenvid(void)
 {
-       syscall_req_t syscall = {SYS_null, 0, {[0 ... (NUM_SYS_ARGS-1)] 0}};
-       desc->cleanup = NULL;
-       desc->data = NULL;
-       return async_syscall(&syscall, desc);
+        return syscall(SYS_getenvid, 0, 0, 0, 0, 0);
 }
 
-void sys_cache_buster(uint32_t num_writes, uint32_t val)
+envid_t sys_getcpuid(void)
 {
-       syscall(SYS_cache_buster, num_writes, val, 0, 0, 0);
+        return syscall(SYS_getcpuid, 0, 0, 0, 0, 0);
 }
 
-error_t sys_cache_buster_async(syscall_desc_t* desc, uint32_t num_writes,
-                               uint32_t val)
+ssize_t sys_cputs(const uint8_t *s, size_t len)
 {
-       syscall_req_t syscall = {SYS_cache_buster, 0,
-                                {num_writes, val, [2 ... (NUM_SYS_ARGS-1)] 0}};
-       // just to be safe, 0 these out.  they should have been 0'd right after
-       // the desc was POOL_GET'd
-       desc->cleanup = NULL;
-       desc->data = NULL;
-       return async_syscall(&syscall, desc);
+    return syscall(SYS_cputs, (intreg_t) s,  len, 0, 0, 0);
 }
 
-error_t sys_cputs_async(const char *s, size_t len, syscall_desc_t* desc,
-                     void (*cleanup_handler)(void*), void* cleanup_data)
+uint16_t sys_cgetc(void)
 {
-       // could just hardcode 4 0's, will eventually wrap this marshaller anyway
-       syscall_req_t syscall = {SYS_cputs, 0, {(uint32_t)s, len, [2 ... (NUM_SYS_ARGS-1)] 0} };
-       desc->cleanup = cleanup_handler;
-       desc->data = cleanup_data;
-       return async_syscall(&syscall, desc);
+    return syscall(SYS_cgetc, 0, 0, 0, 0, 0);
 }
 
-void sys_null()
+//Write a buffer over the serial port
+ssize_t sys_serial_write(void* buf, size_t len) 
 {
-       syscall(SYS_null,0,0,0,0,0);
+       return syscall(SYS_serial_write, (intreg_t)buf, len, 0, 0, 0);
 }
 
-void
-sys_cputs(const char *s, size_t len)
+//Read a buffer over the serial port
+ssize_t sys_serial_read(void* buf, size_t len) 
 {
-       syscall(SYS_cputs, (uint32_t) s,  len, 0, 0, 0);
+       return syscall(SYS_serial_read, (intreg_t)buf, len, 0, 0, 0);
 }
 
-int
-sys_cgetc(void)
+//Run a binary loaded at the specificed address with the specified arguments
+ssize_t sys_run_binary(void* binary_buf, void* arg, size_t len) 
 {
-       return syscall(SYS_cgetc, 0, 0, 0, 0, 0);
+       return syscall(SYS_run_binary, (intreg_t)binary_buf, (intreg_t)arg, len, 0, 0);
 }
 
-int
-sys_env_destroy(envid_t envid)
+//Write a buffer over ethernet
+ssize_t sys_eth_write(void* buf, size_t len) 
 {
-       return syscall(SYS_env_destroy, envid, 0, 0, 0, 0);
+       return syscall(SYS_eth_write, (intreg_t)buf, len, 0, 0, 0);
 }
 
-envid_t
-sys_getenvid(void)
+//Read a buffer via ethernet
+ssize_t sys_eth_read(void* buf, size_t len) 
 {
-        return syscall(SYS_getenvid, 0, 0, 0, 0, 0);
+       return syscall(SYS_eth_read, (intreg_t)buf, len, 0, 0, 0);
 }
-
-