diff options
-rw-r--r-- | src/interrupts.zig | 85 |
1 files changed, 79 insertions, 6 deletions
diff --git a/src/interrupts.zig b/src/interrupts.zig index 4f83fda..3bc2b1b 100644 --- a/src/interrupts.zig +++ b/src/interrupts.zig @@ -4,6 +4,7 @@ const std = @import("std"); +const debug_console = @import("sbi/debug_console.zig"); const instructions = @import("instructions.zig"); pub const SupervisorTrapVector = packed struct(usize) { @@ -55,14 +56,86 @@ pub const TrapFrame = extern struct { hart_id: usize, // Offset: 528 }; -export fn supervisor_trap(epc: usize, tval: usize, cause: usize, hart_id: usize, status: usize, frame: *TrapFrame) usize { - _ = &epc; - _ = &tval; - _ = &cause; - _ = &hart_id; +pub const Cause = packed struct(usize) { + num: u63, + @"async": u1, + + pub fn is_async(self: Cause) bool { + return self.@"async" == 1; + } +}; + +pub const AsyncCause = enum(u63) { + user_software = 0, + supervisor_software = 1, + user_timer = 4, + supervisor_timer = 5, + user_external = 8, + supervisor_external = 9, +}; + +pub const SyncCause = enum(u63) { + instruction_address_misaligned = 0, + instruction_access_fault = 1, + illegal_instruction = 2, + breakpoint = 3, + load_access_fault = 5, + amo_address_misaligned = 6, + store_or_amo_access_fault = 7, + ecall = 8, + instruction_page_fault = 12, + load_page_fault = 13, + store_or_amo_page_fault = 15, +}; + +export fn supervisor_trap(epc: usize, tval: usize, cause_bits: usize, hart_id: usize, status: usize, frame: *TrapFrame) usize { _ = &status; _ = &frame; - return 0; + + const w = debug_console.writer() catch while (true) {}; + + const cause: Cause = @bitCast(cause_bits); + + if (cause.is_async()) { + switch (@as(AsyncCause, @enumFromInt(cause.num))) { + .supervisor_software => w.print("Hart {d}: Supervisor software interrupt\r\n", .{hart_id}) catch while (true) {}, + .supervisor_timer => w.print("Hart {d}: Supervisor timer interrupt\r\n", .{hart_id}) catch while (true) {}, + .supervisor_external => w.print("Hart {d}: Supervisor external interrupt\r\n", .{hart_id}) catch while (true) {}, + else => { + w.print("Hart {d}: Unhandled asynchronous interrupt\r\n", .{hart_id}) catch while (true) {}; + while (true) {} + }, + } + } else { + switch (@as(SyncCause, @enumFromInt(cause.num))) { + .illegal_instruction => { + w.print("Hart {d}: Illegal instruction\r\n", .{hart_id}) catch while (true) {}; + while (true) {} + }, + .ecall => { + w.print("Hart {d}: Environment call from U-mode\r\n", .{hart_id}) catch while (true) {}; + return epc + 4; + }, + .instruction_page_fault => { + w.print("Hart {d}: Instruction page fault, tval = 0x{x:0>16}\r\n", .{ hart_id, tval }) catch while (true) {}; + return epc + 4; + }, + .load_page_fault => { + w.print("Hart {d}: Load page fault, tval = 0x{x:0>16}\r\n", .{ hart_id, tval }) catch while (true) {}; + return epc + 4; + }, + .store_or_amo_page_fault => { + w.print("Hart {d}: Store/AMO page fault, tval = 0x{x:0>16}\r\n", .{ hart_id, tval }) catch while (true) {}; + return epc + 4; + }, + else => { + w.print("Hart {d}: Unhandled synchronous interrupt\r\n", .{hart_id}) catch while (true) {}; + while (true) {} + }, + } + } + + return epc; } export fn supervisor_trap_vector() align(4) callconv(.Naked) noreturn { |