2009-05-22 23:48:49 +03:00
|
|
|
#ifndef __SOS_H
|
|
|
|
#define __SOS_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define KERNEL_MASK 0xfff
|
|
|
|
#define CAPTYPE_MASK 0xe00
|
2009-05-25 01:31:35 +03:00
|
|
|
#define REQUEST_MASK (KERNEL_MASK & ~CAPTYPE_MASK)
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAPTYPE_RECEIVER 0x000
|
|
|
|
#define CAPTYPE_MEMORY 0x200
|
|
|
|
#define CAPTYPE_THREAD 0x400
|
|
|
|
#define CAPTYPE_PAGE 0x600
|
|
|
|
#define CAPTYPE_CAPABILITY 0x800
|
|
|
|
#define CAPTYPE_CAPPAGE 0xa00
|
|
|
|
/*#define CAPTYPE_??? 0xc00*/
|
2009-05-22 23:48:49 +03:00
|
|
|
/*#define CAPTYPE_??? 0xe00*/
|
|
|
|
|
|
|
|
/* This works on all kernel capabilities. */
|
|
|
|
#define CAP_DEGRADE 0
|
|
|
|
|
|
|
|
/* Operations */
|
|
|
|
#define CAP_RECEIVER_SET_OWNER 1
|
|
|
|
#define CAP_RECEIVER_CREATE_CAPABILITY 2
|
|
|
|
#define CAP_RECEIVER_CREATE_CALL_CAPABILITY 3
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_RECEIVER_ALL_RIGHTS 0x7f
|
2009-05-25 01:31:35 +03:00
|
|
|
/* Not an operation; a capability with this bit set is a call capability. */
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_RECEIVER_CALL 7
|
2009-05-27 15:38:52 +03:00
|
|
|
/* Same thing for reply capability. */
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_RECEIVER_REPLY 8
|
2009-05-22 23:48:49 +03:00
|
|
|
|
|
|
|
#define CAP_MEMORY_CREATE 1
|
|
|
|
#define CAP_MEMORY_DESTROY 2
|
|
|
|
#define CAP_MEMORY_LIST 3
|
|
|
|
#define CAP_MEMORY_MAPPING 4
|
2009-05-25 01:31:35 +03:00
|
|
|
#define CAP_MEMORY_SET_LIMIT 5
|
|
|
|
#define CAP_MEMORY_GET_LIMIT 6
|
|
|
|
#define CAP_MEMORY_DROP 7
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_MEMORY_ALL_RIGHTS 0x1ff
|
|
|
|
|
|
|
|
#define CAP_THREAD_GET_INFO 1 /* Details of this are arch-specific. */
|
|
|
|
#define CAP_THREAD_SET_INFO 2 /* Details of this are arch-specific. */
|
|
|
|
#define CAP_THREAD_SCHEDULE 3
|
|
|
|
#define CAP_THREAD_GET_TOP_MEMORY 7
|
|
|
|
#define CAP_THREAD_REGISTER_INTERRUPT 8
|
|
|
|
#define CAP_THREAD_ALL_RIGHTS 0xff
|
|
|
|
#define CAP_THREAD_ALL_PRIV_RIGHTS (CAP_THREAD_ALL_RIGHTS | (1 << CAP_THREAD_REGISTER_INTERRUPT) | (1 << CAP_THREAD_GET_TOP_MEMORY))
|
|
|
|
|
|
|
|
/* These get/set_info are not arch-specific. */
|
2009-05-27 20:29:21 +03:00
|
|
|
#define CAP_THREAD_INFO_PC ~0
|
|
|
|
#define CAP_THREAD_INFO_SP ~1
|
|
|
|
#define CAP_THREAD_INFO_FLAGS ~2
|
2009-05-25 01:31:35 +03:00
|
|
|
/* Flag values for processor state */
|
|
|
|
#define THREAD_FLAG_WAITING 0x80000000
|
|
|
|
#define THREAD_FLAG_RUNNING 0x40000000
|
2009-05-27 15:38:52 +03:00
|
|
|
#define THREAD_FLAG_PRIV 0x20000000
|
|
|
|
#define THREAD_FLAG_USER 0x1fffffff
|
2009-05-22 23:48:49 +03:00
|
|
|
|
|
|
|
#define CAP_PAGE_MAP 1
|
|
|
|
#define CAP_PAGE_SHARE 2
|
|
|
|
#define CAP_PAGE_SHARE_COW 3
|
|
|
|
#define CAP_PAGE_FORGET 4
|
2009-05-25 01:31:35 +03:00
|
|
|
// Not an operation; a capability without this bit cannot write to the page. */
|
|
|
|
#define CAP_PAGE_WRITE 5
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_PAGE_ALL_RIGHTS 0x1ff
|
2009-05-22 23:48:49 +03:00
|
|
|
|
|
|
|
#define CAP_CAPABILITY_GET 1
|
|
|
|
#define CAP_CAPABILITY_SET_DEATH_NOTIFY 2
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_CAPABILITY_ALL_RIGHTS 0x1ff
|
2009-05-22 23:48:49 +03:00
|
|
|
|
2009-05-25 01:31:35 +03:00
|
|
|
#define CAPPAGE_SIZE 102
|
|
|
|
/* Cappage has page's operations as well. */
|
|
|
|
#define CAP_CAPPAGE_SET 6
|
2009-05-27 19:33:05 +03:00
|
|
|
#define CAP_CAPPAGE_ALL_RIGHTS 0x1ff
|
2009-05-25 01:31:35 +03:00
|
|
|
|
|
|
|
#ifndef __KERNEL
|
|
|
|
typedef unsigned __Capability;
|
|
|
|
|
|
|
|
extern __Capability __my_receiver;
|
2009-05-27 19:33:05 +03:00
|
|
|
extern __Capability __my_thread;
|
2009-05-25 01:31:35 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2009-05-27 19:33:05 +03:00
|
|
|
static int __invoke_04 (__Capability t, unsigned d0, unsigned d1, unsigned d2, unsigned d3)
|
|
|
|
{
|
|
|
|
__Message msg;
|
|
|
|
int ret;
|
|
|
|
msg.data[0] = d0;
|
|
|
|
msg.data[1] = d1;
|
|
|
|
msg.data[2] = d2;
|
|
|
|
msg.data[3] = d3;
|
|
|
|
return __invoke (t, &msg);
|
|
|
|
}
|
|
|
|
|
2009-05-25 01:31:35 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-05-27 19:33:05 +03:00
|
|
|
static unsigned __call_n02 (__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.data[0] : 0;
|
|
|
|
}
|
|
|
|
|
2009-05-25 01:31:35 +03:00
|
|
|
static __Capability __degrade (__Capability src, unsigned mask)
|
|
|
|
{
|
|
|
|
return __call_c02 (src, CAP_DEGRADE, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __schedule ()
|
|
|
|
{
|
2009-05-27 19:33:05 +03:00
|
|
|
__invoke_01 (__my_thread, CAP_THREAD_SCHEDULE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __register_interrupt (unsigned num)
|
|
|
|
{
|
|
|
|
__invoke_12 (__my_thread, __my_receiver, CAP_THREAD_REGISTER_INTERRUPT, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __Capability __get_top_memory ()
|
|
|
|
{
|
|
|
|
return __call_c01 (__my_thread, CAP_THREAD_GET_TOP_MEMORY);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __unregister_interrupt (unsigned num)
|
|
|
|
{
|
|
|
|
__invoke_02 (__my_thread, CAP_THREAD_REGISTER_INTERRUPT, num);
|
2009-05-25 01:31:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2009-05-27 19:33:05 +03:00
|
|
|
static int __thread_set_info (__Capability thread, unsigned info, unsigned value, unsigned mask)
|
|
|
|
{
|
|
|
|
return __invoke_04 (thread, CAP_THREAD_SET_INFO, info, value, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __thread_set_pc (__Capability thread, unsigned pc)
|
|
|
|
{
|
|
|
|
return __thread_set_info (thread, CAP_THREAD_INFO_PC, pc, ~0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __thread_set_sp (__Capability thread, unsigned sp)
|
|
|
|
{
|
|
|
|
return __thread_set_info (thread, CAP_THREAD_INFO_SP, sp, ~0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __thread_set_flags (__Capability thread, unsigned value, unsigned mask)
|
|
|
|
{
|
|
|
|
return __thread_set_info (thread, CAP_THREAD_INFO_FLAGS, value, mask);
|
|
|
|
}
|
|
|
|
|
2009-05-25 01:31:35 +03:00
|
|
|
static int __thread_run (__Capability thread, int run)
|
|
|
|
{
|
2009-05-27 19:33:05 +03:00
|
|
|
return __thread_set_flags (thread, run ? THREAD_FLAG_RUNNING : 0, THREAD_FLAG_RUNNING);
|
2009-05-25 01:31:35 +03:00
|
|
|
}
|
|
|
|
|
2009-05-27 19:33:05 +03:00
|
|
|
static int __thread_wait (__Capability thread, int wait)
|
|
|
|
{
|
|
|
|
return __thread_set_flags (thread, wait ? THREAD_FLAG_WAITING : 0, THREAD_FLAG_WAITING);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned __thread_get_info (__Capability thread, unsigned info)
|
|
|
|
{
|
|
|
|
return __call_n02 (thread, CAP_THREAD_GET_INFO, info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned __thread_get_pc (__Capability thread)
|
|
|
|
{
|
|
|
|
return __thread_get_info (thread, CAP_THREAD_INFO_PC);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned __thread_get_sp (__Capability thread)
|
|
|
|
{
|
|
|
|
return __thread_get_info (thread, CAP_THREAD_INFO_SP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned __thread_get_flags (__Capability thread)
|
|
|
|
{
|
|
|
|
return __thread_get_info (thread, CAP_THREAD_INFO_FLAGS);
|
|
|
|
}
|
2009-05-25 01:31:35 +03:00
|
|
|
|
2009-05-27 19:33:05 +03:00
|
|
|
/* TODO. All except map should also work for cappages.
|
2009-05-25 01:31:35 +03:00
|
|
|
#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
|
2009-05-22 23:48:49 +03:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|