diff options
author | Clifford Wolf <clifford@clifford.at> | 2015-06-25 14:08:39 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2015-06-25 14:08:39 +0200 |
commit | 23b700cf73b7b01b4737db106226bd4220799290 (patch) | |
tree | 27a6109332ccf71c4a3b284d05a74d1ab3ac14ed /firmware/start.S | |
parent | 982e5cc60085236be18a5be35f3747e480ed549f (diff) | |
download | picorv32-23b700cf73b7b01b4737db106226bd4220799290.tar.gz picorv32-23b700cf73b7b01b4737db106226bd4220799290.zip |
Added basic IRQ support
Diffstat (limited to 'firmware/start.S')
-rw-r--r-- | firmware/start.S | 163 |
1 files changed, 162 insertions, 1 deletions
diff --git a/firmware/start.S b/firmware/start.S index d9e0b3e..cdb8da0 100644 --- a/firmware/start.S +++ b/firmware/start.S @@ -1,13 +1,174 @@ .section .text - .global start + .global irq .global sieve .global stats #define TEST(n) \ .global n; .global n ## _ret; \ + addi x1, zero, 1000; \ + custom0 0,1,0,5; /* timer x1 */ \ jal zero,n; n ## _ret: +reset_vec: + custom0 0,0,7,3 // maskirq 7 + j start + nop + nop + +irq_vec: + /* save registers */ + + custom0 2,1,0,1 // setq q2, x1 + custom0 3,2,0,1 // setq q3, x2 + + lui x1, %hi(irq_regs) + addi x1, x1, %lo(irq_regs) + + custom0 2,0,0,0 // getq x2, q0 + sw x2, 0*4(x1) + + custom0 2,2,0,0 // getq x2, q2 + sw x2, 1*4(x1) + + custom0 2,3,0,0 // getq x2, q3 + sw x2, 2*4(x1) + + sw x3, 3*4(x1) + sw x4, 4*4(x1) + sw x5, 5*4(x1) + sw x6, 6*4(x1) + sw x7, 7*4(x1) + sw x8, 8*4(x1) + sw x9, 9*4(x1) + sw x10, 10*4(x1) + sw x11, 11*4(x1) + sw x12, 12*4(x1) + sw x13, 13*4(x1) + sw x14, 14*4(x1) + sw x15, 15*4(x1) + sw x16, 16*4(x1) + sw x17, 17*4(x1) + sw x18, 18*4(x1) + sw x19, 19*4(x1) + sw x20, 20*4(x1) + sw x21, 21*4(x1) + sw x22, 22*4(x1) + sw x23, 23*4(x1) + sw x24, 24*4(x1) + sw x25, 25*4(x1) + sw x26, 26*4(x1) + sw x27, 27*4(x1) + sw x28, 28*4(x1) + sw x29, 29*4(x1) + sw x30, 30*4(x1) + sw x31, 31*4(x1) + + /* call interrupt handler */ + + lui sp, %hi(irq_stack_top) + addi sp, sp, %lo(irq_stack_top) + + // arg0 = address of regs + lui a0, %hi(irq_regs) + addi a0, a0, %lo(irq_regs) + + // arg1 = interrupt type + custom0 11,1,0,0 // getq x11, q1 + + // call to c function + jal ra, irq + + /* restore registers */ + + lui x1, %hi(irq_regs) + addi x1, x1, %lo(irq_regs) + + lw x2, 0*4(x1) + custom0 0,2,0,1 // setq q0, x2 + + lw x2, 1*4(x1) + custom0 1,2,0,1 // setq q1, x2 + + lw x2, 2*4(x1) + custom0 2,2,0,1 // setq q2, x2 + + lw x3, 3*4(x1) + lw x4, 4*4(x1) + lw x5, 5*4(x1) + lw x6, 6*4(x1) + lw x7, 7*4(x1) + lw x8, 8*4(x1) + lw x9, 9*4(x1) + lw x10, 10*4(x1) + lw x11, 11*4(x1) + lw x12, 12*4(x1) + lw x13, 13*4(x1) + lw x14, 14*4(x1) + lw x15, 15*4(x1) + lw x16, 16*4(x1) + lw x17, 17*4(x1) + lw x18, 18*4(x1) + lw x19, 19*4(x1) + lw x20, 20*4(x1) + lw x21, 21*4(x1) + lw x22, 22*4(x1) + lw x23, 23*4(x1) + lw x24, 24*4(x1) + lw x25, 25*4(x1) + lw x26, 26*4(x1) + lw x27, 27*4(x1) + lw x28, 28*4(x1) + lw x29, 29*4(x1) + lw x30, 30*4(x1) + lw x31, 31*4(x1) + + custom0 1,1,0,0 // getq x1, q1 + custom0 2,2,0,0 // getq x2, q2 + + custom0 0,0,0,2 // retirq + +irq_regs: + // registers are saved to this memory region + // the program counter is saved as register 0 + .fill 32,4 + +irq_stack: + .fill 128,4 +irq_stack_top: + start: + addi x1, zero, 0 + addi x2, zero, 0 + addi x3, zero, 0 + addi x4, zero, 0 + addi x5, zero, 0 + addi x6, zero, 0 + addi x7, zero, 0 + addi x8, zero, 0 + addi x9, zero, 0 + addi x10, zero, 0 + addi x11, zero, 0 + addi x12, zero, 0 + addi x13, zero, 0 + addi x14, zero, 0 + addi x15, zero, 0 + addi x16, zero, 0 + addi x17, zero, 0 + addi x18, zero, 0 + addi x19, zero, 0 + addi x20, zero, 0 + addi x21, zero, 0 + addi x22, zero, 0 + addi x23, zero, 0 + addi x24, zero, 0 + addi x25, zero, 0 + addi x26, zero, 0 + addi x27, zero, 0 + addi x28, zero, 0 + addi x29, zero, 0 + addi x30, zero, 0 + addi x31, zero, 0 + TEST(lui) TEST(auipc) TEST(j) |