refactor (syscalls): improved syscall handling infrastructure
This commit is contained in:
parent
d9c3b4060b
commit
af95bd2ba1
|
@ -7,11 +7,11 @@
|
|||
#include "utils/status.h"
|
||||
|
||||
typedef enum {
|
||||
SYSCALLS_FILES = 0x00,
|
||||
SYSCALLS_MEMORY = 0x01,
|
||||
SYSCALLS_PROC = 0x02,
|
||||
SYSCALLS_RUNTIME_LINKER = 0x02,
|
||||
SYSCALLS_COMPATABILITY = 0x02,
|
||||
SYSCALLS_FILES = 0x01,
|
||||
SYSCALLS_MEMORY = 0x02,
|
||||
SYSCALLS_PROC = 0x03,
|
||||
SYSCALLS_RUNTIME_LINKER = 0x04,
|
||||
SYSCALLS_COMPATABILITY = 0x05,
|
||||
|
||||
SYSCALLS_KERNEL = 0xFF
|
||||
}syscall_group_E;
|
||||
|
|
|
@ -6,55 +6,84 @@
|
|||
#include "proc/scheduler.h"
|
||||
#include "drivers/fs/vfs.h"
|
||||
|
||||
void syscall_handle_nx_fopen(cpu_state_T* state) {
|
||||
// read arguments
|
||||
uint64_t arg1 = state->rdi;
|
||||
|
||||
vfs_node_T *node = vfs_resolve_path(&g_root_fs, (string_t) arg1);
|
||||
if (node == NULL) {
|
||||
state->rax = STATUS_RESOURCE_NOT_AVAILABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG, "resolved file '%s' -> 0x%x", arg1, node);
|
||||
}
|
||||
|
||||
|
||||
cpu_state_T* syscall_handle(cpu_state_T* state) {
|
||||
cpu_state_T* return_state = state;
|
||||
syscall_group_E group_id = (state->rax & 0xFF00) >> 8;
|
||||
|
||||
if (group_id == SYSCALLS_KERNEL &&
|
||||
scheduler_is_initialized() &&
|
||||
scheduler_get_current_process()->id != PROCESS_KERNEL)
|
||||
{
|
||||
log(LOG_WARNING, "non kernel process[%d:%d] tried to perform a kernel syscall (permission denied)", scheduler_get_current_process(), scheduler_get_current_thread());
|
||||
return return_state;
|
||||
}
|
||||
|
||||
// read arguments
|
||||
uint64_t arg1 = state->rdi;
|
||||
uint64_t arg2 = state->rsi;
|
||||
uint64_t arg3 = state->rdx;
|
||||
uint64_t arg4 = state->rcx;
|
||||
uint64_t ret = STATUS_SUCCESS;
|
||||
|
||||
switch (group_id) {
|
||||
case SYSCALLS_FILES: {
|
||||
|
||||
switch (state->rax) {
|
||||
case SYSCALL_FILES_OPEN: {
|
||||
vfs_node_T* node = vfs_resolve_path(&g_root_fs, (string_t)arg1);
|
||||
if (node == NULL) {
|
||||
ret = STATUS_RESOURCE_NOT_AVAILABLE;
|
||||
syscall_handle_nx_fopen(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG, "resolved file '%s' -> 0x%x", arg1, node);
|
||||
|
||||
case SYSCALLS_MEMORY: {
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALLS_PROC: {
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALLS_RUNTIME_LINKER: {
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALLS_COMPATABILITY: {
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALLS_KERNEL: {
|
||||
|
||||
// check if the current Process is permitted to perform a kernel syscall
|
||||
if (scheduler_is_initialized() &&
|
||||
scheduler_get_current_process()->id != PROCESS_KERNEL)
|
||||
{
|
||||
log(LOG_WARNING, "non kernel process[%d:%d] tried to perform a kernel syscall (permission denied)", scheduler_get_current_process(), scheduler_get_current_thread());
|
||||
state->rax = STATUS_PERMISSION_DENIED;
|
||||
return return_state;
|
||||
}
|
||||
|
||||
switch (state->rax) {
|
||||
case SYSCALL_KERNEL_SCHEDULER_START: {
|
||||
return_state = scheduler_start(state);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_KERNEL_PANIC: {
|
||||
panic(state, (string_t)arg1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
log(LOG_WARNING, "unhandled syscall: 0x%xw", state->rax);
|
||||
log(LOG_WARNING, "unknown syscall group: 0x%xb", group_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// apply return value
|
||||
state->rax = ret;
|
||||
|
||||
return return_state;
|
||||
}
|
Loading…
Reference in New Issue