I implemented timer interrupt support. Now ProcessController live updating is working. Before that thread preemption was not working and system had cooperative multitasking. Also it required some hacks (disabling snooze()
etc.) to avoid freeze than can be removed now.
Timer handling is tricky. Timer interrupt can be only handled in machine mode, but kernel run in supervisor mode. Machine mode don’t support MMU and page table so it is not suitable for running kernel. So machine mode timer interrupt handler that will forward interrupt to supervisor mode is needed. I already have tiny machine mode “kernel” inside Haiku kernel that have its own syscalls (test
, switchToSmode
, setTimer
), I adapted it so it become usable in multithreaded environment and implemented status_t setTimer(bool enable, uint64 time)
syscall that enable/disable timer, set when timer should trigger and deliver sTimerInt
interrupt to supervisor mode. Similar thing is implemented in OpenSBI (lib/sbi/sbi_timer.c).
Timer interrupt delivery looks like this:
MTrap(exception sEcall)
mstatus: (ie: {}, pie: {s}, spp: s, mpp: s)
mepc: <kernel_riscv64> msyscall + 0
mie: {sTimer}
mip: {sTimer, mTimer}
sip: {sTimer}
Stack:
FP: 0x80c5dcd0, PC: <kernel_riscv64> MTrap + 263
FP: 0x80c5ddd0, PC: <kernel_riscv64> MVec + 77
FP: 0x80c5dec0, PC: <kernel_riscv64> 0x8013365f // STrap, msyscall
FP: 0x80c5dfc0, PC: <kernel_riscv64> SVec + 77
FP: 0x80c5dfe0, PC: <kernel_riscv64> arch_int_init + 341
FP: 0x80c5e000, PC: <kernel_riscv64> _start + 369
FP: 0x80145f00, PC: 0x8000019f
FP: 0x80145f60, PC: 0x800266af
FP: 0x80146000, PC: 0x800002dd
FP: 0x0, PC: 0x8000000d
setTimerMmodeSyscall()
MTrap(interrupt mTimer)
mstatus: (ie: {s}, pie: {s, m}, spp: u, mpp: s)
mepc: <kernel_riscv64> arch_int_init + 342
mie: {sTimer, mTimer}
mip: {mTimer}
sip: {}
Stack:
FP: 0x80c5dec0, PC: <kernel_riscv64> MTrap + 263
FP: 0x80c5dfc0, PC: <kernel_riscv64> MVec + 77
FP: 0x80c5dfe0, PC: <kernel_riscv64> arch_int_init + 341
FP: 0x80c5e000, PC: <kernel_riscv64> _start + 369
FP: 0x80145f00, PC: 0x8000019f
FP: 0x80145f60, PC: 0x800266af
FP: 0x80146000, PC: 0x800002dd
FP: 0x0, PC: 0x8000000d
STrap(interrupt sTimer)
sstatus: (ie: {}, pie: {s}, spp: s, fs: 1, sum: 0)
sepc: <kernel_riscv64> arch_int_init + 342
sie: {sTimer}
sip: {sTimer}
sscratch: 0x0, 0x803eb470
tp: 0x803eb0f0()
trap level: 0x1