// HAL ABI - The Contract between L0 (Zig) and L1 (Nim) // This struct is the "contract" for future language integration pub const HAL = extern struct { /// Write to console/serial console_write: *const fn ([*]const u8, usize) void, /// Allocate physical pages palloc: *const fn (usize) ?*anyopaque, /// Free physical pages pfree: *const fn (*anyopaque) void, /// Register interrupt handler irq_register: *const fn (u8, *const fn () void) void, /// Get current time in nanoseconds timer_now_ns: *const fn () u64, /// Halt the CPU halt: *const fn () noreturn, }; /// Global HAL instance - initialized by boot code pub var hal: HAL = undefined; /// Initialize the HAL with platform-specific implementations pub fn init(console: anytype, allocator: anytype) void { hal = HAL{ .console_write = console.write, .palloc = allocator.alloc, .pfree = allocator.free, .irq_register = undefined, // TODO .timer_now_ns = undefined, // TODO .halt = halt_impl, }; } fn halt_impl() noreturn { while (true) { asm volatile ("wfi"); } } // ========================================================= // Exports for Nim FFI // ========================================================= export fn rumpk_console_write(ptr: [*]const u8, len: usize) void { hal.console_write(ptr, len); } export fn rumpk_palloc(pages: usize) ?*anyopaque { return hal.palloc(pages); } export fn rumpk_pfree(ptr: *anyopaque) void { hal.pfree(ptr); } export fn rumpk_halt() noreturn { hal.halt(); } var mock_ticks: u64 = 0; export fn rumpk_timer_now_ns() u64 { // Phase 1 Mock: Incrementing counter to simulate time passage per call mock_ticks += 100000; // 100us per call return mock_ticks; }