#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 enable_fpu(void); void enable_sse(void); void enable_avx(void); void bsp_setup(void) { #ifdef ENABLE_SSE enable_fpu(); enable_sse(); #endif #ifdef ENABLE_AVX enable_avx(); #endif _initDirectory.entries[INIT_OBJECT_PROCESSOR_DIR] = (objdir_entry_t) { .type = KO_OBJECT_DIRECTORY, .data = (uintptr_t)(&s_processor_dir) }; 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; }