summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/processor.c
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-07-30 14:32:01 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-07-30 14:32:01 -0400
commitb905869a35f062a4e5072f10bec3a2ba3db0e365 (patch)
tree0666691804878857b4bb07daca8a54f5ddb8ae0b /arch/x86_64/processor.c
downloadjove-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.c126
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;
+}