diff options
Diffstat (limited to 'kernel/syscall.cpp')
-rw-r--r-- | kernel/syscall.cpp | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp deleted file mode 100644 index e194eb1..0000000 --- a/kernel/syscall.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include <hilbert/kernel/application.hpp> -#include <hilbert/kernel/framebuffer.hpp> -#include <hilbert/kernel/paging.hpp> -#include <hilbert/kernel/input.hpp> -#include <hilbert/kernel/vfile.hpp> - -namespace hilbert::kernel::syscall { - - enum file_result : uint64_t { - file_result_success, - file_result_bad_file_handle, - file_result_device_error, - file_result_file_system_corrupt, - file_result_out_of_bounds, - file_result_does_not_exist, - file_result_directory - }; - - bool is_range_owned_by_application(uint64_t start, uint64_t end) { - auto *app = application::running_app; - uint64_t pstart = (start / 4096) * 4096; - uint64_t pend = ((end - 1) / 4096 + 1) * 4096; - for (uint64_t p = pstart; p < pend; p += 4096) - if (!app->is_page_owned(p)) - return false; - return true; - } - - void set_zero(uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx) { - rax = 0; - rdi = 0; - rsi = 0; - rdx = 0; - } - - void encode_color_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - rax = (uint64_t)framebuffer::encode_color( - rdi & 0xff, (rdi >> 8) & 0xff, (rdi >> 16) & 0xff); - rdi = 0; - rsi = 0; - rdx = 0; - } - - void get_framebuffer_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - auto *app = application::running_app; - if (app->framebuffer_vaddr == 0) { - uint64_t pages_needed = - (framebuffer::dword_pitch * framebuffer::height * 4 - 1) / 4096 + 1; - uint64_t vaddr = app->get_free_vaddr_pages(pages_needed); - for (uint64_t i = 0; i < pages_needed; ++i) - app->map_page( - vaddr + i * 4096, framebuffer::paddr + i * 4096, true, false, false); - app->framebuffer_vaddr = vaddr; - } - - rax = app->framebuffer_vaddr; - rdi = - (uint64_t)(uint32_t)framebuffer::width | - ((uint64_t)(uint32_t)framebuffer::height << 32); - rsi = (uint32_t)framebuffer::dword_pitch; - rdx = 0; - - } - - void open_file_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - if (!is_range_owned_by_application(rdi, rdi + rsi)) { - set_zero(rax, rdi, rsi, rdx); - return; - } - - utility::string path((const char *)rdi, rsi); - vfile::canon_path cp; - vfile::canonize_path(path, cp); - - set_zero(rax, rdi, rsi, rdx); - - vfile::vfile file; - switch (vfile::lookup_path(cp, file, true)) { - case storage::fs_result::success: - break; - case storage::fs_result::device_error: - rax = file_result_device_error; - return; - case storage::fs_result::fs_corrupt: - rax = file_result_file_system_corrupt; - return; - case storage::fs_result::does_not_exist: - rax = file_result_does_not_exist; - return; - } - - if (file.dir_entry.type != storage::file_type::regular_file) { - rax = file_result_directory; - return; - } - - unsigned handler = - application::running_app->open_files.add_new(utility::move(file)); - rax = file_result_success; - rdi = (uint64_t)handler; - - } - - void get_file_length_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - auto &open_files = application::running_app->open_files; - unsigned handle = (unsigned)rdi; - - set_zero(rax, rdi, rsi, rdx); - - if (!open_files.has_id(handle)) { - rax = file_result_bad_file_handle; - return; - } - - rax = file_result_success; - rdi = open_files.get(handle).dir_entry.length; - - } - - void read_from_file_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - if (!is_range_owned_by_application(rdi, rdi + 32)) { - set_zero(rax, rdi, rsi, rdx); - return; - } - - const uint64_t *request = (const uint64_t *)rdi; - unsigned handle = (unsigned)request[0]; - uint64_t start = request[1]; - uint64_t length = request[2]; - uint64_t buffer_vaddr = request[3]; - - set_zero(rax, rdi, rsi, rdx); - - if (!is_range_owned_by_application(buffer_vaddr, buffer_vaddr + length)) - return; - - auto &open_files = application::running_app->open_files; - - if (!open_files.has_id(handle)) - rax = file_result_bad_file_handle; - - vfile::vfile &file = open_files.get(handle); - - if (start + length > file.dir_entry.length) - rax = file_result_out_of_bounds; - - switch (file.read_file(start, length, (void *)buffer_vaddr)) { - case storage::fs_result::success: - rax = file_result_success; - return; - case storage::fs_result::device_error: - rax = file_result_device_error; - return; - case storage::fs_result::fs_corrupt: - case storage::fs_result::does_not_exist: - rax = file_result_file_system_corrupt; - return; - } - - } - - [[noreturn]] void end_this_process_syscall( - uint64_t &, uint64_t &, uint64_t &, uint64_t & - ) { - - //TODO - while (1) - ; - - } - - void get_new_pages_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - uint64_t count = rdi; - set_zero(rax, rdi, rsi, rdx); - - auto *app = application::running_app; - uint64_t vaddr = app->get_free_vaddr_pages(count); - - for (uint64_t i = 0; i < count; ++i) { - uint64_t paddr = paging::take_pram_page(); - app->map_page(vaddr + i * 4096, paddr, true, false, true); - } - - rax = vaddr; - - } - - void close_file_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - unsigned handle = rdi; - set_zero(rax, rdi, rsi, rdx); - application::running_app->open_files.remove_id(handle); - - } - - void read_key_packet_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx - ) { - - set_zero(rax, rdi, rsi, rdx); - - asm ("cli"); - - while (input::key_queue->count == 0) - asm ("sti\nhlt\ncli"); - - rax = (uint64_t)input::key_queue->take(); - - asm ("sti"); - - } - - typedef void (*syscall_handler)( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx); - - syscall_handler handlers[] = { - &encode_color_syscall, - &get_framebuffer_syscall, - &open_file_syscall, - &get_file_length_syscall, - &read_from_file_syscall, - &end_this_process_syscall, - &get_new_pages_syscall, - &close_file_syscall, - &read_key_packet_syscall - }; - - static constexpr int max_syscall_number = 8; - -} - -using namespace hilbert::kernel::syscall; - -extern "C" void do_syscall( - uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx -) { - - if (rax <= max_syscall_number && handlers[rax] != 0) - handlers[rax](rax, rdi, rsi, rdx); - else - set_zero(rax, rdi, rsi, rdx); - -} |