sylveos

Toy Operating System
Log | Files | Refs

commit ae0d61fe9315e3606e3505bf56d021371cca66f7
parent 4fb85d090f08846c57983eaf0e6c9e6d30458f43
Author: Sylvia Ivory <git@sivory.net>
Date:   Tue, 10 Feb 2026 20:29:17 -0800

apply trampoline to rest

Diffstat:
Mpi/interrupts.zig | 127++++++++++++++++++++++++++++++-------------------------------------------------
1 file changed, 48 insertions(+), 79 deletions(-)

diff --git a/pi/interrupts.zig b/pi/interrupts.zig @@ -110,98 +110,67 @@ var fast_interrupt_handler: *const fn (u32, *Registers) void = empty; pub const Registers = struct { gp: [13]usize, lr: usize, - - inline fn get_svc() *@This() { - return @ptrFromInt(@intFromPtr(&pi.svc_stack) + (pi.svc_stack.len * @sizeOf(usize))); - } - - inline fn get_abort() *@This() { - return @ptrCast(&pi.abort_stack); - } - - inline fn get_irq() *@This() { - return @ptrCast(&pi.irq_stack); - } - - inline fn get_fiq() *@This() { - return @ptrCast(&pi.fiq_stack); - } }; -inline fn get_lr() u32 { - return asm volatile ("mov %[result], lr" - : [result] "=r" (-> u32), - ); -} - -inline fn clobber_all() void { - asm volatile ("" ::: .{ - .r0 = true, - .r1 = true, - .r2 = true, - .r3 = true, - .r4 = true, - .r5 = true, - .r6 = true, - .r7 = true, - .r8 = true, - .r9 = true, - .r10 = true, - .r11 = true, - .r12 = true, - .r14 = true, - }); +export fn reset_stub(pc: u32, reg: *Registers) void { + reset_handler(pc, reg); } - -export fn reset() callconv(.{ .arm_interrupt = .{ .type = .generic } }) void { - clobber_all(); - reset_handler(get_lr() - 4, Registers.get_abort()); -} -export fn undefined_instruction() callconv(.{ .arm_interrupt = .{ .type = .undef } }) void { - clobber_all(); - undefined_instruction_handler(get_lr() - 4, Registers.get_abort()); +export fn undefined_instruction_stub(pc: u32, reg: *Registers) void { + undefined_instruction_stub(pc, reg); } -// export fn software_interrupt() callconv(.{ .arm_interrupt = .{ .type = .swi } }) void { -// clobber_all(); -// software_interrupt_handler(get_lr() - 4, Registers.get_svc()); -// } -export fn software_interrupt_handler_v(pc: u32, reg: *Registers) void { +export fn software_interrupt_stub(pc: u32, reg: *Registers) void { software_interrupt_handler(pc, reg); } - -comptime { - asm ( - \\ .global software_interrupt - \\ .type software_interrupt, %function - \\ software_interrupt: - \\ push {r0-r12, lr} - \\ sub lr, lr, #4 - \\ mov r0, lr - \\ mov r1, sp - \\ blx software_interrupt_handler - \\ pop {r0-r12, lr} - \\ movs pc, lr - ); -} -extern fn software_interrupt() void; - -export fn prefetch_abort() callconv(.{ .arm_interrupt = .{ .type = .abort } }) void { - clobber_all(); - prefetch_abort_handler(get_lr() - 8, Registers.get_abort()); +export fn prefetch_abort_stub(pc: u32, reg: *Registers) void { + prefetch_abort_handler(pc, reg); } -export fn data_abort() callconv(.{ .arm_interrupt = .{ .type = .abort } }) void { - clobber_all(); - data_abort_handler(get_lr() - 4, Registers.get_abort()); +export fn data_abort_stub(pc: u32, reg: *Registers) void { + data_abort_handler(pc, reg); } +// export fn interrupt_stub(pc: u32, reg: *Registers) void { +// interrupt_handler(pc, reg); +// } export fn interrupt() callconv(.{ .arm_interrupt = .{ .type = .irq } }) void { - clobber_all(); - interrupt_handler(get_lr() - 4, Registers.get_irq()); + interrupt_handler(0, @ptrFromInt(@frameAddress())); } +// export fn fast_interrupt_stub(pc: u32, reg: *Registers) void { +// fast_interrupt_handler(pc, reg); +// } export fn fast_interrupt() callconv(.{ .arm_interrupt = .{ .type = .fiq } }) void { - clobber_all(); - fast_interrupt_handler(get_lr() - 4, Registers.get_fiq()); + fast_interrupt_handler(0, @ptrFromInt(@frameAddress())); +} + +fn create_trampoline(name: []const u8, offset: []const u8) []const u8 { + return "" ++ + ".global " ++ name ++ "\n" ++ + ".type " ++ name ++ ", %function\n" ++ + name ++ ":\n" ++ + " push {r0-r12, lr}\n" ++ + " sub lr, lr, #" ++ offset ++ "\n" ++ + " mov r0, lr\n" ++ + " mov r1, sp\n" ++ + " blx " ++ name ++ "_stub\n" ++ + " pop {r0-r12, lr}\n" ++ + " movs pc, lr\n"; } +comptime { + asm (create_trampoline("reset", "4")); + asm (create_trampoline("undefined_instruction", "4")); + asm (create_trampoline("software_interrupt", "4")); + asm (create_trampoline("prefetch_abort", "4")); + asm (create_trampoline("data_abort", "8")); + // asm (create_trampoline("interrupt", "4")); + // asm (create_trampoline("fast_interrupt", "4")); +} +extern fn reset() void; +extern fn undefined_instruction() void; +extern fn software_interrupt() void; +extern fn prefetch_abort() void; +extern fn data_abort() void; +// extern fn interrupt() void; +// extern fn fast_interrupt() void; + // https://leiradel.github.io/2019/02/09/Initialization.html pub fn setup_exception_vector() void { var exception_vector: usize = 0;