使用 risc-v 定时器中断和用 spike 模拟的问题

Problems using risc-v timer interrupts and simulating with spike

我正在尝试进行定时器中断,我安装了以下 risc-v_tools riscv64-unknown-elf-gcc 工具链,spike 模拟和 pk 。这是我的代码:


#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;
}

当它编译我的程序时它没有问题,但是当我模拟它时显示以下错误:

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!

我在debug模式下模拟了一下,看到一个进入循环,不再退出,所以已经显示是非法指令,但不知道是哪个。我在中断的 github link https://github.com/riscv/riscv-tests/blob/master/debug/programs/interrupt.c 中模拟并编译了具有 risc-v 的程序,但它抛出了同样的错误。

请问是代码的问题还是模拟器的问题?

任何能指导我的人都会非常感激,因为我是这些 RISC-V 工具的新手

我已经知道这个错误的原因了。

该程序 运行ning 在 pk 之上(pk 仅支持用户模式)。我必须 运行 裸机上的程序(裸机支持机器模式)。这样就不会产生非法指令错误。

希望此信息对以后的人有所帮助。