diff --git a/inc/drivers/builtin/json.h b/inc/drivers/builtin/json.h index af1d385..c08bbbb 100644 --- a/inc/drivers/builtin/json.h +++ b/inc/drivers/builtin/json.h @@ -82,16 +82,18 @@ typedef struct { json_node_T* root_node; } json_T; -json_T* json_from_string (string_t str); -void json_destruct (json_T* json); -json_node_T* json_node_alloc (json_node_T* parent, json_node_type_E type, json_token_T* token); -void json_node_destruct (json_node_T* node); -void json_node_dump (json_node_T* node, uint32_t indent); -string_t json_node_type_to_string (json_node_type_E type); -void json_tokenize (json_T* json, string_t str); -bool json_parse (json_T* json); -bool json_parse_assignment (json_T* json, uint32_t* token_id, json_node_T* node); -bool json_parse_object (json_T* json, uint32_t* token_id, json_node_T* node); -bool json_parse_array (json_T* json, uint32_t* token_id, json_node_T* node); +json_T * json_from_string (string_t str); +void json_destruct (json_T* json); +json_node_T * json_node_alloc (json_node_T* parent, json_node_type_E type, json_token_T* token); +void json_node_destruct (json_node_T* node); +void json_node_dump (json_node_T* node, uint32_t indent); +string_t json_node_type_to_string (json_node_type_E type); +void json_tokenize (json_T* json, string_t str); +bool json_parse (json_T* json); +bool json_parse_assignment (json_T* json, uint32_t* token_id, json_node_T* node); +bool json_parse_object (json_T* json, uint32_t* token_id, json_node_T* node); +bool json_parse_array (json_T* json, uint32_t* token_id, json_node_T* node); +json_node_T * json_resolve_path (json_node_T *base, char *path); #endif //NOXOS_JSON_H + diff --git a/inc/drivers/device_manager.h b/inc/drivers/device_manager.h new file mode 100644 index 0000000..b8a0339 --- /dev/null +++ b/inc/drivers/device_manager.h @@ -0,0 +1,79 @@ + +#ifndef NOXOS_DEVICE_H +#define NOXOS_DEVICE_H + +#include +#include + + +typedef enum { + + DEVICE_PCI = 1, + DEVICE_USB = 2, + DEVICE_VIRTUAL = 255 + +} device_category_E; + +typedef enum { + + DEVICE_CAPABILITY_TRANSMISSION, + DEVICE_CAPABILITY_STORAGE, + DEVICE_CAPABILITY_GRAPHICS, + DEVICE_CAPABILITY_AUDIO + +} device_top_level_capability_E; + +typedef struct device_capabilities_t { + + device_top_level_capability_E *top_level; + + struct device_transmission_capability_t { + // TODO + } transmission; + + struct device_storage_capability_t { + char uuid[32]; + uint64_t size; + } storage; + + struct device_graphics_capability_t { + uint32_t fb_width; + uint32_t fb_height; + uint16_t bits_per_pixel; + } graphics; + + struct device_audio_capability_t { + // TODO + } audio; + +} device_capabilities_T; + +typedef struct device_t { + + uint32_t id; + device_category_E category; + void *specific; + + driver_T *driver; + +} device_T; + + + +typedef struct device_manager_t { + + uint32_t num_devices; + device_T *devices; + +} device_manager_T; + +extern device_manager_T g_device_manager; + + + +void device_manager_init (); +void device_remove (device_T *device); +device_T * device_find (device_capabilities_T capabilities, uint32_t index, uint32_t *out_count); + +#endif + diff --git a/inc/drivers/driver_manager.h b/inc/drivers/driver_manager.h new file mode 100644 index 0000000..576ed39 --- /dev/null +++ b/inc/drivers/driver_manager.h @@ -0,0 +1,117 @@ + +#ifndef NOXOS_DRIVER_H +#define NOXOS_DRIVER_H + +#include "utils/stdtypes.h" + +#define DRIVER_COMMAND_SIZE 32 + +typedef enum { + + DRIVER_UNKNOWN = 0x0000, + DRIVER_RESERVED = 0x0001, + + // Specific Driver + + DRIVER_MASS_STORAGE = 0x0101, + DRIVER_FILESYSTEM = 0x0102, + DRIVER_GRAPHICS = 0x0103, + DRIVER_AUDIO = 0x0104, + + // Drivers which define the transmission of data but have multiple + // intended usages, such as USB for mass storage, input, etc.. + + DRIVER_TRANSMISSION = 0x0201, + DRIVER_USB_DEVICE = 0x0202, + DRIVER_PCI_DEVICE = 0x0203, + DRIVER_PCIE_DEVICE = 0x0204, + DRIVER_NVME_DEVICE = 0x0205, + DRIVER_BLUETOOTH = 0x0206, + DRIVER_ETHERNET = 0x0207, + + // MISCELLANEOUS + + DRIVER_EMULATION = 0x7fff + +} driver_category_E; + +typedef struct driver_mass_storage_t { + + + +} driver_mass_storage_T; + + + +typedef struct driver_configuration_t +{ + uint16_t category; + uint16_t max_command_buffers; + + uint16_t category_dependencies[16]; + + uint8_t reserved[220]; + +} driver_configuration_T; + + + +typedef struct driver_command_buffer_config_t +{ + uint64_t num_commands; + void *mapping_address; + + uint8_t reserved[240]; + +} driver_command_buffer_config_T; + +typedef struct driver_command_buffer_t +{ + uint64_t command_capacity; + void *mapping_address; + +} driver_command_buffer_T; + +typedef struct driver_t // TODO: Accesses must be thread-safe +{ + driver_category_E category; + uint32_t id; + + uint16_t max_command_buffers; + driver_command_buffer_T *command_buffers; + +} driver_T; + + + +typedef struct driver_manager_t { + + uint32_t max_drivers; + uint32_t num_drivers; + driver_T *drivers; + +} driver_manager_T; + +extern driver_manager_T g_driver_manager; + + + +void driver_manager_init (); +void driver_manager_load_single_driver (char *driver_config_path); +void driver_manager_load_drivers (char *main_config_path); + +uint32_t driver_manager_register_driver (driver_configuration_T *configuration); +driver_T * driver_manager_resolve_driver_id (uint32_t id); + +// driver_add_command_buffer: Adds a command buffer to the 'command_buffers'-array in the given driver. +void driver_add_command_buffer (driver_T *driver, driver_command_buffer_config_T *configuration); + +// driver_flush_command_buffer: Flushes the command buffer that 'buffer' points to, +// meaning that it executes all commands stored in it. 'buffer' doesn't need to be the first +// byte; the function will execute from the first command in a buffer even if some byte in the +// middle of the buffer is given into this function. +void driver_flush_command_buffer (driver_T *driver, void *buffer); + + +#endif + diff --git a/inc/platform/syscall.h b/inc/platform/syscall.h index 5468902..8ea0ff7 100644 --- a/inc/platform/syscall.h +++ b/inc/platform/syscall.h @@ -7,9 +7,10 @@ #include "utils/status.h" typedef enum { - SYSCALLS_FILES = 0x01, - SYSCALLS_MEMORY = 0x02, - SYSCALLS_PROC = 0x03, + SYSCALLS_FILES = 0x00, + SYSCALLS_MEMORY = 0x01, + SYSCALLS_PROCESS = 0x02, + SYSCALLS_DRIVER = 0x03, SYSCALLS_RUNTIME_LINKER = 0x04, SYSCALLS_COMPATABILITY = 0x05, @@ -17,40 +18,44 @@ typedef enum { }syscall_group_E; typedef enum { - SYSCALL_FILES_OPEN = 0x0101, - SYSCALL_FILES_CLOSE = 0x0102, - SYSCALL_FILES_READ = 0x0103, - SYSCALL_FILES_WRITE = 0x0104, - SYSCALL_FILES_DELETE = 0x0105, - SYSCALL_FILES_LIST = 0x0106, - SYSCALL_FILES_INFO = 0x0107, + SYSCALL_FILES_OPEN = 0x0001, + SYSCALL_FILES_CLOSE = 0x0002, + SYSCALL_FILES_READ = 0x0003, + SYSCALL_FILES_WRITE = 0x0004, + SYSCALL_FILES_DELETE = 0x0005, + SYSCALL_FILES_LIST = 0x0006, + SYSCALL_FILES_INFO = 0x0007, - SYSCALL_MEMORY_MAP = 0x0201, - SYSCALL_MEMORY_UNMAP = 0x0202, - SYSCALL_MEMORY_LABEL = 0x0203, - SYSCALL_MEMORY_RANGE = 0x0204, - SYSCALL_MEMORY_ACCESS = 0x0205, + SYSCALL_MEMORY_MAP = 0x0101, + SYSCALL_MEMORY_UNMAP = 0x0102, + SYSCALL_MEMORY_LABEL = 0x0103, + SYSCALL_MEMORY_RANGE = 0x0104, + SYSCALL_MEMORY_ACCESS = 0x0105, - SYSCALL_PROCESS_CREATE = 0x0301, - SYSCALL_PROCESS_ENV = 0x0302, - SYSCALL_PROCESS_SIGNAL = 0x0303, - SYSCALL_PROCESS_THREAD_CREATE = 0x0304, - SYSCALL_PROCESS_THREAD_START = 0x0305, - SYSCALL_PROCESS_THREAD_PAUSE = 0x0306, - SYSCALL_PROCESS_THREAD_KILL = 0x0307, + SYSCALL_PROCESS_CREATE = 0x0201, + SYSCALL_PROCESS_ENV = 0x0202, + SYSCALL_PROCESS_SIGNAL = 0x0203, + SYSCALL_PROCESS_THREAD_CREATE = 0x0204, + SYSCALL_PROCESS_THREAD_START = 0x0205, + SYSCALL_PROCESS_THREAD_PAUSE = 0x0206, + SYSCALL_PROCESS_THREAD_KILL = 0x0207, + + SYSCALL_DRIVER_REGISTER = 0x0301, + SYSCALL_DRIVER_CREATE_COMMAND_BUFFER = 0x0302, + SYSCALL_DRIVER_FLUSH_COMMAND_BUFFER = 0x0303, + + SYSCALL_RUNTIME_LINKER_OPEN = 0x7f01, + SYSCALL_RUNTIME_LINKER_CLOSE = 0x7f02, + SYSCALL_RUNTIME_LINKER_LOAD_SYMBOL = 0x7f03, + SYSCALL_RUNTIME_LINKER_STATUS = 0x7f04, + SYSCALL_RUNTIME_LINKER_STANDARD_MOD = 0x7f05, - SYSCALL_RUNTIME_LINKER_OPEN = 0x0401, - SYSCALL_RUNTIME_LINKER_CLOSE = 0x0402, - SYSCALL_RUNTIME_LINKER_LOAD_SYMBOL = 0x0403, - SYSCALL_RUNTIME_LINKER_STATUS = 0x0404, - SYSCALL_RUNTIME_LINKER_STANDARD_MOD = 0x0405, + SYSCALL_COMPATABILITY_ABI_TYPE = 0x0501, + SYSCALL_COMPATABILITY_ABI_VERSION = 0x0502, + SYSCALL_COMPATABILITY_ACTION = 0x0503, - SYSCALL_COMPATABILITY_ABI_TYPE = 0x0501, - SYSCALL_COMPATABILITY_ABI_VERSION = 0x0502, - SYSCALL_COMPATABILITY_ACTION = 0x0503, - - SYSCALL_KERNEL_SCHEDULER_START = 0xFF00, - SYSCALL_KERNEL_PANIC = 0xFF01 + SYSCALL_KERNEL_SCHEDULER_START = 0xFF00, + SYSCALL_KERNEL_PANIC = 0xFF01 } syscall_E; typedef enum { diff --git a/inc/proc/process.h b/inc/proc/process.h index ec39459..023e6fc 100644 --- a/inc/proc/process.h +++ b/inc/proc/process.h @@ -45,6 +45,10 @@ struct process_T { page_map_T* page_map; elf_executable_T* executable; file_descriptor_array_T* fd_array; + + // driver: If this process is a driver, this tells the ID + // of that driver within the driver management system. + uint32_t driver; pipe_T* stdout; pipe_T stdin; @@ -52,12 +56,12 @@ struct process_T { bitmap_T waiting; - uint32_t num_threads; + uint32_t num_threads; void* threads; bitmap_T thread_ids; process_T* parent; - process_T* childs; + process_T* childs; // TODO: Must be 'children' process_T* prev; process_T* next; }; diff --git a/inc/utils/file.h b/inc/utils/file.h new file mode 100644 index 0000000..581864a --- /dev/null +++ b/inc/utils/file.h @@ -0,0 +1,11 @@ + +#ifndef NOXOS_FILE_UTILS_H +#define NOXOS_FILE_UTILS_H + +#include + +uint64_t file_get_length (char *path); +uint64_t file_read_into_buffer (char *path, void *buffer, uint64_t offset, uint64_t num_bytes); + +#endif + diff --git a/ramdisk/modules/config.json b/ramdisk/modules/config.json new file mode 100644 index 0000000..789f9ac --- /dev/null +++ b/ramdisk/modules/config.json @@ -0,0 +1,15 @@ +{ + "drivers": + [ + { + "name": "nxFAT32", + "author": "NOXOS Authors", + "category": "filesystem", + "type": "fat32", + + "definition-path": "/modules/fat32/definition.json", + "binary-path": "/modules/fat32/driver.so" + } + ] +} + diff --git a/ramdisk/modules/fat32/config.json b/ramdisk/modules/fat32/config.json new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/ramdisk/modules/fat32/config.json @@ -0,0 +1 @@ + diff --git a/ramdisk/modules/fat32/definition.json b/ramdisk/modules/fat32/definition.json new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/ramdisk/modules/fat32/definition.json @@ -0,0 +1 @@ + diff --git a/ramdisk/noxos.json b/ramdisk/noxos.json index 22fe65e..a0bd89f 100644 --- a/ramdisk/noxos.json +++ b/ramdisk/noxos.json @@ -1,8 +1,8 @@ { "PS2_ACPI_VALIDATION": true, - "LOG_GRAPHICAL": false, + "LOG_GRAPHICAL": true, "modules": { "FAT32": "/initrd/modules/fat32.nxkm" } -} \ No newline at end of file +} diff --git a/run.sh b/run.sh index de09657..7b96e43 100755 --- a/run.sh +++ b/run.sh @@ -5,6 +5,11 @@ EMUFLAGS="-no-reboot -machine type=q35,accel=kvm -cpu max -m 256M \ -drive file=build/noxos.iso \ -chardev stdio,id=log,logfile=noxos.log -serial chardev:log" +OVMF_PATH="/usr/share/ovmf/x64/OVMF.fd" +if [[ -f "/usr/share/OVMF/OVMF.fd" ]]; then + OVMF_PATH="/usr/share/OVMF/OVMF.fd" +fi + emulate_bios() { echo "<=====| Emulating |=====>" qemu-system-x86_64 $EMUFLAGS @@ -12,13 +17,13 @@ emulate_bios() { emulate_uefi() { echo "<=====| Emulating in UEFI mode |=====>" - qemu-system-x86_64 -bios /usr/share/ovmf/x64/OVMF.fd $EMUFLAGS + qemu-system-x86_64 -bios $OVMF_PATH $EMUFLAGS } # qemu will wait for gdb to connect, before booting emulate_debug() { echo "<=====| Emulating in debug mode |=====>" - qemu-system-x86_64 -s -S -bios /usr/share/ovmf/x64/OVMF.fd $EMUFLAGS + qemu-system-x86_64 -s -S -bios $OVMF_PATH $EMUFLAGS } case $1 in diff --git a/src/boot/kmain.c b/src/boot/kmain.c index cacbf5d..11901b8 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -35,39 +35,41 @@ void kernel_init(boot_info_T* boot_info) { idt_init(); pic_init(); pit_set_divisor(PIT_DIVISOR); - + paging_init(); CORE_INTERRUPTS_ENABLE - + memory_allocator_init((void*)MEM_REGION_KERNEL_HEAP); - + graphics_renderer_init(boot_info); - + vfs_init(boot_info); - + sysconfig_init(); - + if (g_sysconfig->log_graphical) graphical_log_init(); - + scheduler_init(boot_info); - + acpi_init(boot_info); - + module_manager_init(); - + drive_manager_init(); - + pci_init(); - + + driver_manager_init(); + tty_init(); - + ps2_controller_init(); } void kmain(boot_info_T boot_info) { - limine_terminal_print(&boot_info, "Booting NoxOS...\n"); - log(LOG_DEBUG, "Booting NoxOS"); + limine_terminal_print(&boot_info, "Booting NOXOS...\n"); + log(LOG_DEBUG, "Booting NOXOS"); kernel_init(&boot_info); diff --git a/src/drivers/device_manager.c b/src/drivers/device_manager.c new file mode 100644 index 0000000..32a00a8 --- /dev/null +++ b/src/drivers/device_manager.c @@ -0,0 +1,28 @@ +#include + +#include + +device_manager_T g_device_manager; + + + +void device_manager_init() { + + + +} + + + +void device_remove(device_T *device) { + + + +} + +device_T * device_find(device_capabilities_T capabilities, uint32_t index, uint32_t *out_count) { + + + +} + diff --git a/src/drivers/driver_manager.c b/src/drivers/driver_manager.c new file mode 100644 index 0000000..e8175fa --- /dev/null +++ b/src/drivers/driver_manager.c @@ -0,0 +1,140 @@ +#include +#include + +#include +#include +#include + +driver_manager_T g_driver_manager; + + + +void driver_manager_init() +{ + log(LOG_INFO, "Starting Driver Manager!"); + + driver_manager_T manager; + manager.max_drivers = 1024; + manager.num_drivers = 0; + manager.drivers = memory_allocate(sizeof(driver_T) * manager.max_drivers); + + g_driver_manager = manager; +} + +void driver_manager_load_single_driver(char *driver_config_path) +{ // TODO + uint64_t len_file = file_get_length(driver_config_path); + void *content = memory_allocate(len_file+1); + file_read_into_buffer(driver_config_path, content, 0, len_file); + ((uint8_t *) content)[len_file] = 0x00; // End it with a NULL-terminator + + json_T *config_json = json_from_string(content); + // config_json->root_node-> +} + +void driver_manager_load_drivers(char *main_config_path) +{ + + + +} + + + +driver_T * driver_manager_find_free_driver_slot() +{ + driver_T *drivers = g_driver_manager.drivers; + + uint32_t index = 0; + while(index < g_driver_manager.max_drivers) + { + if(drivers[index].category == DRIVER_UNKNOWN) return &drivers[index]; + ++index; + } + return NULL; // TODO: Resize array +} + +uint32_t driver_manager_find_unused_driver_id() +{ + driver_T *drivers = g_driver_manager.drivers; + + uint32_t index = 0; + uint32_t id = 0; + while(id < 131072) + { + while(index < g_driver_manager.max_drivers) + { + if(drivers[index].id == id) break; + ++index; + } + ++id; + } + return id; +} + +bool driver_is_configuration_valid(driver_configuration_T *configuration) +{ + if(configuration->max_command_buffers == 0) return false; + if(configuration->max_command_buffers > 32) return false; + return true; +} + +uint32_t driver_manager_register_driver(driver_configuration_T *configuration) +{ + if(!driver_is_configuration_valid(configuration)) return 0; // TODO: Log + + driver_T *driver = driver_manager_find_free_driver_slot(); + driver->category = DRIVER_RESERVED; + driver->max_command_buffers = configuration->max_command_buffers; + driver->command_buffers = memory_allocate(sizeof(driver_T) * driver->max_command_buffers); + driver->id = driver_manager_find_unused_driver_id(); + + driver->category = configuration->category; // Activate the entry + + return driver->id; +} + +driver_T * driver_manager_resolve_driver_id(uint32_t id) +{ + driver_T *drivers = g_driver_manager.drivers; + + uint32_t index = 0; + while(index < g_driver_manager.max_drivers) + { + if(drivers[index].id == id) return &drivers[index]; + ++index; + } + return NULL; +} + + + +driver_command_buffer_T * driver_find_free_command_buffer_slot(driver_T *driver) +{ + driver_command_buffer_T *buffers = driver->command_buffers; + + uint32_t index = 0; + while(index < driver->max_command_buffers) + { + if(buffers[index].mapping_address == NULL) return &buffers[index]; + ++index; + } + return NULL; +} + +void driver_add_command_buffer(driver_T *driver, driver_command_buffer_config_T *configuration) +{ + driver_command_buffer_T *buffer = driver_find_free_command_buffer_slot(driver); + buffer->command_capacity = configuration->num_commands; + buffer->mapping_address = configuration->mapping_address; +} + + + +void driver_flush_command_buffer(driver_T *driver, void *buffer) +{ + + + +} + diff --git a/src/platform/syscall.c b/src/platform/syscall.c index b246ae8..376075e 100644 --- a/src/platform/syscall.c +++ b/src/platform/syscall.c @@ -6,6 +6,8 @@ #include "utils/memory.h" #include "proc/scheduler.h" #include "drivers/builtin/fs/vfs.h" +#include + #include "mm/page_frame.h" #include "mm/region.h" @@ -25,9 +27,9 @@ void syscall_handle_nx_fopen(cpu_state_T* state) { void syscall_handle_nx_fclose(cpu_state_T* state) { file_descriptor_t fd = (file_descriptor_t)state->rdi; // arg1 - + file_descriptor_free(scheduler_get_current_process()->fd_array, fd); - + state->rax = STATUS_SUCCESS; } @@ -188,11 +190,13 @@ void syscall_handle_nx_mmap(cpu_state_T* state) { } void syscall_handle_nx_munmap(cpu_state_T* state) { - void* addr = (void*)state->rdi; // arg1 - uint64_t n = state->rsi; // arg2 + void *addr = (void *) state->rdi; // arg1 + uint64_t n = state->rsi; // arg2 - if ((uint64_t)&addr[n * PFRAME_SIZE] > MEM_REGION_KERNEL || - (uint64_t)addr < MEM_REGION_PROCESS_USABLE) { + if( + ((uint64_t) &addr[n * PFRAME_SIZE] > MEM_REGION_KERNEL) || + ((uint64_t) addr < MEM_REGION_PROCESS_USABLE) + ) { state->rax = STATUS_PERMISSION_DENIED; return; } @@ -264,6 +268,124 @@ void syscall_handle_nx_psignal(cpu_state_T* state) { state->rax = STATUS_SUCCESS; } + + +uint64_t ceil_to(uint64_t base, uint64_t factor) +{ + return base + (base % factor); +} + +uint64_t floor_to(uint64_t base, uint64_t factor) +{ + return (base + (base % factor)) - factor; +} + +bool are_process_pages_unused(process_T *process, void *address, uint64_t num_pages) +{ + page_map_T *process_page_map = process->page_map; + + uint64_t page_index = 0; + while(page_index < num_pages) + { + if(page_map_check_memory( + process_page_map, + &address[page_index * PFRAME_SIZE]) + ) { + return false; + } + + ++page_index; + } + return true; +} + +bool are_process_memory_bytes_unused(process_T *process, void *address, uint64_t num_bytes) +{ + uint64_t first_full_page_address = floor_to(address, PFRAME_SIZE); + uint64_t num_pages = ceil_to(address+num_bytes, PFRAME_SIZE) / PFRAME_SIZE; + return are_process_pages_unused(process, first_full_page_address, num_pages); +} + +void mark_memory_region_for_process(process_T *process, + void *address, uint64_t num_pages, + bool read_write, bool executable) +{ + uint64_t map_flags = 0; + if(read_write) map_flags |= PM_FLAG_READ_WRITE; + if(!executable) map_flags |= PM_FLAG_NO_EXECUTE; + + page_map_T *process_page_map = process->page_map; + uint64_t page_index = 0; + while(page_index < num_pages) + { + page_map_map_memory(process_page_map, &address[page_index * PFRAME_SIZE], pframe_request(), map_flags); + ++page_index; + } +} + +// map_memory_for_user: Returns FALSE if the action failed and TRUE otherwise. +bool map_memory_for_process(process_T *process,void *address, uint64_t num_pages, bool read_write, bool executable) +{ + if(address == NULL) + { + return false; + } + if(!are_process_pages_unused(process, address, num_pages)) + { + return false; + } + mark_memory_region_for_process(process, address, num_pages, read_write, executable); + return true; +} + +void syscall_handle_nx_drv_register_driver(cpu_state_T* state) +{ + void *configuration = state->rdi; + process_T *caller = scheduler_get_current_process(); + + // Check permissions + if(are_process_memory_bytes_unused(caller, configuration, 256)) + { + state->rax = STATUS_RESOURCE_NOT_AVAILABLE; + return; + } + caller->driver = driver_manager_register_driver(configuration); +} + +void syscall_handle_nx_drv_create_command_buffer(cpu_state_T* state) +{ + void *address = (void *) state->rdi; + uint64_t wanted_commands = state->rsi; + uint64_t num_pages = ceil_to(wanted_commands * DRIVER_COMMAND_SIZE, PFRAME_SIZE) / PFRAME_SIZE; + process_T *caller = scheduler_get_current_process(); + driver_T *driver = driver_manager_resolve_driver_id(caller->driver); + + if(map_memory_for_process(caller, address, num_pages, true, false)) + { + driver_command_buffer_config_T buffer_config; + buffer_config.num_commands = num_pages; + buffer_config.mapping_address = address; + + driver_add_command_buffer(driver, &buffer_config); + + state->rax = address; + return; + } + + // TODO: Select an address for the process and re-run map_memory_for_process. + + state->rax = STATUS_RESOURCE_NOT_AVAILABLE; +} + +void syscall_handle_nx_drv_flush_command_buffer(cpu_state_T* state) +{ + void *command_buffer = state->rsi; + process_T *caller = scheduler_get_current_process(); + driver_T *driver = driver_manager_resolve_driver_id(caller->driver); + + driver_flush_command_buffer(driver, command_buffer); +} + cpu_state_T* syscall_handle(cpu_state_T* state) { cpu_state_T* return_state = state; syscall_group_E group_id = (state->rax & 0xFF00) >> 8; @@ -315,7 +437,7 @@ cpu_state_T* syscall_handle(cpu_state_T* state) { break; } - case SYSCALLS_PROC: { + case SYSCALLS_PROCESS: { switch (state->rax) { case SYSCALL_PROCESS_CREATE: { syscall_handle_nx_pcreate(state); @@ -328,7 +450,23 @@ cpu_state_T* syscall_handle(cpu_state_T* state) { } break; } - + + case SYSCALLS_DRIVER: { + switch(state->rax) { + case SYSCALL_DRIVER_REGISTER: { + syscall_handle_nx_drv_register_driver(state); + } break; + + case SYSCALL_DRIVER_CREATE_COMMAND_BUFFER: { + syscall_handle_nx_drv_create_command_buffer(state); + } break; + + case SYSCALL_DRIVER_FLUSH_COMMAND_BUFFER: { + syscall_handle_nx_drv_flush_command_buffer(state); + } break; + } + } + case SYSCALLS_RUNTIME_LINKER: { break; } @@ -369,4 +507,4 @@ cpu_state_T* syscall_handle(cpu_state_T* state) { } return return_state; -} \ No newline at end of file +} diff --git a/src/utils/file.c b/src/utils/file.c new file mode 100644 index 0000000..fe16d0d --- /dev/null +++ b/src/utils/file.c @@ -0,0 +1,20 @@ +#include + +#include + +uint64_t file_get_length(char *path) +{ + vfs_node_T *file = vfs_resolve_path(&g_root_fs, path); + if(file == NULL) return 0; + return file->size; +} + +uint64_t file_read_into_buffer(char *path, void *buffer, uint64_t offset, uint64_t num_bytes) +{ + vfs_node_T *file = vfs_resolve_path(&g_root_fs, path); + if(file == NULL) return 0; + uint64_t actual_read_bytes = vfs_file_read(file, offset, num_bytes, buffer); + vfs_node_destruct(file); + return actual_read_bytes; +} +