123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include "compiler.h"
- #include "sections.h"
- #include "picorv32.h"
- #include "ioregs.h"
- // The IRQ dispatch code is written in assembly to make
- // better use of the register bank switching: can simply
- // use the saved registers here, no saving needed.
- // registers need to be
- .pushsection ".init.irq","ax"
- .balign 4
- .globl _irq
- .option push
- .option norvc // Alignment matters more here
- _irq:
- addqxi sp,sp,0
- // s10 contains the IRQ return address, s11 the mask of
- // IRQs to be handled.
- // Send EOI for all interrupts (previously done in hardware)
- sw s11,SYS_EOI(zero)
- // Fast dispatch for the ABC-bus interrupt handler
- andi s0,s11,1 << ABC_IRQ
- beqz s0,1f
- jal irqhandler_abc_0
- sub s11,s11,s0
- beqz s11,.L_done
- 1:
- li s1, 0
- .Lirq_loop:
- // ctz would make this more efficient...
- #if IRQ_VECTORS > 16
- slli t0,s11,16
- bnez t0,1f
- srli s11,s11,16
- addi s1,s1,16*4
- 1:
- #endif
- #if IRQ_VECTORS > 8
- zext.b t0,s11
- bnez t0,2f
- srli s11,s11,8
- addi s1,s1,8*4
- 2:
- #endif
- #if IRQ_VECTORS > 4
- andi t0,s11,15
- bnez t0,3f
- srli s11,s11,4
- addi s1,s1,4*4
- 3:
- #endif
- #if IRQ_VECTORS > 2
- andi t0,s11,3
- bnez t0,4f
- srli s11,s11,2
- addi s1,s1,2*4
- 4:
- #endif
- #if IRQ_VECTORS > 1
- andi t0,s11,1
- bnez t0,5f
- srli s11,s11,1
- addi s1,s1,1*4
- 5:
- #endif
- srli a0,s1,2 // Vector number
- mv a1,s10 // PC (including the rvc flag)
- .option norelax // ld will mess up trying to relax this instruction
- jalr s1,%lo(__irq_handler_table) // Must be in zero page
- .option relax
- srli s11,s11,1
- addi s1,s1,4*1
- bnez s11,.Lirq_loop
- .L_done:
- mret
- .type _irq, @function
- .size _irq, . - _irq
- .option pop
- // Debug functions to read and write x-registers from interrupt
- // mode by register number
- .pushsection ".text.hot.rdxreg","ax"
- .globl rdxreg
- .balign 4
- rdxreg:
- la a3,_xreg_smc
- lw a2,8(a3) // addqxi a0,zero,0
- andi a0,a0,31
- slli a0,a0,15 // rs1
- or a2,a2,a0
- sw a2,(a3)
- jr a3
- .type rdxreg, @function
- .size rdxreg, . - rdxreg
- .popsection
- .pushsection ".text.hot.wrxreg","ax"
- .globl wrxreg
- .balign 4
- wrxreg:
- la a3,_xreg_smc
- lw a2,12(a3) // addxqi zero,a1,0
- andi a0,a0,31
- slli a0,a0,7 // rd
- or a2,a2,a0
- sw a2,(a3)
- jr a3
- .type wrxreg, @function
- .size wrxreg, . - wrxreg
- .popsection
- __rwtext
- .balign 4
- .option norvc
- _xreg_smc:
- nop
- ret
- addqxi a0,zero,0
- addxqi zero,a1,0
- .type _xreg_smc, @function
- .size _xreg_smc, . - _xreg_smc
|