Hello, I am trying to handle local interrupts.
That’s what I do, in my handler for timer interrupts:
disable timer interrupts in mie
read a current value from mtime
copy it to mtimecmp (both are 64bit width types)
add some big value to mtimecmp
enable timer interrupts in mie.
And I have two boards and the problem is that on one of them interrupts are permanently generated because mip register is always 1 in mtip position, though mtimecmp is greater than mtime, and are not generated at all on the other.
In this piece of code, I turn on interrupts:
la t0, RISCV_Exception_default
csrs mtvec, t0
li t0, 0x88
csrs mie, t0
csrsi mstatus, 0x8
MTIME and MTIMECMP are 64-bit values, as you mentioned above. But in your start.S, you seem to be treating them only as 32-bit values. MTIMECMP is not reset to 0, so you should, at least, set the upper bits of MTIMECMP as well. The RISC-V Privileged Spec has a snippet for how to safely set MTIMECMP on a 32-bit system.
In your irq.c you are treating them as 64-bit values, but I’m wondering if you are ever even getting that far since the first MTIMECMP may be wrong.
Another note, you probably want to use csrw, not csrs, to set mtvec.
Thank you,
yes, in my start.S it is only 32-bit value as a quick solution, because my counter never overflows 32-bit value(never runs so long). I will change it a bit later.
In my irq.c there is also a temporary static variable cntr, which is incremented at the handler. And after some time running I can see a big value in cntr. Also, there is a static array Times, and now for example, I can run my executable and print the values. These are first 10 values if mtime during interrupts’ triggering:
I found the problem, I made a mistake in my code, instead of:
if ((cause & MCAUSE_MTIME) == MCAUSE_MTIME) {
I have written:
if (cause & MCAUSE_MTIME) {