commit ae0d61fe9315e3606e3505bf56d021371cca66f7
parent 4fb85d090f08846c57983eaf0e6c9e6d30458f43
Author: Sylvia Ivory <git@sivory.net>
Date: Tue, 10 Feb 2026 20:29:17 -0800
apply trampoline to rest
Diffstat:
| M | pi/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;