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
2009-05-29 00:35:27 +03:00
# define CAP_PAGE_COPY 2
# define CAP_PAGE_MOVE 3
# define CAP_PAGE_GET_FLAGS 4
# define CAP_PAGE_SET_FLAGS 5
/* Not an operation; a capability without this bit cannot write to the page. */
# define CAP_PAGE_WRITE 6
2009-05-27 19:33:05 +03:00
# define CAP_PAGE_ALL_RIGHTS 0x1ff
2009-05-29 00:35:27 +03:00
/* Flag values for Page and Cappage objects. */
/* A writable page can be written to. This flag can not be set while the frame is shared. */
# define PAGE_FLAG_WRITABLE 1
/* When paying, the memory's use is incremented if the page holds a frame. It cannot be lost. Frames are lost when the last payer forgets them. */
# define PAGE_FLAG_PAYING 2
/* Frames can be moved to this Page if they are not shared; copying will always fail. Sharing a page while this flag is set will fail; moving it will move the flag with it. A page is guaranteed to be unshared when this flag is set. Trying to set this flag on a shared page has no effect. */
# define PAGE_FLAG_NOSHARE 4
/* This is a read-only flag, which is set if the Page is shared. */
# define PAGE_FLAG_SHARED 8
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. */
2009-05-29 00:35:27 +03:00
# define CAP_CAPPAGE_SET 7
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