Architectural Support: x86_64 (#37)
[lunaix-os.git] / lunaix-os / arch / x86 / hart64.c
diff --git a/lunaix-os/arch/x86/hart64.c b/lunaix-os/arch/x86/hart64.c
new file mode 100644 (file)
index 0000000..af9da33
--- /dev/null
@@ -0,0 +1,44 @@
+#ifdef CONFIG_ARCH_X86_64
+
+#include <lunaix/process.h>
+#include <lunaix/hart_state.h>
+#include <lunaix/mm/vmm.h>
+#include <klibc/string.h>
+
+#include <sys/mm/mempart.h>
+#include <sys/abi.h>
+
+volatile struct x86_tss _tss = { };
+
+void
+hart_prepare_transition(struct hart_transition* ht, 
+                      ptr_t kstack_tp, ptr_t ustack_pt, 
+                      ptr_t entry, bool to_user) 
+{
+    ptr_t stack  = ustack_pt;
+    ptr_t offset = (ptr_t)&ht->transfer.eret - (ptr_t)&ht->transfer;
+    ht->inject = align_stack(kstack_tp - sizeof(ht->transfer));
+
+    ht->transfer.state = (struct hart_state){ 
+                            .registers = { },
+                            .execp = (struct exec_param*)(ht->inject + offset)
+                        };
+    
+    int code_seg = KCODE_SEG, data_seg = KDATA_SEG;
+    int mstate = cpu_ldstate();
+    if (to_user) {
+        code_seg = UCODE_SEG, data_seg = UDATA_SEG;
+        mstate |= 0x200;   // enable interrupt
+    }
+    else {
+        stack = kstack_tp;
+    }
+
+    ht->transfer.eret = (struct exec_param) {
+                            .cs = code_seg, .rip = entry, 
+                            .ss = data_seg, .rsp = align_stack(stack),
+                            .rflags = mstate
+                        };
+}
+
+#endif
\ No newline at end of file