Implement SSE instructions
This commit is contained in:
@@ -1,9 +1,5 @@
|
|||||||
cflags += --target=x86_64-unknown-unknown-elf \
|
cflags += --target=x86_64-unknown-unknown-elf \
|
||||||
-mno-sse \
|
|
||||||
-mno-sse2 \
|
|
||||||
-mno-avx \
|
-mno-avx \
|
||||||
-mno-mmx \
|
|
||||||
-mno-80387 \
|
|
||||||
-mno-red-zone \
|
-mno-red-zone \
|
||||||
-mcmodel=large
|
-mcmodel=large
|
||||||
|
|
||||||
|
|||||||
@@ -363,7 +363,8 @@ static void execute_redir (struct ast_redir* redir, struct context* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void execute (struct ast_node* root, 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) {
|
switch (root->class) {
|
||||||
case AST_NODE_CLASS_CMD:
|
case AST_NODE_CLASS_CMD:
|
||||||
|
|||||||
@@ -169,10 +169,11 @@ void parse_and_execute (struct list_node_link* tokens) {
|
|||||||
parser.next = get_token (tokens);
|
parser.next = get_token (tokens);
|
||||||
|
|
||||||
while (parser.next != NULL) {
|
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) {
|
if (root != NULL) {
|
||||||
struct context context = {0};
|
struct context context;
|
||||||
|
memset (&context, 0, sizeof (context));
|
||||||
execute (root, &context);
|
execute (root, &context);
|
||||||
|
|
||||||
if (context.strbuf.items != NULL)
|
if (context.strbuf.items != NULL)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <amd64/intr_defs.h>
|
#include <amd64/intr_defs.h>
|
||||||
#include <amd64/msr-index.h>
|
#include <amd64/msr-index.h>
|
||||||
#include <amd64/msr.h>
|
#include <amd64/msr.h>
|
||||||
|
#include <amd64/sse.h>
|
||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/partitions.h>
|
#include <device/partitions.h>
|
||||||
@@ -48,6 +49,8 @@ void bootmain (void) {
|
|||||||
pmm_init ();
|
pmm_init ();
|
||||||
mm_init ();
|
mm_init ();
|
||||||
|
|
||||||
|
sse_enable ();
|
||||||
|
|
||||||
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
||||||
|
|
||||||
ioapic_init ();
|
ioapic_init ();
|
||||||
|
|||||||
19
kernel/amd64/fx.h
Normal file
19
kernel/amd64/fx.h
Normal 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
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <amd64/apic.h>
|
#include <amd64/apic.h>
|
||||||
|
#include <amd64/fx.h>
|
||||||
#include <amd64/gdt.h>
|
#include <amd64/gdt.h>
|
||||||
#include <amd64/intr.h>
|
#include <amd64/intr.h>
|
||||||
#include <amd64/intr_defs.h>
|
#include <amd64/intr_defs.h>
|
||||||
@@ -161,7 +162,8 @@ static void intr_exception (struct saved_regs* regs) {
|
|||||||
regs->rbx);
|
regs->rbx);
|
||||||
|
|
||||||
if (regs->cs == (GDT_UCODE | 0x03)) {
|
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);
|
proc_kill (thiscpu->proc_current, &rctx);
|
||||||
|
|
||||||
bool do_thiscpu = false;
|
bool do_thiscpu = false;
|
||||||
@@ -196,6 +198,9 @@ void intr_handler (void* stack_ptr) {
|
|||||||
if (proc_current != NULL) {
|
if (proc_current != NULL) {
|
||||||
spin_lock (&proc_current->lock);
|
spin_lock (&proc_current->lock);
|
||||||
memcpy (&proc_current->pdata.regs, regs, sizeof (struct saved_regs));
|
memcpy (&proc_current->pdata.regs, regs, sizeof (struct saved_regs));
|
||||||
|
|
||||||
|
fx_save (proc_current->pdata.fx_env);
|
||||||
|
|
||||||
spin_unlock (&proc_current->lock);
|
spin_unlock (&proc_current->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +213,8 @@ void intr_handler (void* stack_ptr) {
|
|||||||
if (irq == NULL)
|
if (irq == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct reschedule_ctx rctx = {0};
|
struct reschedule_ctx rctx;
|
||||||
|
memset (&rctx, 0, sizeof (rctx));
|
||||||
irq->func (irq->arg, stack_ptr, &rctx);
|
irq->func (irq->arg, stack_ptr, &rctx);
|
||||||
|
|
||||||
bool do_thiscpu = false;
|
bool do_thiscpu = false;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <amd64/fx.h>
|
||||||
#include <amd64/gdt.h>
|
#include <amd64/gdt.h>
|
||||||
#include <amd64/proc.h>
|
#include <amd64/proc.h>
|
||||||
#include <aux/elf.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.rflags = 0x202;
|
||||||
proc->pdata.regs.cs = GDT_UCODE | 0x03;
|
proc->pdata.regs.cs = GDT_UCODE | 0x03;
|
||||||
proc->pdata.regs.rip = aux.entry;
|
proc->pdata.regs.rip = aux.entry;
|
||||||
|
fx_init (proc->pdata.fx_env);
|
||||||
|
|
||||||
proc->exec_pid = -1;
|
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.rflags = 0x202;
|
||||||
proc->pdata.regs.cs = GDT_UCODE | 0x03;
|
proc->pdata.regs.cs = GDT_UCODE | 0x03;
|
||||||
proc->pdata.regs.rip = (uint64_t)entry;
|
proc->pdata.regs.rip = (uint64_t)entry;
|
||||||
|
fx_init (proc->pdata.fx_env);
|
||||||
|
|
||||||
proc->uvaddr_argument = argument_ptr;
|
proc->uvaddr_argument = argument_ptr;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define _KERNEL_AMD64_PROC_H
|
#define _KERNEL_AMD64_PROC_H
|
||||||
|
|
||||||
#include <amd64/intr.h>
|
#include <amd64/intr.h>
|
||||||
|
#include <aux/compiler.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
/* Top of userspace process' stack */
|
/* Top of userspace process' stack */
|
||||||
@@ -17,6 +18,7 @@ struct proc_platformdata {
|
|||||||
uintptr_t kernel_stack;
|
uintptr_t kernel_stack;
|
||||||
uint64_t fs_base;
|
uint64_t fs_base;
|
||||||
uintptr_t tls_vaddr;
|
uintptr_t tls_vaddr;
|
||||||
|
uint8_t fx_env[512] ALIGNED (16);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_PROC_H
|
#endif // _KERNEL_AMD64_PROC_H
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
.global do_sched1
|
.global do_sched1
|
||||||
do_sched1:
|
do_sched1:
|
||||||
movq %rsi, %cr3
|
|
||||||
movq %rdi, %rsp
|
movq %rdi, %rsp
|
||||||
|
movq %rsi, %cr3
|
||||||
pop_regs
|
pop_regs
|
||||||
addq $16, %rsp
|
addq $16, %rsp
|
||||||
iretq
|
iretq
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
#include <amd64/fx.h>
|
||||||
#include <amd64/msr-index.h>
|
#include <amd64/msr-index.h>
|
||||||
#include <amd64/msr.h>
|
#include <amd64/msr.h>
|
||||||
#include <amd64/sched.h>
|
#include <amd64/sched.h>
|
||||||
|
#include <aux/compiler.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
#include <proc/proc.h>
|
#include <proc/proc.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
#include <sys/mm.h>
|
#include <sys/mm.h>
|
||||||
#include <sys/smp.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);
|
wrmsr (MSR_FS_BASE, proc->pdata.fs_base);
|
||||||
|
|
||||||
void* cr3 = (void*)proc->procgroup->pd.cr3_paddr;
|
void* cr3 = (void*)proc->procgroup->pd.cr3_paddr;
|
||||||
|
|
||||||
struct saved_regs regs;
|
struct saved_regs regs;
|
||||||
memcpy (®s, &proc->pdata.regs, sizeof (regs));
|
memcpy (®s, &proc->pdata.regs, sizeof (regs));
|
||||||
|
|
||||||
|
fx_restore (proc->pdata.fx_env);
|
||||||
|
|
||||||
spin_unlock (&proc->lock);
|
spin_unlock (&proc->lock);
|
||||||
spin_unlock (cpu_lock);
|
spin_unlock (cpu_lock);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <amd64/mm.h>
|
#include <amd64/mm.h>
|
||||||
#include <amd64/msr-index.h>
|
#include <amd64/msr-index.h>
|
||||||
#include <amd64/msr.h>
|
#include <amd64/msr.h>
|
||||||
|
#include <amd64/sse.h>
|
||||||
#include <fs/vfs.h>
|
#include <fs/vfs.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
@@ -93,6 +94,7 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) {
|
|||||||
gdt_init (cpu);
|
gdt_init (cpu);
|
||||||
idt_load ();
|
idt_load ();
|
||||||
syscall_init ();
|
syscall_init ();
|
||||||
|
sse_enable ();
|
||||||
|
|
||||||
lapic_init (1000);
|
lapic_init (1000);
|
||||||
|
|
||||||
@@ -100,7 +102,8 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) {
|
|||||||
|
|
||||||
atomic_fetch_sub (&cpu_counter, 1);
|
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);
|
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
|
||||||
proc_register (spin_proc, thiscpu, &rctx);
|
proc_register (spin_proc, thiscpu, &rctx);
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ c += amd64/bootmain.c \
|
|||||||
S += amd64/intr_stub.S \
|
S += amd64/intr_stub.S \
|
||||||
amd64/spin.S \
|
amd64/spin.S \
|
||||||
amd64/sched.S \
|
amd64/sched.S \
|
||||||
amd64/syscallentry.S
|
amd64/syscallentry.S \
|
||||||
|
amd64/sse.S
|
||||||
|
|
||||||
o += amd64/bootmain.o \
|
o += amd64/bootmain.o \
|
||||||
amd64/io.o \
|
amd64/io.o \
|
||||||
@@ -37,4 +38,5 @@ o += amd64/bootmain.o \
|
|||||||
amd64/proc.o \
|
amd64/proc.o \
|
||||||
amd64/syscall.o \
|
amd64/syscall.o \
|
||||||
amd64/syscallentry.o \
|
amd64/syscallentry.o \
|
||||||
amd64/gdt.o
|
amd64/gdt.o \
|
||||||
|
amd64/sse.o
|
||||||
|
|||||||
12
kernel/amd64/sse.S
Normal file
12
kernel/amd64/sse.S
Normal 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
6
kernel/amd64/sse.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _KERNEL_SSE_H
|
||||||
|
#define _KERNEL_SSE_H
|
||||||
|
|
||||||
|
void sse_enable (void);
|
||||||
|
|
||||||
|
#endif // _KERNEL_SSE_H
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <amd64/fx.h>
|
||||||
#include <amd64/gdt.h>
|
#include <amd64/gdt.h>
|
||||||
#include <amd64/intr.h>
|
#include <amd64/intr.h>
|
||||||
#include <amd64/mm.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));
|
memcpy (&caller->pdata.regs, regs, sizeof (struct saved_regs));
|
||||||
|
|
||||||
|
fx_save (caller->pdata.fx_env);
|
||||||
|
|
||||||
spin_unlock (&caller->lock);
|
spin_unlock (&caller->lock);
|
||||||
spin_unlock (&thiscpu->lock);
|
spin_unlock (&thiscpu->lock);
|
||||||
|
|
||||||
@@ -38,7 +41,8 @@ uintptr_t syscall_dispatch (void* stack_ptr) {
|
|||||||
return -ST_SYSCALL_NOT_FOUND;
|
return -ST_SYSCALL_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct reschedule_ctx rctx = {0};
|
struct reschedule_ctx rctx;
|
||||||
|
memset (&rctx, 0, sizeof (rctx));
|
||||||
|
|
||||||
uintptr_t r =
|
uintptr_t r =
|
||||||
func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9);
|
func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9);
|
||||||
|
|||||||
@@ -314,7 +314,8 @@ void proc_init (void) {
|
|||||||
irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED);
|
irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED);
|
||||||
#endif
|
#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);
|
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
|
||||||
proc_register (spin_proc, thiscpu, &rctx);
|
proc_register (spin_proc, thiscpu, &rctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user