mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ _start:
|
||||
mov rbp, rsp
|
||||
|
||||
mov rdi, rsp
|
||||
sub rdi, 8
|
||||
call _init_libc
|
||||
|
||||
mov rdi, 0
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
3
src/kernel/objects/system.cpp
Normal file
3
src/kernel/objects/system.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "objects/system.h"
|
||||
|
||||
system system::s_instance;
|
||||
18
src/kernel/objects/system.h
Normal file
18
src/kernel/objects/system.h
Normal file
@@ -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) {}
|
||||
};
|
||||
@@ -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<j6_process_init*>(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 *
|
||||
|
||||
@@ -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<endpoint>(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
|
||||
|
||||
@@ -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<endpoint>(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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user