diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2025-07-30 14:32:01 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2025-07-30 14:32:01 -0400 |
commit | b905869a35f062a4e5072f10bec3a2ba3db0e365 (patch) | |
tree | 0666691804878857b4bb07daca8a54f5ddb8ae0b /arch/x86_64/processor.c | |
download | jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.tar.gz jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.tar.bz2 jove-kernel-b905869a35f062a4e5072f10bec3a2ba3db0e365.zip |
working userland with some invoke syscalls
Diffstat (limited to 'arch/x86_64/processor.c')
-rw-r--r-- | arch/x86_64/processor.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/arch/x86_64/processor.c b/arch/x86_64/processor.c new file mode 100644 index 0000000..b39ba63 --- /dev/null +++ b/arch/x86_64/processor.c @@ -0,0 +1,126 @@ +#include "device/processor.h" +#include "arch/x86_64/tables.h" +#include "include/arch/x86_64/idt.h" +#include "include/arch/x86_64/object.h" +#include "jove.h" + +processor_t s_bsp = { + .odir = &_initDirectory +}; + +struct jove_ObjectDirectory s_processor_dir = { + .entries = { + [0] = { + .type = KO_OBJECT_DIRECTORY, + .data = 2 + }, + [1] = { + .type = KO_DEV_PROCESSOR, + .data = (uintptr_t)&s_bsp + } + } +}; + +char s_initial_response_buffer[256] = { 0 }; + +typedef union msr_efer +{ + struct { + uint8_t sce : 1; + uint8_t resv : 7; + uint8_t lme : 1; + uint8_t unk0 : 1; + uint8_t lma : 1; + uint8_t nxe : 1; + uint8_t svme : 1; + uint8_t lmsle : 1; + uint8_t ffxsr : 1; + uint8_t tce : 1; + }; + uint32_t v[2]; +} msr_efer_t; + +typedef union msr_star +{ + struct { + uint32_t eip; + uint16_t kcs; + uint16_t ucs; + }; + uint32_t v[2]; +} msr_star_t; + +typedef union msr_lstar +{ + uint32_t v[2]; + uintptr_t ip; +} msr_lstar_t; + +static void +s_enable_sce(void) +{ + msr_efer_t feat; + rdmsr(MSR_EFER, &feat.v[0], &feat.v[1]); + + feat.sce = 1; + wrmsr(MSR_EFER, feat.v[0], feat.v[1]); + + msr_star_t star; + star.kcs = GDT_ENTRY_KERNEL_CODE * sizeof(segment_descriptor_t); + star.ucs = GDT_ENTRY_USER_CODE * sizeof(segment_descriptor_t); + wrmsr(MSR_STAR, star.v[0], star.v[1]); + + extern void _syscall_entry(void); + msr_lstar_t lstar; + lstar.ip = (uintptr_t)_syscall_entry; + wrmsr(MSR_LSTAR, lstar.v[0], lstar.v[1]); +} + +void +processor_setup(void *_processor) +{ + processor_t *processor = (processor_t*)_processor; + gdt_setup(processor); + idt_setup(processor); + + wrmsr(MSR_GS_BASE, + (uint32_t)((uintptr_t)_processor & 0xFFFFFFFF), + (uint32_t)((uintptr_t)_processor >> 32)); +} + +void +bsp_setup(void) +{ + uint64_t pd_i = _initDirectory.self.data++; + + _initDirectory.entries[pd_i] = (objdir_entry_t) { + .type = KO_OBJECT_DIRECTORY, + .data = (uintptr_t)(&s_processor_dir) + }; + _initData.processor_dir = pd_i; + + ivt_setup(); + s_enable_sce(); + + processor_setup(&s_bsp); +} + +void +rdmsr(uint32_t msr, uint32_t *lo, uint32_t *hi) +{ + __asm__ volatile("rdmsr": "=a"(*lo), "=d"(*hi): "c"(msr)); +} + +void +wrmsr(uint32_t msr, uint32_t lo, uint32_t hi) +{ + __asm__ volatile("wrmsr":: "a"(lo), "d"(hi), "c"(msr)); +} + +void* +processor_current(void) +{ + uint64_t r = 0; + rdmsr(MSR_GS_BASE, (uint32_t*)&r, ((uint32_t*)&r) + 1); + return (void*)r; +} |