libbase/crt0-picorv32: Emulate support for a relocatable IRQ vector (hardcoded at synthesis time).

This commit is contained in:
William D. Jones 2018-11-01 05:02:04 -04:00
parent f32121e0e1
commit e56f71824d
1 changed files with 26 additions and 7 deletions

View File

@ -18,7 +18,23 @@ _start:
.org 0x00000010 # IRQ .org 0x00000010 # IRQ
_irq_vector: _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
/* /*
@ -132,9 +148,7 @@ _irq:
/* restore x1 - x2 from q registers */ /* restore x1 - x2 from q registers */
picorv32_getq_insn(x1, q1) picorv32_getq_insn(x1, q1)
picorv32_getq_insn(x2, q2) picorv32_getq_insn(x2, q2)
ret
/* return from interrupt */
picorv32_retirq_insn()
/* /*
* Reset handler, branched to from the vector. * Reset handler, branched to from the vector.
@ -191,6 +205,12 @@ _crt0:
/* set main stack */ /* set main stack */
la sp, _fstack 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 */ /* jump to main */
jal ra, main jal ra, main
@ -214,7 +234,7 @@ _irq_enable:
picorv32_maskirq_insn(zero, t0) picorv32_maskirq_insn(zero, t0)
ret ret
/* /*
* Disable interrupts by masking all interrupts (the mask should already be * Disable interrupts by masking all interrupts (the mask should already be
* up to date) * up to date)
*/ */
@ -247,7 +267,7 @@ _irq_setmask:
picorv32_maskirq_insn(zero, a0) picorv32_maskirq_insn(zero, a0)
1: 1:
ret ret
.section .bss .section .bss
irq_regs: irq_regs:
@ -280,4 +300,3 @@ _irq_mask:
.global _irq_enabled .global _irq_enabled
_irq_enabled: _irq_enabled:
.word 0 .word 0