mirror of
https://github.com/drasko/codezero.git
synced 2026-01-15 20:33:16 +01:00
Ongoing work for adding per-thread UTCB structures.
Added setting of utcb address to l4_thread_control. This is going to be moved to exchange_registers() since we need to pass both the utcb physical and virtual address and exregs fits such context modification better than thread_control.
This commit is contained in:
23
tasks/fs0/container.c
Normal file
23
tasks/fs0/container.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Container entry point for this task
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <posix/posix_init.h>
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
void main(void);
|
||||
|
||||
void __container_init(void)
|
||||
{
|
||||
/* Generic L4 thread initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* FS0 posix-service initialisation */
|
||||
posix_service_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ SECTIONS
|
||||
.rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) }
|
||||
.data : AT (ADDR(.data) - offset)
|
||||
{
|
||||
. = ALIGN(4K); /* Align UTCB to page boundary */
|
||||
_start_utcb = .;
|
||||
*(.utcb)
|
||||
_end_utcb = .;
|
||||
. = ALIGN(4K);
|
||||
_start_bdev = .;
|
||||
*(.data.memfs)
|
||||
@@ -39,5 +43,6 @@ SECTIONS
|
||||
*(.data)
|
||||
}
|
||||
.bss : AT (ADDR(.bss) - offset) { *(.bss) }
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <lib/malloc.h>
|
||||
#include <lib/idpool.h>
|
||||
@@ -20,6 +21,7 @@
|
||||
#include <syscalls.h>
|
||||
#include <globals.h>
|
||||
|
||||
|
||||
extern void *shared_page;
|
||||
|
||||
struct global_list global_tasks = {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef __ARM_SYSCALLS_H__
|
||||
#define __ARM_SYSCALLS_H__
|
||||
|
||||
|
||||
#include <l4lib/arch/types.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4/generic/space.h>
|
||||
@@ -14,6 +15,12 @@
|
||||
#include <l4/api/ipc.h>
|
||||
#include <l4/api/thread.h>
|
||||
|
||||
struct task_ids {
|
||||
int tid;
|
||||
int spid;
|
||||
int tgid;
|
||||
};
|
||||
|
||||
static inline void *
|
||||
l4_kernel_interface(unsigned int *api_version, unsigned int *api_flags,
|
||||
unsigned int *kernel_id)
|
||||
@@ -46,9 +53,9 @@ typedef int (*__l4_unmap_t)(void *virt, unsigned long npages, l4id_t tid);
|
||||
extern __l4_unmap_t __l4_unmap;
|
||||
int l4_unmap(void *virtual, unsigned long numpages, l4id_t tid);
|
||||
|
||||
typedef int (*__l4_thread_control_t)(unsigned int action, struct task_ids *ids);
|
||||
typedef int (*__l4_thread_control_t)(unsigned int action, struct task_ids *ids, void *utcb_address);
|
||||
extern __l4_thread_control_t __l4_thread_control;
|
||||
int l4_thread_control(unsigned int action, struct task_ids *ids);
|
||||
int l4_thread_control(unsigned int action, struct task_ids *ids, void *utcb_address);
|
||||
|
||||
typedef int (*__l4_space_control_t)(unsigned int action, void *kdata);
|
||||
extern __l4_space_control_t __l4_space_control;
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
#ifndef __L4_ARCH_ARM__
|
||||
#define __L4_ARCH_ARM__
|
||||
#ifndef __L4LIB_ARM_TYPES_H___
|
||||
#define __L4LIB_ARM_TYPES_H__
|
||||
|
||||
#define TASK_ID_INVALID -1
|
||||
struct task_ids {
|
||||
int tid;
|
||||
int spid;
|
||||
int tgid;
|
||||
};
|
||||
|
||||
#include <l4/arch/arm/types.h>
|
||||
|
||||
#endif
|
||||
#endif /* __L4LIB_ARM_TYPES_H__ */
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#ifndef __ARM_UTCB_H__
|
||||
#define __ARM_UTCB_H__
|
||||
|
||||
#define USER_UTCB_REF 0xFF000FF0
|
||||
#define USER_UTCB_REF 0xFF000050
|
||||
#define L4_KIP_ADDRESS 0xFF000000
|
||||
#define UTCB_KIP_OFFSET 0xFF0
|
||||
#define UTCB_KIP_OFFSET 0x50
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <l4lib/types.h>
|
||||
@@ -13,27 +16,37 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* UTCB implementation */
|
||||
|
||||
/*
|
||||
* NOTE: In syslib.h the first few mrs are used by data frequently
|
||||
* needed for all ipcs. Those mrs are defined the kernel message.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 saved_tag;
|
||||
u32 saved_sender;
|
||||
} __attribute__((__packed__));
|
||||
u32 mr[MR_TOTAL]; /* MRs that are mapped to real registers */
|
||||
u32 saved_tag; /* Saved tag field for stacked ipcs */
|
||||
u32 saved_sender; /* Saved sender field for stacked ipcs */
|
||||
u32 mr_rest[MR_REST]; /* Complete the utcb for up to 64 words */
|
||||
};
|
||||
|
||||
extern struct utcb utcb;
|
||||
extern struct kip *kip;
|
||||
|
||||
|
||||
/*
|
||||
* Pointer to Kernel Interface Page's UTCB pointer offset.
|
||||
*/
|
||||
extern struct utcb **kip_utcb_ref;
|
||||
|
||||
static inline struct utcb *l4_get_utcb()
|
||||
{
|
||||
return &utcb;
|
||||
/*
|
||||
* By double dereferencing, we get the private TLS (aka UTCB). First
|
||||
* reference is to the KIP's utcb offset, second is to the utcb itself,
|
||||
* to which the KIP's utcb reference had been updated during context
|
||||
* switch.
|
||||
*/
|
||||
return *kip_utcb_ref;
|
||||
}
|
||||
|
||||
/* Functions to read/write utcb registers */
|
||||
|
||||
@@ -7,6 +7,7 @@ void exregs_set_stack(struct exregs_data *s, unsigned long sp);
|
||||
void exregs_set_mr(struct exregs_data *s, int offset, unsigned long val);
|
||||
void exregs_set_pc(struct exregs_data *s, unsigned long pc);
|
||||
void exregs_set_pager(struct exregs_data *s, l4id_t pagerid);
|
||||
void exregs_set_utcb(struct exregs_data *s, unsigned long phys, unsigned long virt);
|
||||
|
||||
/*
|
||||
exregs_set_stack(unsigned long sp)
|
||||
|
||||
6
tasks/libl4/include/l4lib/init.h
Normal file
6
tasks/libl4/include/l4lib/init.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __L4LIB_INIT__
|
||||
#define __L4LIB_INIT__
|
||||
|
||||
void __l4_init(void);
|
||||
|
||||
#endif
|
||||
14
tasks/libl4/include/l4lib/thread.h
Normal file
14
tasks/libl4/include/l4lib/thread.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __L4_THREAD_H__
|
||||
#define __L4_THREAD_H__
|
||||
|
||||
#include <libl4/arch/utcb.h>
|
||||
#include <libl4/arch/types.h>
|
||||
|
||||
struct l4_thread_struct {
|
||||
l4id_t tlid; /* Thread local id */
|
||||
struct task_ids ids; /* Thread L4-defined ids */
|
||||
struct utcb *utcb; /* Thread utcb */
|
||||
unsigned long stack_start; /* Thread start of stack */
|
||||
};
|
||||
|
||||
#endif /* __L4_THREAD_H__ */
|
||||
@@ -9,6 +9,7 @@
|
||||
#include INC_GLUE(message.h)
|
||||
|
||||
|
||||
|
||||
void exregs_set_mr(struct exregs_data *s, int offset, unsigned long val)
|
||||
{
|
||||
/* Get MR0 */
|
||||
@@ -30,6 +31,14 @@ void exregs_set_pager(struct exregs_data *s, l4id_t pagerid)
|
||||
s->flags |= EXREGS_SET_PAGER;
|
||||
}
|
||||
|
||||
void exregs_set_utcb(struct exregs_data *s, unsigned long phys,
|
||||
unsigned long virt)
|
||||
{
|
||||
s->utcb_phys = phys;
|
||||
s->utcb_virt = virt;
|
||||
s->flags |= EXREGS_SET_UTCB;
|
||||
}
|
||||
|
||||
void exregs_set_stack(struct exregs_data *s, unsigned long sp)
|
||||
{
|
||||
s->context.sp = sp;
|
||||
|
||||
@@ -9,9 +9,18 @@
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(message.h)
|
||||
|
||||
/* Old macro */
|
||||
#if 0
|
||||
.macro utcb_address rx
|
||||
ldr \rx, =utcb
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/* New macro does double dereference */
|
||||
.macro utcb_address rx
|
||||
ldr \rx, =kip_utcb_ref @ First get pointer to utcb pointer in KIP
|
||||
ldr \rx, [\rx] @ Get UTCB address from UTCB pointer in KIP
|
||||
.endm
|
||||
|
||||
BEGIN_PROC(l4_thread_switch)
|
||||
ldr r12, =__l4_thread_switch
|
||||
@@ -152,7 +161,7 @@ END_PROC(l4_time)
|
||||
|
||||
/*
|
||||
* System call that controls thread creation, destruction and modification.
|
||||
* @r0 = thread action, @r1 = &ids
|
||||
* @r0 = thread action, @r1 = &ids, @r2 = utcb address
|
||||
*/
|
||||
BEGIN_PROC(l4_thread_control)
|
||||
stmfd sp!, {lr}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Initialise system call offsets.
|
||||
* Initialise system call offsets and utcb reference.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
#include <l4lib/kip.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
@@ -27,16 +27,20 @@ __l4_time_t __l4_time = 0;
|
||||
struct kip *kip;
|
||||
|
||||
/*
|
||||
* Private UTCB of this task. Used only for pushing/reading ipc
|
||||
* message registers.
|
||||
* Reference to private UTCB of this thread.
|
||||
* Used only for pushing/reading ipc message registers.
|
||||
*/
|
||||
struct utcb utcb;
|
||||
struct utcb **kip_utcb_ref;
|
||||
|
||||
|
||||
void __l4_init(void)
|
||||
{
|
||||
/* Kernel interface page */
|
||||
kip = l4_kernel_interface(0, 0, 0);
|
||||
|
||||
/* Reference to utcb field of KIP */
|
||||
kip_utcb_ref = (struct utcb **)&kip->utcb;
|
||||
|
||||
__l4_ipc = (__l4_ipc_t)kip->ipc;
|
||||
__l4_map = (__l4_map_t)kip->map;
|
||||
__l4_unmap = (__l4_unmap_t)kip->unmap;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <posix_init.h>
|
||||
#include <shpage.h>
|
||||
|
||||
static inline int l4_fork(void)
|
||||
{
|
||||
@@ -43,10 +43,10 @@ int fork(void)
|
||||
|
||||
/*
|
||||
* If we're a child, we need to initialise the default
|
||||
* shared page via posix_init()
|
||||
* shared page via libposix_init()
|
||||
*/
|
||||
if (ret == 0)
|
||||
posix_init();
|
||||
shared_page_init();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef __POSIX_INIT_H__
|
||||
#define __POSIX_INIT_H__
|
||||
#ifndef __LIBPOSIX_INIT_H__
|
||||
#define __LIBPOSIX_INIT_H__
|
||||
|
||||
void posix_init(void);
|
||||
void libposix_init(void);
|
||||
void posix_service_init(void);
|
||||
|
||||
#endif /* __POSIX_INIT_H__ */
|
||||
#endif /* __LIBPOSIX_INIT_H__ */
|
||||
|
||||
@@ -3,28 +3,20 @@
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Balban
|
||||
*/
|
||||
|
||||
#include <shpage.h>
|
||||
#include <posix_init.h>
|
||||
|
||||
void posix_init(void)
|
||||
void posix_service_init(void)
|
||||
{
|
||||
/* Non-pager tasks initialise their shared communication page */
|
||||
if (self_tid() != PAGER_TID)
|
||||
shared_page_init();
|
||||
BUG_ON(self_tid() != VFS_TID);
|
||||
shared_page_init();
|
||||
}
|
||||
|
||||
int main(void);
|
||||
|
||||
/*
|
||||
* Entry point for posix services container.
|
||||
*
|
||||
* This is executed by all posix system services and tasks
|
||||
* that run in this container.
|
||||
*/
|
||||
void __container_init(void)
|
||||
void libposix_init(void)
|
||||
{
|
||||
posix_init();
|
||||
main();
|
||||
/* Shall only be run by posix applications */
|
||||
BUG_ON(self_tid() == PAGER_TID || self_tid() == VFS_TID);
|
||||
shared_page_init();
|
||||
}
|
||||
|
||||
|
||||
28
tasks/mm0/container.c
Normal file
28
tasks/mm0/container.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Container entry point for pager
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
|
||||
#include <posix/posix_init.h>
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
/*
|
||||
* Application specific utcb allocation
|
||||
* for this container.
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Balban
|
||||
*/
|
||||
|
||||
void main(void);
|
||||
|
||||
void __container_init(void)
|
||||
{
|
||||
/* Generic L4 initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,11 @@ SECTIONS
|
||||
/* rodata is needed else your strings will link at physical! */
|
||||
.rodata : AT (ADDR(.rodata) - offset) { *(.rodata) }
|
||||
.rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) }
|
||||
.data : AT (ADDR(.data) - offset) { *(.data) }
|
||||
.data : AT (ADDR(.data) - offset)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
. = ALIGN(4K);
|
||||
_start_init = .;
|
||||
.init : AT (ADDR(.init) - offset) { *(.init.stack) }
|
||||
. = ALIGN(8);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include INC_GLUE(memlayout.h)
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4lib/arch/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <lib/addr.h>
|
||||
#include <l4/api/kip.h>
|
||||
@@ -53,6 +54,20 @@ struct task_vma_head {
|
||||
int tcb_refs;
|
||||
};
|
||||
|
||||
/*
|
||||
* TLS and UTCB bookkeeping:
|
||||
*
|
||||
* This structure is shared among threads whose utcbs are on the same
|
||||
* physical page. Threads with utcbs on different physical pages have
|
||||
* their own utcb_data structure, even though they are in the same
|
||||
* address space, and share their vm_area_list structure.
|
||||
*/
|
||||
struct utcb_data {
|
||||
unsigned long phys; /* Physical utcb address */
|
||||
unsigned long virt; /* Virtual utcb address */
|
||||
u32 bit; /* Bitvector of free utcb slots on page */
|
||||
struct page *p; /* Physical page */
|
||||
};
|
||||
|
||||
/* Stores all task information that can be kept in userspace. */
|
||||
struct tcb {
|
||||
@@ -104,6 +119,9 @@ struct tcb {
|
||||
/* Default ipc-shared-page information */
|
||||
void *shared_page;
|
||||
|
||||
/* Task's utcb data */
|
||||
struct utcb_data *utcb;
|
||||
|
||||
/* Virtual memory areas */
|
||||
struct task_vma_head *vm_area_head;
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
#define __VM_AREA_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <task.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include <l4/types.h>
|
||||
#include <task.h>
|
||||
#include <arch/mm.h>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <test.h>
|
||||
#include <boot.h>
|
||||
|
||||
|
||||
/* A separate list than the generic file list that keeps just the boot files */
|
||||
LIST_HEAD(boot_file_list);
|
||||
|
||||
|
||||
27
tasks/mm0/src/utcb.c
Normal file
27
tasks/mm0/src/utcb.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Management of task utcb regions and own utcb.
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
|
||||
#include <l4lib/arch/utcb.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
/*
|
||||
* UTCB management in Codezero:
|
||||
*
|
||||
* 1.) Every task in the system defines an array of utcbs in a special .utcb
|
||||
* section that is page-aligned and to be kept wired in by the pager.
|
||||
* 2.) The region marks are written to bootdesc structure at compile-time.
|
||||
* 3.) Pager reads the bootdesc struct from the microkernel during init.
|
||||
* 4.) Pager initialises structures to alloc/dealloc new utcbs for every address
|
||||
* space.
|
||||
* 5.) Pagers dynamically allocate utcb addresses as each thread is created
|
||||
* via a thread_control() system call.
|
||||
* 6.) Each thread in an address space learns their utcb address from a
|
||||
* well-defined KIP offset. This is updated as each thread becomes runnable.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
CPPFLAGS = "-D__USERSPACE__",
|
||||
CPPPATH = ['#include', libl4_incpath, libposix_incpath, kernel_incpath])
|
||||
|
||||
src = [glob("src/*.c"), glob("*.c"), glob("*.S"), glob("src/arch/arm/*.c")]
|
||||
src = [glob("src/*.c"), glob("*.c"), glob("*.S"), glob("src/arch/arm/*.c"), glob("../libcont/*.c")]
|
||||
objs = env.Object(src)
|
||||
physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
|
||||
crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
|
||||
|
||||
25
tasks/test0/container.c
Normal file
25
tasks/test0/container.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Container entry point for this task.
|
||||
*
|
||||
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
|
||||
*/
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <posix_init.h> /* Initialisers for posix library */
|
||||
|
||||
void main(void);
|
||||
|
||||
void __container_init(void)
|
||||
{
|
||||
/* Generic L4 thread initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* Initialise posix library for application */
|
||||
libposix_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -30,10 +30,9 @@ SECTIONS
|
||||
/* rodata is needed else your strings will link at physical! */
|
||||
.rodata : AT (ADDR(.rodata) - offset) { *(.rodata) }
|
||||
.rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) }
|
||||
|
||||
. = ALIGN(4K);
|
||||
.data : AT (ADDR(.data) - offset)
|
||||
{
|
||||
. = ALIGN(4K);
|
||||
_start_test1 = .;
|
||||
*(.test1)
|
||||
_end_test1 = .;
|
||||
|
||||
Reference in New Issue
Block a user