riscvinterrupt-handlinginstruction-setriscv32spike

Problems using risc-v timer interrupts and simulating with spike


I'm trying to make a timer interrupt, I have the following risc-v_tools installed riscv64-unknown-elf-gcc toolchain, spike simulate and pk . this is my code:


#define  MTIME       *((volatile uint64_t *) 0x02000000 + 0xbff8)
#define  MTIMECMP    *((volatile uint64_t *) 0x02000000 + 0x4000)

#define  MTIME_INTERRUPT_PERIOD  12000000   

void interruptHandler() __attribute__ ((interrupt, section(".interrupt_handler")));

void interruptHandler() {
    MTIME = 0;
    MTIMECMP = MTIME_INTERRUPT_PERIOD;
  
    printf("Machine Interrupt");
}

void printf_status(uint64_t mstatus, uint64_t mie, uint64_t mip, uint64_t mcause) {
    asm volatile ("csrr %[reg], mie" : [reg] "=r" (mie));
    asm volatile ("csrr %[reg], mip" : [reg] "=r" (mip));
    asm volatile ("csrr %[reg], mstatus" : [reg] "=r" (mstatus));
    asm volatile ("csrr %[reg], mcause" : [reg] "=r" (mcause));
    printf("mie=%x, mip=%x, mstatus=%x, mcause=%x\r\n", mie, mip, mstatus, mcause);
}

int main() {

    uint64_t mstatus, mie, mip, mcause, mtvec;
    printf_status(mstatus, mie, mip, mcause);
    
    // basic (non vectored) interrupt handler (to force non vectored, set 0 to lower two bits of mtvec, so force 4 byte aligned on linker script for interrupt handler)
    asm volatile ("csrw mtvec, %[reg]" : : [reg] "r" ((uint64_t) interruptHandler));
    asm volatile ("csrr %[reg], mtvec" : [reg] "=r" (mtvec));
    printf("mtvec=%x\r\n", mtvec);
    
    // machine interrupt enable
    asm volatile ("csrw mie, %[reg]" : : [reg] "r" ((uint32_t) 0x80));

    asm volatile ("csrsi mstatus, 8");

    // configure interrupt period
    MTIME = 0;
    MTIMECMP = MTIME_INTERRUPT_PERIOD;

    // sleep
    while (1){
        asm volatile ("wfi");
    }  
    
    return 0;
}

When it compiled my program it does it without problems, but when I simulate it shows me the following error:

jjrh@ubuntu-20:~/risc-v/Programs$ riscv64-unknown-elf-gcc -march=rv64g -o manejador manejador.c -static-libgcc -lm
jjrh@ubuntu-20:~/risc-v/Programs$ spike pk manejador
bbl loader
z  0000000000000000 ra 00000000000101e0 sp 0000003ffffffae0 gp 000000000001edc0
tp 0000000000000000 t0 0000000000000000 t1 000000000000000f t2 0000000000000000
s0 0000003ffffffb10 s1 0000000000000000 a0 0000000000000000 a1 0000000000000000
a2 0000000000000000 a3 0000000000000000 a4 0000000000000001 a5 0000000000000000
a6 000000000000001f a7 0000000000000000 s2 0000000000000000 s3 0000000000000000
s4 0000000000000000 s5 0000000000000000 s6 0000000000000000 s7 0000000000000000
s8 0000000000000000 s9 0000000000000000 sA 0000000000000000 sB 0000000000000000
t3 0000000000000000 t4 0000000000000000 t5 0000000000000000 t6 0000000000000000
pc 000000000001016c va/inst 00000000304027f3 sr 8000000200006020
An illegal instruction was executed!

I simulated it in debug mode, I see one that goes into a loop and no longer exits, so it already shows that it is due to an illegal instruction, but I don't know which one. I simulated and compiled the program that has risc-v in the github link https://github.com/riscv/riscv-tests/blob/master/debug/programs/interrupt.c of interrupts but it throws me what that same mistake.

My question is, is the problem the codes or the simulator?

Anyone who can guide me would be very grateful as I am new to these RISC-V tools


Solution

  • I already realized the reason for this error.

    The program was running on top of pk (pk only supports user mode). I have to run the program on bare metal (bare metal supports Machine mode). This way the illegal instructions error is not generated.

    Hope this information helps someone in the future.