mov $0x202, %r11 # EFLAGS
sysretq
+.globl load_tss
+load_tss:
+ mov $GDT.TSS, %ax
+ ltr %ax
+ ret
+
.globl syscall_64bit_handler
syscall_64bit_handler:
push %rcx
mov %r10, %rcx
- call syscall_64bit_handler_cpp
+ cmp $syscall_n, %rax
+ jae incorrect_syscall
+ callq *syscalls_call_table(, %rax, 8)
+ pop %rcx
+ sysretq
+incorrect_syscall:
+ call syscall_rax_error_handler
pop %rcx
sysretq
-.globl load_tss
-load_tss:
- mov $GDT.TSS, %ax
- ltr %ax
- ret
+.section .rodata
+syscalls_call_table:
+ .quad syscall_print
+ .quad syscall_println
+.set syscall_n, 2
tss.rsp0 = stack;
}
-extern "C" void syscall_64bit_handler();
-
void os::enable_syscalls() {
// Enable bit 0 (SYSCALL Enable) of msr IA32_EFER.
// This is required to enable syscall/sysret on x86_64 intel.
os::set_msr(0xC0000084, 0x00000000); // syscall flag mask, we don't want to change the flags for now.
}
-extern "C" void syscall_64bit_handler_cpp(std::uint64_t v) {
- os::printc((char)v);
+extern "C" void syscall_print(char v) {
+ os::printc(v);
+}
+
+extern "C" void syscall_println(char v) {
+ os::printc(v);
+ os::printc('\n');
+}
+
+extern "C" void syscall_rax_error_handler() {
+ os::assert(false, "Incorrect %rax for syscall.");
}
std::uint16_t iopb;
};
-void set_ring0_stack(tss& tss, std::uint64_t stack);
+extern "C" void ftl_to_userspace(void* program, std::byte* stack);
extern "C" void load_tss();
+extern "C" void syscall_64bit_handler();
+
+extern "C" void syscall_print(char c);
+extern "C" void syscall_println(char c);
+extern "C" void syscall_rax_error_handler();
+
+void set_ring0_stack(tss& tss, std::uint64_t stack);
void enable_syscalls();
-extern "C" void ftl_to_userspace(void* program, std::byte* stack);
} // namespace os
.globl print
print:
+ mov $0, %rax
syscall
ret