|
AquilaOS documentation
How it works, and its code
|
x86: the FPU and SSE registers, switched lazily between threads. More...
#include <core/system.h>#include <core/panic.h>#include <core/assert.h>#include <core/arch.h>#include <core/string.h>#include <cpu/cpu.h>#include <sys/proc.h>#include <sys/sched.h>#include <sys/signal.h>Go to the source code of this file.
Macros | |
| #define | CPUID_EDX_FXSR _BV(24) |
| #define | CPUID_EDX_SSE _BV(25) |
| #define | last_fpu_thread (curcpu()->arch.fpu_thread) |
Functions | |
| void | x86_fpu_setup (void) |
| Sets up the FPU on the running CPU, at boot: CR0.TS set so that the first FPU or SSE instruction raises #NM (x86_fpu_trap()), SSE turned on if the CPU has it, and the clean starting state recorded. | |
| void | x86_fpu_enable (void) |
| Lets the running CPU use the FPU without trapping (clears CR0.TS). | |
| void | x86_fpu_disable (void) |
| Makes the next FPU instruction trap (sets CR0.TS). | |
| void | x86_fpu_init (void) |
| Loads the clean starting state into the FPU, for a thread's first use of it. | |
| static void | fpu_save (void) |
| Saves the FPU's state into fpu_context. | |
| static void | fpu_restore (void) |
| Loads the FPU's state from fpu_context. | |
| void | x86_fpu_trap (void) |
| Handles #NM, the current thread's first FPU or SSE instruction since it was switched in: it saves the previous owner's state, and gives the FPU to this thread, with its own state or a clean one. | |
| void | x86_fpu_switch_out (void) |
| Saves the current thread's FPU state when it is switched out, if the FPU holds it, because the thread may run on another CPU next. | |
| int | x86_fpu_save_to (void *buf) |
| Copies the current thread's FPU state, for a signal handler's frame (sys/signal.c). | |
| void | x86_fpu_reset (void) |
| Makes the current thread start with a clean FPU state at its next use of the FPU, as a signal handler does. | |
| void | x86_fpu_load_from (const void *buf, int valid) |
| Gives the current thread back the FPU state saved in a signal frame, at sigreturn. | |
Variables | |
| static char | fpu_context [512] |
| static int | fpu_fxsr = 0 |
| static uint32_t | mxcsr_mask = 0xFFBF |
| static char | fpu_clean [512] |
x86: the FPU and SSE registers, switched lazily between threads.
Saving and restoring the FPU's 512 bytes on every thread switch would be costly, and most threads never use it. So the switch only sets CR0.TS; the first FPU or SSE instruction a thread runs afterwards raises #NM, and x86_fpu_trap() saves the previous owner's state and loads this thread's. A thread that never touches the FPU never pays for it.
Definition in file fpu.c.
| #define CPUID_EDX_FXSR _BV(24) |
Definition at line 24 of file fpu.c.
Referenced by x86_fpu_setup().
| #define CPUID_EDX_SSE _BV(25) |
Definition at line 25 of file fpu.c.
Referenced by x86_fpu_setup().
| #define last_fpu_thread (curcpu()->arch.fpu_thread) |
Definition at line 32 of file fpu.c.
Referenced by x86_fpu_reset(), x86_fpu_save_to(), x86_fpu_switch_out(), and x86_fpu_trap().
|
inlinestatic |
Loads the FPU's state from fpu_context.
Definition at line 117 of file fpu.c.
References fpu_context, fpu_fxsr, and fpu_restore().
Referenced by fpu_restore(), and x86_fpu_trap().
|
inlinestatic |
Saves the FPU's state into fpu_context.
Definition at line 108 of file fpu.c.
References fpu_context, fpu_fxsr, and fpu_save().
Referenced by fpu_save(), x86_fpu_save_to(), x86_fpu_switch_out(), and x86_fpu_trap().
| void x86_fpu_disable | ( | void | ) |
Makes the next FPU instruction trap (sets CR0.TS).
Definition at line 88 of file fpu.c.
References CR0_TS, and x86_fpu_disable().
Referenced by arch_thread_spawn(), arch_thread_switch(), x86_fpu_disable(), x86_fpu_reset(), and x86_fpu_setup().
| void x86_fpu_enable | ( | void | ) |
Lets the running CPU use the FPU without trapping (clears CR0.TS).
Definition at line 82 of file fpu.c.
References x86_fpu_enable().
Referenced by x86_fpu_enable(), x86_fpu_save_to(), x86_fpu_setup(), x86_fpu_switch_out(), and x86_fpu_trap().
| void x86_fpu_init | ( | void | ) |
Loads the clean starting state into the FPU, for a thread's first use of it.
Definition at line 95 of file fpu.c.
References assert_alignof, fpu_clean, fpu_context, fpu_fxsr, memcpy(), and x86_fpu_init().
Referenced by x86_fpu_init(), and x86_fpu_trap().
| void x86_fpu_load_from | ( | const void * | buf, |
| int | valid ) |
Gives the current thread back the FPU state saved in a signal frame, at sigreturn.
It is loaded at the thread's next use of the FPU, with the MXCSR bits the CPU doesn't accept cleared.
| buf | the saved state: 512 bytes |
| valid | whether the frame has a state (the thread had used the FPU); if not, the thread starts afresh |
Definition at line 239 of file fpu.c.
References curthread, x86_thread::fpu_context, x86_thread::fpu_enabled, fpu_fxsr, kmalloc(), memcpy(), mxcsr_mask, x86_fpu_load_from(), and x86_fpu_reset().
Referenced by arch_sigreturn(), and x86_fpu_load_from().
| void x86_fpu_reset | ( | void | ) |
Makes the current thread start with a clean FPU state at its next use of the FPU, as a signal handler does.
Definition at line 218 of file fpu.c.
References curthread, x86_thread::fpu_enabled, last_fpu_thread, NULL, x86_fpu_disable(), and x86_fpu_reset().
Referenced by deliver(), x86_fpu_load_from(), and x86_fpu_reset().
| int x86_fpu_save_to | ( | void * | buf | ) |
Copies the current thread's FPU state, for a signal handler's frame (sys/signal.c).
| buf | where to copy it: 512 bytes, 16-byte aligned |
Definition at line 198 of file fpu.c.
References curthread, fpu_context, x86_thread::fpu_context, x86_thread::fpu_enabled, fpu_save(), last_fpu_thread, memcpy(), x86_fpu_enable(), and x86_fpu_save_to().
Referenced by arch_proc_fork(), deliver(), and x86_fpu_save_to().
| void x86_fpu_setup | ( | void | ) |
Sets up the FPU on the running CPU, at boot: CR0.TS set so that the first FPU or SSE instruction raises #NM (x86_fpu_trap()), SSE turned on if the CPU has it, and the clean starting state recorded.
CR0.EM must stay clear, or SSE instructions would raise #UD instead.
Definition at line 50 of file fpu.c.
References CPUID_EDX_FXSR, CPUID_EDX_SSE, CR0_EM, CR0_MP, CR0_NE, CR0_TS, CR4_OSFXSR, CR4_OSXMMEXCPT, fpu_clean, fpu_fxsr, memset(), mxcsr_mask, read_cr4(), write_cr4(), x86_fpu_disable(), x86_fpu_enable(), and x86_fpu_setup().
Referenced by x86_cpu_init(), and x86_fpu_setup().
| void x86_fpu_switch_out | ( | void | ) |
Saves the current thread's FPU state when it is switched out, if the FPU holds it, because the thread may run on another CPU next.
Afterwards, the FPU belongs to no thread.
Definition at line 178 of file fpu.c.
References curthread, fpu_context, x86_thread::fpu_context, fpu_save(), last_fpu_thread, memcpy(), NULL, x86_fpu_enable(), and x86_fpu_switch_out().
Referenced by x86_fpu_switch_out(), and x86_thread_saved().
| void x86_fpu_trap | ( | void | ) |
Handles #NM, the current thread's first FPU or SSE instruction since it was switched in: it saves the previous owner's state, and gives the FPU to this thread, with its own state or a clean one.
If there's no memory for the thread's save area, the process is killed.
Definition at line 131 of file fpu.c.
References curproc, curthread, fpu_context, x86_thread::fpu_context, x86_thread::fpu_enabled, fpu_restore(), fpu_save(), kmalloc(), last_fpu_thread, memcpy(), panic, signal_proc_send(), x86_fpu_enable(), x86_fpu_init(), and x86_fpu_trap().
Referenced by isr_dispatch(), and x86_fpu_trap().
|
static |
Definition at line 42 of file fpu.c.
Referenced by x86_fpu_init(), and x86_fpu_setup().
|
static |
Definition at line 28 of file fpu.c.
Referenced by fpu_restore(), fpu_save(), x86_fpu_init(), x86_fpu_save_to(), x86_fpu_switch_out(), and x86_fpu_trap().
|
static |
Definition at line 29 of file fpu.c.
Referenced by fpu_restore(), fpu_save(), x86_fpu_init(), x86_fpu_load_from(), and x86_fpu_setup().
|
static |
Definition at line 37 of file fpu.c.
Referenced by x86_fpu_load_from(), and x86_fpu_setup().