85 lines
2.1 KiB
Zig
85 lines
2.1 KiB
Zig
const std = @import("std");
|
|
|
|
// --- Protocol Definitions (Match core/ion.nim) ---
|
|
|
|
pub const CmdPacket = extern struct {
|
|
kind: u32,
|
|
arg: u32,
|
|
id: [16]u8, // SipHash Provenance (Matches Nim array[16, byte])
|
|
};
|
|
|
|
pub const IonPacket = extern struct {
|
|
data: u64, // ptr
|
|
phys: u64,
|
|
len: u16,
|
|
id: u16,
|
|
};
|
|
|
|
// Generic Lock-Free Ring Buffer (Single Producer / Single Consumer safe)
|
|
pub fn RingBuffer(comptime T: type) type {
|
|
return extern struct {
|
|
head: u32,
|
|
tail: u32,
|
|
mask: u32,
|
|
data: [256]T,
|
|
|
|
pub fn push(self: *volatile @This(), item: T) bool {
|
|
const head = self.head;
|
|
const tail = self.tail;
|
|
const mask = self.mask;
|
|
|
|
// Check full
|
|
if (((head + 1) & mask) == (tail & mask)) {
|
|
return false;
|
|
}
|
|
|
|
// Write data
|
|
self.data[head & mask] = item;
|
|
|
|
// Commit
|
|
asm volatile ("fence" ::: .{ .memory = true });
|
|
self.head = (head + 1) & mask;
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
|
|
// System Table Layout (Located at 0x83000000)
|
|
pub const SysTable = extern struct {
|
|
magic: u32,
|
|
s_rx: *RingBuffer(IonPacket),
|
|
s_tx: *RingBuffer(IonPacket),
|
|
s_event: *RingBuffer(IonPacket),
|
|
s_cmd: *RingBuffer(CmdPacket),
|
|
s_input: *RingBuffer(IonPacket),
|
|
};
|
|
|
|
const SYSTABLE_ADDR: usize = 0x83000000;
|
|
|
|
// --- API ---
|
|
|
|
pub fn sys_cmd_push(pkt: CmdPacket) bool {
|
|
const sys = @as(*const volatile SysTable, @ptrFromInt(SYSTABLE_ADDR));
|
|
|
|
// Safety check magic (0x4E585553 = "NXUS")
|
|
if (sys.magic != 0x4E585553) return false;
|
|
|
|
// Push to Command Ring
|
|
return sys.s_cmd.push(pkt);
|
|
}
|
|
|
|
pub fn sys_input_pop(out_pkt: *IonPacket) bool {
|
|
const sys = @as(*const volatile SysTable, @ptrFromInt(SYSTABLE_ADDR));
|
|
if (sys.magic != 0x4E585553) return false;
|
|
|
|
const ring = sys.s_input;
|
|
const head = @atomicLoad(u32, &ring.head, .acquire);
|
|
const tail = @atomicLoad(u32, &ring.tail, .monotonic);
|
|
|
|
if (head == tail) return false;
|
|
|
|
out_pkt.* = ring.data[tail & ring.mask];
|
|
@atomicStore(u32, &ring.tail, tail + 1, .release);
|
|
return true;
|
|
}
|