46 lines
1.3 KiB
C++
46 lines
1.3 KiB
C++
#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
|