#include "./core_ring.h" #include "./core_interrupt.h" #include "./gdt.h" namespace Core { namespace Ring { [[gnu::noreturn]] void switchToUsermode(void *stackpointer, void *kickoff, void *kickoff_parameter) { (void)stackpointer; (void)kickoff; (void)kickoff_parameter; // Segment Selectors for Ring 3 constexpr uint16_t user_cs = 3 << 3 | 3; constexpr uint16_t user_ds = 4 << 3 | 3; asm volatile ( \ "mov %[user_data], %%ds \n" \ "mov %[user_data], %%es \n" \ "mov %[user_data], %%fs \n" \ "mov %[user_data], %%gs \n" \ "pushq %[user_data] \n" \ "pushq %[user_stack] \n" \ "pushq %[user_eflags] \n" \ "pushq %[user_code] \n" \ "pushq %[user_function] \n" \ "mov %[user_parameter], %%rdi\n" \ "iretq \n" \ : \ : [user_data] "r"((uint64_t)user_ds), [user_code] "r"((uint64_t)user_cs), [user_stack] "r"((uint64_t)stackpointer), [user_eflags] "r"((uint64_t)1<<9 | 2), // Interrupt Enable Flag [user_function] "r"((uint64_t)kickoff), [user_parameter] "r"((uint64_t)kickoff_parameter) \ : "memory", "rdi"\ ); __builtin_unreachable(); } } // namespace Ring } // namespace Core