mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
x86: fix FPU lazy swap
The ucontext->x86_fxsave is initialize as 512 bytes of zeros, but it is not a valid value to be set onto FPU registers, causing a General Protection Fault: Interrupt 0x0d (General Protection Fault) while handling 0x07 (Device not available) EAX=0012f4c0 ECX=001336e4 EDX=001334ac EBX=001336e0 ESP=00123784 EBP=001237c8 ESI=00000200 EDI=00000000 Error code=00000000 CR0=80010031 CR2=00000000 CR3=0012d000 CR4=000001e0 EIP=0000:80010031 EFLAGS=0012d000 <stack trace> 00000000 ??? </stack trace> Halting. So lets copy the initial state of FPU registers before FPU is used and set it as the initial state of FPU to new threads(coroutine).
This commit is contained in:
parent
56f5a836a8
commit
684b081a16
@ -55,6 +55,8 @@ static kernel_pid_t fpu_owner = KERNEL_PID_UNDEF;
|
||||
|
||||
//static ucontext_t *cur_ctx, *isr_ctx;
|
||||
|
||||
static struct x86_fxsave initial_fpu_state;
|
||||
|
||||
int inISR(void)
|
||||
{
|
||||
return x86_in_isr;
|
||||
@ -169,6 +171,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta
|
||||
p->uc_stack.ss_size = stacksize;
|
||||
p->uc_link = &end_context;
|
||||
p->uc_context.flags |= X86_IF;
|
||||
p->__fxsave = initial_fpu_state;
|
||||
makecontext(p, (makecontext_fun_t) task_func, 1, arg);
|
||||
|
||||
return (char *) p;
|
||||
@ -218,6 +221,7 @@ void x86_init_threading(void)
|
||||
makecontext(&end_context, x86_thread_exit, 0);
|
||||
|
||||
x86_interrupt_handler_set(X86_INT_NM, fpu_used_interrupt);
|
||||
asm volatile ("fxsave (%0)" :: "r"(&initial_fpu_state));
|
||||
|
||||
DEBUG("Threading initialized\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user