const std = @import("std"); const system = @import("system"); const thread = @import("thread.zig"); const boot = @import("boot.zig"); const vm = system.vm; const syscalls = system.syscalls; const buffer = system.ring_buffer; const heap = system.heap; const PAGE_SIZE = vm.PAGE_SIZE; fn setTokens() void { var tokens: u64 = 0; tokens |= @intFromEnum(system.kernel.Token.Root); tokens |= @intFromEnum(system.kernel.Token.PhysicalMemory); tokens |= @intFromEnum(system.kernel.Token.CreateProcess); syscalls.setTokens(syscalls.getThreadId(), tokens) catch {}; } export fn _start(base: u64, address: u64) callconv(.C) noreturn { main(base, address) catch { while (true) {} }; } inline fn main(base: u64, address: u64) !void { setTokens(); const mapper = vm.MemoryMapper.create(.{ .address = address }, base); var sys_alloc = heap.SystemAllocator.init(mapper, 0x200000, base - 0x200000); // FIXME: Let's not hardcode these. const allocator = sys_alloc.allocator(); const threads = boot.discoverThreadLimit(); var thread_list = std.AutoHashMap(u64, thread.Thread).init(allocator); try thread_list.ensureTotalCapacity(@intCast(threads)); errdefer thread_list.deinit(); var pid: u64 = 1; while (pid <= threads) : (pid += 1) { if (pid == syscalls.getThreadId()) continue; const t = try thread.setupThread(pid, base); try thread_list.put(pid, t); } try boot.setupKernelRingBuffer(base); var kernel_queue = system.ipc.getKernelBuffer().?; outer: while (true) { var msg_type: u64 = undefined; while (kernel_queue.readType(u64, &msg_type)) { switch (msg_type) { @intFromEnum(system.kernel.KernelMessage.MessageReceived) => { var id: u64 = undefined; if (!kernel_queue.readType(u64, &id)) continue :outer; var sender = thread_list.getPtr(id).?; var data: u8 = undefined; if (sender.connection.read(u8, &data)) { syscalls.print(id); syscalls.print(data); } }, else => {}, } } syscalls.wait(); } }