From 3e9bdf72c955c7685722c7c3c9f839f8c077cf2b Mon Sep 17 00:00:00 2001 From: Marvin Friedrich Date: Wed, 16 Sep 2026 04:37:37 +0200 Subject: [PATCH] yeah --- .gitignore | 1 + Kconfig | 7 ++ README.md | 3 +- arch/x86_64/hpet.c | 2 +- arch/x86_64/meson.build | 1 + arch/x86_64/syscall.c | 2 + arch/x86_64/tsc.c | 10 +- arch/x86_64/usercopy.c | 18 +-- boot/main.c | 4 +- core/clock.c | 6 +- core/console.c | 2 +- core/elf.c | 6 +- core/futex.c | 4 +- core/meson.build | 5 +- core/panic.c | 4 +- core/print.c | 2 +- core/{sched_simple.c => sched_dumb.c} | 4 +- core/spin.c | 4 +- device/Kconfig | 15 +++ device/acpi/meson.build | 13 ++- {core => device/acpi}/uacpi_glue.c | 12 +- device/common/memfiles.c | 0 device/common/meson.build | 3 + device/dt/meson.build | 0 device/meson.build | 8 +- include/uapi/archctl.h | 2 +- include/uapi/epoll.h | 6 +- include/uapi/errno.h | 2 +- include/uapi/fcntl.h | 2 +- include/uapi/mman.h | 15 ++- include/uapi/mount.h | 2 +- include/uapi/poll.h | 6 +- include/uapi/stat.h | 4 +- include/uapi/syscall_numbers.h | 151 ------------------------- include/uapi/time.h | 2 +- include/uapi/types.h | 2 +- include/uapi/uio.h | 2 +- include/uapi/utsname.h | 2 +- include/zinnia/{mem => }/alloc.h | 0 include/zinnia/archctl.h | 3 - include/zinnia/bits/archctl.h | 7 ++ include/zinnia/elf.h | 1 + include/zinnia/irq.h | 8 +- include/zinnia/mman.h | 25 +++++ include/zinnia/{mem => }/object.h | 4 +- include/zinnia/{mem => }/page.h | 2 +- include/zinnia/{mem => }/pager.h | 2 +- include/zinnia/percpu.h | 4 +- include/zinnia/{mem => }/pmap.h | 12 +- include/zinnia/print.h | 2 +- include/zinnia/rcu.h | 4 + include/zinnia/refcount.h | 16 +-- include/zinnia/spin.h | 8 +- include/zinnia/syscall.h | 22 +++- include/zinnia/syscall_list.h | 149 +++++++++++++++++++++++++ include/zinnia/vas.h | 6 +- include/zinnia/vfs.h | 11 +- include/zinnia/wait.h | 2 +- mem/init.c | 27 +++-- mem/pmap.c | 12 +- mem/pmm.c | 8 +- mem/slab.c | 8 +- mem/vas.c | 13 ++- meson.build | 28 +++-- meson.options | 13 +-- subprojects/uacpi | 2 +- syscalls/archctl.c | 8 +- syscalls/dispatch.c | 155 ++++++++++++++++++++++++-- syscalls/handle.c | 48 -------- syscalls/meson.build | 1 + syscalls/random.c | 10 -- syscalls/system.c | 46 -------- syscalls/thread.c | 115 ------------------- syscalls/vas.c | 6 - 74 files changed, 555 insertions(+), 567 deletions(-) create mode 100644 Kconfig rename core/{sched_simple.c => sched_dumb.c} (98%) create mode 100644 device/Kconfig rename {core => device/acpi}/uacpi_glue.c (92%) create mode 100644 device/common/memfiles.c create mode 100644 device/common/meson.build create mode 100644 device/dt/meson.build delete mode 100644 include/uapi/syscall_numbers.h rename include/zinnia/{mem => }/alloc.h (100%) delete mode 100644 include/zinnia/archctl.h create mode 100644 include/zinnia/bits/archctl.h create mode 100644 include/zinnia/mman.h rename include/zinnia/{mem => }/object.h (95%) rename include/zinnia/{mem => }/page.h (96%) rename include/zinnia/{mem => }/pager.h (100%) rename include/zinnia/{mem => }/pmap.h (84%) create mode 100644 include/zinnia/rcu.h create mode 100644 include/zinnia/syscall_list.h delete mode 100644 syscalls/handle.c delete mode 100644 syscalls/random.c delete mode 100644 syscalls/system.c delete mode 100644 syscalls/thread.c delete mode 100644 syscalls/vas.c diff --git a/.gitignore b/.gitignore index 1301351..a1c8cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.config* build/ .cache/ .wraplock diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..e7b515f --- /dev/null +++ b/Kconfig @@ -0,0 +1,7 @@ +mainmenu "Zinnia Kernel Configuration" + +source "device/Kconfig" + +config KERNEL_FLAVOR + string "Kernel flavor name" + default "vanilla" diff --git a/README.md b/README.md index 36ec603..9d1829c 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,13 @@ # Zinnia ![GitHub License](https://img.shields.io/github/license/zinnia-os/zinnia?style=flat&color=green) +![GitHub top language](https://img.shields.io/github/languages/top/zinnia-os/zinnia) ![GitHub Repo stars](https://img.shields.io/github/stars/zinnia-os/zinnia?style=flat) ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/zinnia-os/zinnia/ci.yml) ![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/zinnia-os/zinnia?style=flat) ![Discord](https://img.shields.io/discord/1305893510704267327?logo=discord&logoColor=white&label=discord) -Zinnia is a lightweight BSD-like monolithic kernel targeting 64-bit devices. +Zinnia is a lightweight Unix-like monolithic kernel targeting 64-bit devices. ## Building Zinnia diff --git a/arch/x86_64/hpet.c b/arch/x86_64/hpet.c index 915b5af..080b771 100644 --- a/arch/x86_64/hpet.c +++ b/arch/x86_64/hpet.c @@ -58,7 +58,7 @@ void hpet_init() { struct acpi_hpet* hpet = table.ptr; hpet_clock.regs = mmio_new(hpet->address.address, 0x1000); uacpi_table_unref(&table); - printf("HPET regs at %p\n", hpet_clock.regs.base); + kprintf("HPET regs at %p\n", hpet_clock.regs.base); mmio_store(&hpet_clock.regs, HPET_CFG, mmio_load(&hpet_clock.regs, HPET_CFG) | 1); diff --git a/arch/x86_64/meson.build b/arch/x86_64/meson.build index b75ec1e..c2842e1 100644 --- a/arch/x86_64/meson.build +++ b/arch/x86_64/meson.build @@ -2,6 +2,7 @@ kernel_c_args += [ '-mgeneral-regs-only', '-mno-red-zone', '-mcmodel=kernel', + '-masm=intel', ] kernel_sources += files( diff --git a/arch/x86_64/syscall.c b/arch/x86_64/syscall.c index 016d4e2..1c0a000 100644 --- a/arch/x86_64/syscall.c +++ b/arch/x86_64/syscall.c @@ -5,6 +5,8 @@ #include #include +// TODO: Refactor to only push callee-saved registers. + [[__naked]] void arch_syscall_stub() { asm volatile( diff --git a/arch/x86_64/tsc.c b/arch/x86_64/tsc.c index fd8200b..7fc02f4 100644 --- a/arch/x86_64/tsc.c +++ b/arch/x86_64/tsc.c @@ -11,7 +11,7 @@ void tsc_init() { return; if (!(asm_cpuid(1, 0).edx & CPUID_1D_TSC) || !(asm_cpuid(0x8000'0007, 0).edx & (1 << 8))) { - printf("No invariant TSC detected!\n"); + kprintf("No invariant TSC detected!\n"); return; } @@ -34,18 +34,18 @@ void tsc_init() { // On a normal system, this should usually never be called and is a last resort // since at this point we have at least the HPET timer. if (tsc_leaf.ecx != 0 && tsc_leaf.ebx != 0 && tsc_leaf.eax != 0) { - printf("Calibrating TSC using CPUID 0x15"); + kprintf("Calibrating TSC using CPUID 0x15"); freq = tsc_leaf.ecx * tsc_leaf.ebx / tsc_leaf.eax; } else { - printf("Unable to calibrate TSC using CPUID frequency information"); + kprintf("Unable to calibrate TSC using CPUID frequency information"); return; } } else { - printf("Unable to calibrate the TSC without a clock or static frequency info!\n"); + kprintf("Unable to calibrate the TSC without a clock or static frequency info!\n"); return; } - printf("Timer frequency is %lu MHz\n", freq / 1'000'000); + kprintf("Timer frequency is %lu MHz\n", freq / 1'000'000); } static void tsc_option(bool opt) { diff --git a/arch/x86_64/usercopy.c b/arch/x86_64/usercopy.c index 8d85829..baee3dd 100644 --- a/arch/x86_64/usercopy.c +++ b/arch/x86_64/usercopy.c @@ -17,7 +17,7 @@ bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct us // Setup regs for `rep movsb`. "xchg rcx, rdx\n" "mov rax, [rip + %0]\n" - "mov [rdx], rax\n" + "xchg [rdx], rax\n" ".global x86_64_read_start\n" "x86_64_read_start:\n" @@ -26,7 +26,7 @@ bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct us ".global x86_64_read_end\n" "x86_64_read_end:\n" "xor rax, rax\n" - "mov [rdx], rax\n" + "xchg [rdx], rax\n" "mov rax, 1\n" "clac\n" "ret\n" @@ -34,7 +34,7 @@ bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct us ".global x86_64_read_fault\n" "x86_64_read_fault:\n" "xor rax, rax\n" - "mov [rdx], rax\n" + "xchg [rdx], rax\n" "clac\n" "ret\n" : @@ -69,7 +69,7 @@ bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct u ".global x86_64_write_end\n" "x86_64_write_end:\n" "xor rax, rax\n" - "mov [rdx], rax\n" + "xchg [rdx], rax\n" "mov rax, 1\n" "clac\n" "ret\n" @@ -77,11 +77,11 @@ bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct u ".global x86_64_write_fault\n" "x86_64_write_fault:\n" "xor rax, rax\n" - "mov [rdx], rax\n" + "xchg [rdx], rax\n" "clac\n" "ret\n" : - : "i"(&read_region) + : "i"(&write_region) : "memory" ); return false; @@ -102,7 +102,7 @@ bool arch_usercopy_strlen(const __user char* str, size_t max, size_t* len, struc asm volatile( "stac\n" "mov rax, [rip + %0]\n" - "mov [rcx], rax\n" + "xchg [rcx], rax\n" ".global x86_64_strlen_start\n" "x86_64_strlen_start:\n" @@ -119,7 +119,7 @@ bool arch_usercopy_strlen(const __user char* str, size_t max, size_t* len, struc ".global x86_64_strlen_end\n" "x86_64_strlen_end:\n" "xor rax, rax\n" - "mov [rcx], rax\n" + "xchg [rcx], rax\n" "mov rax, 1\n" "clac\n" "ret\n" @@ -127,7 +127,7 @@ bool arch_usercopy_strlen(const __user char* str, size_t max, size_t* len, struc ".global x86_64_strlen_fault\n" "x86_64_strlen_fault:\n" "xor rax, rax\n" - "mov [rcx], rax\n" + "xchg [rcx], rax\n" "clac\n" "ret\n" : diff --git a/boot/main.c b/boot/main.c index 6f8733b..f3f8a93 100644 --- a/boot/main.c +++ b/boot/main.c @@ -17,11 +17,11 @@ #include static const char zinnia_banner[] = - "Zinnia " ZINNIA_VERSION " (" ZINNIA_ARCH ", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")"; + "Zinnia " ZINNIA_VERSION " " CONFIG_VARIANT " (" ZINNIA_ARCH ", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")"; static void kernel_main_task(uintptr_t arg0) { struct boot_info* info = (struct boot_info*)arg0; - printf("%s\n", zinnia_banner); // Say hello! + kprintf("%s\n", zinnia_banner); // Say hello! assert(info->num_files >= 1, "No init executable provided\n"); diff --git a/core/clock.c b/core/clock.c index 865afe0..4e51a1b 100644 --- a/core/clock.c +++ b/core/clock.c @@ -7,7 +7,7 @@ static struct clock* active_clock = nullptr; static uint64_t counter_base = 0; -static struct spinlock lock = {}; +static spinlock_t lock = {}; bool clock_available() { return active_clock != nullptr; @@ -31,7 +31,7 @@ bool clock_switch(struct clock* clock) { } } - printf("Switching to clock source \"%s\"\n", clock->name); + kprintf("Switching to clock source \"%s\"\n", clock->name); uint64_t elapsed = clock_get_elapsed_ns(); counter_base += elapsed; @@ -43,7 +43,7 @@ bool clock_switch(struct clock* clock) { void clock_spin_ns(uint64_t ns) { if (active_clock == nullptr) { - printf("Unable to sleep for %lu ns, no clock available!\n", ns); + kprintf("Unable to sleep for %lu ns, no clock available!\n", ns); return; } diff --git a/core/console.c b/core/console.c index 6849ad0..adb2b0b 100644 --- a/core/console.c +++ b/core/console.c @@ -38,6 +38,6 @@ void console_init() { if (active->init(active) == false) active = nullptr; else - printf("Logging on console \"%s\"\n", active->name); + kprintf("Logging on console \"%s\"\n", active->name); } } diff --git a/core/elf.c b/core/elf.c index ed3e53f..75e4e69 100644 --- a/core/elf.c +++ b/core/elf.c @@ -1,6 +1,6 @@ +#include #include #include -#include #include #include #include @@ -42,7 +42,7 @@ errno_t elf_load(struct exec_info* info, struct task** out) { if (phdr.p_type == PT_LOAD) { enum zn_vm_flags prot = 0; if (phdr.p_flags & PF_R) - prot |= ZN_VM_MAP_READ; + prot |= PROT_READ; if (phdr.p_flags & PF_W) prot |= ZN_VM_MAP_WRITE; if (phdr.p_flags & PF_X) @@ -181,7 +181,7 @@ errno_t elf_load(struct exec_info* info, struct task** out) { uintptr_t argc = num_argv; vmo_write(&stack->object, stack_off, &argc, sizeof(argc), nullptr); - status = vma_map_vmo(info->space, &stack->object, stack_start, stack_size, ZN_VM_MAP_READ | ZN_VM_MAP_WRITE, 0); + status = vma_map_vmo(info->space, &stack->object, stack_start, stack_size, PROT_READ | ZN_VM_MAP_WRITE, 0); if (status) return status; diff --git a/core/futex.c b/core/futex.c index 4f553ab..124a457 100644 --- a/core/futex.c +++ b/core/futex.c @@ -15,10 +15,10 @@ struct futex_bucket { #define FUTEX_BUCKET_COUNT 64 static struct futex_bucket futex_table[FUTEX_BUCKET_COUNT]; -static struct spinlock futex_table_lock; +static spinlock_t futex_table_lock; void futex_init(void) { - futex_table_lock = (struct spinlock){0}; + futex_table_lock = (spinlock_t){0}; for (size_t i = 0; i < FUTEX_BUCKET_COUNT; i++) { wait_queue_init(&futex_table[i].wq); futex_table[i].key = 0; diff --git a/core/meson.build b/core/meson.build index bde4c8f..89a1445 100644 --- a/core/meson.build +++ b/core/meson.build @@ -8,9 +8,6 @@ kernel_sources += files( 'percpu.c', 'print.c', 'spin.c', - 'uacpi_glue.c', ) -if get_option('sched') == 'simple' - kernel_sources += files('sched_simple.c') -endif +kernel_sources += files('sched_dumb.c') diff --git a/core/panic.c b/core/panic.c index 984bfc1..7d3b255 100644 --- a/core/panic.c +++ b/core/panic.c @@ -11,7 +11,7 @@ void panic(const char* msg, ...) { struct percpu* cpu = percpu_get(); struct task* current = cpu->sched.current; - printf( + kprintf( "----[ Kernel panic ]----\n" "In task \"%s\" (TID %zu) on CPU %zu!\n", current ? current->name : nullptr, @@ -24,7 +24,7 @@ void panic(const char* msg, ...) { kvprintf(msg, args); va_end(args); - printf("----[ End of panic ]----\n"); + kprintf("----[ End of panic ]----\n"); while (1) { arch_irq_wait(); diff --git a/core/print.c b/core/print.c index 2cfae29..3aaa84c 100644 --- a/core/print.c +++ b/core/print.c @@ -387,7 +387,7 @@ static void printf_console(void*, const char* msg, size_t len) { console_write(msg, len); } -void printf(const char* message, ...) { +void kprintf(const char* message, ...) { va_list args; va_start(args, message); do_print(printf_console, nullptr, message, args); diff --git a/core/sched_simple.c b/core/sched_dumb.c similarity index 98% rename from core/sched_simple.c rename to core/sched_dumb.c index dce4582..0c1ed52 100644 --- a/core/sched_simple.c +++ b/core/sched_dumb.c @@ -43,7 +43,7 @@ void sched_init(struct sched_percpu* sched) { tailq_init(&sched->run_queue); - printf("Scheduler initialized\n"); + kprintf("Scheduler initialized\n"); } void sched_add_task(struct sched_percpu* sched, struct task* task) { @@ -143,7 +143,7 @@ void task_entry(task_fn_t entry, uintptr_t arg0) { void wait_queue_init(struct wait_queue* wq) { tailq_init(&wq->waiters); - wq->lock = (struct spinlock){0}; + wq->lock = (spinlock_t){0}; } void sched_block(struct sched_percpu* sched, struct wait_queue* wq) { diff --git a/core/spin.c b/core/spin.c index 13d9d90..a8398e1 100644 --- a/core/spin.c +++ b/core/spin.c @@ -1,7 +1,7 @@ #include #include -void spin_lock(struct spinlock* spin) { +void spin_lock(spinlock_t* spin) { uint32_t my = atomic_fetch_add_explicit(&spin->next, 1, memory_order_relaxed); while (atomic_load_explicit(&spin->owner, memory_order_acquire) != my) { @@ -9,7 +9,7 @@ void spin_lock(struct spinlock* spin) { } } -void spin_unlock(struct spinlock* spin) { +void spin_unlock(spinlock_t* spin) { uint32_t val = atomic_load_explicit(&spin->owner, memory_order_relaxed); atomic_store_explicit(&spin->owner, val + 1, memory_order_release); } diff --git a/device/Kconfig b/device/Kconfig new file mode 100644 index 0000000..ca4a461 --- /dev/null +++ b/device/Kconfig @@ -0,0 +1,15 @@ +menu "Device Drivers" + +config OF + bool "Support for OpenFirmware" + default y + help + Adds support for flattened device trees and OF platform drivers. + +config ACPI + bool "Support for ACPI firmware" + default y + help + Adds support for ACPI firmware, tables and devices. + +endmenu diff --git a/device/acpi/meson.build b/device/acpi/meson.build index a2903fa..c41fb03 100644 --- a/device/acpi/meson.build +++ b/device/acpi/meson.build @@ -1,10 +1,15 @@ -# uACPI uacpi = subproject('uacpi') -uacpi_sources = uacpi.get_variable('sources') -uacpi_includes = uacpi.get_variable('includes') + +kernel_sources += uacpi.get_variable('sources') +kernel_includes += uacpi.get_variable('includes') kernel_c_args += [ '-DUACPI_FORMATTED_LOGGING', - '-DUACPI_BAREBONES_MODE', + '-DUACPI_BAREBONES_MODE', # TODO '-DUACPI_OVERRIDE_TYPES', ] +# For uacpi_types.h kernel_includes += include_directories('include') + +kernel_sources += files( + 'uacpi_glue.c', +) diff --git a/core/uacpi_glue.c b/device/acpi/uacpi_glue.c similarity index 92% rename from core/uacpi_glue.c rename to device/acpi/uacpi_glue.c index b1a872b..57cf4d1 100644 --- a/core/uacpi_glue.c +++ b/device/acpi/uacpi_glue.c @@ -1,11 +1,11 @@ -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr* out_rsdp_address) { *out_rsdp_address = (uacpi_phys_addr)rsdp_addr; @@ -13,11 +13,11 @@ uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr* out_rsdp_address) { } void* uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) { - return mmio_new(addr, len); + return (void*)mmio_new(addr, len).base; } void uacpi_kernel_unmap(void* addr, uacpi_size len) { - mmio_free(addr, len); + // TODO } void uacpi_kernel_log(uacpi_log_level lvl, const uacpi_char* msg, ...) { diff --git a/device/common/memfiles.c b/device/common/memfiles.c new file mode 100644 index 0000000..e69de29 diff --git a/device/common/meson.build b/device/common/meson.build new file mode 100644 index 0000000..330ae19 --- /dev/null +++ b/device/common/meson.build @@ -0,0 +1,3 @@ +kernel_sources += files( + 'memfiles.c', +) diff --git a/device/dt/meson.build b/device/dt/meson.build new file mode 100644 index 0000000..e69de29 diff --git a/device/meson.build b/device/meson.build index 1b0ad7c..6a3d7d7 100644 --- a/device/meson.build +++ b/device/meson.build @@ -1,3 +1,9 @@ -if get_option('acpi') +subdir('common') + +if cfg.get('CONFIG_ACPI', 0) == 1 subdir('acpi') endif + +if cfg.get('CONFIG_DT', 0) == 1 + subdir('dt') +endif diff --git a/include/uapi/archctl.h b/include/uapi/archctl.h index fcfee9e..b86a8c5 100644 --- a/include/uapi/archctl.h +++ b/include/uapi/archctl.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_ARCHCTL_H #define __ZINNIA_UAPI_ARCHCTL_H diff --git a/include/uapi/epoll.h b/include/uapi/epoll.h index e4b07b0..36526c7 100644 --- a/include/uapi/epoll.h +++ b/include/uapi/epoll.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_EPOLL_H #define __ZINNIA_UAPI_EPOLL_H @@ -24,7 +24,7 @@ #define __EPOLL_CTL_DEL 2 #define __EPOLL_CTL_MOD 3 -union epoll_data { +union __epoll_data { void* ptr; int fd; uint32_t u32; @@ -33,7 +33,7 @@ union epoll_data { struct epoll_event { uint32_t events; - union epoll_data data; + union __epoll_data data; }; #endif diff --git a/include/uapi/errno.h b/include/uapi/errno.h index 1246007..6d8d0ca 100644 --- a/include/uapi/errno.h +++ b/include/uapi/errno.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_ERRNO_H #define __ZINNIA_UAPI_ERRNO_H diff --git a/include/uapi/fcntl.h b/include/uapi/fcntl.h index 293c8f9..e96ada1 100644 --- a/include/uapi/fcntl.h +++ b/include/uapi/fcntl.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_FCNTL_H #define __ZINNIA_UAPI_FCNTL_H diff --git a/include/uapi/mman.h b/include/uapi/mman.h index 5474159..509c6cb 100644 --- a/include/uapi/mman.h +++ b/include/uapi/mman.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_MMAN_H #define __ZINNIA_UAPI_MMAN_H @@ -7,13 +7,12 @@ #define __PROT_WRITE 0x02 #define __PROT_EXEC 0x04 -#define __MAP_FAILED ((void*)-1) -#define __MAP_FILE 0x00 -#define __MAP_SHARED 0x01 -#define __MAP_PRIVATE 0x02 -#define __MAP_FIXED 0x10 -#define __MAP_ANON 0x20 -#define __MAP_ANONYMOUS 0x20 +#define __MAP_FAILED ((void*)-1) +#define __MAP_FILE 0x00 +#define __MAP_SHARED 0x01 +#define __MAP_PRIVATE 0x02 +#define __MAP_FIXED 0x10 +#define __MAP_ANON 0x20 #define __MS_ASYNC 0x1 #define __MS_INVALIDATE 0x2 diff --git a/include/uapi/mount.h b/include/uapi/mount.h index 79c4ca7..e31b901 100644 --- a/include/uapi/mount.h +++ b/include/uapi/mount.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_MOUNT_H #define __ZINNIA_UAPI_MOUNT_H diff --git a/include/uapi/poll.h b/include/uapi/poll.h index b2d5fce..771decf 100644 --- a/include/uapi/poll.h +++ b/include/uapi/poll.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_POLL_H #define __ZINNIA_UAPI_POLL_H @@ -16,9 +16,9 @@ #define __POLLWRNORM 0x200 #define __POLLWRBAND 0x400 -typedef intptr_t nfds_t; +typedef intptr_t __nfds_t; -struct pollfd { +struct __pollfd { int fd; int16_t events; int16_t revents; diff --git a/include/uapi/stat.h b/include/uapi/stat.h index 4a89ccc..d291d62 100644 --- a/include/uapi/stat.h +++ b/include/uapi/stat.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_STAT_H #define __ZINNIA_UAPI_STAT_H @@ -32,7 +32,7 @@ #define __S_IWRITE __S_IWUSR #define __S_IEXEC __S_IXUSR -struct stat { +struct __stat { dev_t st_dev; ino_t st_ino; mode_t st_mode; diff --git a/include/uapi/syscall_numbers.h b/include/uapi/syscall_numbers.h deleted file mode 100644 index b7a7d7f..0000000 --- a/include/uapi/syscall_numbers.h +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef __ZINNIA_UAPI_SYSCALL_NUMBERS_H -#define __ZINNIA_UAPI_SYSCALL_NUMBERS_H - -#define __SYS_exit 0 -#define __SYS_syslog 1 -#define __SYS_getuname 2 -#define __SYS_setuname 3 -#define __SYS_archctl 4 -#define __SYS_reboot 5 -#define __SYS_mmap 6 -#define __SYS_munmap 7 -#define __SYS_mprotect 8 -#define __SYS_madvise 9 -#define __SYS_sigprocmask 10 -#define __SYS_sigsuspend 11 -#define __SYS_sigpending 12 -#define __SYS_sigaction 13 -#define __SYS_sigtimedwait 14 -#define __SYS_sigaltstack 15 -#define __SYS_sigreturn 16 -#define __SYS_sigqueue 17 -#define __SYS_execve 18 -#define __SYS_fexecve 19 -#define __SYS_fork 20 -#define __SYS_kill 21 -#define __SYS_gettid 22 -#define __SYS_getpid 23 -#define __SYS_getppid 24 -#define __SYS_waitid 25 -#define __SYS_waitpid 26 -#define __SYS_pread 27 -#define __SYS_readv 28 -#define __SYS_pwrite 29 -#define __SYS_writev 30 -#define __SYS_seek 31 -#define __SYS_ioctl 32 -#define __SYS_openat 33 -#define __SYS_close 34 -#define __SYS_fstat 35 -#define __SYS_fstatat 36 -#define __SYS_statvfs 37 -#define __SYS_fstatvfs 38 -#define __SYS_faccessat 39 -#define __SYS_fcntl 40 -#define __SYS_ftruncate 41 -#define __SYS_truncate 42 -#define __SYS_fallocate 43 -#define __SYS_fadvise 44 -#define __SYS_utimensat 45 -#define __SYS_mknodat 46 -#define __SYS_getcwd 47 -#define __SYS_chdir 48 -#define __SYS_fchdir 49 -#define __SYS_mkdirat 50 -#define __SYS_rmdirat 51 -#define __SYS_getdents 52 -#define __SYS_renameat 53 -#define __SYS_fchmod 54 -#define __SYS_fchmodat 55 -#define __SYS_fchownat 56 -#define __SYS_linkat 57 -#define __SYS_symlinkat 58 -#define __SYS_unlinkat 59 -#define __SYS_readlinkat 60 -#define __SYS_flock 61 -#define __SYS_ppoll 62 -#define __SYS_dup 63 -#define __SYS_dup3 64 -#define __SYS_sync 65 -#define __SYS_fsync 66 -#define __SYS_fdatasync 67 -#define __SYS_getgroups 68 -#define __SYS_setgroups 69 -#define __SYS_getsid 70 -#define __SYS_setsid 71 -#define __SYS_setuid 72 -#define __SYS_getuid 73 -#define __SYS_setgid 74 -#define __SYS_getgid 75 -#define __SYS_geteuid 76 -#define __SYS_seteuid 77 -#define __SYS_getegid 78 -#define __SYS_setegid 79 -#define __SYS_getpgid 80 -#define __SYS_setpgid 81 -#define __SYS_getresuid 82 -#define __SYS_setresuid 83 -#define __SYS_getresgid 84 -#define __SYS_setresgid 85 -#define __SYS_setreuid 86 -#define __SYS_setregid 87 -#define __SYS_umask 88 -#define __SYS_pipe 89 -#define __SYS_futex_wait 90 -#define __SYS_futex_wake 91 -#define __SYS_thread_create 92 -#define __SYS_thread_kill 93 -#define __SYS_thread_exit 94 -#define __SYS_thread_setname 95 -#define __SYS_thread_getname 96 -#define __SYS_timer_create 97 -#define __SYS_timer_set 98 -#define __SYS_timer_get 99 -#define __SYS_timer_getoverrun 100 -#define __SYS_timer_delete 101 -#define __SYS_itimer_get 102 -#define __SYS_itimer_set 103 -#define __SYS_clock_get 104 -#define __SYS_clock_getres 105 -#define __SYS_clock_set 106 -#define __SYS_sleep 107 -#define __SYS_yield 108 -#define __SYS_chroot 109 -#define __SYS_mount 110 -#define __SYS_umount 111 -#define __SYS_socket 112 -#define __SYS_socketpair 113 -#define __SYS_shutdown 114 -#define __SYS_bind 115 -#define __SYS_connect 116 -#define __SYS_accept 117 -#define __SYS_listen 118 -#define __SYS_getpeername 119 -#define __SYS_getsockname 120 -#define __SYS_getsockopt 121 -#define __SYS_setsockopt 122 -#define __SYS_sendmsg 123 -#define __SYS_recvmsg 124 -#define __SYS_getentropy 125 -#define __SYS_getrusage 126 -#define __SYS_getrlimit 127 -#define __SYS_setrlimit 128 -#define __SYS_getpriority 129 -#define __SYS_setpriority 130 -#define __SYS_sched_getparam 131 -#define __SYS_sched_setparam 132 -#define __SYS_module_insert 133 -#define __SYS_module_remove 134 -#define __SYS_epoll_create 135 -#define __SYS_epoll_ctl 136 -#define __SYS_epoll_pwait 137 -#define __SYS_timerfd_create 138 -#define __SYS_timerfd_gettime 139 -#define __SYS_timerfd_settime 140 -#define __SYS_signalfd_create 141 -#define __SYS_eventfd_create 142 -#define __SYS_msync 143 -#define __SYS_sysconf 144 - -#endif diff --git a/include/uapi/time.h b/include/uapi/time.h index ffc057c..1fbd429 100644 --- a/include/uapi/time.h +++ b/include/uapi/time.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_TIME_H #define __ZINNIA_UAPI_TIME_H diff --git a/include/uapi/types.h b/include/uapi/types.h index 494e966..071c727 100644 --- a/include/uapi/types.h +++ b/include/uapi/types.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_TYPES_H #define __ZINNIA_UAPI_TYPES_H diff --git a/include/uapi/uio.h b/include/uapi/uio.h index 8428862..0b3110c 100644 --- a/include/uapi/uio.h +++ b/include/uapi/uio.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_UIO_H #define __ZINNIA_UAPI_UIO_H diff --git a/include/uapi/utsname.h b/include/uapi/utsname.h index 20fdf3f..9163606 100644 --- a/include/uapi/utsname.h +++ b/include/uapi/utsname.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ZINNIA_UAPI_UTSNAME_H #define __ZINNIA_UAPI_UTSNAME_H diff --git a/include/zinnia/mem/alloc.h b/include/zinnia/alloc.h similarity index 100% rename from include/zinnia/mem/alloc.h rename to include/zinnia/alloc.h diff --git a/include/zinnia/archctl.h b/include/zinnia/archctl.h deleted file mode 100644 index 07d15ba..0000000 --- a/include/zinnia/archctl.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include diff --git a/include/zinnia/bits/archctl.h b/include/zinnia/bits/archctl.h new file mode 100644 index 0000000..9f4b93a --- /dev/null +++ b/include/zinnia/bits/archctl.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include + +errno_t arch_archctl(uintptr_t op, uintptr_t value); diff --git a/include/zinnia/elf.h b/include/zinnia/elf.h index 6c796cb..9808027 100644 --- a/include/zinnia/elf.h +++ b/include/zinnia/elf.h @@ -1,5 +1,6 @@ #pragma once +#include #include constexpr char ELF_MAG[4] = {0x7F, 'E', 'L', 'F'}; diff --git a/include/zinnia/irq.h b/include/zinnia/irq.h index 71ff500..e4f0f71 100644 --- a/include/zinnia/irq.h +++ b/include/zinnia/irq.h @@ -1,9 +1,9 @@ #pragma once -#include -#include #include #include +#include +#include enum irq_status : uint8_t { IRQ_STATUS_HANDLED, @@ -35,13 +35,13 @@ struct irq_line { bool is_busy; }; -void irq_line_attach(struct irq_line* self, struct irq_handler* handler); - struct irq_percpu { uint32_t level; bool in_interrupt; }; +void irq_line_attach(struct irq_line* self, struct irq_handler* handler); + void irq_lock(); void irq_unlock(); bool irq_set_interrupted(bool is_interrupted); diff --git a/include/zinnia/mman.h b/include/zinnia/mman.h new file mode 100644 index 0000000..403829c --- /dev/null +++ b/include/zinnia/mman.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +enum prot_flags : uint8_t { + PROT_NONE = __PROT_NONE, + PROT_READ = __PROT_READ, + PROT_WRITE = __PROT_WRITE, + PROT_EXEC = __PROT_EXEC, +}; + +enum map_flags : uint8_t { + MAP_FILE = __MAP_FILE, + MAP_SHARED = __MAP_SHARED, + MAP_PRIVATE = __MAP_PRIVATE, + MAP_FIXED = __MAP_FIXED, + MAP_ANON = __MAP_ANON, +}; + +enum ms_flags : uint8_t { + MS_ASYNC = __MS_ASYNC, + MS_INVALIDATE = __MS_INVALIDATE, + MS_SYNC = __MS_SYNC, +}; diff --git a/include/zinnia/mem/object.h b/include/zinnia/object.h similarity index 95% rename from include/zinnia/mem/object.h rename to include/zinnia/object.h index 20f86d0..916aaec 100644 --- a/include/zinnia/mem/object.h +++ b/include/zinnia/object.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -37,7 +37,7 @@ struct paged_vmo { struct vmo object; struct pager_ops source; list_head(struct page_list*) cache; - struct spinlock lock; + spinlock_t lock; }; errno_t vmo_new_paged(struct pager_ops ops, struct paged_vmo** out); diff --git a/include/zinnia/mem/page.h b/include/zinnia/page.h similarity index 96% rename from include/zinnia/mem/page.h rename to include/zinnia/page.h index 6b3c0dc..e67048c 100644 --- a/include/zinnia/mem/page.h +++ b/include/zinnia/page.h @@ -3,7 +3,7 @@ #include #include -enum page_type : uint32_t { +enum page_type : uint8_t { PAGE_PHYS = 0, // Regular physical memory. }; diff --git a/include/zinnia/mem/pager.h b/include/zinnia/pager.h similarity index 100% rename from include/zinnia/mem/pager.h rename to include/zinnia/pager.h index c73b083..35ee304 100644 --- a/include/zinnia/mem/pager.h +++ b/include/zinnia/pager.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include struct pager { errno_t (*try_get_page)(struct pager* pager, uintptr_t offset); diff --git a/include/zinnia/percpu.h b/include/zinnia/percpu.h index 6a4764f..af2399c 100644 --- a/include/zinnia/percpu.h +++ b/include/zinnia/percpu.h @@ -1,11 +1,11 @@ #pragma once -#include -#include #include #include #include #include +#include +#include ASSERT_TYPE(struct arch_percpu); diff --git a/include/zinnia/mem/pmap.h b/include/zinnia/pmap.h similarity index 84% rename from include/zinnia/mem/pmap.h rename to include/zinnia/pmap.h index 12b499f..5182eb8 100644 --- a/include/zinnia/mem/pmap.h +++ b/include/zinnia/pmap.h @@ -1,12 +1,12 @@ #pragma once +#include #include -#include #include #include #include -enum pte_flags { +enum pte_flags : uint8_t { PTE_READ = 1 << 0, // Can read from this page. PTE_WRITE = 1 << 1, // Can write to this page. PTE_EXEC = 1 << 2, // Can execute code on this page. @@ -14,8 +14,8 @@ enum pte_flags { PTE_DIR = 1 << 4, // Is a non-leaf page. }; -enum cache_mode { - CACHE_NONE, // None means "nothing explicit" here. +enum cache_mode : uint8_t { + CACHE_ANY, CACHE_WRITE_COMBINE, CACHE_WRITE_THROUGH, CACHE_WRITE_BACK, @@ -24,7 +24,7 @@ enum cache_mode { struct pmap { phys_t root; - struct spinlock lock; + spinlock_t lock; bool is_user; }; @@ -35,8 +35,6 @@ errno_t pmap_protect(struct pmap* pt, uintptr_t vaddr, enum pte_flags flags); errno_t pmap_unmap(struct pmap* pt, uintptr_t vaddr); void pmap_set(struct pmap* pt); -pte_t* pmap_pte_resolve(struct pmap* pt, virt_t virt); - void pte_clear(pte_t* pte); pte_t pte_build(phys_t addr, enum pte_flags flags, enum cache_mode cache); bool pte_is_present(pte_t* pte); diff --git a/include/zinnia/print.h b/include/zinnia/print.h index c5044c5..e843405 100644 --- a/include/zinnia/print.h +++ b/include/zinnia/print.h @@ -4,6 +4,6 @@ #include [[__format(printf, 1, 2)]] -void printf(const char* message, ...); +void kprintf(const char* message, ...); void kvprintf(const char* message, va_list args); diff --git a/include/zinnia/rcu.h b/include/zinnia/rcu.h new file mode 100644 index 0000000..a9297a7 --- /dev/null +++ b/include/zinnia/rcu.h @@ -0,0 +1,4 @@ +#pragma once + +void rcu_read_lock(); +void rcu_read_unlock(); diff --git a/include/zinnia/refcount.h b/include/zinnia/refcount.h index c4b8f4e..0620202 100644 --- a/include/zinnia/refcount.h +++ b/include/zinnia/refcount.h @@ -7,17 +7,5 @@ struct refcount { size_t count; }; -static inline void refcount_inc(struct refcount* rc) { - rc->count++; -} - -struct foo { - int a; - struct refcount rc; -}; - -static void do_foo() { - struct foo f = {.a = 4, .rc = {0}}; - - refcount_inc(&f.rc); -} +void refcount_inc(struct refcount* rc); +void refcount_dec(struct refcount* rc); diff --git a/include/zinnia/spin.h b/include/zinnia/spin.h index 0372df8..f7728a9 100644 --- a/include/zinnia/spin.h +++ b/include/zinnia/spin.h @@ -4,13 +4,13 @@ // Busy-waits in a loop until the lock is freed. // Does not put the CPU to sleep. -struct spinlock { +typedef struct { uint32_t owner; uint32_t next; -}; +} spinlock_t; // Attempts to lock a spinlock. If it's already locked, waits until it's freed. -void spin_lock(struct spinlock* spin); +void spin_lock(spinlock_t* spin); // Unlocks a spinlock. -void spin_unlock(struct spinlock* spin); +void spin_unlock(spinlock_t* spin); diff --git a/include/zinnia/syscall.h b/include/zinnia/syscall.h index 74765d7..b90d495 100644 --- a/include/zinnia/syscall.h +++ b/include/zinnia/syscall.h @@ -2,10 +2,24 @@ #include -typedef void (*syscall_fn_t)(struct arch_context* ctx); +enum syscall_kind { + SYSKIND_CALL = 0, // Regular call, returns error and/or value. + SYSKIND_CONTEXT, // Consumes the entire register image. + SYSKIND_NORETURN, // Does not resume control to the calling process. +}; + +struct syscall { + void (*handler)(struct arch_context*); + enum syscall_kind kind; +}; + +struct syscall_return { + int errno; + uintptr_t value; +}; void syscall_dispatch(struct arch_context* ctx); -#define __SYSCALL_DEFINE(_idx, name) void syscall_##name(struct arch_context* ctx); -#include -#undef __SYSCALL_DEFINE +#include + +extern const struct syscall syscall_table[256]; diff --git a/include/zinnia/syscall_list.h b/include/zinnia/syscall_list.h new file mode 100644 index 0000000..cdb7c0a --- /dev/null +++ b/include/zinnia/syscall_list.h @@ -0,0 +1,149 @@ +#pragma once + +#include + +extern void sys_exit(struct arch_context* ctx); +extern void sys_syslog(struct arch_context* ctx); +extern void sys_getuname(struct arch_context* ctx); +extern void sys_setuname(struct arch_context* ctx); +extern void sys_archctl(struct arch_context* ctx); +extern void sys_reboot(struct arch_context* ctx); +extern void sys_mmap(struct arch_context* ctx); +extern void sys_munmap(struct arch_context* ctx); +extern void sys_mprotect(struct arch_context* ctx); +extern void sys_madvise(struct arch_context* ctx); +extern void sys_sigprocmask(struct arch_context* ctx); +extern void sys_sigsuspend(struct arch_context* ctx); +extern void sys_sigpending(struct arch_context* ctx); +extern void sys_sigaction(struct arch_context* ctx); +extern void sys_sigtimedwait(struct arch_context* ctx); +extern void sys_sigaltstack(struct arch_context* ctx); +extern void sys_sigreturn(struct arch_context* ctx); +extern void sys_sigqueue(struct arch_context* ctx); +extern void sys_execve(struct arch_context* ctx); +extern void sys_fexecve(struct arch_context* ctx); +extern void sys_fork(struct arch_context* ctx); +extern void sys_kill(struct arch_context* ctx); +extern void sys_gettid(struct arch_context* ctx); +extern void sys_getpid(struct arch_context* ctx); +extern void sys_getppid(struct arch_context* ctx); +extern void sys_waitid(struct arch_context* ctx); +extern void sys_waitpid(struct arch_context* ctx); +extern void sys_pread(struct arch_context* ctx); +extern void sys_readv(struct arch_context* ctx); +extern void sys_pwrite(struct arch_context* ctx); +extern void sys_writev(struct arch_context* ctx); +extern void sys_seek(struct arch_context* ctx); +extern void sys_ioctl(struct arch_context* ctx); +extern void sys_openat(struct arch_context* ctx); +extern void sys_close(struct arch_context* ctx); +extern void sys_fstat(struct arch_context* ctx); +extern void sys_fstatat(struct arch_context* ctx); +extern void sys_statvfs(struct arch_context* ctx); +extern void sys_fstatvfs(struct arch_context* ctx); +extern void sys_faccessat(struct arch_context* ctx); +extern void sys_fcntl(struct arch_context* ctx); +extern void sys_ftruncate(struct arch_context* ctx); +extern void sys_truncate(struct arch_context* ctx); +extern void sys_fallocate(struct arch_context* ctx); +extern void sys_fadvise(struct arch_context* ctx); +extern void sys_utimensat(struct arch_context* ctx); +extern void sys_mknodat(struct arch_context* ctx); +extern void sys_getcwd(struct arch_context* ctx); +extern void sys_chdir(struct arch_context* ctx); +extern void sys_fchdir(struct arch_context* ctx); +extern void sys_mkdirat(struct arch_context* ctx); +extern void sys_rmdirat(struct arch_context* ctx); +extern void sys_getdents(struct arch_context* ctx); +extern void sys_renameat(struct arch_context* ctx); +extern void sys_fchmod(struct arch_context* ctx); +extern void sys_fchmodat(struct arch_context* ctx); +extern void sys_fchownat(struct arch_context* ctx); +extern void sys_linkat(struct arch_context* ctx); +extern void sys_symlinkat(struct arch_context* ctx); +extern void sys_unlinkat(struct arch_context* ctx); +extern void sys_readlinkat(struct arch_context* ctx); +extern void sys_flock(struct arch_context* ctx); +extern void sys_ppoll(struct arch_context* ctx); +extern void sys_dup(struct arch_context* ctx); +extern void sys_dup3(struct arch_context* ctx); +extern void sys_sync(struct arch_context* ctx); +extern void sys_fsync(struct arch_context* ctx); +extern void sys_fdatasync(struct arch_context* ctx); +extern void sys_getgroups(struct arch_context* ctx); +extern void sys_setgroups(struct arch_context* ctx); +extern void sys_getsid(struct arch_context* ctx); +extern void sys_setsid(struct arch_context* ctx); +extern void sys_setuid(struct arch_context* ctx); +extern void sys_getuid(struct arch_context* ctx); +extern void sys_setgid(struct arch_context* ctx); +extern void sys_getgid(struct arch_context* ctx); +extern void sys_geteuid(struct arch_context* ctx); +extern void sys_seteuid(struct arch_context* ctx); +extern void sys_getegid(struct arch_context* ctx); +extern void sys_setegid(struct arch_context* ctx); +extern void sys_getpgid(struct arch_context* ctx); +extern void sys_setpgid(struct arch_context* ctx); +extern void sys_getresuid(struct arch_context* ctx); +extern void sys_setresuid(struct arch_context* ctx); +extern void sys_getresgid(struct arch_context* ctx); +extern void sys_setresgid(struct arch_context* ctx); +extern void sys_setreuid(struct arch_context* ctx); +extern void sys_setregid(struct arch_context* ctx); +extern void sys_umask(struct arch_context* ctx); +extern void sys_pipe(struct arch_context* ctx); +extern void sys_futex_wait(struct arch_context* ctx); +extern void sys_futex_wake(struct arch_context* ctx); +extern void sys_thread_create(struct arch_context* ctx); +extern void sys_thread_kill(struct arch_context* ctx); +extern void sys_thread_exit(struct arch_context* ctx); +extern void sys_thread_setname(struct arch_context* ctx); +extern void sys_thread_getname(struct arch_context* ctx); +extern void sys_timer_create(struct arch_context* ctx); +extern void sys_timer_set(struct arch_context* ctx); +extern void sys_timer_get(struct arch_context* ctx); +extern void sys_timer_getoverrun(struct arch_context* ctx); +extern void sys_timer_delete(struct arch_context* ctx); +extern void sys_itimer_get(struct arch_context* ctx); +extern void sys_itimer_set(struct arch_context* ctx); +extern void sys_clock_get(struct arch_context* ctx); +extern void sys_clock_getres(struct arch_context* ctx); +extern void sys_clock_set(struct arch_context* ctx); +extern void sys_sleep(struct arch_context* ctx); +extern void sys_yield(struct arch_context* ctx); +extern void sys_chroot(struct arch_context* ctx); +extern void sys_mount(struct arch_context* ctx); +extern void sys_umount(struct arch_context* ctx); +extern void sys_socket(struct arch_context* ctx); +extern void sys_socketpair(struct arch_context* ctx); +extern void sys_shutdown(struct arch_context* ctx); +extern void sys_bind(struct arch_context* ctx); +extern void sys_connect(struct arch_context* ctx); +extern void sys_accept(struct arch_context* ctx); +extern void sys_listen(struct arch_context* ctx); +extern void sys_getpeername(struct arch_context* ctx); +extern void sys_getsockname(struct arch_context* ctx); +extern void sys_getsockopt(struct arch_context* ctx); +extern void sys_setsockopt(struct arch_context* ctx); +extern void sys_sendmsg(struct arch_context* ctx); +extern void sys_recvmsg(struct arch_context* ctx); +extern void sys_getentropy(struct arch_context* ctx); +extern void sys_getrusage(struct arch_context* ctx); +extern void sys_getrlimit(struct arch_context* ctx); +extern void sys_setrlimit(struct arch_context* ctx); +extern void sys_getpriority(struct arch_context* ctx); +extern void sys_setpriority(struct arch_context* ctx); +extern void sys_sched_getparam(struct arch_context* ctx); +extern void sys_sched_setparam(struct arch_context* ctx); +extern void sys_module_insert(struct arch_context* ctx); +extern void sys_module_remove(struct arch_context* ctx); +extern void sys_epoll_create(struct arch_context* ctx); +extern void sys_epoll_ctl(struct arch_context* ctx); +extern void sys_epoll_pwait(struct arch_context* ctx); +extern void sys_timerfd_create(struct arch_context* ctx); +extern void sys_timerfd_gettime(struct arch_context* ctx); +extern void sys_timerfd_settime(struct arch_context* ctx); +extern void sys_signalfd_create(struct arch_context* ctx); +extern void sys_eventfd_create(struct arch_context* ctx); +extern void sys_msync(struct arch_context* ctx); +extern void sys_sysconf(struct arch_context* ctx); diff --git a/include/zinnia/vas.h b/include/zinnia/vas.h index ea33ac0..e277423 100644 --- a/include/zinnia/vas.h +++ b/include/zinnia/vas.h @@ -1,10 +1,10 @@ #pragma once +#include #include -#include -#include -#include #include +#include +#include // Virtual address space. struct vas { diff --git a/include/zinnia/vfs.h b/include/zinnia/vfs.h index c6f8ad2..2f09743 100644 --- a/include/zinnia/vfs.h +++ b/include/zinnia/vfs.h @@ -1,12 +1,11 @@ #pragma once -#include -#include -#include #include #include #include -#include +#include +#include +#include struct vfs_mount { struct refcount rc; @@ -25,7 +24,7 @@ struct vfs_node; struct vfs_regular_ops { errno_t (*read)(struct vfs_node* file, struct iovec_iter* buffer, uint64_t offset, ssize_t* out_read); errno_t (*write)(struct vfs_node* file, struct iovec_iter* buffer, uint64_t offset, ssize_t* out_written); - errno_t (*devctl)(struct vfs_node* file, ); + errno_t (*devctl)(struct vfs_node* file); }; struct vfs_node { @@ -33,7 +32,7 @@ struct vfs_node { const struct vfs_regular_ops* ops; struct vfs_vnode* vnode; struct vfs_path path; - struct string abs_path; + const char* abs_path; bool has_path; }; diff --git a/include/zinnia/wait.h b/include/zinnia/wait.h index 83d14f6..8cd1758 100644 --- a/include/zinnia/wait.h +++ b/include/zinnia/wait.h @@ -8,7 +8,7 @@ struct task; // A queue of tasks waiting for an event. struct wait_queue { tailq_head(struct task) waiters; - struct spinlock lock; + spinlock_t lock; }; void wait_queue_init(struct wait_queue* wq); diff --git a/mem/init.c b/mem/init.c index 26999a6..a4eef31 100644 --- a/mem/init.c +++ b/mem/init.c @@ -5,7 +5,6 @@ #include #include #include -#include #include extern uint8_t __ld_text_start[]; @@ -24,7 +23,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ const size_t pgsz = arch_mem_page_size(); - printf("Memory map:\n"); + kprintf("Memory map:\n"); for (size_t i = 0; i < map_len; i++) { if (map[i].length == 0) continue; @@ -45,7 +44,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ break; } - printf("[%p - %p] %s\n", (void*)map[i].address, (void*)(map[i].address + map[i].length - 1), label); + kprintf("[%p - %p] %s\n", (void*)map[i].address, (void*)(map[i].address + map[i].length - 1), label); } // Set up the bootstrap allocator. @@ -55,7 +54,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ largest = &map[i]; } mem_phys_bootstrap(largest); - printf( + kprintf( "Using region [%p - %p] for bootstrap allocator\n", (void*)largest->address, (void*)(largest->address + largest->length - 1) @@ -66,43 +65,43 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ // since we're likely going to map it at a different base address. mem_hhdm_base = tmp_hhdm; - assert(pmap_new_kernel(&kernel_vas.pmap, 0) == 0, "Unable to allocate the kernel page table\n"); + kassert(pmap_new_kernel(&kernel_vas.pmap, 0) == 0, "Unable to allocate the kernel page table\n"); // text - printf("Mapping text segment at %p\n", __ld_text_start); + kprintf("Mapping text segment at %p\n", __ld_text_start); for (uint8_t* p = __ld_text_start; p <= __ld_text_end; p += pgsz) { errno_t status = pmap_map( &kernel_vas.pmap, (uintptr_t)p, (phys_t)(p - __ld_kernel_start + kernel_phys), PTE_READ | PTE_EXEC, - CACHE_NONE + CACHE_ANY ); assert(!status, "Failed to map %p with error %i\n", p, status); } // rodata - printf("Mapping rodata segment at %p\n", __ld_rodata_start); + kprintf("Mapping rodata segment at %p\n", __ld_rodata_start); for (uint8_t* p = __ld_rodata_start; p < __ld_rodata_end; p += pgsz) { errno_t status = pmap_map( &kernel_vas.pmap, (uintptr_t)p, (phys_t)(p - __ld_kernel_start + kernel_phys), PTE_READ, - CACHE_NONE + CACHE_ANY ); assert(!status, "Failed to map %p with error %i\n", p, status); } // data - printf("Mapping data segment at %p\n", __ld_data_start); + kprintf("Mapping data segment at %p\n", __ld_data_start); for (uint8_t* p = __ld_data_start; p < __ld_data_end; p += pgsz) { errno_t status = pmap_map( &kernel_vas.pmap, (uintptr_t)p, (phys_t)(p - __ld_kernel_start + kernel_phys), PTE_READ | PTE_WRITE, - CACHE_NONE + CACHE_ANY ); assert(!status, "Failed to map %p with error %i\n", p, status); } @@ -122,7 +121,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ for (size_t p = 0; p <= map[i].length; p += pgsz) { uintptr_t vaddr = (uintptr_t)(map[i].address + p + tmp_hhdm); phys_t paddr = (phys_t)(map[i].address + p); - errno_t status = pmap_map(&kernel_vas.pmap, vaddr, paddr, PTE_READ | PTE_WRITE, CACHE_NONE); + errno_t status = pmap_map(&kernel_vas.pmap, vaddr, paddr, PTE_READ | PTE_WRITE, CACHE_ANY); assert(!status, "Failed to map HHDM page %p to %p with error %i\n", (void*)vaddr, (void*)paddr, status); } } @@ -152,7 +151,7 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ for (size_t page = 0; page < length; page += pgsz) { phys_t paddr; assert(!mem_phys_alloc(1, 0, &paddr), "Failed to allocate memory for PFNDB!\n"); - pmap_map(&kernel_vas.pmap, vaddr + page, paddr, PTE_READ | PTE_WRITE, CACHE_NONE); + pmap_map(&kernel_vas.pmap, vaddr + page, paddr, PTE_READ | PTE_WRITE, CACHE_ANY); } } vm_pfndb = (struct page*)arch_vm_pfndb_addr(); @@ -163,5 +162,5 @@ void mem_init(struct phys_mem* map, size_t map_len, uintptr_t kernel_virt, phys_ slab_init(); - printf("Memory initialization complete\n"); + kprintf("Memory initialization complete\n"); } diff --git a/mem/pmap.c b/mem/pmap.c index a5ab52f..90e2e90 100644 --- a/mem/pmap.c +++ b/mem/pmap.c @@ -1,6 +1,6 @@ +#include #include -#include -#include +#include #include #include #include @@ -15,7 +15,7 @@ errno_t pmap_kernel(struct pmap* pt, enum alloc_flags flags) { struct pmap result = { .root = addr, - .lock = (struct spinlock){0}, + .lock = (spinlock_t){0}, .is_user = false, }; @@ -35,7 +35,7 @@ errno_t pmap_new_user(struct pmap* pt, enum alloc_flags flags) { struct pmap result = { .root = user_l1, - .lock = (struct spinlock){0}, + .lock = (spinlock_t){0}, .is_user = true, }; @@ -67,7 +67,7 @@ static pte_t* get_pte(struct pmap* pt, uintptr_t vaddr, bool is_user, bool check if (pte_is_present(pte)) { // Get the next level. - *pte = pte_build(pte_address(pte), level_flags, CACHE_NONE); + *pte = pte_build(pte_address(pte), level_flags, CACHE_ANY); current_head = HHDM_PTR(pte_address(pte)); } else { // If the current level isn't present, we can skip the rest. @@ -78,7 +78,7 @@ static pte_t* get_pte(struct pmap* pt, uintptr_t vaddr, bool is_user, bool check if (mem_phys_alloc(1, 0, &addr) != 0) return nullptr; - *pte = pte_build(addr, level_flags, CACHE_NONE); + *pte = pte_build(addr, level_flags, CACHE_ANY); current_head = HHDM_PTR(addr); } } diff --git a/mem/pmm.c b/mem/pmm.c index f2a3ea0..aa368ee 100644 --- a/mem/pmm.c +++ b/mem/pmm.c @@ -1,6 +1,6 @@ +#include #include -#include -#include +#include #include #include #include @@ -56,7 +56,7 @@ void mem_phys_bootstrap(struct phys_mem* mem) { } static struct page* pmm_head = nullptr; -static struct spinlock pmm_lock = {0}; +static spinlock_t pmm_lock = {0}; static size_t pmm_total_free = 0; static errno_t freelist_alloc(size_t num_pages, enum alloc_flags flags, phys_t* out) { @@ -150,5 +150,5 @@ void mem_phys_init(struct phys_mem* map, size_t length) { } const size_t free_bytes = (pmm_total_free * arch_mem_page_size()); - printf("Total available memory: %zu MiB\n", free_bytes / 1024 / 1024); + kprintf("Total available memory: %zu MiB\n", free_bytes / 1024 / 1024); } diff --git a/mem/slab.c b/mem/slab.c index 8bd6a11..c74496f 100644 --- a/mem/slab.c +++ b/mem/slab.c @@ -1,8 +1,8 @@ -#include #include #include #include #include +#include typedef struct { size_t num_pages; // Amount of pages connected to this slab. @@ -10,8 +10,8 @@ typedef struct { } slab_info; struct slab { - struct spinlock lock; // Access lock. - size_t ent_size; // Size of one entry. + spinlock_t lock; // Access lock. + size_t ent_size; // Size of one entry. void** head; }; @@ -24,7 +24,7 @@ typedef struct { static struct slab slabs[8] = {0}; static errno_t slab_new(struct slab* slab, size_t size) { - slab->lock = (struct spinlock){0}; + slab->lock = (spinlock_t){0}; // Allocate a new page for the head. phys_t addr; diff --git a/mem/vas.c b/mem/vas.c index 0073df9..c48bf75 100644 --- a/mem/vas.c +++ b/mem/vas.c @@ -1,8 +1,9 @@ -#include #include #include +#include #include #include +#include // Try to create a new, empty virtual address space. errno_t vma_new(struct vas** out) { @@ -51,7 +52,7 @@ errno_t vma_map_vmo( struct vmo* vmo, uintptr_t addr, size_t len, - enum zn_vm_flags flags, + enum prot_flags flags, uintptr_t vmo_offset ) { const size_t page_size = arch_mem_page_size(); @@ -79,16 +80,16 @@ errno_t vma_map_vmo( phys_t paddr = (phys_t)vm_page_addr(page_obj); enum pte_flags pf = 0; - if (flags & ZN_VM_MAP_READ) + if (flags & PROT_READ) pf |= PTE_READ; - if (flags & ZN_VM_MAP_WRITE) + if (flags & PROT_WRITE) pf |= PTE_WRITE; - if (flags & ZN_VM_MAP_EXEC) + if (flags & PROT_EXEC) pf |= PTE_EXEC; if (vas->pmap.is_user) pf |= PTE_USER; - status = pmap_map(&vas->pmap, p * page_size, paddr, pf, CACHE_NONE); + status = pmap_map(&vas->pmap, p * page_size, paddr, pf, CACHE_ANY); if (status != 0) return status; } diff --git a/meson.build b/meson.build index 194c8ce..8014aa7 100644 --- a/meson.build +++ b/meson.build @@ -48,10 +48,6 @@ add_project_link_arguments( language: 'c', ) -if target_machine.cpu_family() == 'x86_64' - add_project_arguments('-masm=intel', language: 'c') -endif - common_includes = include_directories('include') cfg = configuration_data() @@ -60,11 +56,21 @@ cfg.set_quoted('ZINNIA_ARCH', target_machine.cpu_family()) cfg.set_quoted('ZINNIA_COMPILER_ID', c_compiler.get_id() + ' ' + c_compiler.version()) cfg.set_quoted('ZINNIA_LINKER_ID', c_compiler.get_linker_id()) +# Parse kernel config +kv = import('keyval') +kconfig = kv.load(get_option('config_path')) +foreach k, v : kconfig + if v == 'y' + cfg.set10(k, true) + else + cfg.set(k, v) + endif +endforeach + kernel_c_args = [ '-ffreestanding', '-nostdinc', # We provide our own headers. '-fno-stack-protector', - '-fno-omit-frame-pointer', '-fno-pie', ] @@ -78,14 +84,16 @@ kernel_link_args = [ ] kernel_includes = [ - include_directories( - 'arch' / target_machine.cpu_family() / 'include', - ), + include_directories('arch' / target_machine.cpu_family() / 'include'), ] kernel_sources = [] -configure_file(configuration: cfg, output: 'config.h') +configure_file( + configuration: cfg, + output: 'config.h', + depfile: get_option('config_path'), +) # Goes first so we can add arch-specific flags to drivers. subdir('arch' / target_machine.cpu_family()) @@ -105,14 +113,12 @@ executable( include_directories: [ common_includes, kernel_includes, - uacpi_includes, ], c_args: kernel_c_args, link_args: kernel_link_args, link_depends: kernel_lds, sources: [ kernel_sources, - uacpi_sources, ], install: true, install_dir: '/boot', diff --git a/meson.options b/meson.options index 1531305..c2159ca 100644 --- a/meson.options +++ b/meson.options @@ -1,4 +1,3 @@ -# Meta options option( 'headers_only', type: 'boolean', @@ -6,9 +5,9 @@ option( description: 'Only install headers', ) -# Core options -option('sched', type: 'combo', choices: ['simple'], value: 'simple') - -# Firmware -option('acpi', type: 'boolean', value: true) -option('open_firmware', type: 'boolean', value: true) +option( + 'config_path', + type: 'string', + value: '.config', + description: 'Relative path to the generated Kconfig file', +) diff --git a/subprojects/uacpi b/subprojects/uacpi index 9c9b26d..f5f6cc2 160000 --- a/subprojects/uacpi +++ b/subprojects/uacpi @@ -1 +1 @@ -Subproject commit 9c9b26d6291a1cdd9014cc5bb6b03e596697cbfd +Subproject commit f5f6cc29f85dd5db0dd79c47700c8f3ebce18be4 diff --git a/syscalls/archctl.c b/syscalls/archctl.c index b1ab46b..a7c2705 100644 --- a/syscalls/archctl.c +++ b/syscalls/archctl.c @@ -1,8 +1,6 @@ #include -#include +#include -errno_t arch_archctl(zn_archctl_t op, uintptr_t value); - -errno_t syscall_archctl(struct arch_context* ctx) { - return arch_archctl((zn_archctl_t)ctx->ARCH_CTX_A0, (uintptr_t)ctx->ARCH_CTX_A1); +void syscall_archctl(struct arch_context* ctx) { + ctx->ARCH_CTX_RET0 = arch_archctl(ctx->ARCH_CTX_A0, ctx->ARCH_CTX_A1); } diff --git a/syscalls/dispatch.c b/syscalls/dispatch.c index 5c3b802..ec44bf9 100644 --- a/syscalls/dispatch.c +++ b/syscalls/dispatch.c @@ -6,20 +6,161 @@ #include #include -static const syscall_fn_t dispatch_table[] = { -#undef __ZINNIA_UAPI_SYSCALL_NUMBERS_H // We want to include the header again -#define __SYSCALL_DEFINE(idx, name) [idx] = syscall_##name, -#include -#undef __SYSCALL_DEFINE +const struct syscall syscall_table[256] = { + [0] = {sys_exit, 0}, + [1] = {sys_syslog, 0}, + [2] = {sys_getuname, 0}, + [3] = {sys_setuname, 0}, + [4] = {sys_archctl, 0}, + [5] = {sys_reboot, 0}, + [6] = {sys_mmap, 0}, + [7] = {sys_munmap, 0}, + [8] = {sys_mprotect, 0}, + [9] = {sys_madvise, 0}, + [10] = {sys_sigprocmask, 0}, + [11] = {sys_sigsuspend, 0}, + [12] = {sys_sigpending, 0}, + [13] = {sys_sigaction, 0}, + [14] = {sys_sigtimedwait, 0}, + [15] = {sys_sigaltstack, 0}, + [16] = {sys_sigreturn, 0}, + [17] = {sys_sigqueue, 0}, + [18] = {sys_execve, 0}, + [19] = {sys_fexecve, 0}, + [20] = {sys_fork, SYSKIND_CONTEXT}, + [21] = {sys_kill, 0}, + [22] = {sys_gettid, 0}, + [23] = {sys_getpid, 0}, + [24] = {sys_getppid, 0}, + [25] = {sys_waitid, 0}, + [26] = {sys_waitpid, 0}, + [27] = {sys_pread, 0}, + [28] = {sys_readv, 0}, + [29] = {sys_pwrite, 0}, + [30] = {sys_writev, 0}, + [31] = {sys_seek, 0}, + [32] = {sys_ioctl, 0}, + [33] = {sys_openat, 0}, + [34] = {sys_close, 0}, + [35] = {sys_fstat, 0}, + [36] = {sys_fstatat, 0}, + [37] = {sys_statvfs, 0}, + [38] = {sys_fstatvfs, 0}, + [39] = {sys_faccessat, 0}, + [40] = {sys_fcntl, 0}, + [41] = {sys_ftruncate, 0}, + [42] = {sys_truncate, 0}, + [43] = {sys_fallocate, 0}, + [44] = {sys_fadvise, 0}, + [45] = {sys_utimensat, 0}, + [46] = {sys_mknodat, 0}, + [47] = {sys_getcwd, 0}, + [48] = {sys_chdir, 0}, + [49] = {sys_fchdir, 0}, + [50] = {sys_mkdirat, 0}, + [51] = {sys_rmdirat, 0}, + [52] = {sys_getdents, 0}, + [53] = {sys_renameat, 0}, + [54] = {sys_fchmod, 0}, + [55] = {sys_fchmodat, 0}, + [56] = {sys_fchownat, 0}, + [57] = {sys_linkat, 0}, + [58] = {sys_symlinkat, 0}, + [59] = {sys_unlinkat, 0}, + [60] = {sys_readlinkat, 0}, + [61] = {sys_flock, 0}, + [62] = {sys_ppoll, 0}, + [63] = {sys_dup, 0}, + [64] = {sys_dup3, 0}, + [65] = {sys_sync, 0}, + [66] = {sys_fsync, 0}, + [67] = {sys_fdatasync, 0}, + [68] = {sys_getgroups, 0}, + [69] = {sys_setgroups, 0}, + [70] = {sys_getsid, 0}, + [71] = {sys_setsid, 0}, + [72] = {sys_setuid, 0}, + [73] = {sys_getuid, 0}, + [74] = {sys_setgid, 0}, + [75] = {sys_getgid, 0}, + [76] = {sys_geteuid, 0}, + [77] = {sys_seteuid, 0}, + [78] = {sys_getegid, 0}, + [79] = {sys_setegid, 0}, + [80] = {sys_getpgid, 0}, + [81] = {sys_setpgid, 0}, + [82] = {sys_getresuid, 0}, + [83] = {sys_setresuid, 0}, + [84] = {sys_getresgid, 0}, + [85] = {sys_setresgid, 0}, + [86] = {sys_setreuid, 0}, + [87] = {sys_setregid, 0}, + [88] = {sys_umask, 0}, + [89] = {sys_pipe, 0}, + [90] = {sys_futex_wait, 0}, + [91] = {sys_futex_wake, 0}, + [92] = {sys_thread_create, 0}, + [93] = {sys_thread_kill, 0}, + [94] = {sys_thread_exit, 0}, + [95] = {sys_thread_setname, 0}, + [96] = {sys_thread_getname, 0}, + [97] = {sys_timer_create, 0}, + [98] = {sys_timer_set, 0}, + [99] = {sys_timer_get, 0}, + [100] = {sys_timer_getoverrun, 0}, + [101] = {sys_timer_delete, 0}, + [102] = {sys_itimer_get, 0}, + [103] = {sys_itimer_set, 0}, + [104] = {sys_clock_get, 0}, + [105] = {sys_clock_getres, 0}, + [106] = {sys_clock_set, 0}, + [107] = {sys_sleep, 0}, + [108] = {sys_yield, 0}, + [109] = {sys_chroot, 0}, + [110] = {sys_mount, 0}, + [111] = {sys_umount, 0}, + [112] = {sys_socket, 0}, + [113] = {sys_socketpair, 0}, + [114] = {sys_shutdown, 0}, + [115] = {sys_bind, 0}, + [116] = {sys_connect, 0}, + [117] = {sys_accept, 0}, + [118] = {sys_listen, 0}, + [119] = {sys_getpeername, 0}, + [120] = {sys_getsockname, 0}, + [121] = {sys_getsockopt, 0}, + [122] = {sys_setsockopt, 0}, + [123] = {sys_sendmsg, 0}, + [124] = {sys_recvmsg, 0}, + [125] = {sys_getentropy, 0}, + [126] = {sys_getrusage, 0}, + [127] = {sys_getrlimit, 0}, + [128] = {sys_setrlimit, 0}, + [129] = {sys_getpriority, 0}, + [130] = {sys_setpriority, 0}, + [131] = {sys_sched_getparam, 0}, + [132] = {sys_sched_setparam, 0}, + [133] = {sys_module_insert, 0}, + [134] = {sys_module_remove, 0}, + [135] = {sys_epoll_create, 0}, + [136] = {sys_epoll_ctl, 0}, + [137] = {sys_epoll_pwait, 0}, + [138] = {sys_timerfd_create, 0}, + [139] = {sys_timerfd_gettime, 0}, + [140] = {sys_timerfd_settime, 0}, + [141] = {sys_signalfd_create, 0}, + [142] = {sys_eventfd_create, 0}, + [143] = {sys_msync, 0}, + [144] = {sys_sysconf, 0}, }; void syscall_dispatch(struct arch_context* ctx) { const size_t num = ctx->ARCH_CTX_NUM; - if (num >= ARRAY_SIZE(dispatch_table)) { + if (num >= ARRAY_SIZE(syscall_table) || syscall_table[num].handler == nullptr) { ctx->ARCH_CTX_RET0 = ENOSYS; return; } - dispatch_table[num](ctx); + syscall_table[num].handler(ctx); } diff --git a/syscalls/handle.c b/syscalls/handle.c deleted file mode 100644 index 213556b..0000000 --- a/syscalls/handle.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -errno_t syscall_handle_clone(struct arch_context* ctx) { - zn_handle_t handle = ctx->ARCH_CTX_A0; - zn_rights_t cloned_rights = ctx->ARCH_CTX_A1; - __user zn_handle_t* cloned = (__user zn_handle_t*)ctx->ARCH_CTX_A2; - - struct task* current = percpu_get()->sched.current; - struct namespace* ns = current->namespace; - - struct namespace_desc desc; - errno_t status = namespace_get(ns, handle, &desc); - if (status != 0) - return status; - - zn_handle_t new_handle; - status = namespace_clone_desc(ns, &desc, cloned_rights, &new_handle); - if (status != 0) - return status; - - if (!usercopy_write(cloned, &new_handle, sizeof(new_handle))) { - namespace_del_desc(ns, new_handle); - return ZN_ERR_BAD_BUFFER; - } - - return 0; -} - -errno_t syscall_handle_drop(struct arch_context* ctx) { - zn_handle_t handle = ctx->ARCH_CTX_A0; - struct task* current = percpu_get()->sched.current; - - return namespace_del_desc(current->namespace, handle); -} - -errno_t syscall_handle_validate(struct arch_context* ctx) { - zn_handle_t handle = ctx->ARCH_CTX_A0; - struct task* current = percpu_get()->sched.current; - - struct namespace_desc desc; - return namespace_get(current->namespace, handle, &desc); -} diff --git a/syscalls/meson.build b/syscalls/meson.build index b1120c4..c2826eb 100644 --- a/syscalls/meson.build +++ b/syscalls/meson.build @@ -1,4 +1,5 @@ kernel_sources += files( 'archctl.c', 'dispatch.c', + 'futex.c', ) diff --git a/syscalls/random.c b/syscalls/random.c deleted file mode 100644 index 89d5ff3..0000000 --- a/syscalls/random.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -errno_t syscall_random_entropy(struct arch_context* ctx) { - return ZN_ERR_UNSUPPORTED; -} - -errno_t syscall_random_get(struct arch_context* ctx) { - return ZN_ERR_UNSUPPORTED; -} diff --git a/syscalls/system.c b/syscalls/system.c deleted file mode 100644 index b981e14..0000000 --- a/syscalls/system.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include -#include - -errno_t syscall_log(struct arch_context* ctx) { - __user const char* msg = (__user const char*)ctx->ARCH_CTX_A0; - size_t len = ctx->ARCH_CTX_A1; - - char* buf = mem_alloc(len, ALLOC_NOZERO); - if (!buf) { - return ENOMEM; - } - - if (usercopy_read(buf, msg, len)) { - console_write(buf, len); - - mem_free(buf); - return 0; - } - - mem_free(buf); - return ZN_ERR_BAD_BUFFER; -} - -errno_t syscall_page_size(struct arch_context* ctx) { - __user size_t* out = (__user size_t*)ctx->ARCH_CTX_A0; - - size_t size = arch_mem_page_size(); - if (!usercopy_write(out, &size, sizeof(size))) - return ZN_ERR_BAD_BUFFER; - - return 0; -} - -errno_t syscall_time(struct arch_context* ctx) { - __user uint64_t* out = (__user uint64_t*)ctx->ARCH_CTX_A0; - - uint64_t time = clock_get_elapsed_ns(); - if (!usercopy_write(out, &time, sizeof(time))) - return ZN_ERR_BAD_BUFFER; - - return 0; -} diff --git a/syscalls/thread.c b/syscalls/thread.c deleted file mode 100644 index f6d46cb..0000000 --- a/syscalls/thread.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -errno_t syscall_thread_create(struct arch_context* ctx) { - zn_handle_t ns_handle = ctx->ARCH_CTX_A0; - __user const char* name = (__user const char*)ctx->ARCH_CTX_A1; - size_t name_len = ctx->ARCH_CTX_A2; - enum zn_thread_flags flags = ctx->ARCH_CTX_A3; - __user zn_handle_t* out = (__user zn_handle_t*)ctx->ARCH_CTX_A4; - - struct task* current = percpu_get()->sched.current; - // Resolve namespace. - struct namespace* ns; - if (ns_handle == ZN_HANDLE_THIS_NS) { - ns = current->namespace; - } else { - struct namespace_desc ns_desc; - errno_t status = namespace_get(current->namespace, ns_handle, &ns_desc); - if (status != 0) - return status; - if (ns_desc.type != NAMESPACE_DESC_NS) - return ZN_ERR_BAD_HANDLE; - ns = ns_desc.value.namespace; - } - - // Copy name from userspace. - if (name_len == 0 || name_len >= TASK_NAME_MAX) - return EINVAL; - - char task_name[TASK_NAME_MAX] = {}; - if (!usercopy_read(task_name, name, name_len)) - return ZN_ERR_BAD_BUFFER; - - // Create the task sharing the caller's address space. - // Uses sched_to_user as a placeholder entry — the real IP/SP come from thread_start. - struct task* new_task; - errno_t status = task_create(task_name, current->space, ns, sched_to_user, 0, &new_task); - if (status != 0) - return status; - - // Register the task as a handle in the caller's namespace. - struct namespace_desc desc = { - .type = NAMESPACE_DESC_TASK, - .rights = ZN_RIGHTS_ALL, - .value.task = new_task, - }; - - zn_handle_t handle; - status = namespace_add_desc(current->namespace, desc, &handle); - if (status != 0) - return status; - - if (!usercopy_write(out, &handle, sizeof(handle))) { - namespace_del_desc(current->namespace, handle); - return ZN_ERR_BAD_BUFFER; - } - - return 0; -} - -errno_t syscall_thread_start(struct arch_context* ctx) { - zn_handle_t thread_handle = ctx->ARCH_CTX_A0; - uintptr_t ip = ctx->ARCH_CTX_A1; - uintptr_t sp = ctx->ARCH_CTX_A2; - uintptr_t arg = ctx->ARCH_CTX_A3; - - struct task* current = percpu_get()->sched.current; - struct sched_percpu* sched = &percpu_get()->sched; - - // Look up the task. - struct namespace_desc desc; - errno_t status = namespace_get(current->namespace, thread_handle, &desc); - if (status != 0) - return status; - if (desc.type != NAMESPACE_DESC_TASK) - return ZN_ERR_BAD_HANDLE; - - struct task* task = desc.value.task; - - // Allocate a start info block for the thread entry. - struct task_start_info* info = mem_alloc(sizeof(struct task_start_info), 0); - if (!info) - return ENOMEM; - - info->ip = ip; - info->sp = sp; - info->arg = arg; - - // Re-initialize the task's arch context to enter user mode via sched_to_user_arg. - status = - arch_task_init(&task->context, sched_to_user, (uintptr_t)info, task->kernel_stack + KERNEL_STACK_SIZE, true); - if (status != 0) { - mem_free(info); - return status; - } - - // Add to run queue. - sched_add_task(sched, task); - return 0; -} - -errno_t syscall_thread_exit(struct arch_context* ctx) { - struct sched_percpu* sched = &percpu_get()->sched; - sched->current->state = TASK_STATE_DEAD; - sched_yield(sched); - unreachable(); -} diff --git a/syscalls/vas.c b/syscalls/vas.c deleted file mode 100644 index 2e94473..0000000 --- a/syscalls/vas.c +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include - -errno_t syscall_vas_create(struct arch_context* ctx) { - return ZN_ERR_UNSUPPORTED; -}