From ac3935a5d908e6fe6c2b7f89e5dac6596f401989 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Tue, 18 Mar 2008 21:50:47 +0000 Subject: [PATCH] Initial efforts to transform utcb handling. --- tasks/libl4/include/l4lib/arch-arm/utcb.h | 19 ++++---- tasks/libl4/include/l4lib/ipcdefs.h | 6 +-- tasks/libl4/src/init.c | 54 ++++++++++++++++++++--- tasks/libposix/read.c | 6 +-- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/tasks/libl4/include/l4lib/arch-arm/utcb.h b/tasks/libl4/include/l4lib/arch-arm/utcb.h index f9e949a..75ecdf6 100644 --- a/tasks/libl4/include/l4lib/arch-arm/utcb.h +++ b/tasks/libl4/include/l4lib/arch-arm/utcb.h @@ -15,23 +15,20 @@ * needed for all ipcs. Those mrs are defined the kernel message.h */ -/* Compact utcb for now! :-) */ +/* + * This is a per-task private structure where message registers are + * pushed for ipc. Its *not* TLS, but can be part of TLS when it is + * supported. + */ struct utcb { u32 mr[MR_TOTAL]; u32 tid; /* Thread id */ - - /* - * For passing ipc data larger than mrs, - * that is, if the callee is allowed to map it - */ - char buf[]; -}; -extern struct utcb *utcb; +}; __attribute__((__packed__)); +extern struct utcb utcb; static inline struct utcb *l4_get_utcb() { - return utcb; - // (struct utcb **)USER_UTCB_REF; + return &utcb; } /* Functions to read/write utcb registers */ diff --git a/tasks/libl4/include/l4lib/ipcdefs.h b/tasks/libl4/include/l4lib/ipcdefs.h index 4997bb0..c8e94b9 100644 --- a/tasks/libl4/include/l4lib/ipcdefs.h +++ b/tasks/libl4/include/l4lib/ipcdefs.h @@ -19,10 +19,10 @@ /* For ping ponging */ #define L4_IPC_TAG_WAIT 3 -/* To negotiate a shared memory mapping */ -#define L4_IPC_TAG_SHM 4 +/* To obtain utcb address */ +#define L4_IPC_TAG_UTCB 4 -/* To negotiate a grant mapping */ +/* XXX: unused */ #define L4_IPC_TAG_GRANT 5 /* Posix system call tags */ diff --git a/tasks/libl4/src/init.c b/tasks/libl4/src/init.c index 8c20967..1479b75 100644 --- a/tasks/libl4/src/init.c +++ b/tasks/libl4/src/init.c @@ -5,8 +5,11 @@ */ #include #include +#include +#include #include #include INC_GLUE(memlayout.h) +#include __l4_ipc_t __l4_ipc = 0; __l4_map_t __l4_map = 0; @@ -23,9 +26,47 @@ __l4_kmem_reclaim_t __l4_kmem_reclaim = 0; struct kip *kip; -/* UTCB address of this task. */ -struct utcb *utcb; -#include +/* + * Private UTCB of this task. Used only for pushing/reading ipc + * message registers. + */ +struct utcb utcb; + +/* + * Shared utcb page for this task. Used for passing data among ipc + * parties when message registers are not big enough. Every thread + * has right to own one, and it has an address unique to every + * thread. It must be explicitly mapped by both parties of the ipc + * in order to be useful. + */ +void *utcb_page; + + +/* + * Obtains a unique address for the task's shared utcb page. Note this + * does *not* map the utcb, just returns the address. This address + * is used as an shm key to map it via shmget()/shmat() later on. + */ +static void *l4_utcb_page(void) +{ + void *addr; + int err; + + /* Call pager with utcb address request. Check ipc error. */ + if ((err = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_UTCB)) < 0) { + printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); + return PTR_ERR(err); + } + + /* Check if syscall itself was successful */ + if (IS_ERR(addr = (void *)l4_get_retval())) { + printf("%s: Request UTCB Address Error: %d.\n", + __FUNCTION__, (int)addr); + return addr; + } + + return addr; +} void __l4_init(void) { @@ -47,10 +88,9 @@ void __l4_init(void) /* Initialise utcb only if we're not the pager */ if (self_tid() != PAGER_TID) { - /* FIXME: C library should give the environ pointer for this */ - utcb = *(struct utcb **)(USER_AREA_END - PAGE_SIZE); - printf("UTCB Read from userspace as: 0x%x\n", - (unsigned long)utcb); + utcb_page = l4_utcb_page(); + printf("UTCB Read from mm0 as: 0x%x\n", + (unsigned long)utcb_page); } } diff --git a/tasks/libposix/read.c b/tasks/libposix/read.c index 2533585..5abcef2 100644 --- a/tasks/libposix/read.c +++ b/tasks/libposix/read.c @@ -20,7 +20,7 @@ static inline int l4_readdir(int fd, void *buf, size_t count) write_mr(L4SYS_ARG1, (unsigned long)buf); write_mr(L4SYS_ARG2, count); - /* Call pager with shmget() request. Check ipc error. */ + /* Call pager with readdir() request. Check ipc error. */ if ((cnt = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_READDIR)) < 0) { printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, cnt); return cnt; @@ -42,8 +42,8 @@ static inline int l4_read(int fd, void *buf, size_t count) write_mr(L4SYS_ARG1, (unsigned long)buf); write_mr(L4SYS_ARG2, count); - /* Call pager with shmget() request. Check ipc error. */ - if ((cnt = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_READ)) < 0) { + /* Call pager with read() request. Check ipc error. */ + if ((cnt = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_READ)) < 0) { printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, cnt); return cnt; }