sylveos

Toy Operating System
Log | Files | Refs

commit 6a121abe685d378dd68813044283f763bdbc3107
parent df5c42c175e426c3425088bb629739c8c00916db
Author: Sylvia Ivory <git@sivory.net>
Date:   Tue, 10 Feb 2026 19:14:08 -0800

Clobber all registers in interrupts

Diffstat:
Mpi/interrupts.zig | 64+++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/pi/interrupts.zig b/pi/interrupts.zig @@ -97,16 +97,9 @@ fn empty(lr: u32) void { _ = lr; } -// TODO; r1-r6 -fn empty_swi(n: u32, r0: u32) callconv(.c) i32 { - _ = n; - _ = r0; - return -1; -} - var reset_handler: *const fn (u32) void = empty; var undefined_instruction_handler: *const fn (u32) void = empty; -export var software_interrupt_handler: *const fn (u32, u32) callconv(.c) i32 = empty_swi; +var software_interrupt_handler: *const fn (u32) void = empty; var prefetch_abort_handler: *const fn (u32) void = empty; var data_abort_handler: *const fn (u32) void = empty; var interrupt_handler: *const fn (u32) void = empty; @@ -118,43 +111,54 @@ inline fn get_lr() 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() callconv(.{ .arm_interrupt = .{ .type = .generic } }) void { - reset_handler(0); + clobber_all(); + reset_handler(get_lr() - 4); } export fn undefined_instruction() callconv(.{ .arm_interrupt = .{ .type = .undef } }) void { + clobber_all(); undefined_instruction_handler(get_lr() - 4); } +export fn software_interrupt() callconv(.{ .arm_interrupt = .{ .type = .swi } }) void { + clobber_all(); + software_interrupt_handler(get_lr() - 4); +} export fn prefetch_abort() callconv(.{ .arm_interrupt = .{ .type = .abort } }) void { + clobber_all(); prefetch_abort_handler(get_lr() - 8); } export fn data_abort() callconv(.{ .arm_interrupt = .{ .type = .abort } }) void { + clobber_all(); data_abort_handler(get_lr() - 4); } export fn interrupt() callconv(.{ .arm_interrupt = .{ .type = .irq } }) void { + clobber_all(); interrupt_handler(get_lr() - 4); } export fn fast_interrupt() callconv(.{ .arm_interrupt = .{ .type = .fiq } }) void { + clobber_all(); fast_interrupt_handler(get_lr() - 4); } -// TODO; fix -comptime { - asm ( - \\ .global software_interrupt; - \\ .type software_interrupt, %function; - \\ software_interrupt: - \\ push {r0-r12, lr} - \\ sub lr, lr, #4 - \\ mov r1, r0 - \\ mov r0, lr - \\ bl syscall_handler - \\ pop {r0-r12, lr} - \\ movs pc, lr - ); -} -extern fn software_interrupt() void; -export fn syscall_handler() void {} - // https://leiradel.github.io/2019/02/09/Initialization.html pub fn setup_exception_vector() void { var exception_vector: usize = 0; @@ -193,6 +197,7 @@ pub fn setup_exception_vector() void { const ExceptionVector = enum { Reset, UndefinedInstruction, + SoftwareInterrupt, PrefetchAbort, DataAbort, IRQ, @@ -203,13 +208,10 @@ pub fn set_exception_handler(vector: ExceptionVector, handler: *const fn (u32) v switch (vector) { .Reset => reset_handler = handler, .UndefinedInstruction => undefined_instruction_handler = handler, + .SoftwareInterrupt => software_interrupt_handler = handler, .PrefetchAbort => prefetch_abort_handler = handler, .DataAbort => data_abort_handler = handler, .IRQ => interrupt_handler = handler, .FIQ => fast_interrupt_handler = handler, } } - -pub fn set_software_interrupt(handler: *const fn (u32, u32) callconv(.c) i32) void { - software_interrupt_handler = handler; -}