libbase/crt0-picorv32: Emulate support for a relocatable IRQ vector (hardcoded at...
authorWilliam D. Jones <thor0505@comcast.net>
Thu, 1 Nov 2018 09:02:04 +0000 (05:02 -0400)
committerWilliam D. Jones <thor0505@comcast.net>
Thu, 1 Nov 2018 09:02:04 +0000 (05:02 -0400)
litex/soc/software/libbase/crt0-picorv32.S

index 054f84d32416fd4a85c3e90fa2a92933b79008c0..7e4c712b325ae73482db345b8b0c1237c6e26780 100644 (file)
@@ -18,7 +18,23 @@ _start:
 
 .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
 
 
 /*
@@ -132,9 +148,7 @@ _irq:
   /* 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.
@@ -191,6 +205,12 @@ _crt0:
   /* 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
 
@@ -214,7 +234,7 @@ _irq_enable:
   picorv32_maskirq_insn(zero, t0)
   ret
 
-/* 
+/*
  * Disable interrupts by masking all interrupts (the mask should already be
  * up to date)
  */
@@ -247,7 +267,7 @@ _irq_setmask:
   picorv32_maskirq_insn(zero, a0)
 1:
   ret
-  
+
 
 .section .bss
 irq_regs:
@@ -280,4 +300,3 @@ _irq_mask:
 .global _irq_enabled
 _irq_enabled:
   .word 0
-