From 27cd9535664a83e7c9986dc8a1b0e1a80aee1629 Mon Sep 17 00:00:00 2001
From: Ian Moffett <ian@osmora.org>
Date: Mon, 11 Mar 2024 12:56:50 -0400
Subject: kernel/amd64: machdep: Enable SSE/SSE2 per core

Signed-off-by: Ian Moffett <ian@osmora.org>
---
 sys/arch/amd64/amd64/machdep.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index e5fe83e..d936912 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -40,6 +40,7 @@
 #include <machine/spectre.h>
 #include <machine/cpu.h>
 #include <machine/uart.h>
+#include <machine/cpuid.h>
 #include <vm/vm.h>
 #include <vm/dynalloc.h>
 #include <vm/physseg.h>
@@ -84,6 +85,15 @@ interrupts_init(void)
     idt_load();
 }
 
+static bool
+is_sse_supported(void)
+{
+    uint32_t edx, unused;
+
+    __CPUID(0x00000001, unused, unused, unused, edx);
+    return __TEST(edx, __BIT(25)) && __TEST(edx, __BIT(26));
+}
+
 void
 processor_halt(void)
 {
@@ -150,6 +160,7 @@ processor_init(void)
 {
     /* Indicates what doesn't need to be init anymore */
     static uint8_t init_flags = 0;
+    static uint64_t reg_tmp;
     struct cpu_info *cur_cpu;
 
     /* Create our cpu_info structure */
@@ -160,6 +171,21 @@ processor_init(void)
     /* Set %GS to cpu_info */
     amd64_write_gs_base((uintptr_t)cur_cpu);
 
+    if (is_sse_supported) {
+        /* Enable SSE/SSE2 */
+        reg_tmp = amd64_read_cr0();
+        reg_tmp &= ~(__BIT(2));
+        reg_tmp |= __BIT(1);
+        amd64_write_cr0(reg_tmp);
+
+        /* Enable FXSAVE/FXRSTOR */
+        reg_tmp = amd64_read_cr4();
+        reg_tmp |= 3 << 9;
+        amd64_write_cr4(reg_tmp);
+    } else {
+        panic("SSE/SSE2 not supported!\n");
+    }
+
     CPU_INFO_LOCK(cur_cpu);
     init_tss(cur_cpu);
 
-- 
cgit v1.2.3