os::paging::setup_page(PML4T, (void*)0xFFFF'C000'0000'0000, 1, 0); // The startup module.
+ bool module_specified = false;
for (auto it = multiboot2::next(info); it->type != multiboot2::info::type_t::end; it = multiboot2::next(it)) {
switch (it->type) {
case multiboot2::info::type_t::memory_map:
break;
case multiboot2::info::type_t::modules:
os::print("{}->{}: {}\n", multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it), multiboot2::modules_string(it));
- os::assert(!os::get_process(0).exists, "Multiple modules specified in the multiboot. This is unsupported.");
+ os::assert(!module_specified, "Multiple modules specified in the multiboot. This is unsupported.");
+ module_specified = true;
os::elf::load_elf(os::get_process(0),
(std::byte*)multiboot2::modules_mod_start(it),
multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it),
}
}
- os::assert(os::get_process(0).exists, "No modules specified in the multiboot. This is unsupported.");
+ os::assert(module_specified, "No modules specified in the multiboot. This is unsupported.");
// kernel_start and kernel_end are aligned to 4K by the linker script.
const os::phys_ptr<os::paging::page> kernel_s = ([]() {
.globl syscall_64bit_handler
syscall_64bit_handler:
- mov %rax, rax_save
- movq current_pid, %rax
- shl $17, %rax # * 0x1000 * 32 (i.e. the size of a process)
- addq process_struct_table, %rax
- # %rax now contains the address of the current process struct.
- movq %rcx, 0x10(%rax) # %rip
- movq %rbx, 0x18(%rax)
- movq %rsp, 0x20(%rax)
- movq %rbp, 0x28(%rax)
- movq %r12, 0x30(%rax)
- movq %r13, 0x38(%rax)
- movq %r14, 0x40(%rax)
- movq %r15, 0x48(%rax)
- fstcw 0x58(%rax)
- # Current process registers have now all been saved.
- mov rax_save, %rax
-
- mov %r10, %rcx
+ # Save all registers:
+ .irp reg,rax,rbx,rcx,rdx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15
+ mov %\reg, save_reg_tmp_\reg
+ .endr
+ # Setup stack:
+ mov $stack_top, %rsp
+ # Get process data location:
+ mov current_pid, %rdi
+ call get_process
+ # Really save all regs:
+ .irp reg,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+ mov save_regs_tmp + \reg * 8, %rbx # Get %r\reg
+ mov %rbx, 8 + \reg * 8(%rax) # And store it.
+ .endr
+ mov save_reg_tmp_rcx, %rbx # Save the rip also.
+ mov %rbx, 0x88(%rax)
+ # Get ready for syscall:
+ mov save_reg_tmp_rdi, %rdi
+ mov save_reg_tmp_rsi, %rsi
+ mov save_reg_tmp_rdx, %rdx
+ mov save_reg_tmp_r10, %rcx # Syscall ABI -> C ABI
+ mov save_reg_tmp_r8, %r8
+ mov save_reg_tmp_r9, %r9
+ mov save_reg_tmp_rax, %rax
cmp $syscall_n, %rax
- mov $stack_top, %rsp # Setup stack
jae incorrect_syscall
callq *syscalls_call_table(, %rax, 8)
syscall_end:
- mov %rax, rax_save
- movq current_pid, %rax
- shl $17, %rax # * 0x1000 * 32 (i.e. the size of a process)
- addq process_struct_table, %rax
- # %rax now contains the address of the current process struct.
- movq 0x10(%rax), %rcx # %rip
- movq 0x18(%rax), %rbx
- movq 0x20(%rax), %rsp
- movq 0x28(%rax), %rbp
- movq 0x30(%rax), %r12
- movq 0x38(%rax), %r13
- movq 0x40(%rax), %r14
- movq 0x48(%rax), %r15
- fldcw 0x58(%rax)
- # Current process registers have now all been loaded.
- mov rax_save, %rax
+ mov %rax, %rbp # Save the return
+ mov %rdx, %rbx # registers.
+ # Get process data location:
+ mov current_pid, %rdi
+ call get_process
+ # Restore all regs:
+ .irp reg,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+ mov 8 + \reg * 8(%rax), %rbx # Get %r\reg
+ mov %rbx, save_regs_tmp + \reg * 8 # And restore it.
+ .endr
+ mov %rbp, save_reg_tmp_rax # Restore the return
+ mov %rbx, save_reg_tmp_rdx # registers as well.
+ mov 0x88(%rax), %rbx # Save the rip in place of rcx, because this is sysret.
+ mov %rbx, save_reg_tmp_rcx
+ # Really restore all regs:
+ .irp reg,rax,rbx,rcx,rdx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15
+ mov save_reg_tmp_\reg, %\reg
+ .endr
+ # Current process registers have now all been restored.
sysretq
incorrect_syscall:
call syscall_rax_error_handler
process_struct_table: .quad 0xFFFFC00000000000
.section .data
-rax_save: .quad 1
+save_regs_tmp:
+save_reg_tmp_rax: .quad 1
+save_reg_tmp_rbx: .quad 1
+save_reg_tmp_rcx: .quad 1
+save_reg_tmp_rdx: .quad 1
+save_reg_tmp_rsp: .quad 1
+save_reg_tmp_rbp: .quad 1
+save_reg_tmp_rsi: .quad 1
+save_reg_tmp_rdi: .quad 1
+save_reg_tmp_r8: .quad 1
+save_reg_tmp_r9: .quad 1
+save_reg_tmp_r10: .quad 1
+save_reg_tmp_r11: .quad 1
+save_reg_tmp_r12: .quad 1
+save_reg_tmp_r13: .quad 1
+save_reg_tmp_r14: .quad 1
+save_reg_tmp_r15: .quad 1