rumpk/hal/abi.zig

85 lines
2.6 KiB
Zig

// 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 HAL ABI: The Contract between L0 (Zig) and L1 (Nim)
//!
//! This struct defines the function pointer table for platform abstraction.
//! All function pointers use C calling convention for Nim FFI compatibility.
// NOTE(Build): Zig 0.15.x requires explicit callconv on extern struct fn pointers
pub const HAL = extern struct {
/// Write to console/serial
console_write: *const fn ([*]const u8, usize) callconv(.c) void,
/// Allocate physical pages
palloc: *const fn (usize) callconv(.c) ?*anyopaque,
/// Free physical pages
pfree: *const fn (*anyopaque) callconv(.c) void,
/// Register interrupt handler
irq_register: *const fn (u8, *const fn () callconv(.c) void) callconv(.c) void,
/// Get current time in nanoseconds
timer_now_ns: *const fn () callconv(.c) u64,
/// Halt the CPU
halt: *const fn () callconv(.c) noreturn,
};
// SAFETY(HAL): Global instance initialized by init() before any access.
// SAFETY(HAL): Global HAL instance is populated by `init()` during the early boot phase.
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,
// SAFETY(HAL): Placeholders for future implementation.
// These function pointers are not called until implemented.
.irq_register = undefined, // TODO(HAL): Implement IRQ registration
.timer_now_ns = undefined, // TODO(HAL): Implement timer
.halt = halt_impl,
};
}
fn halt_impl() callconv(.c) 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;
}