diff --git a/include/l4/api/syscall.h b/include/l4/api/syscall.h index 0e99967..d001faa 100644 --- a/include/l4/api/syscall.h +++ b/include/l4/api/syscall.h @@ -7,6 +7,8 @@ #define __SYSCALL_H__ #include INC_GLUE(syscall.h) +#include INC_API(exregs.h) +#include #define syscall_offset_mask 0xFF @@ -29,19 +31,20 @@ void print_syscall_context(struct ktcb *t); -int sys_ipc(struct syscall_context *); -int sys_thread_switch(struct syscall_context *); -int sys_thread_control(struct syscall_context *); -int sys_exchange_registers(struct syscall_context *); -int sys_schedule(struct syscall_context *); -int sys_unmap(struct syscall_context *); -int sys_space_control(struct syscall_context *); -int sys_ipc_control(struct syscall_context *); -int sys_map(struct syscall_context *); -int sys_getid(struct syscall_context *); -int sys_kread(struct syscall_context *); -int sys_kmem_control(struct syscall_context *); -int sys_time(struct syscall_context *); -int sys_mutex_control(struct syscall_context *); +int sys_ipc(l4id_t to, l4id_t from, unsigned int flags); +int sys_thread_switch(void); +int sys_thread_control(unsigned int flags, struct task_ids *ids); +int sys_exchange_registers(struct exregs_data *exregs, l4id_t tid); +int sys_schedule(void); +int sys_unmap(unsigned long virtual, unsigned long npages, unsigned int tid); +int sys_space_control(void); +int sys_ipc_control(void); +int sys_map(unsigned long phys, unsigned long virt, unsigned long npages, + unsigned long flags, unsigned int tid); +int sys_getid(struct task_ids *ids); +int sys_kread(int rd, void *addr); +int sys_kmem_control(unsigned long pfn, int npages, int grant); +int sys_time(struct timeval *tv, int set); +int sys_mutex_control(unsigned long mutex_address, int mutex_op); #endif /* __SYSCALL_H__ */ diff --git a/include/l4/generic/time.h b/include/l4/generic/time.h index fdbf709..62471c5 100644 --- a/include/l4/generic/time.h +++ b/include/l4/generic/time.h @@ -7,6 +7,12 @@ #ifndef __GENERIC_TIMER_H__ #define __GENERIC_TIMER_H__ +/* Used by posix systems */ +struct timeval { + int tv_sec; + int tv_usec; +}; + extern volatile u32 jiffies; int do_timer_irq(void); diff --git a/src/api/ipc.c b/src/api/ipc.c index a9e2e92..2222571 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -149,7 +149,7 @@ int ipc_msg_copy(struct ktcb *to, struct ktcb *from) return ret; } -int sys_ipc_control(syscall_context_t *regs) +int sys_ipc_control(void) { return -ENOSYS; } @@ -540,11 +540,8 @@ void printk_sysregs(syscall_context_t *regs) * - Can propagate messages from third party threads. * - A thread can both send and receive on the same call. */ -int sys_ipc(syscall_context_t *regs) +int sys_ipc(l4id_t to, l4id_t from, unsigned int flags) { - l4id_t to = (l4id_t)regs->r0; - l4id_t from = (l4id_t)regs->r1; - unsigned int flags = (unsigned int)regs->r2; unsigned int ipc_type = 0; int ret = 0; diff --git a/src/api/kip.c b/src/api/kip.c index cde9e29..4fe3884 100644 --- a/src/api/kip.c +++ b/src/api/kip.c @@ -56,15 +56,12 @@ int __sys_kread(int rd, void *dest) * support file positions, any such features aren't supported since this is call * is discarded after startup. */ -int sys_kread(struct syscall_context *a) +int sys_kread(int rd, void *addr) { - unsigned int *arg = KTCB_REF_ARG0(current); - void *addr = (void *)arg[1]; /* Buffer address */ - int rd = (int)arg[0]; /* Request descriptor */ - /* Error checking */ if (rd < 0) return -EINVAL; + return __sys_kread(rd, addr); } diff --git a/src/api/mutex.c b/src/api/mutex.c index 615eb10..94c9eec 100644 --- a/src/api/mutex.c +++ b/src/api/mutex.c @@ -242,10 +242,8 @@ int mutex_control_unlock(unsigned long mutex_address) return 0; } -int sys_mutex_control(syscall_context_t *regs) +int sys_mutex_control(unsigned long mutex_address, int mutex_op) { - unsigned long mutex_address = (unsigned long)regs->r0; - int mutex_op = (int)regs->r1; unsigned long mutex_physical; int ret = 0; diff --git a/src/api/space.c b/src/api/space.c index 69accf1..b3407cb 100644 --- a/src/api/space.c +++ b/src/api/space.c @@ -16,13 +16,9 @@ * well. struct link new_mappings; */ -int sys_map(syscall_context_t *regs) +int sys_map(unsigned long phys, unsigned long virt, unsigned long npages, + unsigned long flags, unsigned int tid) { - unsigned long phys = regs->r0; - unsigned long virt = regs->r1; - unsigned long npages = regs->r2; - unsigned long flags = regs->r3; - unsigned int tid = regs->r4; struct ktcb *target; if (tid == current->tid) { /* The easiest case */ @@ -46,11 +42,8 @@ found: * sucessfully, returns 0. If part of the range was found to be already * unmapped, returns -1. This is may or may not be an error. */ -int sys_unmap(syscall_context_t *regs) +int sys_unmap(unsigned long virtual, unsigned long npages, unsigned int tid) { - unsigned long virtual = regs->r0; - unsigned long npages = regs->r1; - unsigned int tid = regs->r2; struct ktcb *target; int ret = 0, retval = 0; diff --git a/src/api/syscall.c b/src/api/syscall.c index 2bb05d6..c55c276 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -98,12 +98,10 @@ void do_exchange_registers(struct ktcb *task, struct exregs_data *exregs) * condition so that the scheduler does not execute it as we modify * its context. */ -int sys_exchange_registers(syscall_context_t *regs) +int sys_exchange_registers(struct exregs_data *exregs, l4id_t tid) { int err = 0; struct ktcb *task; - struct exregs_data *exregs = (struct exregs_data *)regs->r0; - l4id_t tid = regs->r1; /* Find tcb from its list */ if (!(task = tcb_find(tid))) @@ -150,20 +148,19 @@ out: return err; } -int sys_schedule(syscall_context_t *regs) +int sys_schedule(void) { printk("(SVC) %s called. Tid (%d)\n", __FUNCTION__, current->tid); return 0; } -int sys_space_control(syscall_context_t *regs) +int sys_space_control(void) { return -ENOSYS; } -int sys_getid(syscall_context_t *regs) +int sys_getid(struct task_ids *ids) { - struct task_ids *ids = (struct task_ids *)regs->r0; struct ktcb *this = current; ids->tid = this->tid; @@ -192,12 +189,8 @@ int validate_granted_pages(unsigned long pfn, int npages) * this memory is used for thread creation and memory mapping, (e.g. new * page tables, page middle directories, per-task kernel stack etc.) */ -int sys_kmem_control(syscall_context_t *regs) +int sys_kmem_control(unsigned long pfn, int npages, int grant) { - unsigned long pfn = (unsigned long)regs->r0; - int npages = (int)regs->r1; - int grant = (int)regs->r2; - /* Pager is granting us pages */ if (grant) { /* diff --git a/src/api/thread.c b/src/api/thread.c index 4cee760..095b710 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -15,7 +15,7 @@ #include INC_ARCH(asm.h) #include INC_SUBARCH(mm.h) -int sys_thread_switch(syscall_context_t *regs) +int sys_thread_switch(void) { schedule(); return 0; @@ -343,11 +343,9 @@ out_err: * space for a thread that doesn't already have one, or destroys it if the last * thread that uses it is destroyed. */ -int sys_thread_control(syscall_context_t *regs) +int sys_thread_control(unsigned int flags, struct task_ids *ids) { int ret = 0; - unsigned int flags = regs->r0; - struct task_ids *ids = (struct task_ids *)regs->r1; switch (flags & THREAD_ACTION_MASK) { case THREAD_CREATE: diff --git a/src/generic/time.c b/src/generic/time.c index bd70ddd..b33321f 100644 --- a/src/generic/time.c +++ b/src/generic/time.c @@ -37,12 +37,6 @@ struct time_info { u64 sec; /* Seconds so far */ }; -/* Used by posix systems */ -struct timeval { - int tv_sec; - int tv_usec; -}; - static struct time_info systime = { 0 }; /* @@ -71,13 +65,12 @@ void update_system_time(void) } /* Read system time */ -int sys_time(syscall_context_t *args) +int sys_time(struct timeval *tv, int set) { - struct timeval *tv = (struct timeval *)args->r0; - int set = (int)args->r1; int retries = 20; - if (check_access((unsigned long)tv, sizeof(*tv), MAP_USR_RW_FLAGS, 1) < 0) + if (check_access((unsigned long)tv, sizeof(*tv), + MAP_USR_RW_FLAGS, 1) < 0) return -EINVAL; /* Get time */ diff --git a/src/glue/arm/systable.c b/src/glue/arm/systable.c index f6992f5..da6a73e 100644 --- a/src/glue/arm/systable.c +++ b/src/glue/arm/systable.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include INC_GLUE(memlayout.h) #include INC_GLUE(syscall.h) @@ -35,26 +36,104 @@ void kip_init_syscalls(void) /* Jump table for all system calls. */ syscall_fn_t syscall_table[SYSCALLS_TOTAL]; + +int arch_sys_ipc(syscall_context_t *regs) +{ + return sys_ipc((l4id_t)regs->r0, (l4id_t)regs->r1, + (unsigned int)regs->r2); +} + +int arch_sys_thread_switch(syscall_context_t *regs) +{ + return sys_thread_switch(); +} + +int arch_sys_thread_control(syscall_context_t *regs) +{ + return sys_thread_control((unsigned int)regs->r0, + (struct task_ids *)regs->r1); +} + +int arch_sys_exchange_registers(syscall_context_t *regs) +{ + return sys_exchange_registers((struct exregs_data *)regs->r0, + (l4id_t)regs->r1); +} + +int arch_sys_schedule(syscall_context_t *regs) +{ + return sys_schedule(); +} + +int arch_sys_getid(syscall_context_t *regs) +{ + return sys_getid((struct task_ids *)regs->r0); +} + +int arch_sys_unmap(syscall_context_t *regs) +{ + return sys_unmap((unsigned long)regs->r0, (unsigned long)regs->r1, + (unsigned int)regs->r2); +} + +int arch_sys_space_control(syscall_context_t *regs) +{ + return sys_space_control(); +} + +int arch_sys_ipc_control(syscall_context_t *regs) +{ + return sys_ipc_control(); +} + +int arch_sys_map(syscall_context_t *regs) +{ + return sys_map((unsigned long)regs->r0, (unsigned long)regs->r1, + (unsigned long)regs->r2, (unsigned long)regs->r3, + (unsigned int)regs->r4); +} + +int arch_sys_kread(syscall_context_t *regs) +{ + return sys_kread((int)regs->r0, (void *)regs->r1); +} + +int arch_sys_kmem_control(syscall_context_t *regs) +{ + return sys_kmem_control((unsigned long)regs->r0, (int)regs->r1, (int)regs->r2); +} + +int arch_sys_time(syscall_context_t *regs) +{ + return sys_time((struct timeval *)regs->r0, (int)regs->r1); +} + +int arch_sys_mutex_control(syscall_context_t *regs) +{ + return sys_mutex_control((unsigned long)regs->r0, (int)regs->r1); +} + + /* * Initialises the system call jump table, for kernel to use. * Also maps the system call page into userspace. */ void syscall_init() { - syscall_table[sys_ipc_offset >> 2] = (syscall_fn_t)sys_ipc; - syscall_table[sys_thread_switch_offset >> 2] = (syscall_fn_t)sys_thread_switch; - syscall_table[sys_thread_control_offset >> 2] = (syscall_fn_t)sys_thread_control; - syscall_table[sys_exchange_registers_offset >> 2] = (syscall_fn_t)sys_exchange_registers; - syscall_table[sys_schedule_offset >> 2] = (syscall_fn_t)sys_schedule; - syscall_table[sys_getid_offset >> 2] = (syscall_fn_t)sys_getid; - syscall_table[sys_unmap_offset >> 2] = (syscall_fn_t)sys_unmap; - syscall_table[sys_space_control_offset >> 2] = (syscall_fn_t)sys_space_control; - syscall_table[sys_ipc_control_offset >> 2] = (syscall_fn_t)sys_ipc_control; - syscall_table[sys_map_offset >> 2] = (syscall_fn_t)sys_map; - syscall_table[sys_kread_offset >> 2] = (syscall_fn_t)sys_kread; - syscall_table[sys_kmem_control_offset >> 2] = (syscall_fn_t)sys_kmem_control; - syscall_table[sys_time_offset >> 2] = (syscall_fn_t)sys_time; - syscall_table[sys_mutex_control_offset >> 2] = (syscall_fn_t)sys_mutex_control; + syscall_table[sys_ipc_offset >> 2] = (syscall_fn_t)arch_sys_ipc; + syscall_table[sys_thread_switch_offset >> 2] = (syscall_fn_t)arch_sys_thread_switch; + syscall_table[sys_thread_control_offset >> 2] = (syscall_fn_t)arch_sys_thread_control; + syscall_table[sys_exchange_registers_offset >> 2] = (syscall_fn_t)arch_sys_exchange_registers; + syscall_table[sys_schedule_offset >> 2] = (syscall_fn_t)arch_sys_schedule; + syscall_table[sys_getid_offset >> 2] = (syscall_fn_t)arch_sys_getid; + syscall_table[sys_unmap_offset >> 2] = (syscall_fn_t)arch_sys_unmap; + syscall_table[sys_space_control_offset >> 2] = (syscall_fn_t)arch_sys_space_control; + syscall_table[sys_ipc_control_offset >> 2] = (syscall_fn_t)arch_sys_ipc_control; + syscall_table[sys_map_offset >> 2] = (syscall_fn_t)arch_sys_map; + syscall_table[sys_kread_offset >> 2] = (syscall_fn_t)arch_sys_kread; + syscall_table[sys_kmem_control_offset >> 2] = (syscall_fn_t)arch_sys_kmem_control; + syscall_table[sys_time_offset >> 2] = (syscall_fn_t)arch_sys_time; + syscall_table[sys_mutex_control_offset >> 2] = (syscall_fn_t)arch_sys_mutex_control; add_mapping(virt_to_phys(&__syscall_page_start), ARM_SYSCALL_PAGE, PAGE_SIZE, MAP_USR_RO_FLAGS);