// SPDX-License-Identifier: LCL-1.0 // Copyright (c) 2026 Markus Maiwald // Stewardship: Self Sovereign Society Foundation // // This file is part of the Nexus Commonwealth. // See legal/LICENSE_COMMONWEALTH.md for license terms. //! Rumpk Layer 0: libc Stubs (Bump Allocator) //! //! We are the standard library now. Provides malloc/free/realloc/calloc //! for libraries that expect libc (e.g., LwIP). //! //! DECISION(Alloc): Bump allocator chosen for simplicity and determinism. //! Memory is never reclaimed; system reboots to reset. const uart = @import("uart.zig"); // Sovereign timer — canonical time source for the entire kernel extern fn rumpk_timer_now_ns() u64; // ========================================================= // Heap Stubs (Bump Allocator with Block Headers) // ========================================================= // Simple Bump Allocator for L0 // SAFETY(Heap): Memory is written by malloc before any read occurs. // Initialized to `undefined` to avoid zeroing 32MB at boot. var heap: [16 * 1024 * 1024]u8 align(4096) = undefined; var heap_idx: usize = 0; var heap_init_done: bool = false; export fn debug_print(s: [*]const u8, len: usize) void { uart.print(s[0..len]); } // Support for C-shim printf (clib.c) // REMOVED: Already exported by entry_riscv.zig (hal.o) // export fn hal_console_write(ptr: [*]const u8, len: usize) void { // uart.print(ptr[0..len]); // } // Header structure (64 bytes aligned to match LwIP MEM_ALIGNMENT) const BlockHeader = struct { size: usize, _pad: [64 - @sizeOf(usize)]u8, }; export fn malloc(size: usize) ?*anyopaque { if (size == 0) return null; if (!heap_init_done) { if (heap_idx != 0) { uart.print("[Alloc] WARNING: BSS NOT ZEROED! heap_idx: "); uart.print_hex(heap_idx); uart.print("\n"); heap_idx = 0; } heap_init_done = true; } const total_needed = size + @sizeOf(BlockHeader); const align_mask: usize = 63; // 64-byte alignment const aligned_idx = (heap_idx + align_mask) & ~align_mask; if (aligned_idx + total_needed > heap.len) { uart.print("[Alloc] OOM! Size: "); uart.print_hex(size); uart.print(" Used: "); uart.print_hex(heap_idx); uart.print("\n"); return null; } // Trace allocations (disabled to reduce noise) uart.print("[Alloc] "); uart.print_hex(size); uart.print(" -> Used: "); uart.print_hex(aligned_idx + total_needed); uart.print("\n"); const base_ptr = &heap[aligned_idx]; const header = @as(*BlockHeader, @ptrCast(@alignCast(base_ptr))); header.size = size; heap_idx = aligned_idx + total_needed; return @as(*anyopaque, @ptrFromInt(@intFromPtr(base_ptr) + @sizeOf(BlockHeader))); } export fn free(ptr: ?*anyopaque) void { // Bump allocator: no-op free. _ = ptr; } export fn realloc(ptr: ?*anyopaque, size: usize) ?*anyopaque { if (ptr == null) return malloc(size); if (size == 0) { free(ptr); return null; } // Retrieve old size from header const base_addr = @intFromPtr(ptr.?) - @sizeOf(BlockHeader); const header = @as(*BlockHeader, @ptrFromInt(base_addr)); const old_size = header.size; // Optimization: If new size is smaller and it's the last block, we could shrink? // But for a bump allocator, just allocate new. const new_ptr = malloc(size); if (new_ptr) |np| { const copy_size = if (size < old_size) size else old_size; const src = @as([*]const u8, @ptrCast(ptr.?)); const dst = @as([*]u8, @ptrCast(np)); var i: usize = 0; while (i < copy_size) : (i += 1) { dst[i] = src[i]; } free(ptr); return np; } return null; } export fn calloc(nmemb: usize, size: usize) ?*anyopaque { const total = nmemb * size; const ptr = malloc(total); if (ptr) |p| { const dst = @as([*]u8, @ptrCast(p)); var i: usize = 0; while (i < total) : (i += 1) { dst[i] = 0; } } return ptr; } // ========================================================= // Rumpk Runtime Support // ========================================================= export fn get_ticks() u32 { // Delegate to sovereign timer — single source of truth for all time const ns = rumpk_timer_now_ns(); return @truncate(ns / 1_000_000); // ns → ms } // export fn rumpk_timer_set_ns(ns: u64) void { // // Stub: Timer not implemented in L0 yet // _ = ns; // } export fn fb_kern_get_addr() usize { return 0; // Stub: No framebuffer } export fn nexshell_main() void { uart.print("[Kernel] NexShell Stub Executed\n"); } extern fn k_handle_syscall(nr: usize, a0: usize, a1: usize, a2: usize) usize; // export fn exit(code: c_int) noreturn { // _ = code; // while (true) asm volatile ("wfi"); // } // ========================================================= // Atomic Stubs (To resolve linker errors with libcompiler_rt) // ========================================================= export fn __atomic_compare_exchange(len: usize, ptr: ?*anyopaque, expected: ?*anyopaque, desired: ?*anyopaque, success: c_int, failure: c_int) bool { _ = len; _ = ptr; _ = expected; _ = desired; _ = success; _ = failure; return true; } export fn __atomic_fetch_add_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_sub_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_and_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_or_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_xor_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_nand_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_umax_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_fetch_umin_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_load_16(ptr: ?*const anyopaque, model: c_int) u128 { _ = ptr; _ = model; return 0; } export fn __atomic_store_16(ptr: ?*anyopaque, val: u128, model: c_int) void { _ = ptr; _ = val; _ = model; } export fn __atomic_exchange_16(ptr: ?*anyopaque, val: u128, model: c_int) u128 { _ = ptr; _ = val; _ = model; return 0; } export fn __atomic_compare_exchange_16(ptr: ?*anyopaque, exp: ?*anyopaque, des: u128, weak: bool, success: c_int, failure: c_int) bool { _ = ptr; _ = exp; _ = des; _ = weak; _ = success; _ = failure; return true; } // ========================================================= // Nim Runtime Stubs // ========================================================= export fn setLengthStr() void {} export fn addChar() void {} export fn callDepthLimitReached__OOZOOZOOZOOZOOZOOZOOZOOZOOZusrZlibZnimZsystem_u3026() void { while (true) {} } export var NTIdefect__SEK9acOiG0hv2dnGQbk52qg_: ?*anyopaque = null;