Implement SSE instructions

This commit is contained in:
2026-03-07 17:36:09 +01:00
parent 40bfc1e916
commit 5e616c1879
16 changed files with 80 additions and 15 deletions

View File

@@ -1,9 +1,5 @@
cflags += --target=x86_64-unknown-unknown-elf \
-mno-sse \
-mno-sse2 \
-mno-avx \
-mno-mmx \
-mno-80387 \
-mno-red-zone \
-mcmodel=large

View File

@@ -363,7 +363,8 @@ static void execute_redir (struct ast_redir* redir, struct context* context) {
}
void execute (struct ast_node* root, struct context* context) {
struct context subcontext = {0};
struct context subcontext;
memset (&subcontext, 0, sizeof (subcontext));
switch (root->class) {
case AST_NODE_CLASS_CMD:

View File

@@ -169,10 +169,11 @@ void parse_and_execute (struct list_node_link* tokens) {
parser.next = get_token (tokens);
while (parser.next != NULL) {
struct ast_node* root = parse_precedence (&parser, PREC_NONE);
volatile struct ast_node* root = parse_precedence (&parser, PREC_NONE);
if (root != NULL) {
struct context context = {0};
struct context context;
memset (&context, 0, sizeof (context));
execute (root, &context);
if (context.strbuf.items != NULL)

View File

@@ -6,6 +6,7 @@
#include <amd64/intr_defs.h>
#include <amd64/msr-index.h>
#include <amd64/msr.h>
#include <amd64/sse.h>
#include <aux/compiler.h>
#include <device/device.h>
#include <device/partitions.h>
@@ -48,6 +49,8 @@ void bootmain (void) {
pmm_init ();
mm_init ();
sse_enable ();
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
ioapic_init ();

19
kernel/amd64/fx.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _KERNEL_AMD64_FX_H
#define _KERNEL_AMD64_FX_H
#define fx_save(buf) \
do { \
__asm__ volatile ("fxsave64 (%0)" ::"r"((buf)) : "memory"); \
} while (0)
#define fx_restore(buf) \
do { \
__asm__ volatile ("fxrstor64 (%0)" ::"r"((buf)) : "memory"); \
} while (0)
#define fx_init(buf) \
do { \
__asm__ volatile ("fninit; fxsave64 (%0)" ::"r"((buf)) : "memory"); \
} while (0)
#endif // _KERNEL_AMD64_FX_H

View File

@@ -1,4 +1,5 @@
#include <amd64/apic.h>
#include <amd64/fx.h>
#include <amd64/gdt.h>
#include <amd64/intr.h>
#include <amd64/intr_defs.h>
@@ -161,7 +162,8 @@ static void intr_exception (struct saved_regs* regs) {
regs->rbx);
if (regs->cs == (GDT_UCODE | 0x03)) {
struct reschedule_ctx rctx = {0};
struct reschedule_ctx rctx;
memset (&rctx, 0, sizeof (rctx));
proc_kill (thiscpu->proc_current, &rctx);
bool do_thiscpu = false;
@@ -196,6 +198,9 @@ void intr_handler (void* stack_ptr) {
if (proc_current != NULL) {
spin_lock (&proc_current->lock);
memcpy (&proc_current->pdata.regs, regs, sizeof (struct saved_regs));
fx_save (proc_current->pdata.fx_env);
spin_unlock (&proc_current->lock);
}
@@ -208,7 +213,8 @@ void intr_handler (void* stack_ptr) {
if (irq == NULL)
return;
struct reschedule_ctx rctx = {0};
struct reschedule_ctx rctx;
memset (&rctx, 0, sizeof (rctx));
irq->func (irq->arg, stack_ptr, &rctx);
bool do_thiscpu = false;

View File

@@ -1,3 +1,4 @@
#include <amd64/fx.h>
#include <amd64/gdt.h>
#include <amd64/proc.h>
#include <aux/elf.h>
@@ -58,6 +59,7 @@ struct proc* proc_from_elf (uint8_t* elf_contents) {
proc->pdata.regs.rflags = 0x202;
proc->pdata.regs.cs = GDT_UCODE | 0x03;
proc->pdata.regs.rip = aux.entry;
fx_init (proc->pdata.fx_env);
proc->exec_pid = -1;
@@ -98,6 +100,7 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent
proc->pdata.regs.rflags = 0x202;
proc->pdata.regs.cs = GDT_UCODE | 0x03;
proc->pdata.regs.rip = (uint64_t)entry;
fx_init (proc->pdata.fx_env);
proc->uvaddr_argument = argument_ptr;

View File

@@ -2,6 +2,7 @@
#define _KERNEL_AMD64_PROC_H
#include <amd64/intr.h>
#include <aux/compiler.h>
#include <libk/std.h>
/* Top of userspace process' stack */
@@ -17,6 +18,7 @@ struct proc_platformdata {
uintptr_t kernel_stack;
uint64_t fs_base;
uintptr_t tls_vaddr;
uint8_t fx_env[512] ALIGNED (16);
};
#endif // _KERNEL_AMD64_PROC_H

View File

@@ -2,8 +2,8 @@
.global do_sched1
do_sched1:
movq %rsi, %cr3
movq %rdi, %rsp
movq %rsi, %cr3
pop_regs
addq $16, %rsp
iretq

View File

@@ -1,10 +1,13 @@
#include <amd64/fx.h>
#include <amd64/msr-index.h>
#include <amd64/msr.h>
#include <amd64/sched.h>
#include <aux/compiler.h>
#include <libk/std.h>
#include <libk/string.h>
#include <proc/proc.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
#include <sys/mm.h>
#include <sys/smp.h>
@@ -16,9 +19,12 @@ void do_sched (struct proc* proc, spin_lock_t* cpu_lock) {
wrmsr (MSR_FS_BASE, proc->pdata.fs_base);
void* cr3 = (void*)proc->procgroup->pd.cr3_paddr;
struct saved_regs regs;
memcpy (&regs, &proc->pdata.regs, sizeof (regs));
fx_restore (proc->pdata.fx_env);
spin_unlock (&proc->lock);
spin_unlock (cpu_lock);

View File

@@ -5,6 +5,7 @@
#include <amd64/mm.h>
#include <amd64/msr-index.h>
#include <amd64/msr.h>
#include <amd64/sse.h>
#include <fs/vfs.h>
#include <libk/std.h>
#include <libk/string.h>
@@ -93,6 +94,7 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) {
gdt_init (cpu);
idt_load ();
syscall_init ();
sse_enable ();
lapic_init (1000);
@@ -100,7 +102,8 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) {
atomic_fetch_sub (&cpu_counter, 1);
struct reschedule_ctx rctx = {0};
struct reschedule_ctx rctx;
memset (&rctx, 0, sizeof (rctx));
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
proc_register (spin_proc, thiscpu, &rctx);

View File

@@ -17,7 +17,8 @@ c += amd64/bootmain.c \
S += amd64/intr_stub.S \
amd64/spin.S \
amd64/sched.S \
amd64/syscallentry.S
amd64/syscallentry.S \
amd64/sse.S
o += amd64/bootmain.o \
amd64/io.o \
@@ -37,4 +38,5 @@ o += amd64/bootmain.o \
amd64/proc.o \
amd64/syscall.o \
amd64/syscallentry.o \
amd64/gdt.o
amd64/gdt.o \
amd64/sse.o

12
kernel/amd64/sse.S Normal file
View File

@@ -0,0 +1,12 @@
.global sse_enable
sse_enable:
movq %cr0, %rax
andq $~0x4, %rax
orq $0x2, %rax
movq %rax, %cr0
movq %cr4, %rax
orq $(1 << 9) | (1 << 10), %rax
movq %rax, %cr4
ret

6
kernel/amd64/sse.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _KERNEL_SSE_H
#define _KERNEL_SSE_H
void sse_enable (void);
#endif // _KERNEL_SSE_H

View File

@@ -1,3 +1,4 @@
#include <amd64/fx.h>
#include <amd64/gdt.h>
#include <amd64/intr.h>
#include <amd64/mm.h>
@@ -28,6 +29,8 @@ uintptr_t syscall_dispatch (void* stack_ptr) {
memcpy (&caller->pdata.regs, regs, sizeof (struct saved_regs));
fx_save (caller->pdata.fx_env);
spin_unlock (&caller->lock);
spin_unlock (&thiscpu->lock);
@@ -38,7 +41,8 @@ uintptr_t syscall_dispatch (void* stack_ptr) {
return -ST_SYSCALL_NOT_FOUND;
}
struct reschedule_ctx rctx = {0};
struct reschedule_ctx rctx;
memset (&rctx, 0, sizeof (rctx));
uintptr_t r =
func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9);

View File

@@ -314,7 +314,8 @@ void proc_init (void) {
irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED);
#endif
struct reschedule_ctx rctx = {0};
struct reschedule_ctx rctx;
memset (&rctx, 0, sizeof (rctx));
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
proc_register (spin_proc, thiscpu, &rctx);