#ifndef __SOS_H #define __SOS_H #ifdef __cplusplus extern "C" { #endif #define KERNEL_MASK 0xfff #define CAPTYPE_MASK 0xe00 #define REQUEST_MASK (KERNEL_MASK & ~CAPTYPE_MASK) #define CAPTYPE_ADMIN 0x000 #define CAPTYPE_RECEIVER 0x200 #define CAPTYPE_MEMORY 0x400 #define CAPTYPE_THREAD 0x600 #define CAPTYPE_PAGE 0x800 #define CAPTYPE_CAPABILITY 0xa00 #define CAPTYPE_CAPPAGE 0xc00 /*#define CAPTYPE_??? 0xe00*/ /* This works on all kernel capabilities. */ #define CAP_DEGRADE 0 /* Operations */ #define CAP_ADMIN_SCHEDULE 1 /* TODO: add priviledged operations. */ #define CAP_RECEIVER_SET_OWNER 1 #define CAP_RECEIVER_CREATE_CAPABILITY 2 #define CAP_RECEIVER_CREATE_CALL_CAPABILITY 3 /* Not an operation; a capability with this bit set is a call capability. */ #define CAP_RECEIVER_CALL 4 #define CAP_MEMORY_CREATE 1 #define CAP_MEMORY_DESTROY 2 #define CAP_MEMORY_LIST 3 #define CAP_MEMORY_MAPPING 4 #define CAP_MEMORY_SET_LIMIT 5 #define CAP_MEMORY_GET_LIMIT 6 #define CAP_MEMORY_DROP 7 #define CAP_THREAD_RUN 1 #define CAP_THREAD_GET_INFO 2 /* Details of this are arch-specific. */ #define CAP_THREAD_SET_INFO 3 /* Details of this are arch-specific. */ /* Flag values for processor state */ #define THREAD_FLAG_WAITING 0x80000000 #define THREAD_FLAG_RUNNING 0x40000000 #define CAP_PAGE_MAP 1 #define CAP_PAGE_SHARE 2 #define CAP_PAGE_SHARE_COW 3 #define CAP_PAGE_FORGET 4 // Not an operation; a capability without this bit cannot write to the page. */ #define CAP_PAGE_WRITE 5 #define CAP_CAPABILITY_GET 1 #define CAP_CAPABILITY_SET_DEATH_NOTIFY 2 #define CAPPAGE_SIZE 102 /* Cappage has page's operations as well. */ #define CAP_CAPPAGE_SET 6 #ifndef __KERNEL typedef unsigned __Capability; extern __Capability __my_receiver; extern __Capability __my_admin; extern __Capability __my_memory; extern __Capability __my_call; __Capability __cap_copy (__Capability src) { return src | 2; } typedef struct __Message { unsigned data[4]; __Capability cap[4]; } __Message; static int __invoke (__Capability target, __Message *msg) { register int ret __asm__ ("v0"); register unsigned v0 __asm__ ("v0") = target; register unsigned a0 __asm__ ("a0") = msg->cap[0]; register unsigned a1 __asm__ ("a1") = msg->cap[1]; register unsigned a2 __asm__ ("a2") = msg->cap[2]; register unsigned a3 __asm__ ("a3") = msg->cap[3]; register unsigned t0 __asm__ ("t0") = msg->data[0]; register unsigned t1 __asm__ ("t1") = msg->data[1]; register unsigned t2 __asm__ ("t2") = msg->data[2]; register unsigned t3 __asm__ ("t3") = msg->data[3]; __asm__ volatile ("syscall" : "+r" (v0), "=r" (a0), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (t0), "=r" (t1), "=r" (t2), "=r" (t3)); return ret; } static int __call (__Capability target, __Message *msg) { register int ret __asm__ ("v0"); register unsigned v0 __asm__ ("v0") = target; register unsigned a0 __asm__ ("a0") = msg->cap[0]; register unsigned a1 __asm__ ("a1") = msg->cap[1]; register unsigned a2 __asm__ ("a2") = msg->cap[2]; register unsigned a3 __asm__ ("a3") = msg->cap[3]; register unsigned t0 __asm__ ("t0") = msg->data[0]; register unsigned t1 __asm__ ("t1") = msg->data[1]; register unsigned t2 __asm__ ("t2") = msg->data[2]; register unsigned t3 __asm__ ("t3") = msg->data[3]; __asm__ volatile ("syscall" : "+r" (v0), "+r" (a0), "+r" (a1), "+r" (a2), "+r" (a3), "+r" (t0), "+r" (t1), "+r" (t2), "+r" (t3)); msg->cap[0] = a0; msg->cap[1] = a1; msg->cap[2] = a2; msg->cap[3] = a3; msg->data[0] = t0; msg->data[1] = t1; msg->data[2] = t2; msg->data[3] = t3; return ret; } static int __invoke_01 (__Capability t, unsigned d) { __Message msg; int ret; msg.data[0] = d; return __invoke (t, &msg); } static int __invoke_02 (__Capability t, unsigned d0, unsigned d1) { __Message msg; int ret; msg.data[0] = d0; msg.data[1] = d1; return __invoke (t, &msg); } static int __invoke_11 (__Capability t, __Capability c, unsigned d) { __Message msg; int ret; msg.cap[0] = c; msg.data[0] = d; return __invoke (t, &msg); } static int __invoke_12 (__Capability t, __Capability c, unsigned d0, unsigned d1) { __Message msg; int ret; msg.cap[0] = c; msg.data[0] = d0; msg.data[1] = d1; return __invoke (t, &msg); } static __Capability __call_c01 (__Capability c, unsigned d) { __Message msg; int ret; msg.cap[0] = c; msg.data[0] = d; ret = __call (__my_call, &msg); return ret ? msg.cap[0] : 0; } static __Capability __call_c02 (__Capability c, unsigned d0, unsigned d1) { __Message msg; int ret; msg.cap[0] = c; msg.data[0] = d0; msg.data[1] = d1; ret = __call (__my_call, &msg); return ret ? msg.cap[0] : 0; } static __Capability __degrade (__Capability src, unsigned mask) { return __call_c02 (src, CAP_DEGRADE, mask); } static void __schedule () { __invoke_01 (__my_admin, CAP_ADMIN_SCHEDULE); } static int __receiver_set_owner (__Capability receiver, __Capability owner) { return __invoke_11 (receiver, owner, CAP_RECEIVER_SET_OWNER); } static __Capability __receiver_create_capability (__Capability receiver, unsigned protected_data) { return __call_c02 (receiver, CAP_RECEIVER_CREATE_CAPABILITY, protected_data); } static __Capability __receiver_create_call_capability (__Capability receiver, unsigned protected_data) { return __call_c02 (receiver, CAP_RECEIVER_CREATE_CALL_CAPABILITY, protected_data); } static __Capability __memory_create (__Capability memory, unsigned type) { return __call_c02 (memory, CAP_MEMORY_CREATE, type); } static __Capability __memory_create_page (__Capability memory) { return __memory_create (memory, CAPTYPE_PAGE); } static __Capability __memory_create_thread (__Capability memory) { return __memory_create (memory, CAPTYPE_THREAD); } static __Capability __memory_create_receiver (__Capability memory) { return __memory_create (memory, CAPTYPE_RECEIVER); } static __Capability __memory_create_memory (__Capability memory) { return __memory_create (memory, CAPTYPE_MEMORY); } static __Capability __memory_create_cappage (__Capability memory) { return __memory_create (memory, CAPTYPE_CAPPAGE); } static int __memory_destroy (__Capability memory, __Capability target) { return __invoke_11 (memory, target, CAP_MEMORY_DESTROY); } /* TODO: #define CAP_MEMORY_LIST 3 */ static __Capability __memory_mapping (__Capability memory, unsigned address) { return __call_c02 (memory, CAP_MEMORY_MAPPING, address); } static void __drop (__Capability cap) { __invoke_11 (__my_memory, cap, CAP_MEMORY_DROP); } static int __thread_run (__Capability thread, int run) { return __invoke_02 (thread, CAP_THREAD_RUN, run); } /* TODO: #define CAP_THREAD_GET_INFO 4 #define CAP_THREAD_SET_INFO 5 */ /* TODO: all except map should also work for cappages. #define CAP_PAGE_MAP 1 #define CAP_PAGE_SHARE 2 #define CAP_PAGE_SHARE_COW 3 #define CAP_PAGE_FORGET 4 */ static __Capability __capability_get (__Capability cap) { return __call_c01 (cap, CAP_CAPABILITY_GET); } static int __capability_set_death_notify (__Capability source, __Capability target) { return __invoke_11 (source, target, CAP_CAPABILITY_SET_DEATH_NOTIFY); } static int __capability_cappage_set (__Capability page, __Capability cap, unsigned index) { return __invoke_12 (page, cap, CAP_CAPPAGE_SET, index); } #endif #ifdef __cplusplus } #endif #endif