A clean FPU state is now saved during init, and copied into every fresh

thread. That also allows kernel threads to use the FPU as well.
arch_thread_enter_uspace() no longer needs to initialize the FPU.
i386_stack_init() is now only called once, in arch_thread_init(), as
thought.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9508 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-10-25 22:29:00 +00:00
parent 63be222e2f
commit f9fea8ac78

View File

@ -28,6 +28,30 @@ extern void i386_stack_init(struct farcall *interrupt_stack_offset);
extern void i386_restore_frame_from_syscall(struct iframe frame);
static struct arch_thread sInitialState;
// ToDo:
// __attribute__ ((aligned(16)));
// the fpu_state must be aligned on a 16 byte boundary, so that fxsave can use it
status_t
arch_thread_init(struct kernel_args *args)
{
// save one global valid FPU state; it will be copied in the arch dependent
// part of each new thread
asm("fninit");
// ToDo: add MMX/SSE support (ie. use fxsave)
i386_fsave(sInitialState.fpu_state);
// let the asm function know the offset to the interrupt stack within struct thread
// I know no better ( = static) way to tell the asm function the offset
i386_stack_init(&((struct thread *)0)->arch_info.interrupt_stack);
return B_OK;
}
void
i386_push_iframe(struct thread *thread, struct iframe *frame)
{
@ -77,29 +101,23 @@ set_tls_context(struct thread *thread)
}
int
status_t
arch_team_init_team_struct(struct team *p, bool kernel)
{
return 0;
return B_OK;
}
int
arch_thread_init_thread_struct(struct thread *t)
status_t
arch_thread_init_thread_struct(struct thread *thread)
{
// set up an initial state (stack & fpu)
memset(&t->arch_info, 0, sizeof(t->arch_info));
// ToDo: note, this has to be done only once
// let the asm function know the offset to the interrupt stack within struct thread
// I know no better ( = static) way to tell the asm function the offset
i386_stack_init(&((struct thread *)0)->arch_info.interrupt_stack);
return 0;
memcpy(&thread->arch_info, &sInitialState, sizeof(struct arch_thread));
return B_OK;
}
int
status_t
arch_thread_init_kthread_stack(struct thread *t, int (*start_func)(void), void (*entry_func)(void), void (*exit_func)(void))
{
addr_t *kstack = (addr_t *)t->kernel_stack_base;
@ -139,7 +157,7 @@ arch_thread_init_kthread_stack(struct thread *t, int (*start_func)(void), void (
t->arch_info.current_stack.esp = kstack_top;
t->arch_info.current_stack.ss = (addr_t *)KERNEL_DATA_SEG;
return 0;
return B_OK;
}
@ -244,9 +262,6 @@ arch_thread_enter_uspace(struct thread *t, addr_t entry, void *args1, void *args
TRACE(("arch_thread_enter_uspace: entry 0x%lx, args %p %p, ustack_top 0x%lx\n",
entry, args1, args2, ustack_top));
// make sure the fpu is in a good state
asm("fninit");
// access the new stack to make sure the memory page is present
// while interrupts are disabled.
// XXX does this belong there, should caller take care of it?