// 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: Sovereign Channels (Lock-Free Ring Buffers) //! //! Implements atomic lock-free ring buffers for ION packet communication. //! Provides the "pipes" between kernel and userspace with invariant protection. //! //! SAFETY: All operations use atomic loads/stores with proper memory fences. const std = @import("std"); pub const IonPacket = extern struct { data: u64, phys: u64, len: u16, id: u16, _pad: u32, // Match Nim's 24-byte alignment }; pub const CmdPacket = extern struct { kind: u32, _pad: u32, // Explicit Padding for 8-byte alignment arg: u64, id: u128, // SipHash Provenance (16 bytes) }; // Size: 32 bytes (matches libs/membrane/ion.zig and core/ion.nim) pub fn Ring(comptime T: type) type { return extern struct { head: u32, tail: u32, mask: u32, data: [256]T, }; } // INVARIANT 1: The Handle Barrier fn validate_ring_ptr(ptr: u64) void { // 0x8000_0000 is kernel base, 0x8300_0000 is ION base. if (ptr < 0x8000_0000) { @panic("HAL: Invariant Violation - Invalid Ring Pointer"); } } fn pushGeneric(comptime T: type, ring: *Ring(T), pkt: T) bool { const head = @atomicLoad(u32, &ring.head, .monotonic); const tail = @atomicLoad(u32, &ring.tail, .monotonic); // INVARIANT 2: Overflow Protection const next = (head + 1) & ring.mask; if (next == tail) { return false; } ring.data[head & ring.mask] = pkt; @atomicStore(u32, &ring.head, next, .release); return true; } fn popGeneric(comptime T: type, ring: *Ring(T), out_pkt: *T) bool { const head = @atomicLoad(u32, &ring.head, .monotonic); const tail = @atomicLoad(u32, &ring.tail, .monotonic); // INVARIANT 3: Underflow Protection if (head == tail) { return false; } // Ensure we see data written by producer before reading it asm volatile ("fence r, rw" ::: .{ .memory = true }); out_pkt.* = ring.data[tail & ring.mask]; const next = (tail + 1) & ring.mask; @atomicStore(u32, &ring.tail, next, .release); return true; } // Exported ABI Functions (Hardened) export fn hal_channel_push(handle: u64, pkt: IonPacket) bool { validate_ring_ptr(handle); const ring: *Ring(IonPacket) = @ptrFromInt(handle); return pushGeneric(IonPacket, ring, pkt); } export fn hal_channel_pop(handle: u64, out_pkt: *IonPacket) bool { validate_ring_ptr(handle); const ring: *Ring(IonPacket) = @ptrFromInt(handle); return popGeneric(IonPacket, ring, out_pkt); } export fn hal_cmd_push(handle: u64, pkt: CmdPacket) bool { validate_ring_ptr(handle); const ring: *Ring(CmdPacket) = @ptrFromInt(handle); // uart.print("[HAL] Pushing CMD to "); uart.print_hex(handle); uart.print("\n"); return pushGeneric(CmdPacket, ring, pkt); } export fn hal_cmd_pop(handle: u64, out_pkt: *CmdPacket) bool { validate_ring_ptr(handle); const ring: *Ring(CmdPacket) = @ptrFromInt(handle); // uart.print("[HAL] Popping CMD from "); uart.print_hex(handle); uart.print("\n"); return popGeneric(CmdPacket, ring, out_pkt); } // Stub for term.nim compatibility export fn fiber_can_run_on_channels() bool { return true; }