From 8fd7e5e623647866db88b632347261e5d9f30da1 Mon Sep 17 00:00:00 2001 From: Silvan Jegen Date: Sat, 10 Aug 2019 17:40:59 +0200 Subject: Implement first version of ISR --- software/first/setup_timer_irq.S | 62 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'software/first/setup_timer_irq.S') diff --git a/software/first/setup_timer_irq.S b/software/first/setup_timer_irq.S index 4ae714f..97b5f6c 100644 --- a/software/first/setup_timer_irq.S +++ b/software/first/setup_timer_irq.S @@ -1,6 +1,7 @@ .section .text .align 2 .global setup_timer_irq +.include "gpio.inc" .include "memory_map.inc" setup_timer_irq: @@ -29,6 +30,65 @@ setup_timer_irq: addi sp, sp, 16 # deallocate stack frame ret +# Unix C ABI has high context switch cost. The current RISC-V ABI +# requires (ignoring floating-point registers; from +# https://content.riscv.org/wp-content/uploads/2018/05/08.45-09.10-RISCV-20180509-FastInts.pdf +# ): +# +# addi sp, sp, -FRAMESIZE +# sw ra, x(sp) # 1 return address +# sw t0-t6, x(sp) # 7 temporaries +# sw a0-a7, x(sp) # 8 arguments +# +# jal c_handler +# +# lw a0-a7, x(sp) # 8 arguments +# lw t0-t6, x(sp) # 7 temporaries +# lw ra, x(sp) # 1 return address +# addi sp, sp, FRAMESIZE +# mret + irq_handler: - mret + # save only the registers we use in this function + addi sp, sp, -24 # Allocate stack frame + sw ra, 20(sp) # save return address to the stack + sw t0, 16(sp) # save temporary + sw t1, 12(sp) # save temporary + sw t2, 8(sp) # save temporary + sw t3, 4(sp) # save temporary + + li t0, GPIO_CTRL_ADDR # load base GPIO address + lw t1, GPIO_OUTPUT_VAL(t0) # load state + + beqz t1, switchOnRed # if none is blinking yet, blink the red one + li t3, GPIO_RED_LED + beq t1, t3, switchOnBlue # if red is on, switch on blue LED + li t3, GPIO_BLUE_LED + beq t1, t3, switchOnGreen # if blue is on, switch on green LED + # here, neither the red or blue are on, so the one that is on + # must be the green one. In that case we just fall through to + # switch on the red LED + +switchOnRed: + li t2, GPIO_RED_LED # load value indicating red LED + j exit + +switchOnBlue: + li t2, GPIO_BLUE_LED # load value indicating blue LED + j exit + +switchOnGreen: + li t2, GPIO_GREEN_LED # load value indicating green LED + j exit + + +exit: + sw t2, GPIO_OUTPUT_VAL(t0) # write new LED values to the right address + lw ra, 20(sp) # load return address + lw t0, 16(sp) # restore temporary + lw t1, 12(sp) # restore temporary + lw t2, 8(sp) # restore temporary + lw t3, 4(sp) # restore temporary + addi sp, sp, 24 # deallocate stack frame + mret # exit IRQ handler -- cgit v1.2.1-18-gbd029