// SPDX-FileCopyrightText: 2024 Himbeer // // SPDX-License-Identifier: AGPL-3.0-or-later const std = @import("std"); const instructions = @import("instructions.zig"); const mem = @import("mem.zig"); const paging = @import("paging.zig"); const process = @import("process.zig"); const sysexchange = @import("sysexchange.zig"); const trap = @import("trap.zig"); pub const Error = error{ Unimplemented, }; pub const HandleError = error{ UnknownSyscall, }; pub fn handler(proc: *process.Info, trap_frame: *trap.Frame) !void { const ret = sysexchange.frameReturn; switch (trap_frame.general_purpose_registers[17]) { 100000 => ret(trap_frame, uprint(trap_frame)), 100001 => ret(trap_frame, launch(trap_frame)), 100002 => ret(trap_frame, end(proc)), 100003 => ret(trap_frame, terminate(proc, trap_frame)), 100004 => ret(trap_frame, processId(proc)), 100005 => ret(trap_frame, threadId(proc)), else => return HandleError.UnknownSyscall, } } // uprint(str_addr: usize, len: usize) void fn uprint(trap_frame: *const trap.Frame) void { const procmem: *paging.Table = @ptrFromInt(instructions.satp.read().ppn << 12); const paddr = procmem.translate(trap_frame.general_purpose_registers[10]).?; const str_ptr: [*]const u8 = @ptrFromInt(paddr); const str = str_ptr[0..trap_frame.general_purpose_registers[11]]; const w = @import("Console.zig").autoChoose().?.writer(); w.print("User message: {s}\r\n", .{str}) catch unreachable; } // launch(bytes: [*]align(@alignOf(std.elf.Elf64_Ehdr)) const u8, len: usize) !usize fn launch(trap_frame: *const trap.Frame) !usize { const alignment = @alignOf(std.elf.Elf64_Ehdr); const bytes_addr = trap_frame.general_purpose_registers[10]; // fixme: Kernel panic if null pointer const bytes_ptr: [*]align(alignment) const u8 = @ptrFromInt(bytes_addr); const len = trap_frame.general_purpose_registers[11]; const bytes = bytes_ptr[0..len]; const new_proc = try process.create(mem.page_allocator, bytes); return new_proc.id; } // end() void fn end(proc: *process.Info) void { proc.terminate(); process.schedule() catch |err| { std.debug.panic("schedule error: {}", .{err}); }; } pub const TerminateError = error{ PidOutOfRange, ProcessNotFound, }; // terminate(pid: u16, tid: usize) !void fn terminate(proc: *const process.Info, trap_frame: *const trap.Frame) !void { const pid_wide = trap_frame.general_purpose_registers[10]; const pid = std.math.cast(u16, pid_wide) orelse { return TerminateError.PidOutOfRange; }; const tid = trap_frame.general_purpose_registers[11]; const target = process.findThread(pid, tid) orelse { return TerminateError.ProcessNotFound; }; target.terminate(); if (target.shouldTerminate(proc)) { process.schedule() catch |err| { std.debug.panic("schedule error: {}", .{err}); }; } } // processId() usize fn processId(proc: *const process.Info) usize { return proc.id; } // threadId() usize fn threadId(proc: *const process.Info) usize { return proc.thread_id; }