diff --git a/include/l4/arch/arm/v5/mm.h b/include/l4/arch/arm/v5/mm.h index f0d2dab..35b763b 100644 --- a/include/l4/arch/arm/v5/mm.h +++ b/include/l4/arch/arm/v5/mm.h @@ -127,6 +127,8 @@ typedef struct pmd_table { #define TASK_PGD(x) (x)->space->pgd +#define STACK_ALIGNMENT 8 + /* Kernel's data about the fault */ typedef struct fault_kdata { u32 faulty_pc; diff --git a/include/l4/generic/kmalloc.h b/include/l4/generic/kmalloc.h deleted file mode 100644 index 7f9fcc9..0000000 --- a/include/l4/generic/kmalloc.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __KMALLOC_H__ -#define __KMALLOC_H__ - -void *kmalloc(int size); -int kfree(void *p); -void *kzalloc(int size); -void init_kmalloc(); - -#endif diff --git a/include/l4/lib/idpool.h b/include/l4/lib/idpool.h index 62c9383..43ee4fd 100644 --- a/include/l4/lib/idpool.h +++ b/include/l4/lib/idpool.h @@ -20,7 +20,7 @@ struct id_pool_variable { u32 bitmap[]; }; -struct id_pool *id_pool_new_init(int mapsize); +struct id_pool *id_pool_new_init(int mapsize, void *buffer); int id_new(struct id_pool *pool); int id_del(struct id_pool *pool, int id); int id_get(struct id_pool *pool, int id); diff --git a/src/api/ipc.c b/src/api/ipc.c index 2222571..c1bbfb9 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -11,7 +11,6 @@ #include #include #include -#include #include INC_API(syscall.h) #include INC_GLUE(message.h) #include INC_GLUE(ipc.h) diff --git a/src/api/mutex.c b/src/api/mutex.c index bc5fa31..6e2062c 100644 --- a/src/api/mutex.c +++ b/src/api/mutex.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -79,7 +78,7 @@ struct mutex_queue *mutex_control_create(unsigned long mutex_physical) struct mutex_queue *mutex_queue; /* Allocate the mutex queue structure */ - if (!(mutex_queue = kzalloc(sizeof(struct mutex_queue)))) + if (!(mutex_queue = alloc_user_mutex())) return 0; /* Init and return */ @@ -98,7 +97,7 @@ void mutex_control_delete(struct mutex_queue *mq) BUG_ON(!list_empty(&mq->wqh_contenders.task_list)); BUG_ON(!list_empty(&mq->wqh_holders.task_list)); - kfree(mq); + free_user_mutex(mq); } /* diff --git a/src/arch/arm/bootdesc.c b/src/arch/arm/bootdesc.c index 3475634..c568deb 100644 --- a/src/arch/arm/bootdesc.c +++ b/src/arch/arm/bootdesc.c @@ -6,7 +6,6 @@ #include #include -#include #include #include INC_ARCH(linker.h) #include INC_ARCH(bootdesc.h) @@ -16,6 +15,7 @@ struct bootdesc *bootdesc; +#if 0 void copy_bootdesc() { struct bootdesc *new = kzalloc(bootdesc->desc_size); @@ -43,3 +43,4 @@ void read_bootdesc(void) __svc_images_end = bootdesc->images[i].phys_end; } +#endif diff --git a/src/generic/SConscript b/src/generic/SConscript index 47043fc..ebb9255 100644 --- a/src/generic/SConscript +++ b/src/generic/SConscript @@ -4,7 +4,7 @@ Import('env') # The set of source files associated with this SConscript file. -src_local = ['physmem.c', 'irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'kmalloc.c', 'space.c', 'bootm.c', 'resource.c', 'container.c', 'capability.c'] +src_local = ['physmem.c', 'irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'space.c', 'bootm.c', 'resource.c', 'container.c', 'capability.c'] obj = env.Object(src_local) Return('obj') diff --git a/src/generic/container.c b/src/generic/container.c index 0c8a86a..7693646 100644 --- a/src/generic/container.c +++ b/src/generic/container.c @@ -9,6 +9,8 @@ #include #include #include INC_GLUE(memory.h) +#include INC_SUBARCH(mm.h) +#include INC_ARCH(linker.h) /* * FIXME: @@ -192,21 +194,45 @@ void task_setup_utcb(struct ktcb *task, struct pager *pager) } #if 0 -void switch_stack(struct ktcb *task) -{ - register u32 stack asm("sp"); - register u32 fp asm("fp"); - register u32 newstack = align((unsigned long)task + PAGE_SIZE, sizeof(short)); - signed long long offset = newstack - __bootstack; - fp += offset; - sp += offset; +/* + * NOTE: This is not useful because FP stores references to + * old stack so even if stacks are copied, unwinding is not + * possible, which makes copying pointless. If there was no + * FP, it may make sense, but this is not tested. + * + * Copy current stack contents to new one, + * and jump to that stack by modifying sp and frame pointer. + */ +int switch_stacks(struct ktcb *task) +{ + volatile register unsigned int stack asm("sp"); + volatile register unsigned int frameptr asm("fp"); + volatile register unsigned int newstack; + unsigned int stack_size = (unsigned int)_bootstack - stack; + + newstack = align((unsigned long)task + PAGE_SIZE - 1, + STACK_ALIGNMENT); /* Copy stack contents to new stack */ - memcpy(&newstack, __bootstack, stack - __bootstack); + memcpy((void *)(newstack - stack_size), + (void *)stack, stack_size); - /* Switch to new stack */ + /* + * Switch to new stack, as new stack + * minus currently used stack size + */ + stack = newstack - stack_size; + /* + * Frame ptr is new stack minus the original + * difference from start of boot stack to current fptr + */ + frameptr = newstack - + ((unsigned int)_bootstack - frameptr); + + /* We should be able to return safely */ + return 0; } #endif @@ -247,6 +273,7 @@ int init_first_pager(struct pager *pager, task->space = space; task->container = cont; + pager->tcb = task; /* Map the task's space */ add_mapping_pgd(pager->start_lma, pager->start_vma, @@ -291,6 +318,8 @@ int init_pager(struct pager *pager, struct container *cont) task->container = cont; + pager->tcb = task; + add_mapping_pgd(pager->start_lma, pager->start_vma, page_align_up(pager->memsize), MAP_USR_DEFAULT_FLAGS, TASK_PGD(task)); diff --git a/src/generic/kmalloc.c b/src/generic/kmalloc.c deleted file mode 100644 index bebac98..0000000 --- a/src/generic/kmalloc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Memory pool based kmalloc. - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -#include -#include -#include INC_GLUE(memory.h) - -/* Supports this many different kmalloc sizes */ -#define KMALLOC_POOLS_MAX 5 - -struct kmalloc_pool_head { - struct link cache_list; - int occupied; - int total_caches; - int cache_size; -}; - -struct kmalloc_mempool { - int total; - struct kmalloc_pool_head pool_head[KMALLOC_POOLS_MAX]; - struct mutex kmalloc_mutex; -}; -struct kmalloc_mempool km_pool; - -void init_kmalloc() -{ - for (int i = 0; i < KMALLOC_POOLS_MAX; i++) { - link_init(&km_pool.pool_head[i].cache_list); - km_pool.pool_head[i].occupied = 0; - km_pool.pool_head[i].total_caches = 0; - km_pool.pool_head[i].cache_size = 0; - } - mutex_init(&km_pool.kmalloc_mutex); -} - -void *kmalloc(int size) -{ - return 0; -} - -int kfree(void *p) -{ - return 0; -} - -void *kzalloc(int size) -{ - return 0; -} - diff --git a/src/generic/space.c b/src/generic/space.c index 8f9b0b1..892ff98 100644 --- a/src/generic/space.c +++ b/src/generic/space.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -87,7 +86,7 @@ void address_space_delete(struct address_space *space) id_del(space_id_pool, space->spid); /* Deallocate the space structure */ - kfree(space); + free_space(space); } struct address_space *address_space_create(struct address_space *orig) @@ -126,7 +125,7 @@ struct address_space *address_space_create(struct address_space *orig) /* Copy its user entries/tables */ if ((err = copy_user_tables(space, orig)) < 0) { free_pgd(pgd); - kfree(space); + free_space(space); return PTR_ERR(err); } } diff --git a/src/glue/arm/init.c b/src/glue/arm/init.c index c947fa2..64bb775 100644 --- a/src/glue/arm/init.c +++ b/src/glue/arm/init.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -237,6 +236,8 @@ void jump(struct ktcb *task) "mov lr, %0\n" /* Load pointer to context area */ "ldr r0, [lr]\n" /* Load spsr value to r0 */ "msr spsr, r0\n" /* Set SPSR as ARM_MODE_USR */ + "add sp, lr, %1\n" /* Reset SVC stack */ + "sub sp, sp, %2\n" /* Align to stack alignment */ "ldmib lr, {r0-r14}^\n" /* Load all USR registers */ "nop \n" /* Spec says dont touch banked registers @@ -245,7 +246,7 @@ void jump(struct ktcb *task) "ldr lr, [lr]\n" /* Load the PC_USR to LR */ "movs pc, lr\n" /* Jump to userspace, also switching SPSR/CPSR */ : - : "r" (task) + : "r" (task), "r" (PAGE_SIZE), "r" (STACK_ALIGNMENT) ); } @@ -331,7 +332,6 @@ void init_pager(char *name, struct task_ids *ids) /* Scheduler initialises the very first task itself */ } -#endif void init_tasks() { @@ -357,6 +357,7 @@ void init_tasks() */ // init_pager(__PAGERNAME__, &ids); } +#endif void setup_dummy_current() { @@ -370,6 +371,49 @@ void setup_dummy_current() TASK_PGD(current) = &init_pgd; } +void free_bootmem(void) +{ + /* TODO: Fill. */ +} + +void init_finalize(struct kernel_container *kcont) +{ + volatile register unsigned int stack asm("sp"); + volatile register unsigned int newstack; + struct ktcb *first_task; + struct container *c; + + /* Get the first container */ + c = link_to_struct(kcont->containers.list.next, + struct container, + list); + + /* Get the first pager ktcb */ + first_task = c->pager[0].tcb; + + /* Calculate first stack address */ + newstack = align((unsigned long)first_task + PAGE_SIZE - 1, + STACK_ALIGNMENT); + + /* Switch to new stack */ + stack = newstack; + + /* -- Point of no stack unwinding/referencing -- */ + + /* + * Unmap boot memory, and add it as + * an unused kernel memcap + */ + free_bootmem(); + + /* + * Start the scheduler, jumping to task + */ + scheduler_start(); + + /* FIXME: Make sure SP_SVC is reset in jump() */ +} + void start_kernel(void) { printascii("\n"__KERNELNAME__": start kernel...\n"); @@ -410,8 +454,8 @@ void start_kernel(void) /* Evaluate system resources and set up resource pools */ init_system_resources(&kernel_container); - /* Start the scheduler with available tasks in the runqueue */ - scheduler_start(); + /* Free boot memory, jump to first task's stack and start scheduler */ + init_finalize(&kernel_container); BUG(); } diff --git a/src/glue/arm/memory.c b/src/glue/arm/memory.c index 0220093..e779710 100644 --- a/src/glue/arm/memory.c +++ b/src/glue/arm/memory.c @@ -45,6 +45,7 @@ void task_init_registers(struct ktcb *task, unsigned long pc) task->context.spsr = ARM_MODE_USR; } +#if 0 /* Sets up struct page array and the physical memory descriptor. */ void paging_init(void) { @@ -53,6 +54,7 @@ void paging_init(void) memory_init(); copy_bootdesc(); } +#endif /* * Copies global kernel entries into another pgd. Even for sub-pmd ranges diff --git a/src/lib/idpool.c b/src/lib/idpool.c index 59f033e..d8a718b 100644 --- a/src/lib/idpool.c +++ b/src/lib/idpool.c @@ -5,14 +5,14 @@ */ #include #include -#include #include INC_GLUE(memory.h) -struct id_pool *id_pool_new_init(int totalbits) +struct id_pool *id_pool_new_init(int totalbits, void *freebuf) { int nwords = BITWISE_GETWORD(totalbits); - struct id_pool *new = kzalloc((nwords * SZ_WORD) - + sizeof(struct id_pool)); + struct id_pool *new = freebuf; + // int bufsize = (nwords * SZ_WORD) + sizeof(struct id_pool); + spin_lock_init(&new->lock); new->nwords = nwords; return new;