diff --git a/amd64/flags.mk b/amd64/flags.mk index 69e7a8d..9c2cc5b 100644 --- a/amd64/flags.mk +++ b/amd64/flags.mk @@ -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 diff --git a/ce/interp.c b/ce/interp.c index f1287fc..78a0d92 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -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: diff --git a/ce/parser.c b/ce/parser.c index 6ca8bc8..f4e1ffd 100644 --- a/ce/parser.c +++ b/ce/parser.c @@ -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) diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index b1809af..87a950f 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -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 (); diff --git a/kernel/amd64/fx.h b/kernel/amd64/fx.h new file mode 100644 index 0000000..6e2d849 --- /dev/null +++ b/kernel/amd64/fx.h @@ -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 diff --git a/kernel/amd64/intr.c b/kernel/amd64/intr.c index dd35e74..abcee68 100644 --- a/kernel/amd64/intr.c +++ b/kernel/amd64/intr.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -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; diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index 0ffd5ef..0dab0ff 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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; diff --git a/kernel/amd64/proc.h b/kernel/amd64/proc.h index 623f6fa..08b126f 100644 --- a/kernel/amd64/proc.h +++ b/kernel/amd64/proc.h @@ -2,6 +2,7 @@ #define _KERNEL_AMD64_PROC_H #include +#include #include /* 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 diff --git a/kernel/amd64/sched.S b/kernel/amd64/sched.S index 19df996..43604fa 100644 --- a/kernel/amd64/sched.S +++ b/kernel/amd64/sched.S @@ -2,8 +2,8 @@ .global do_sched1 do_sched1: - movq %rsi, %cr3 movq %rdi, %rsp + movq %rsi, %cr3 pop_regs addq $16, %rsp iretq diff --git a/kernel/amd64/sched1.c b/kernel/amd64/sched1.c index 7b012ca..d4aab1d 100644 --- a/kernel/amd64/sched1.c +++ b/kernel/amd64/sched1.c @@ -1,10 +1,13 @@ +#include #include #include #include +#include #include #include #include #include +#include #include #include @@ -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 (®s, &proc->pdata.regs, sizeof (regs)); + fx_restore (proc->pdata.fx_env); + spin_unlock (&proc->lock); spin_unlock (cpu_lock); diff --git a/kernel/amd64/smp.c b/kernel/amd64/smp.c index 5d15ea1..eb47975 100644 --- a/kernel/amd64/smp.c +++ b/kernel/amd64/smp.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/kernel/amd64/src.mk b/kernel/amd64/src.mk index 5f63ba8..3aa812f 100644 --- a/kernel/amd64/src.mk +++ b/kernel/amd64/src.mk @@ -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 diff --git a/kernel/amd64/sse.S b/kernel/amd64/sse.S new file mode 100644 index 0000000..213309d --- /dev/null +++ b/kernel/amd64/sse.S @@ -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 diff --git a/kernel/amd64/sse.h b/kernel/amd64/sse.h new file mode 100644 index 0000000..a969c52 --- /dev/null +++ b/kernel/amd64/sse.h @@ -0,0 +1,6 @@ +#ifndef _KERNEL_SSE_H +#define _KERNEL_SSE_H + +void sse_enable (void); + +#endif // _KERNEL_SSE_H diff --git a/kernel/amd64/syscall.c b/kernel/amd64/syscall.c index f35ddb2..9f4df56 100644 --- a/kernel/amd64/syscall.c +++ b/kernel/amd64/syscall.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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); diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 46b53ad..41bcb87 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -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);