mirror of
https://github.com/drasko/codezero.git
synced 2026-04-18 01:39:05 +02:00
Removed special-case utcb shared page from posix services.
Previously a so-called utcb shared page was used for transfering data between posix services. This was a special shmat/get/dt case allocating from its own virtual pool. Now the term utcb is renamed as a shared page and integrated with the shm* handling routines. Generic l4 threads will use long-ipc and not this method. Posix services will continue to communicate on a shared page for now. modified: tasks/libl4/include/l4lib/ipcdefs.h modified: tasks/libl4/src/init.c new file: tasks/libposix/init.c modified: tasks/mm0/include/shm.h modified: tasks/mm0/include/task.h deleted: tasks/mm0/include/utcb.h modified: tasks/mm0/main.c modified: tasks/mm0/src/boot.c modified: tasks/mm0/src/clone.c modified: tasks/mm0/src/execve.c modified: tasks/mm0/src/exit.c modified: tasks/mm0/src/init.c modified: tasks/mm0/src/shm.c modified: tasks/mm0/src/task.c deleted: tasks/mm0/src/utcb.c deleted: tools/l4-qemu
This commit is contained in:
@@ -19,8 +19,8 @@
|
|||||||
/* For ping ponging */
|
/* For ping ponging */
|
||||||
#define L4_IPC_TAG_SYNC 3
|
#define L4_IPC_TAG_SYNC 3
|
||||||
|
|
||||||
/* To obtain utcb address */
|
/* To obtain default shared page address */
|
||||||
#define L4_IPC_TAG_UTCB 4
|
#define L4_IPC_TAG_SHPAGE 4
|
||||||
|
|
||||||
/* XXX: unused */
|
/* XXX: unused */
|
||||||
#define L4_IPC_TAG_GRANT 5
|
#define L4_IPC_TAG_GRANT 5
|
||||||
|
|||||||
@@ -34,77 +34,6 @@ struct kip *kip;
|
|||||||
*/
|
*/
|
||||||
struct utcb utcb;
|
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;
|
|
||||||
|
|
||||||
/* We're asking it for ourself. */
|
|
||||||
write_mr(L4SYS_ARG0, self_tid());
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialises a non-pager task's shared memory utcb page
|
|
||||||
* using posix semantics. Used during task initialisation
|
|
||||||
* and by child tasks after a fork.
|
|
||||||
*/
|
|
||||||
int utcb_init(void)
|
|
||||||
{
|
|
||||||
int shmid;
|
|
||||||
void *shmaddr;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise utcb only if we're not the pager.
|
|
||||||
* The pager does it differently for itself.
|
|
||||||
*/
|
|
||||||
if (self_tid() != PAGER_TID) {
|
|
||||||
|
|
||||||
/* Obtain our utcb page address */
|
|
||||||
utcb_page = l4_utcb_page();
|
|
||||||
//printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__,
|
|
||||||
// (unsigned long)utcb_page);
|
|
||||||
|
|
||||||
/* Use it as a key to create a shared memory region */
|
|
||||||
BUG_ON((shmid = shmget((key_t)utcb_page,
|
|
||||||
PAGE_SIZE, IPC_CREAT)) < 0);
|
|
||||||
|
|
||||||
/* Attach to the region */
|
|
||||||
BUG_ON((shmaddr = shmat(shmid, utcb_page, 0)) < 0);
|
|
||||||
BUG_ON(shmaddr != utcb_page);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __l4_init(void)
|
void __l4_init(void)
|
||||||
{
|
{
|
||||||
@@ -123,7 +52,5 @@ void __l4_init(void)
|
|||||||
(__l4_exchange_registers_t)kip->exchange_registers;
|
(__l4_exchange_registers_t)kip->exchange_registers;
|
||||||
__l4_kmem_control = (__l4_kmem_control_t)kip->kmem_control;
|
__l4_kmem_control = (__l4_kmem_control_t)kip->kmem_control;
|
||||||
__l4_time = (__l4_time_t)kip->time;
|
__l4_time = (__l4_time_t)kip->time;
|
||||||
|
|
||||||
utcb_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
79
tasks/libposix/init.c
Normal file
79
tasks/libposix/init.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Shared page initialisation of posix-like tasks.
|
||||||
|
*
|
||||||
|
* POSIX tasks currently use a default shared page for communciation.
|
||||||
|
* This could have been also done by long ipc calls.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shared 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 *shared_page;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtains a unique address for the task's shared page. Note this
|
||||||
|
* just returns the address. This address is used as an shm key
|
||||||
|
* to map it via shmget()/shmat() later on.
|
||||||
|
*/
|
||||||
|
static void *shared_page_address(void)
|
||||||
|
{
|
||||||
|
void *addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* We're asking it for ourself. */
|
||||||
|
write_mr(L4SYS_ARG0, self_tid());
|
||||||
|
|
||||||
|
/* Call pager with utcb address request. Check ipc error. */
|
||||||
|
if ((err = l4_sendrecv(PAGER_TID, PAGER_TID,
|
||||||
|
L4_IPC_TAG_DEFAULT_SHPAGE)) < 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialises a non-pager task's default shared memory page
|
||||||
|
* using posix semantics. Used during task initialisation
|
||||||
|
* and by child tasks after a fork.
|
||||||
|
*/
|
||||||
|
int shared_page_init(void)
|
||||||
|
{
|
||||||
|
int shmid;
|
||||||
|
void *shmaddr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise shared page only if we're not the pager.
|
||||||
|
* The pager does it differently for itself.
|
||||||
|
*/
|
||||||
|
BUG_ON(self_tid() == PAGER_TID);
|
||||||
|
|
||||||
|
/* Obtain our utcb page address */
|
||||||
|
utcb_page = l4_utcb_page();
|
||||||
|
//printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__,
|
||||||
|
// (unsigned long)utcb_page);
|
||||||
|
|
||||||
|
/* Use it as a key to create a shared memory region */
|
||||||
|
BUG_ON((shmid = shmget((key_t)utcb_page,
|
||||||
|
PAGE_SIZE, IPC_CREAT)) < 0);
|
||||||
|
|
||||||
|
/* Attach to the region */
|
||||||
|
BUG_ON((shmaddr = shmat(shmid, utcb_page, 0)) < 0);
|
||||||
|
BUG_ON(shmaddr != utcb_page);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -47,4 +47,25 @@ void *shmat_shmget_internal(struct tcb *task, key_t key, void *shmaddr);
|
|||||||
struct vm_file *shm_new(key_t key, unsigned long npages);
|
struct vm_file *shm_new(key_t key, unsigned long npages);
|
||||||
void *shm_new_address(int npages);
|
void *shm_new_address(int npages);
|
||||||
|
|
||||||
|
|
||||||
|
/* Below is the special-case per-task default shared memory page prototypes */
|
||||||
|
|
||||||
|
/* Prefaults shared page after mapping */
|
||||||
|
#define SHPAGE_PREFAULT (1 << 0)
|
||||||
|
|
||||||
|
/* Creates new shm segment for default shpage */
|
||||||
|
#define SHPAGE_NEW_SHM (1 << 1)
|
||||||
|
|
||||||
|
/* Allocates a virtual address for default shpage */
|
||||||
|
#define SHPAGE_NEW_ADDRESS (1 << 2)
|
||||||
|
|
||||||
|
/* IPC to send utcb address information to tasks */
|
||||||
|
void *task_send_shpage_address(struct tcb *sender, l4id_t taskid);
|
||||||
|
|
||||||
|
int shpage_map_to_task(struct tcb *owner, struct tcb *mapper, unsigned int flags);
|
||||||
|
int shpage_unmap_from_task(struct tcb *owner, struct tcb *mapper);
|
||||||
|
|
||||||
|
/* Prefault a *mmaped* default shared page */
|
||||||
|
int shpage_prefault(struct tcb *task, unsigned int vmflags);
|
||||||
|
|
||||||
#endif /* __SHM_H__ */
|
#endif /* __SHM_H__ */
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
/* POSIX minimum is 4Kb */
|
/* POSIX minimum is 4Kb */
|
||||||
#define DEFAULT_ENV_SIZE SZ_4K
|
#define DEFAULT_ENV_SIZE SZ_4K
|
||||||
#define DEFAULT_STACK_SIZE SZ_32K
|
#define DEFAULT_STACK_SIZE SZ_32K
|
||||||
#define DEFAULT_UTCB_SIZE PAGE_SIZE
|
#define DEFAULT_SHPAGE_SIZE PAGE_SIZE
|
||||||
|
|
||||||
#define TCB_NO_SHARING 0
|
#define TCB_NO_SHARING 0
|
||||||
#define TCB_SHARED_VM (1 << 0)
|
#define TCB_SHARED_VM (1 << 0)
|
||||||
@@ -101,8 +101,8 @@ struct tcb {
|
|||||||
unsigned long map_start;
|
unsigned long map_start;
|
||||||
unsigned long map_end;
|
unsigned long map_end;
|
||||||
|
|
||||||
/* UTCB information */
|
/* Default ipc-shared-page information */
|
||||||
void *utcb;
|
void *shared_page;
|
||||||
|
|
||||||
/* Virtual memory areas */
|
/* Virtual memory areas */
|
||||||
struct task_vma_head *vm_area_head;
|
struct task_vma_head *vm_area_head;
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
#ifndef __MM0_UTCB_H__
|
|
||||||
#define __MM0_UTCB_H__
|
|
||||||
|
|
||||||
#include <l4lib/types.h>
|
|
||||||
#include <task.h>
|
|
||||||
|
|
||||||
#define UTCB_PREFAULT (1 << 0) /* Prefaults utcb pages after mapping */
|
|
||||||
#define UTCB_NEW_SHM (1 << 1) /* Creates a new shm segment for utcb */
|
|
||||||
#define UTCB_NEW_ADDRESS (1 << 2) /* Allocates a virtual address for utcb */
|
|
||||||
|
|
||||||
int utcb_pool_init(void);
|
|
||||||
void *utcb_new_address(void);
|
|
||||||
int utcb_delete_address(void *utcb_addr);
|
|
||||||
|
|
||||||
/* IPC to send utcb address information to tasks */
|
|
||||||
void *task_send_utcb_address(struct tcb *sender, l4id_t taskid);
|
|
||||||
|
|
||||||
int utcb_map_to_task(struct tcb *owner, struct tcb *mapper, unsigned int flags);
|
|
||||||
int utcb_unmap_from_task(struct tcb *owner, struct tcb *mapper);
|
|
||||||
|
|
||||||
/* Prefault an *mmaped* utcb */
|
|
||||||
int utcb_prefault(struct tcb *task, unsigned int vmflags);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <file.h>
|
#include <file.h>
|
||||||
#include <shm.h>
|
#include <shm.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <mmap.h>
|
#include <mmap.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <boot.h>
|
#include <boot.h>
|
||||||
@@ -85,8 +84,8 @@ void handle_requests(void)
|
|||||||
ret = sys_shmdt(sender, (void *)mr[0]);
|
ret = sys_shmdt(sender, (void *)mr[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L4_IPC_TAG_UTCB:
|
case L4_IPC_TAG_SHPAGE:
|
||||||
ret = (int)task_send_utcb_address(sender, (l4id_t)mr[0]);
|
ret = (int)task_send_shpage_address(sender, (l4id_t)mr[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L4_IPC_TAG_READ:
|
case L4_IPC_TAG_READ:
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
#include <boot.h>
|
#include <boot.h>
|
||||||
#include <mmap.h>
|
#include <mmap.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <shm.h>
|
#include <shm.h>
|
||||||
#include <l4/api/thread.h>
|
#include <l4/api/thread.h>
|
||||||
#include <l4lib/arch/syslib.h>
|
#include <l4lib/arch/syslib.h>
|
||||||
@@ -74,11 +73,12 @@ int boottask_mmap_regions(struct tcb *task, struct vm_file *file)
|
|||||||
return (int)mapped;
|
return (int)mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Task's utcb */
|
/* Task's default shared page */
|
||||||
task->utcb = utcb_new_address();
|
task->shared_page = shm_new_address(DEFAULT_SHPAGE_SIZE/PAGE_SIZE);
|
||||||
|
|
||||||
/* Create a shared memory segment available for shmat() */
|
/* Create a shared memory segment available for shmat() */
|
||||||
if (IS_ERR(shm = shm_new((key_t)task->utcb, __pfn(DEFAULT_UTCB_SIZE))))
|
if (IS_ERR(shm = shm_new((key_t)task->shared_page,
|
||||||
|
__pfn(DEFAULT_SHPAGE_SIZE))))
|
||||||
return (int)shm;
|
return (int)shm;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <vm_area.h>
|
#include <vm_area.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
#include <mmap.h>
|
#include <mmap.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <shm.h>
|
#include <shm.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <clone.h>
|
#include <clone.h>
|
||||||
@@ -31,7 +30,7 @@ int vfs_notify_fork(struct tcb *child, struct tcb *parent, unsigned int flags)
|
|||||||
/* Write parent and child information */
|
/* Write parent and child information */
|
||||||
write_mr(L4SYS_ARG0, parent->tid);
|
write_mr(L4SYS_ARG0, parent->tid);
|
||||||
write_mr(L4SYS_ARG1, child->tid);
|
write_mr(L4SYS_ARG1, child->tid);
|
||||||
write_mr(L4SYS_ARG2, (unsigned int)child->utcb);
|
write_mr(L4SYS_ARG2, (unsigned int)child->shared_page);
|
||||||
write_mr(L4SYS_ARG3, flags);
|
write_mr(L4SYS_ARG3, flags);
|
||||||
|
|
||||||
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
|
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
|
||||||
@@ -85,8 +84,10 @@ int sys_fork(struct tcb *parent)
|
|||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* Create and prefault a utcb for child and map it to vfs task */
|
/* Create and prefault a utcb for child and map it to vfs task */
|
||||||
utcb_map_to_task(child, find_task(VFS_TID),
|
shpage_map_to_task(child, find_task(VFS_TID),
|
||||||
UTCB_NEW_ADDRESS | UTCB_NEW_SHM | UTCB_PREFAULT);
|
SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM |
|
||||||
|
SHPAGE_PREFAULT);
|
||||||
|
|
||||||
// printf("Mapped 0x%p to vfs as utcb of %d\n", child->utcb, child->tid);
|
// printf("Mapped 0x%p to vfs as utcb of %d\n", child->utcb, child->tid);
|
||||||
|
|
||||||
/* We can now notify vfs about forked process */
|
/* We can now notify vfs about forked process */
|
||||||
@@ -138,8 +139,9 @@ int do_clone(struct tcb *parent, unsigned long child_stack, unsigned int flags)
|
|||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* Create and prefault a utcb for child and map it to vfs task */
|
/* Create and prefault a utcb for child and map it to vfs task */
|
||||||
utcb_map_to_task(child, find_task(VFS_TID),
|
shpage_map_to_task(child, find_task(VFS_TID),
|
||||||
UTCB_NEW_ADDRESS | UTCB_NEW_SHM | UTCB_PREFAULT);
|
SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM |
|
||||||
|
SHPAGE_PREFAULT);
|
||||||
|
|
||||||
/* We can now notify vfs about forked process */
|
/* We can now notify vfs about forked process */
|
||||||
vfs_notify_fork(child, parent, flags);
|
vfs_notify_fork(child, parent, flags);
|
||||||
|
|||||||
@@ -37,16 +37,16 @@ int vfs_open_bypath(const char *pathname, unsigned long *vnum, unsigned long *le
|
|||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy string to vfs utcb.
|
* Copy string to vfs shared page.
|
||||||
*
|
*
|
||||||
* FIXME: There's a chance we're overwriting other tasks'
|
* FIXME: There's a chance we're overwriting other tasks'
|
||||||
* ipc information that is on the vfs utcb.
|
* ipc information that is on the vfs shared page.
|
||||||
*/
|
*/
|
||||||
strcpy(vfs->utcb, pathname);
|
strcpy(vfs->shared_page, pathname);
|
||||||
|
|
||||||
l4_save_ipcregs();
|
l4_save_ipcregs();
|
||||||
|
|
||||||
write_mr(L4SYS_ARG0, (unsigned long)vfs->utcb);
|
write_mr(L4SYS_ARG0, (unsigned long)vfs->shared_page);
|
||||||
|
|
||||||
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
|
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
|
||||||
L4_IPC_TAG_PAGER_OPEN_BYPATH)) < 0) {
|
L4_IPC_TAG_PAGER_OPEN_BYPATH)) < 0) {
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2008 Bahadir Balban
|
* Copyright (C) 2008 Bahadir Balban
|
||||||
*/
|
*/
|
||||||
|
#include <shm.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
#include <file.h>
|
#include <file.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <exit.h>
|
#include <exit.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <vm_area.h>
|
#include <vm_area.h>
|
||||||
@@ -90,7 +90,7 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig)
|
|||||||
new->pagerid = orig->pagerid;
|
new->pagerid = orig->pagerid;
|
||||||
|
|
||||||
/* Copy utcb */
|
/* Copy utcb */
|
||||||
new->utcb = orig->utcb;
|
new->shared_page = orig->shared_page;
|
||||||
|
|
||||||
/* Copy parent relationship */
|
/* Copy parent relationship */
|
||||||
BUG_ON(new->parent);
|
BUG_ON(new->parent);
|
||||||
@@ -131,9 +131,9 @@ void do_exit(struct tcb *task, int status)
|
|||||||
/* Tell vfs that task is exiting */
|
/* Tell vfs that task is exiting */
|
||||||
vfs_notify_exit(task, status);
|
vfs_notify_exit(task, status);
|
||||||
|
|
||||||
/* Remove utcb shm areas from vfs */
|
/* Remove default shared page shm areas from vfs */
|
||||||
// printf("Unmapping 0x%p from vfs as utcb of %d\n", task->utcb, task->tid);
|
// printf("Unmapping 0x%p from vfs as shared-page of %d\n", task->shared_page, task->tid);
|
||||||
utcb_unmap_from_task(task, find_task(VFS_TID));
|
shpage_unmap_from_task(task, find_task(VFS_TID));
|
||||||
|
|
||||||
/* Free task's local tcb */
|
/* Free task's local tcb */
|
||||||
tcb_destroy(task);
|
tcb_destroy(task);
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <shm.h>
|
#include <shm.h>
|
||||||
#include <file.h>
|
#include <file.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
#include <boot.h>
|
#include <boot.h>
|
||||||
|
|
||||||
@@ -168,12 +167,8 @@ void init_mm(struct initdata *initdata)
|
|||||||
printf("SHM initialisation failed.\n");
|
printf("SHM initialisation failed.\n");
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
// printf("%s: Initialised shm structures.\n", __TASKNAME__);
|
printf("%s: Initialised shm structures.\n", __TASKNAME__);
|
||||||
|
|
||||||
if (utcb_pool_init() < 0) {
|
|
||||||
printf("UTCB initialisation failed.\n");
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For supplying contiguous virtual addresses to pager */
|
/* For supplying contiguous virtual addresses to pager */
|
||||||
pager_address_pool_init();
|
pager_address_pool_init();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
#include <mmap.h>
|
#include <mmap.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <vm_area.h>
|
#include <vm_area.h>
|
||||||
#include <globals.h>
|
#include <globals.h>
|
||||||
#include <lib/malloc.h>
|
#include <lib/malloc.h>
|
||||||
@@ -181,15 +180,8 @@ void shm_destroy_priv_data(struct vm_file *shm_file)
|
|||||||
struct shm_descriptor *shm_desc = shm_file_to_desc(shm_file);
|
struct shm_descriptor *shm_desc = shm_file_to_desc(shm_file);
|
||||||
|
|
||||||
/* Release the shared memory address */
|
/* Release the shared memory address */
|
||||||
if ((unsigned long)shm_desc->shm_addr >= UTCB_AREA_START &&
|
BUG_ON(shm_delete_address(shm_desc->shm_addr,
|
||||||
(unsigned long)shm_desc->shm_addr < UTCB_AREA_END) {
|
shm_file->vm_obj.npages) < 0);
|
||||||
BUG_ON(utcb_delete_address(shm_desc->shm_addr) < 0);
|
|
||||||
} else if ((unsigned long)shm_desc->shm_addr >= SHM_AREA_START &&
|
|
||||||
(unsigned long)shm_desc->shm_addr < SHM_AREA_END) {
|
|
||||||
BUG_ON(shm_delete_address(shm_desc->shm_addr,
|
|
||||||
shm_file->vm_obj.npages) < 0);
|
|
||||||
} else
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
/* Release the shared memory id */
|
/* Release the shared memory id */
|
||||||
BUG_ON(id_del(shm_ids, shm_desc->shmid) < 0);
|
BUG_ON(id_del(shm_ids, shm_desc->shmid) < 0);
|
||||||
@@ -320,3 +312,76 @@ int sys_shmget(key_t key, int size, int shmflg)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently, a default shm page is allocated to every thread in the system
|
||||||
|
* for efficient ipc communication. This part below provides the allocation
|
||||||
|
* and mapping of this page using shmat/get/dt call semantics.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends shpage address information to requester. The requester then uses
|
||||||
|
* this address as a shm key and maps it via shmget/shmat.
|
||||||
|
*/
|
||||||
|
void *task_send_shpage_address(struct tcb *sender, l4id_t taskid)
|
||||||
|
{
|
||||||
|
struct tcb *task = find_task(taskid);
|
||||||
|
|
||||||
|
/* Is the task asking for its own utcb address */
|
||||||
|
if (sender->tid == taskid) {
|
||||||
|
/* It hasn't got one allocated. */
|
||||||
|
BUG_ON(!task->shared_page);
|
||||||
|
|
||||||
|
/* Return it to requester */
|
||||||
|
return task->shared_page;
|
||||||
|
|
||||||
|
/* A task is asking for someone else's utcb */
|
||||||
|
} else {
|
||||||
|
/* Only vfs is allowed to do so yet, because its a server */
|
||||||
|
if (sender->tid == VFS_TID) {
|
||||||
|
/*
|
||||||
|
* Return shpage address to requester. Note if there's
|
||||||
|
* none allocated so far, requester gets 0. We don't
|
||||||
|
* allocate one here.
|
||||||
|
*/
|
||||||
|
return task->shared_page;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int shpage_map_to_task(struct tcb *owner, struct tcb *mapper, unsigned int flags)
|
||||||
|
{
|
||||||
|
struct vm_file *default_shm;
|
||||||
|
|
||||||
|
/* Allocate a new utcb address */
|
||||||
|
if (flags & SHPAGE_NEW_ADDRESS)
|
||||||
|
owner->shared_page =
|
||||||
|
shm_new_address(DEFAULT_SHPAGE_SIZE/PAGE_SIZE);
|
||||||
|
else if (!owner->shared_page)
|
||||||
|
BUG();
|
||||||
|
|
||||||
|
/* Create a new shared memory segment for utcb */
|
||||||
|
if (flags & SHPAGE_NEW_SHM)
|
||||||
|
if (IS_ERR(default_shm = shm_new((key_t)owner->shared_page,
|
||||||
|
__pfn(DEFAULT_SHPAGE_SIZE))))
|
||||||
|
return (int)default_shm;
|
||||||
|
|
||||||
|
/* Map the utcb to mapper */
|
||||||
|
if (IS_ERR(shmat_shmget_internal(mapper, (key_t)owner->shared_page,
|
||||||
|
owner->shared_page)))
|
||||||
|
BUG();
|
||||||
|
|
||||||
|
/* Prefault the owner's utcb to mapper's address space */
|
||||||
|
if (flags & SHPAGE_PREFAULT)
|
||||||
|
for (int i = 0; i < __pfn(DEFAULT_SHPAGE_SIZE); i++)
|
||||||
|
prefault_page(mapper, (unsigned long)owner->shared_page +
|
||||||
|
__pfn_to_addr(i), VM_READ | VM_WRITE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int shpage_unmap_from_task(struct tcb *owner, struct tcb *mapper)
|
||||||
|
{
|
||||||
|
return sys_shmdt(mapper, owner->shared_page);
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <vm_area.h>
|
#include <vm_area.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <file.h>
|
#include <file.h>
|
||||||
#include <utcb.h>
|
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
#include <exec.h>
|
#include <exec.h>
|
||||||
#include <shm.h>
|
#include <shm.h>
|
||||||
@@ -611,13 +610,13 @@ int vfs_send_task_data(struct tcb *vfs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(!(self = find_task(self_tid())));
|
BUG_ON(!(self = find_task(self_tid())));
|
||||||
BUG_ON(!vfs->utcb);
|
BUG_ON(!vfs->shared_page);
|
||||||
|
|
||||||
/* Attach mm0 to vfs's utcb segment just like a normal task */
|
/* Attach mm0 to vfs's utcb segment just like a normal task */
|
||||||
utcb_map_to_task(vfs, self, UTCB_PREFAULT);
|
shpage_map_to_task(vfs, self, SHPAGE_PREFAULT);
|
||||||
|
|
||||||
/* Write all requested task information to utcb's user buffer area */
|
/* Write all requested task information to shared pages's user buffer area */
|
||||||
tdata_head = (struct task_data_head *)vfs->utcb;
|
tdata_head = (struct task_data_head *)vfs->shared_page;
|
||||||
|
|
||||||
/* First word is total number of tcbs */
|
/* First word is total number of tcbs */
|
||||||
tdata_head->total = global_tasks.total;
|
tdata_head->total = global_tasks.total;
|
||||||
@@ -625,7 +624,7 @@ int vfs_send_task_data(struct tcb *vfs)
|
|||||||
/* Write per-task data for all tasks */
|
/* Write per-task data for all tasks */
|
||||||
list_for_each_entry(t, &global_tasks.list, list) {
|
list_for_each_entry(t, &global_tasks.list, list) {
|
||||||
tdata_head->tdata[li].tid = t->tid;
|
tdata_head->tdata[li].tid = t->tid;
|
||||||
tdata_head->tdata[li].utcb_address = (unsigned long)t->utcb;
|
tdata_head->tdata[li].utcb_address = (unsigned long)t->shared_page;
|
||||||
li++;
|
li++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* utcb address allocation for user tasks.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Bahadir Balban
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <utcb.h>
|
|
||||||
#include <lib/addr.h>
|
|
||||||
#include <l4/macros.h>
|
|
||||||
#include <l4lib/arch/syscalls.h>
|
|
||||||
#include <l4lib/arch/syslib.h>
|
|
||||||
#include <task.h>
|
|
||||||
#include <shm.h>
|
|
||||||
#include <vm_area.h>
|
|
||||||
#include <syscalls.h>
|
|
||||||
#include INC_GLUE(memlayout.h)
|
|
||||||
|
|
||||||
static struct address_pool utcb_vaddr_pool;
|
|
||||||
|
|
||||||
int utcb_pool_init()
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
if ((err = address_pool_init(&utcb_vaddr_pool,
|
|
||||||
UTCB_AREA_START,
|
|
||||||
UTCB_AREA_END)) < 0) {
|
|
||||||
printf("UTCB address pool initialisation failed: %d\n", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *utcb_new_address(void)
|
|
||||||
{
|
|
||||||
return address_new(&utcb_vaddr_pool, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int utcb_delete_address(void *utcb_addr)
|
|
||||||
{
|
|
||||||
return address_del(&utcb_vaddr_pool, utcb_addr, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sends utcb address information to requester task, allocates
|
|
||||||
* an address if it doesn't exist and the requester is asking
|
|
||||||
* for its own. The requester then uses this address as a shm key and
|
|
||||||
* maps its own utcb via shmget/shmat.
|
|
||||||
*/
|
|
||||||
void *task_send_utcb_address(struct tcb *sender, l4id_t taskid)
|
|
||||||
{
|
|
||||||
struct tcb *task = find_task(taskid);
|
|
||||||
|
|
||||||
/* Is the task asking for its own utcb address */
|
|
||||||
if (sender->tid == taskid) {
|
|
||||||
/* It hasn't got one allocated. */
|
|
||||||
BUG_ON(!task->utcb);
|
|
||||||
|
|
||||||
/* Return it to requester */
|
|
||||||
return task->utcb;
|
|
||||||
|
|
||||||
/* A task is asking for someone else's utcb */
|
|
||||||
} else {
|
|
||||||
/* Only vfs is allowed to do so yet, because its a server */
|
|
||||||
if (sender->tid == VFS_TID) {
|
|
||||||
/*
|
|
||||||
* Return utcb address to requester. Note if there's
|
|
||||||
* none allocated so far, requester gets 0. We don't
|
|
||||||
* allocate one here.
|
|
||||||
*/
|
|
||||||
return task->utcb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int utcb_map_to_task(struct tcb *owner, struct tcb *mapper, unsigned int flags)
|
|
||||||
{
|
|
||||||
struct vm_file *utcb_shm;
|
|
||||||
|
|
||||||
/* Allocate a new utcb address */
|
|
||||||
if (flags & UTCB_NEW_ADDRESS)
|
|
||||||
owner->utcb = utcb_new_address();
|
|
||||||
else if (!owner->utcb)
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
/* Create a new shared memory segment for utcb */
|
|
||||||
if (flags & UTCB_NEW_SHM)
|
|
||||||
if (IS_ERR(utcb_shm = shm_new((key_t)owner->utcb,
|
|
||||||
__pfn(DEFAULT_UTCB_SIZE))))
|
|
||||||
return (int)utcb_shm;
|
|
||||||
|
|
||||||
/* Map the utcb to mapper */
|
|
||||||
if (IS_ERR(shmat_shmget_internal(mapper, (key_t)owner->utcb,
|
|
||||||
owner->utcb)))
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
/* Prefault the owner's utcb to mapper's address space */
|
|
||||||
if (flags & UTCB_PREFAULT)
|
|
||||||
for (int i = 0; i < __pfn(DEFAULT_UTCB_SIZE); i++)
|
|
||||||
prefault_page(mapper, (unsigned long)owner->utcb +
|
|
||||||
__pfn_to_addr(i), VM_READ | VM_WRITE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int utcb_unmap_from_task(struct tcb *owner, struct tcb *mapper)
|
|
||||||
{
|
|
||||||
return sys_shmdt(mapper, owner->utcb);
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
cd build
|
|
||||||
#arm-none-eabi-insight &
|
|
||||||
/opt/qemu-0.10.2/bin/qemu-system-arm -s -kernel final.axf -nographic -m 128 -M versatilepb &
|
|
||||||
#qemu-system-arm -s -kernel final.axf -nographic -m 128 -M versatilepb &
|
|
||||||
#qemu-system-arm -s -kernel final.axf -nographic -m 128 -M versatilepb &
|
|
||||||
arm-none-linux-gnueabi-insight ; pkill qemu-system-arm
|
|
||||||
#arm-none-linux-gnueabi-gdb ; pkill qemu-system-arm
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# insight works ok if gdbinit script is run from the insight
|
|
||||||
# command window. Then one needs to break at bkpt_phys_to_virt and do:
|
|
||||||
# sym start.axf
|
|
||||||
# Then continue execution to see all symbols. This must be done automatic.
|
|
||||||
Reference in New Issue
Block a user