From 8bb9e222183376015c6189e05e9c8a4bbdb7b28b Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 18 Oct 2020 20:45:06 -0700 Subject: [PATCH] [kernel] Move bind_irq syscall to new system object In order to implement capabilities on system resources like IRQs so that they may be restricted to drivers only, add a new 'system' kobject type, and move the bind_irq functionality from endpoint to system. Also fix some stack bugs passing the initial handles to a program. --- modules.yaml | 1 + src/drivers/nulldrv/main.cpp | 12 +++++++----- src/drivers/nulldrv/main.s | 1 - src/include/j6/types.h | 10 ++++++++-- src/include/syscalls.inc | 3 ++- src/kernel/device_manager.cpp | 3 +++ src/kernel/loader.s | 3 +++ src/kernel/objects/kobject.h | 4 +++- src/kernel/objects/system.cpp | 3 +++ src/kernel/objects/system.h | 18 ++++++++++++++++++ src/kernel/scheduler.cpp | 12 ++++++++---- src/kernel/syscalls/endpoint.cpp | 12 ------------ src/kernel/syscalls/system.cpp | 22 ++++++++++++++++++++++ src/libraries/libc/arch/x86_64/_Exit.s | 4 ++-- 14 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 src/kernel/objects/system.cpp create mode 100644 src/kernel/objects/system.h diff --git a/modules.yaml b/modules.yaml index 2d227c3..5c7f6b1 100644 --- a/modules.yaml +++ b/modules.yaml @@ -39,6 +39,7 @@ modules: - src/kernel/objects/kobject.cpp - src/kernel/objects/thread.cpp - src/kernel/objects/process.cpp + - src/kernel/objects/system.cpp - src/kernel/objects/vm_area.cpp - src/kernel/page_table.cpp - src/kernel/pci.cpp diff --git a/src/drivers/nulldrv/main.cpp b/src/drivers/nulldrv/main.cpp index d778bbe..a239eb4 100644 --- a/src/drivers/nulldrv/main.cpp +++ b/src/drivers/nulldrv/main.cpp @@ -11,10 +11,9 @@ #include "serial.h" char inbuf[1024]; +j6_handle_t sys = j6_handle_invalid; j6_handle_t endp = j6_handle_invalid; -j6_process_init *init = nullptr; - extern "C" { void _init_libc(j6_process_init *); int main(int, const char **); @@ -53,9 +52,9 @@ thread_proc() } void -_init_libc(j6_process_init *i) +_init_libc(j6_process_init *init) { - init = i; + sys = init->handles[0]; } int @@ -98,6 +97,10 @@ main(int argc, const char **argv) if (tag != 17) _syscall_system_log("GOT WRONG TAG FROM SENDRECV"); + result = _syscall_system_bind_irq(sys, endp, 3); + if (result != j6_status_ok) + return result; + _syscall_system_log(message); _syscall_system_log("main thread waiting on child"); @@ -108,7 +111,6 @@ main(int argc, const char **argv) _syscall_system_log("main testing irqs"); - _syscall_endpoint_bind_irq(endp, 3); serial_port com2(COM2); diff --git a/src/drivers/nulldrv/main.s b/src/drivers/nulldrv/main.s index 07ffdfe..e79154b 100644 --- a/src/drivers/nulldrv/main.s +++ b/src/drivers/nulldrv/main.s @@ -13,7 +13,6 @@ _start: mov rbp, rsp mov rdi, rsp - sub rdi, 8 call _init_libc mov rdi, 0 diff --git a/src/include/j6/types.h b/src/include/j6/types.h index 73890af..15d762c 100644 --- a/src/include/j6/types.h +++ b/src/include/j6/types.h @@ -38,6 +38,12 @@ typedef uint64_t j6_handle_t; /// A process' initial data structure for communicating with the system struct j6_process_init { - j6_handle_t input; - j6_handle_t output; + j6_handle_t process; + j6_handle_t handles[3]; +}; + +/// A thread's initial data structure +struct j6_thread_init +{ + j6_handle_t thread; }; diff --git a/src/include/syscalls.inc b/src/include/syscalls.inc index d483835..4cd636f 100644 --- a/src/include/syscalls.inc +++ b/src/include/syscalls.inc @@ -1,5 +1,7 @@ SYSCALL(0x00, system_log, const char *) SYSCALL(0x01, system_noop, void) +SYSCALL(0x02, system_get_log, j6_handle_t, j6_handle_t *) +SYSCALL(0x03, system_bind_irq, j6_handle_t, j6_handle_t, unsigned) SYSCALL(0x08, object_koid, j6_handle_t, j6_koid_t *) SYSCALL(0x09, object_wait, j6_handle_t, j6_signal_t, j6_signal_t *) @@ -21,7 +23,6 @@ SYSCALL(0x28, endpoint_create, j6_handle_t *) SYSCALL(0x29, endpoint_send, j6_handle_t, j6_tag_t, size_t, void *) SYSCALL(0x2a, endpoint_receive, j6_handle_t, j6_tag_t *, size_t *, void *) SYSCALL(0x2b, endpoint_sendrecv, j6_handle_t, j6_tag_t *, size_t *, void *) -SYSCALL(0x2c, endpoint_bind_irq, j6_handle_t, unsigned) SYSCALL(0x30, vma_create, j6_handle_t *, size_t, uint32_t) SYSCALL(0x31, vma_create_map, j6_handle_t *, size_t, uintptr_t, uint32_t) diff --git a/src/kernel/device_manager.cpp b/src/kernel/device_manager.cpp index 530bd7a..6d611c4 100644 --- a/src/kernel/device_manager.cpp +++ b/src/kernel/device_manager.cpp @@ -67,6 +67,9 @@ device_manager::device_manager() : { m_irqs.ensure_capacity(32); m_irqs.set_size(16); + for (int i = 0; i < 16; ++i) + m_irqs[i] = nullptr; + m_irqs[2] = ignore_endpoint; } diff --git a/src/kernel/loader.s b/src/kernel/loader.s index 761231d..07c31e0 100644 --- a/src/kernel/loader.s +++ b/src/kernel/loader.s @@ -15,6 +15,9 @@ preloaded_process_init: call load_process_image + ; user rsp is now in rax, put it in the right place for iret + mov [rsp + 0x18], rax + ; the entrypoint should already be on the stack swapgs iretq diff --git a/src/kernel/objects/kobject.h b/src/kernel/objects/kobject.h index 852a741..63843fc 100644 --- a/src/kernel/objects/kobject.h +++ b/src/kernel/objects/kobject.h @@ -17,6 +17,7 @@ public: enum class type : uint16_t { none, + system, event, channel, @@ -24,9 +25,10 @@ public: vma, - job, process, thread, + + max }; kobject(type t, j6_signal_t signals = 0ull); diff --git a/src/kernel/objects/system.cpp b/src/kernel/objects/system.cpp new file mode 100644 index 0000000..54c09f2 --- /dev/null +++ b/src/kernel/objects/system.cpp @@ -0,0 +1,3 @@ +#include "objects/system.h" + +system system::s_instance; diff --git a/src/kernel/objects/system.h b/src/kernel/objects/system.h new file mode 100644 index 0000000..1491776 --- /dev/null +++ b/src/kernel/objects/system.h @@ -0,0 +1,18 @@ +#pragma once +/// \file system.h +/// Definition of kobject type representing the system + +#include "objects/kobject.h" + +class system : + public kobject +{ +public: + static constexpr kobject::type type = kobject::type::event; + + inline static system * get() { return &s_instance; } + +private: + static system s_instance; + system() : kobject(type::system) {} +}; diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index e870bcc..a11e692 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -13,6 +13,7 @@ #include "msr.h" #include "objects/channel.h" #include "objects/process.h" +#include "objects/system.h" #include "objects/vm_area.h" #include "scheduler.h" @@ -26,7 +27,7 @@ const uint64_t rflags_int = 0x202; extern "C" { void preloaded_process_init(); - void load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb); + uintptr_t load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb); }; extern uint64_t idle_stack_end; @@ -59,7 +60,7 @@ scheduler::scheduler(lapic *apic) : bsp_cpu_data.t = idle; } -void +uintptr_t load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb) { using memory::page_align_down; @@ -81,10 +82,13 @@ load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb) tcb->rsp3 -= sizeof(j6_process_init); j6_process_init *init = reinterpret_cast(tcb->rsp3); - extern channel *std_out; - init->output = proc.add_handle(std_out); + init->process = proc.add_handle(&proc); + init->handles[0] = proc.add_handle(system::get()); + init->handles[1] = j6_handle_invalid; + init->handles[2] = j6_handle_invalid; thread::current().clear_state(thread::state::loading); + return tcb->rsp3; } thread * diff --git a/src/kernel/syscalls/endpoint.cpp b/src/kernel/syscalls/endpoint.cpp index 6f83bc5..3b5e59c 100644 --- a/src/kernel/syscalls/endpoint.cpp +++ b/src/kernel/syscalls/endpoint.cpp @@ -55,16 +55,4 @@ endpoint_sendrecv(j6_handle_t handle, j6_tag_t *tag, size_t *len, void *data) return e->receive(tag, len, data); } -j6_status_t -endpoint_bind_irq(j6_handle_t handle, unsigned irq) -{ - endpoint *e = get_handle(handle); - if (!e) return j6_err_invalid_arg; - - if (device_manager::get().bind_irq(irq, e)) - return j6_status_ok; - - return j6_err_invalid_arg; -} - } // namespace syscalls diff --git a/src/kernel/syscalls/system.cpp b/src/kernel/syscalls/system.cpp index bd832c0..9730121 100644 --- a/src/kernel/syscalls/system.cpp +++ b/src/kernel/syscalls/system.cpp @@ -1,8 +1,11 @@ #include "j6/errors.h" #include "j6/types.h" +#include "device_manager.h" #include "log.h" +#include "objects/endpoint.h" #include "objects/thread.h" +#include "syscalls/helpers.h" namespace syscalls { @@ -25,4 +28,23 @@ system_noop() return j6_status_ok; } +j6_status_t +system_get_log(j6_handle_t sys, j6_handle_t *log) +{ + return j6_err_nyi; +} + +j6_status_t +system_bind_irq(j6_handle_t sys, j6_handle_t endp, unsigned irq) +{ + // TODO: check capabilities on sys handle + endpoint *e = get_handle(endp); + if (!e) return j6_err_invalid_arg; + + if (device_manager::get().bind_irq(irq, e)) + return j6_status_ok; + + return j6_err_invalid_arg; +} + } // namespace syscalls diff --git a/src/libraries/libc/arch/x86_64/_Exit.s b/src/libraries/libc/arch/x86_64/_Exit.s index da96a5c..995783b 100644 --- a/src/libraries/libc/arch/x86_64/_Exit.s +++ b/src/libraries/libc/arch/x86_64/_Exit.s @@ -1,5 +1,5 @@ +extern _syscall_process_exit global _PDCLIB_Exit _PDCLIB_Exit: ; arg should already be in rdi - mov rax, 0x11 ; Exit syscall - syscall + jmp _syscall_process_exit