ARM: add context switch implementation

This commit is contained in:
Ithamar R. Adema 2012-11-05 01:41:05 +01:00
parent f8b47f2b2a
commit 4fc1dadd58
1 changed files with 43 additions and 18 deletions

View File

@ -20,13 +20,20 @@
#include <boot/stage2.h> #include <boot/stage2.h>
#include <kernel.h> #include <kernel.h>
#include <thread.h> #include <thread.h>
#include <tls.h>
#include <vm/vm_types.h> #include <vm/vm_types.h>
#include <vm/VMAddressSpace.h> #include <vm/VMAddressSpace.h>
#include <arch_vm.h> #include <arch_vm.h>
//#include <arch/vm_translation_map.h> #include <arch/vm_translation_map.h>
#include <string.h> #include <string.h>
#define TRACE_ARCH_THREAD
#ifdef TRACE_ARCH_THREAD
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
// Valid initial arch_thread state. We just memcpy() it when initializing // Valid initial arch_thread state. We just memcpy() it when initializing
// a new thread structure. // a new thread structure.
@ -67,35 +74,53 @@ void
arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
void (*function)(void*), const void* data) void (*function)(void*), const void* data)
{ {
#warning ARM:WRITEME addr_t* stackTop = (addr_t*)_stackTop;
TRACE(("arch_thread_init_kthread_stack(%s): stack top %p, function %p, data: "
"%p\n", thread->name, stackTop, function, data));
// push the function address -- that's the return address used after the
// context switch (lr/r14 register)
*--stackTop = (addr_t)function;
// simulate storing registers r1-r12
for (int i = 1; i <= 12; i++)
*--stackTop = 0;
// push the function argument as r0
*--stackTop = (addr_t)data;
// save the stack position
thread->arch_info.sp = stackTop;
} }
status_t status_t
arch_thread_init_tls(Thread *thread) arch_thread_init_tls(Thread *thread)
{ {
// TODO: Implement! uint32 tls[TLS_USER_THREAD_SLOT + 1];
return B_OK;
thread->user_local_storage = thread->user_stack_base
+ thread->user_stack_size;
// initialize default TLS fields
memset(tls, 0, sizeof(tls));
tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage;
tls[TLS_THREAD_ID_SLOT] = thread->id;
tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread;
return user_memcpy((void *)thread->user_local_storage, tls, sizeof(tls));
} }
extern "C" void arm_context_switch(void *from, void *to);
void void
arch_thread_context_switch(Thread *from, Thread *to) arch_thread_context_switch(Thread *from, Thread *to)
{ {
#if 0 TRACE(("arch_thread_context_switch: %p(%s/%p) -> %p(%s/%p)\n",
addr_t newPageDirectory; from, from->name, from->arch_info.sp, to, to->name, to->arch_info.sp));
arm_context_switch(&from->arch_info, &to->arch_info);
newPageDirectory = (addr_t)m68k_next_page_directory(from, to); TRACE(("arch_thread_context_switch %p %p\n", to, from));
if ((newPageDirectory % B_PAGE_SIZE) != 0)
panic("arch_thread_context_switch: bad pgdir 0x%lx\n",
newPageDirectory);
#warning M68K: export from arch_vm.c
m68k_set_pgdir(newPageDirectory);
m68k_context_switch(&from->arch_info.sp, to->arch_info.sp);
#endif
#warning ARM:WRITEME
} }