I’ve got a Sparkfun RED-V board, which is very similar to the HiFive. It’s got an FE310-G002.
I’m having trouble clearing the timer interrupt. I enable interrupts (mstatus.mie=1, mie.mtie=1) and set mtimecmp to a value higher than mtime. I get the interrupt okay (mip.mtip=1, mcause.interrupt=1, mcause.code=7).
My understanding is that to clear the timer interrupt I need to write a value to mtimecmp that’s higher than the current value of mtime. I do that (keeping in mind that these are 64-bit registers split into two 32-bit registers), but mip.mtip stays set to one and the interrupt handler is immediately reentered when the handler executes the mret instruction.
Am I doing anything wrong here? The CLINT chapter in the FE310 manual is only one page long and is short on details, but I think I’m doing everything correctly.
unsigned long
handle_timer_trap(unsigned long mcause, unsigned long mepc)
{
unsigned long mtimelo, mtimehi;
unsigned long long mtime;
mtimelo = CLINT_REG(CLINT_MTIME);
mtimehi = CLINT_REG(CLINT_MTIME + 4);
mtime = ((unsigned long long)mtimehi << 32) + mtimelo;
mtime += MTIME_VALUE;
CLINT_REG(CLINT_MTIMECMP) = mtime & 0xffffffff;
CLINT_REG(CLINT_MTIMECMP + 4) = (mtime >> 32);
return(mepc);
}