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

问题描述

我正在尝试进行计时器中断,我安装了以下 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,mcause,mtvec;
    printf_status(mstatus,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!

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

我的问题是,是代码的问题还是模拟器的问题?

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

解决方法

我已经意识到这个错误的原因。

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

希望这些信息对未来有所帮助。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...