I will be as detailed as possible. I have tried and debugged everything I can possibly think of. Either RTC does not cause a machine level timer interrupt, or I’m missing something.
Here is the start of the code.
_play is called from main.c. This is all in sifive freedom studio, under a blank solution.
.equ .sys.high_mem, 0x80004000 .align 4 .text .globl _play _play: lui sp, %pcrel_hi(.sys.high_mem) jal ra, _set_mtvec jal ra, _set_plic jal ra, _gpio_init jal ra, _gpio_green jal ra, _set_rccmp wfi j .
First I enable machine level interrupts and define a global _fail_handler, this handler has a breakpoint. It never gets hit.
.align 4 .globl _set_mtvec _set_mtvec: csrrci t0, mstatus, 3 # disable interrupts la a0, _fail_handler # loads fail handler csrrw a1, mtvec, a0 # get address of fail handler csrrci t1, mtvec, 1 # set to direct mode csrrsi t0, mstatus, 3 # enable interrupts ret .align 8 _fail_handler: addi t0, x0, 0xFFFFFFFF ...
I have confirmed it does get hit if i tried to write to ROM causing a synchronous machine exception.
Next is plic and aon.
.equ PLIC_BASE, 0x0C000008 .equ PLIC_ENABLE, 0x0C002000 .equ PLIC_THRESHOLD, 0x0C200000 .equ PLIC_CLAIM, 0x0C200004 .globl _set_plic _set_plic: la t0, PLIC_BASE lw t1, 0(t0) ori t1, t1, 0x7 sw t1, 0(t0) la t0, PLIC_ENABLE lw t1, 0(t0) ori t1, t1, 0x4 sw t1, 0(t0) # right after doing this there appear to be some bits set in the PLIC_CLAIM, but not the 3rd bit. appears to be wdog la t0, PLIC_THRESHOLD lw t1, 0(t0) and t1, t1, x0 sw t1, 0(t0) la t0, PLIC_CLAIM #Set all claims to 0 lw t1, 0(t0) sw t1, 0(t0) ret
Next is setting up RTC.
.globl _set_rccmp _set_rccmp: li t0, AONBASE # gets the AON base address lw t1, rtccfg(t0) # loads the data at config which is rtcscale li t2, 0x100F or t2, t1, t2 # ori the rtcscale to seconds in t1, and enable sw t2, rtccfg(t0) # store the new rtcscale .align 8 # do this just in case, rtcscale needs a few cycles. disassembly does show several nops inbetween. lw t1, rtcs(t0) # loads the current clock time addi t1, t1, 0x30 # set to 0x30 to ensure rtcs doesn't go above rtccmp until after this proc is exited. sw t1, rtccmp0(t0) # sets the time to compare several seconds higher ret
And through lots of debugging, i have confirmed that the rtccmp will eventually trigger the rtcip0 flag, every setup address/register seems to be set exactly how the riscv gods intended the docs to be interpreted, but control will never flow to the fail_handler. So I feel as though I have failed the riscv gods and misinterpreted their work.