rumpk/hal/stubs.zig

97 lines
2.7 KiB
Zig

// Markus Maiwald (Architect) | Voxis Forge (AI)
// RUMPK L0
// libc_stubs.zig
// We are the standard library now.
const uart = @import("uart.zig");
// =========================================================
// Heap Stubs (Bump Allocator with Block Headers)
// =========================================================
// Simple Bump Allocator for L0
var heap: [8 * 1024 * 1024]u8 align(4096) = undefined; // 8MB Heap
var heap_idx: usize = 0;
// 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;
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) {
return null;
}
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 {
return 0; // TODO: Implement real timer
}