.org 0x00000010 # IRQ
_irq_vector:
- j _irq
+ addi sp, sp, -16
+ sw t0, 4(sp)
+ sw ra, 8(sp)
+ /* By convention, q2 holds true IRQ vector, but remains caller-save.
+ We rely on the assumption that compiler-generated code will never touch
+ the QREGs. q3 is truly scratch/caller-save. */
+ picorv32_getq_insn(t0, q2)
+ sw t0, 12(sp)
+
+ jalr t0 // Call the true IRQ vector.
+
+ lw t0, 12(sp)
+ picorv32_setq_insn(q2, t0) // Restore the true IRQ vector.
+ lw ra, 8(sp)
+ lw t0, 4(sp)
+ addi sp, sp, 16
+ picorv32_retirq_insn() // return from interrupt
/*
/* restore x1 - x2 from q registers */
picorv32_getq_insn(x1, q1)
picorv32_getq_insn(x2, q2)
-
- /* return from interrupt */
- picorv32_retirq_insn()
+ ret
/*
* Reset handler, branched to from the vector.
/* set main stack */
la sp, _fstack
+ /* Set up address to IRQ handler since vector is hardcoded.
+ By convention, q2 keeps the pointer to the true IRQ handler,
+ to emulate relocatable interrupts. */
+ la t0, _irq
+ picorv32_setq_insn(q2, t0)
+
/* jump to main */
jal ra, main
picorv32_maskirq_insn(zero, t0)
ret
-/*
+/*
* Disable interrupts by masking all interrupts (the mask should already be
* up to date)
*/
picorv32_maskirq_insn(zero, a0)
1:
ret
-
+
.section .bss
irq_regs:
.global _irq_enabled
_irq_enabled:
.word 0
-