mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01: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 */
|
||||
#define L4_IPC_TAG_SYNC 3
|
||||
|
||||
/* To obtain utcb address */
|
||||
#define L4_IPC_TAG_UTCB 4
|
||||
/* To obtain default shared page address */
|
||||
#define L4_IPC_TAG_SHPAGE 4
|
||||
|
||||
/* XXX: unused */
|
||||
#define L4_IPC_TAG_GRANT 5
|
||||
|
||||
@@ -34,77 +34,6 @@ struct kip *kip;
|
||||
*/
|
||||
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)
|
||||
{
|
||||
@@ -123,7 +52,5 @@ void __l4_init(void)
|
||||
(__l4_exchange_registers_t)kip->exchange_registers;
|
||||
__l4_kmem_control = (__l4_kmem_control_t)kip->kmem_control;
|
||||
__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);
|
||||
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__ */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* POSIX minimum is 4Kb */
|
||||
#define DEFAULT_ENV_SIZE SZ_4K
|
||||
#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_SHARED_VM (1 << 0)
|
||||
@@ -101,8 +101,8 @@ struct tcb {
|
||||
unsigned long map_start;
|
||||
unsigned long map_end;
|
||||
|
||||
/* UTCB information */
|
||||
void *utcb;
|
||||
/* Default ipc-shared-page information */
|
||||
void *shared_page;
|
||||
|
||||
/* Virtual memory areas */
|
||||
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 <file.h>
|
||||
#include <shm.h>
|
||||
#include <utcb.h>
|
||||
#include <mmap.h>
|
||||
#include <test.h>
|
||||
#include <boot.h>
|
||||
@@ -85,8 +84,8 @@ void handle_requests(void)
|
||||
ret = sys_shmdt(sender, (void *)mr[0]);
|
||||
break;
|
||||
|
||||
case L4_IPC_TAG_UTCB:
|
||||
ret = (int)task_send_utcb_address(sender, (l4id_t)mr[0]);
|
||||
case L4_IPC_TAG_SHPAGE:
|
||||
ret = (int)task_send_shpage_address(sender, (l4id_t)mr[0]);
|
||||
break;
|
||||
|
||||
case L4_IPC_TAG_READ:
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#include <boot.h>
|
||||
#include <mmap.h>
|
||||
#include <utcb.h>
|
||||
#include <shm.h>
|
||||
#include <l4/api/thread.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
@@ -74,11 +73,12 @@ int boottask_mmap_regions(struct tcb *task, struct vm_file *file)
|
||||
return (int)mapped;
|
||||
}
|
||||
|
||||
/* Task's utcb */
|
||||
task->utcb = utcb_new_address();
|
||||
/* Task's default shared page */
|
||||
task->shared_page = shm_new_address(DEFAULT_SHPAGE_SIZE/PAGE_SIZE);
|
||||
|
||||
/* 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 0;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <vm_area.h>
|
||||
#include <task.h>
|
||||
#include <mmap.h>
|
||||
#include <utcb.h>
|
||||
#include <shm.h>
|
||||
#include <test.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_mr(L4SYS_ARG0, parent->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);
|
||||
|
||||
if ((err = l4_sendrecv(VFS_TID, VFS_TID,
|
||||
@@ -85,8 +84,10 @@ int sys_fork(struct tcb *parent)
|
||||
BUG();
|
||||
|
||||
/* Create and prefault a utcb for child and map it to vfs task */
|
||||
utcb_map_to_task(child, find_task(VFS_TID),
|
||||
UTCB_NEW_ADDRESS | UTCB_NEW_SHM | UTCB_PREFAULT);
|
||||
shpage_map_to_task(child, find_task(VFS_TID),
|
||||
SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM |
|
||||
SHPAGE_PREFAULT);
|
||||
|
||||
// printf("Mapped 0x%p to vfs as utcb of %d\n", child->utcb, child->tid);
|
||||
|
||||
/* 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();
|
||||
|
||||
/* Create and prefault a utcb for child and map it to vfs task */
|
||||
utcb_map_to_task(child, find_task(VFS_TID),
|
||||
UTCB_NEW_ADDRESS | UTCB_NEW_SHM | UTCB_PREFAULT);
|
||||
shpage_map_to_task(child, find_task(VFS_TID),
|
||||
SHPAGE_NEW_ADDRESS | SHPAGE_NEW_SHM |
|
||||
SHPAGE_PREFAULT);
|
||||
|
||||
/* We can now notify vfs about forked process */
|
||||
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;
|
||||
|
||||
/*
|
||||
* Copy string to vfs utcb.
|
||||
* Copy string to vfs shared page.
|
||||
*
|
||||
* 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();
|
||||
|
||||
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,
|
||||
L4_IPC_TAG_PAGER_OPEN_BYPATH)) < 0) {
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#include <shm.h>
|
||||
#include <task.h>
|
||||
#include <file.h>
|
||||
#include <utcb.h>
|
||||
#include <exit.h>
|
||||
#include <test.h>
|
||||
#include <vm_area.h>
|
||||
@@ -90,7 +90,7 @@ int execve_recycle_task(struct tcb *new, struct tcb *orig)
|
||||
new->pagerid = orig->pagerid;
|
||||
|
||||
/* Copy utcb */
|
||||
new->utcb = orig->utcb;
|
||||
new->shared_page = orig->shared_page;
|
||||
|
||||
/* Copy parent relationship */
|
||||
BUG_ON(new->parent);
|
||||
@@ -131,9 +131,9 @@ void do_exit(struct tcb *task, int status)
|
||||
/* Tell vfs that task is exiting */
|
||||
vfs_notify_exit(task, status);
|
||||
|
||||
/* Remove utcb shm areas from vfs */
|
||||
// printf("Unmapping 0x%p from vfs as utcb of %d\n", task->utcb, task->tid);
|
||||
utcb_unmap_from_task(task, find_task(VFS_TID));
|
||||
/* Remove default shared page shm areas from vfs */
|
||||
// printf("Unmapping 0x%p from vfs as shared-page of %d\n", task->shared_page, task->tid);
|
||||
shpage_unmap_from_task(task, find_task(VFS_TID));
|
||||
|
||||
/* Free task's local tcb */
|
||||
tcb_destroy(task);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <shm.h>
|
||||
#include <file.h>
|
||||
#include <init.h>
|
||||
#include <utcb.h>
|
||||
#include <test.h>
|
||||
#include <boot.h>
|
||||
|
||||
@@ -168,12 +167,8 @@ void init_mm(struct initdata *initdata)
|
||||
printf("SHM initialisation failed.\n");
|
||||
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 */
|
||||
pager_address_pool_init();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <stdio.h>
|
||||
#include <task.h>
|
||||
#include <mmap.h>
|
||||
#include <utcb.h>
|
||||
#include <vm_area.h>
|
||||
#include <globals.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);
|
||||
|
||||
/* Release the shared memory address */
|
||||
if ((unsigned long)shm_desc->shm_addr >= UTCB_AREA_START &&
|
||||
(unsigned long)shm_desc->shm_addr < UTCB_AREA_END) {
|
||||
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();
|
||||
BUG_ON(shm_delete_address(shm_desc->shm_addr,
|
||||
shm_file->vm_obj.npages) < 0);
|
||||
|
||||
/* Release the shared memory id */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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 <memory.h>
|
||||
#include <file.h>
|
||||
#include <utcb.h>
|
||||
#include <task.h>
|
||||
#include <exec.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(!vfs->utcb);
|
||||
BUG_ON(!vfs->shared_page);
|
||||
|
||||
/* 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 */
|
||||
tdata_head = (struct task_data_head *)vfs->utcb;
|
||||
/* Write all requested task information to shared pages's user buffer area */
|
||||
tdata_head = (struct task_data_head *)vfs->shared_page;
|
||||
|
||||
/* First word is total number of tcbs */
|
||||
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 */
|
||||
list_for_each_entry(t, &global_tasks.list, list) {
|
||||
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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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