aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/amd64/machdep.c25
-rw-r--r--sys/include/sys/machdep.h2
-rw-r--r--sys/kern/kern_sched.c2
3 files changed, 29 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 809e395..0789f5a 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -154,6 +154,31 @@ intr_unmask(void)
__ASMV("sti");
}
+int
+processor_init_pcb(struct proc *proc)
+{
+ struct pcb *pcb = &proc->pcb;
+ const uint16_t FPU_FCW = 0x33F;
+ const uint32_t SSE_MXCSR = 0x1F80;
+
+ /* Allocate FPU save area, aligned on a 16 byte boundary */
+ pcb->fpu_state = PHYS_TO_VIRT(vm_alloc_pageframe(1));
+ if (pcb->fpu_state == 0) {
+ return -1;
+ }
+
+ /*
+ * Setup x87 FPU control word and SSE MXCSR bits
+ * as per the sysv ABI
+ */
+ __ASMV("fldcw %0\n"
+ "ldmxcsr %1"
+ :: "m" (FPU_FCW),
+ "m" (SSE_MXCSR) : "memory");
+
+ amd64_fxsave(pcb->fpu_state);
+ return 0;
+}
void
processor_init(void)
{
diff --git a/sys/include/sys/machdep.h b/sys/include/sys/machdep.h
index 713b7db..151d5f8 100644
--- a/sys/include/sys/machdep.h
+++ b/sys/include/sys/machdep.h
@@ -32,11 +32,13 @@
#include <sys/types.h>
#include <sys/cdefs.h>
+#include <sys/proc.h>
#if defined(_KERNEL)
#define MAXCPUS 32
+int processor_init_pcb(struct proc *proc);
void processor_init(void);
void processor_halt(void);
void intr_mask(void);
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
index 7be8241..f8f09c4 100644
--- a/sys/kern/kern_sched.c
+++ b/sys/kern/kern_sched.c
@@ -36,6 +36,7 @@
#include <sys/spinlock.h>
#include <sys/loader.h>
#include <sys/panic.h>
+#include <sys/machdep.h>
#include <fs/initramfs.h>
#include <vm/dynalloc.h>
#include <vm/physseg.h>
@@ -264,6 +265,7 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv,
td->cpu = NULL; /* Not yet assigned a core */
td->tf = tf;
td->addrsp = vas;
+ processor_init_pcb(td);
/* Setup trapframe */
if (!is_user) {