diff --git a/src/example_dtree/CMakeLists.txt b/src/example_dtree/CMakeLists.txt index a438bbae..945e82d9 100644 --- a/src/example_dtree/CMakeLists.txt +++ b/src/example_dtree/CMakeLists.txt @@ -1,5 +1,5 @@ SETUP_EXECUTABLE(example_dtree) -target_link_libraries(example_dtree PRIVATE device_tree_access Debug startup stdbigos) +target_link_libraries(example_dtree PRIVATE dt_access Debug startup stdbigos) ADD_QEMU_TARGET(example_dtree) diff --git a/src/example_trap/CMakeLists.txt b/src/example_trap/CMakeLists.txt deleted file mode 100644 index 2f42d853..00000000 --- a/src/example_trap/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -SETUP_EXECUTABLE(example_trap) - -target_link_libraries(example_trap PRIVATE startup hal Debug stdbigos) - -ADD_QEMU_TARGET(example_trap) diff --git a/src/example_trap/entry.c b/src/example_trap/entry.c deleted file mode 100644 index 8a27dee4..00000000 --- a/src/example_trap/entry.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include - -/** - * Syscall handler - called when userspace makes an ecall. - * Receives syscall arguments as reg_t (architecture-dependent). - * Returns error code and value - error in a0, value in a1. - */ -hal_syscall_result_t syscall_handler(reg_t syscall_id, reg_t arg0, reg_t arg1, reg_t arg2, reg_t arg3, reg_t arg4, - reg_t arg5) { - (void)arg1; - (void)arg2; - (void)arg3; - (void)arg4; - (void)arg5; - switch (syscall_id) { - case 0: // Example syscall 0 - DEBUG_PRINTF("syscall: got 0x%lx\n", arg0); - return (hal_syscall_result_t){.error = 0, .value = 0xeed}; - - default: - // unknown syscall - DEBUG_PRINTF("syscall: unknown number %lu\n", (u64)syscall_id); - return (hal_syscall_result_t){.error = 1, .value = 0}; - } -} - -static u8 g_user_mode_stack[4096] __attribute__((aligned(4096))); -static u8 g_task_frame_storage[512] __attribute__((aligned(64))); - -void user_fn(void) { - while (1) { - DEBUG_PRINTF("from user mode\n"); - - register reg_t a0 __asm__("a0") = 0xbade; - register reg_t a1 __asm__("a1") = 0xaaaa; - register reg_t syscallid __asm__("a7") = 0; - __asm__ volatile("ecall" : "+r"(a0), "+r"(a1) : "r"(syscallid) : "memory"); - DEBUG_PRINTF("syscall returned: 0x%lx, 0x%lx\n", a0, a1); - } -} - -static inline void* get_sp(void) { - void* sp; - __asm__("mv %0, sp" : "=r"(sp)); - return sp; -} - -void main([[maybe_unused]] u32 hartid, [[maybe_unused]] const void* fdt) { - DEBUG_PRINTF("on old stack: hartid %d, fdt %p, sp %p\n", hartid, fdt, get_sp()); - - // Initialize trap handling system - if (hal_trap_init() != ERR_NONE) { - DEBUG_PRINTF("failed to initialize trap handling\n"); - return; - } - - if (hal_trap_register_syscall_handler(syscall_handler) != ERR_NONE) { - DEBUG_PRINTF("failed to register syscall handler\n"); - return; - } - - // Prepare initial userspace task and start it. - hal_trap_frame_t* task_frame = hal_trap_frame_from_buffer(g_task_frame_storage, sizeof(g_task_frame_storage)); - if (!task_frame) { - DEBUG_PRINTF("failed to allocate task frame\n"); - return; - } - - void* user_stack_top = &g_user_mode_stack[sizeof(g_user_mode_stack)]; - DEBUG_PRINTF("starting user task, pc=%p, sp=%p\n", (void*)user_fn, user_stack_top); - hal_trap_frame_init_userspace(task_frame, (uintptr_t)user_stack_top, (uintptr_t)user_fn); - hal_trap_start_task(task_frame); - - // Should never reach here (hal_trap_start_task is noreturn) -} diff --git a/src/example_umode_concurrency/CMakeLists.txt b/src/example_umode_concurrency/CMakeLists.txt deleted file mode 100644 index fae04c11..00000000 --- a/src/example_umode_concurrency/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -SETUP_EXECUTABLE(example_umode_concurrency) - -target_link_libraries(example_umode_concurrency PRIVATE startup hal Debug stdbigos) - -ADD_QEMU_TARGET(example_umode_concurrency) diff --git a/src/example_umode_concurrency/entry.c b/src/example_umode_concurrency/entry.c deleted file mode 100644 index d4fee263..00000000 --- a/src/example_umode_concurrency/entry.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include - -enum { - SYSCALL_PRINT = 1, - SYSCALL_YIELD = 2, -}; - -// extracted from fdt /cpus/timebase-frequency -// QEMU tells 10MHz -#define TIMEBASE_FREQUENCY 10000000ul -#define SLEEP_TIME (u64)(TIMEBASE_FREQUENCY * 1) - -static hal_trap_frame_t* g_inactive_task_frame = nullptr; - -static u8 g_user_mode_stack_a[4096] __attribute__((aligned(4096))); -static u8 g_user_mode_stack_b[4096] __attribute__((aligned(4096))); - -// Backing storage for both task frames. -static u8 g_active_frame_storage[512] __attribute__((aligned(64))); -static u8 g_saved_frame_storage[512] __attribute__((aligned(64))); - -static inline u64 read_time() { - u64 now; - __asm__ volatile("rdtime %0" : "=r"(now)::"memory"); - return now; -} - -static inline void user_sys_print(const char* str) { - register reg_t a0 __asm__("a0") = (reg_t)str; - register reg_t a7 __asm__("a7") = SYSCALL_PRINT; - __asm__ volatile("ecall" : "+r"(a0) : "r"(a7) : "memory"); - if (a0 != 0) { - dprintf("print syscall failed: %lu\n", (u64)a0); - } -} - -static inline void user_sys_yield() { - register reg_t a0 __asm__("a0") = 0; - register reg_t a7 __asm__("a7") = SYSCALL_YIELD; - __asm__ volatile("ecall" : "=r"(a0) : "r"(a7) : "memory"); - if (a0 != 0) { - dprintf("yield syscall failed: %lu\n", (u64)a0); - } -} - -[[noreturn]] void user_task_a() { - while (true) { - user_sys_print("[U-task A] running\n"); - u64 start = read_time(); - while (read_time() - start < SLEEP_TIME) user_sys_yield(); - } -} - -[[noreturn]] void user_task_b() { - while (true) { - user_sys_print("[U-task B] running\n"); - u64 start = read_time(); - while (read_time() - start < SLEEP_TIME) user_sys_yield(); - } -} - -hal_syscall_result_t syscall_handler(reg_t syscall_id, reg_t arg0, reg_t arg1, reg_t arg2, reg_t arg3, reg_t arg4, - reg_t arg5) { - (void)arg1; - (void)arg2; - (void)arg3; - (void)arg4; - (void)arg5; - - switch (syscall_id) { - case SYSCALL_PRINT: dputs((const char*)arg0); return (hal_syscall_result_t){.error = 0, .value = 0}; - case SYSCALL_YIELD: - if (!g_inactive_task_frame) { - return (hal_syscall_result_t){.error = 1, .value = 0}; - } - - error_t swap_err = hal_trap_request_deferred_frame_swap(g_inactive_task_frame); - if (swap_err != ERR_NONE) { - return (hal_syscall_result_t){.error = (reg_t)swap_err, .value = 0}; - } - return (hal_syscall_result_t){.error = 0, .value = 0}; - default: - dprintf("unknown syscall id=%lu\n", (u64)syscall_id); - return (hal_syscall_result_t){.error = 1, .value = 0}; - } -} - -void main([[maybe_unused]] u32 hartid, [[maybe_unused]] const void* fdt) { - if (hal_trap_init() != ERR_NONE) { - dputs("trap_init failed\n"); - return; - } - - hal_trap_frame_t* active_task_frame = - hal_trap_frame_from_buffer(g_active_frame_storage, sizeof(g_active_frame_storage)); - g_inactive_task_frame = hal_trap_frame_from_buffer(g_saved_frame_storage, sizeof(g_saved_frame_storage)); - if (!active_task_frame || !g_inactive_task_frame) { - dputs("trap frame allocation failed\n"); - return; - } - - __asm__ volatile("csrs scounteren, 0b111"); // enable all scounteren bits so that user mode can read timebase - - hal_trap_frame_init_userspace(active_task_frame, (uintptr_t)&g_user_mode_stack_a[sizeof(g_user_mode_stack_a)], - (uintptr_t)user_task_a); - hal_trap_frame_init_userspace(g_inactive_task_frame, (uintptr_t)&g_user_mode_stack_b[sizeof(g_user_mode_stack_b)], - (uintptr_t)user_task_b); - - if (hal_trap_register_syscall_handler(syscall_handler) != ERR_NONE) { - dputs("syscall handler registration failed\n"); - return; - } - - dputs("starting U-mode concurrency example\n"); - hal_trap_start_task(active_task_frame); -} diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 9c44d0e8..da60efea 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -1,7 +1,7 @@ SETUP_EXECUTABLE(kernel) target_compile_definitions(kernel PRIVATE $,__DEBUG__ __LOGLVL__=3, __LOGLVL__=1>) -target_link_libraries(kernel PRIVATE Debug stdbigos hal) +target_link_libraries(kernel PRIVATE Debug stdbigos dt_access) target_link_options(kernel PRIVATE -static-pie -e kinit) diff --git a/src/kernel/address_space/address_space.c b/src/kernel/address_space/address_space.c new file mode 100644 index 00000000..e69de29b diff --git a/src/kernel/address_space/address_space.h b/src/kernel/address_space/address_space.h new file mode 100644 index 00000000..d62ffa45 --- /dev/null +++ b/src/kernel/address_space/address_space.h @@ -0,0 +1,35 @@ +#ifndef KERNEL_ADDRESS_SPACE_ADDRESS_SPACE +#define KERNEL_ADDRESS_SPACE_ADDRESS_SPACE + +#include "stdbigos/error.h" +#include "stdbigos/types.h" + +typedef enum : u16 { + AS_FLAGS_READ = (1ull << 0), + AS_FLAGS_WRITE = (1ull << 1), + AS_FLAGS_EXECUTE = (1ull << 2), + AS_FLAGS_MAPPED = (1ull << 3), + AS_FLAGS_GLOBAL = (1ull << 4), + AS_FLAGS_USER = (1ull << 5), +} address_space_region_flags_t; + +typedef struct { + address_space_region_flags_t flags; + void* addr; + size_t size; +} address_space_region_t; + +typedef struct { + address_space_region_t* regions; + size_t regions_count; + bool does_manage_own_memory; + bool active; +} address_space_t; + +error_t address_space_init(); + +error_t address_space_init_from_buffer(address_space_region_t* regions, size_t count); + +error_t address_space_delegate_memory_management(void** addrOUT); + +#endif // !KERNEL_ADDRESS_SPACE_ADDRESS_SPACE diff --git a/src/kernel/hal/arch/riscv/address_space.c b/src/kernel/hal/arch/riscv/address_space.c new file mode 100644 index 00000000..fba54c16 --- /dev/null +++ b/src/kernel/hal/arch/riscv/address_space.c @@ -0,0 +1 @@ +#include "hal/include/address_space.h" diff --git a/src/lib/hal/arch/riscv/csr.h b/src/kernel/hal/arch/riscv/csr.h similarity index 100% rename from src/lib/hal/arch/riscv/csr.h rename to src/kernel/hal/arch/riscv/csr.h diff --git a/src/lib/hal/arch/riscv/csr_vals.h b/src/kernel/hal/arch/riscv/csr_vals.h similarity index 100% rename from src/lib/hal/arch/riscv/csr_vals.h rename to src/kernel/hal/arch/riscv/csr_vals.h diff --git a/src/lib/hal/arch/riscv/memory_region.c b/src/kernel/hal/arch/riscv/memory_region.c similarity index 95% rename from src/lib/hal/arch/riscv/memory_region.c rename to src/kernel/hal/arch/riscv/memory_region.c index 6b8d22c5..27143301 100644 --- a/src/lib/hal/arch/riscv/memory_region.c +++ b/src/kernel/hal/arch/riscv/memory_region.c @@ -1,6 +1,7 @@ -#include #include +#include "hal/include/memory_regions.h" + typedef struct { u32 idx; bool is_in_resmem; diff --git a/src/lib/hal/arch/riscv/trap.S b/src/kernel/hal/arch/riscv/trap.S similarity index 100% rename from src/lib/hal/arch/riscv/trap.S rename to src/kernel/hal/arch/riscv/trap.S diff --git a/src/lib/hal/arch/riscv/trap.c b/src/kernel/hal/arch/riscv/trap.c similarity index 99% rename from src/lib/hal/arch/riscv/trap.c rename to src/kernel/hal/arch/riscv/trap.c index 065bb288..ddb3061a 100644 --- a/src/lib/hal/arch/riscv/trap.c +++ b/src/kernel/hal/arch/riscv/trap.c @@ -1,7 +1,6 @@ -#include "trap.h" +#include "hal/include/trap.h" #include -#include #include #include #include @@ -10,6 +9,7 @@ #include "csr.h" #include "csr_vals.h" +#include "trap.h" extern void hal_riscv_trap_entry(); extern void hal_riscv_trap_restore(void*); diff --git a/src/lib/hal/arch/riscv/trap.h b/src/kernel/hal/arch/riscv/trap.h similarity index 99% rename from src/lib/hal/arch/riscv/trap.h rename to src/kernel/hal/arch/riscv/trap.h index 3ac5e74b..b4a00011 100644 --- a/src/lib/hal/arch/riscv/trap.h +++ b/src/kernel/hal/arch/riscv/trap.h @@ -9,7 +9,6 @@ #ifndef HAL_ARCH_RISCV_TRAP_H #define HAL_ARCH_RISCV_TRAP_H -#include #include /** diff --git a/src/lib/hal/hal.c b/src/kernel/hal/hal.c similarity index 96% rename from src/lib/hal/hal.c rename to src/kernel/hal/hal.c index ad80d3bb..d0e346bc 100644 --- a/src/lib/hal/hal.c +++ b/src/kernel/hal/hal.c @@ -1,4 +1,4 @@ -#include +#include "hal/include/hal.h" #include "dt/dt.h" diff --git a/src/lib/hal/hal_internal.h b/src/kernel/hal/hal_internal.h similarity index 100% rename from src/lib/hal/hal_internal.h rename to src/kernel/hal/hal_internal.h diff --git a/src/kernel/hal/include/address_space.h b/src/kernel/hal/include/address_space.h new file mode 100644 index 00000000..46ea8e9b --- /dev/null +++ b/src/kernel/hal/include/address_space.h @@ -0,0 +1,45 @@ +#ifndef HAL_ADDRESS_SPACE +#define HAL_ADDRESS_SPACE + +#include "stdbigos/error.h" +#include "stdbigos/memory_types.h" +#include "stdbigos/types.h" + +typedef struct { + alignas(64) u8 data[32]; +} hal_address_space_t; + +typedef enum : u16 { + HAL_ASR_FLAGS_READ = (1ull << 0), + HAL_ASR_FLAGS_WRITE = (1ull << 1), + HAL_ASR_FLAGS_EXECUTE = (1ull << 2), +} hal_address_region_flag_t; + +typedef enum : u16 { + HAL_AS_GLOBAL = (1ull << 0), + HAL_AS_USER = (1ull << 1), +} hal_address_space_flag_t; + +error_t hal_enable_virtual_address_spaces(hal_address_space_t* initial_as); + +error_t hal_address_space_init(hal_address_space_t* as, hal_address_space_flag_t flags); + +/** + * @brief Gets an array of available frame sizes + * + * Returns an array of available frame sizes in ascending order + * + * @param countOUT Pointer to a variable where the size of the array will be written to + * @returns Pointer to the first element of the array + * */ +[[nodiscard]] [[gnu::nonnull]] +const u32* hal_get_available_frame_sizes(u32* countOUT); + +error_t hal_address_space_set_active(hal_address_space_t* as); + +error_t hal_address_space_map(hal_address_space_t as, uintptr_t vaddr, physical_memory_region_t pmem, + hal_address_region_flag_t flags); + +error_t hal_address_space_unmap(hal_address_space_t as, uintptr_t vaddr, physical_memory_region_t* pmemOUT); + +#endif // !HAL_ADDRESS_SPACE diff --git a/include/hal/hal.h b/src/kernel/hal/include/hal.h similarity index 100% rename from include/hal/hal.h rename to src/kernel/hal/include/hal.h diff --git a/include/hal/memory_regions.h b/src/kernel/hal/include/memory_regions.h similarity index 100% rename from include/hal/memory_regions.h rename to src/kernel/hal/include/memory_regions.h diff --git a/include/hal/trap.h b/src/kernel/hal/include/trap.h similarity index 100% rename from include/hal/trap.h rename to src/kernel/hal/include/trap.h diff --git a/src/kernel/memory_management/physical_memory/manager.c b/src/kernel/memory_management/physical_memory/manager.c index 916ae23b..dbd52e63 100644 --- a/src/kernel/memory_management/physical_memory/manager.c +++ b/src/kernel/memory_management/physical_memory/manager.c @@ -5,7 +5,7 @@ #include #include "allocator.h" -#include "hal/memory_regions.h" +#include "hal/include/memory_regions.h" #include "stdbigos/address.h" #include "stdbigos/error.h" #include "stdbigos/types.h" diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 2e47f342..bf4ff0be 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,6 +1,6 @@ file(GLOB CHILDREN RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *) foreach(CHILD ${CHILDREN}) - if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${CHILD}) + if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${CHILD} AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CHILD}/CMakeLists.txt) add_subdirectory(${CHILD}) endif() endforeach() diff --git a/src/lib/dt/CMakeLists.txt b/src/lib/dt/CMakeLists.txt index f78c5788..af171cd5 100644 --- a/src/lib/dt/CMakeLists.txt +++ b/src/lib/dt/CMakeLists.txt @@ -1,6 +1,6 @@ -SETUP_LIBRARY(device_tree_access) +SETUP_LIBRARY(dt_access) -target_link_libraries(device_tree_access +target_link_libraries(dt_access PUBLIC stdbigos PRIVATE Debug ) diff --git a/src/lib/hal/CMakeLists.txt b/src/lib/hal/CMakeLists.txt deleted file mode 100644 index 76e1d885..00000000 --- a/src/lib/hal/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -SETUP_LIBRARY(hal) - -target_link_libraries(hal - PUBLIC stdbigos - PRIVATE Debug - PRIVATE device_tree_access -) diff --git a/src/lib/startup/CMakeLists.txt b/src/lib/startup/CMakeLists.txt index 66c3d226..e5717098 100644 --- a/src/lib/startup/CMakeLists.txt +++ b/src/lib/startup/CMakeLists.txt @@ -2,6 +2,6 @@ SETUP_LIBRARY(startup) set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld) -target_link_libraries(startup PRIVATE hal relocations stdbigos) +target_link_libraries(startup PRIVATE relocations stdbigos) target_link_options(startup PUBLIC -static-pie -T ${LINKER_SCRIPT}) set_target_properties(startup PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT}) diff --git a/src/lib/startup/startup.c b/src/lib/startup/startup.c index 392c9ef4..82e08fe7 100644 --- a/src/lib/startup/startup.c +++ b/src/lib/startup/startup.c @@ -6,7 +6,6 @@ */ -#include #include #include #include @@ -23,7 +22,7 @@ extern int main(u32 hartid, const void* fdt); [[gnu::section(".fini"), noreturn, gnu::noinline]] static void _Exit([[maybe_unused]] int return_code) { - while (1) hal_wait_for_interrupt(); + while (1) __asm__ volatile("wfi" ::: "memory"); } // NOLINTBEGIN(clang-analyzer-security.ArrayBound)