[英]RISC-V jump to interrupt handler
Hello I am writing a small kernel to better understand RISC-V. 您好,我在写一个小的内核,以更好地了解RISC-V。 Until now I managed to use the UART and setup a simple memory manager.
到目前为止,我设法使用UART并设置了一个简单的内存管理器。 To be able to parse user input I setup an interrupt handler and set its address to MTVEC.
为了能够解析用户输入,我设置了一个中断处理程序并将其地址设置为MTVEC。 Then I enabled interrupt in MSTATUS and MIE.
然后我在MSTATUS和MIE中启用了中断。 After that I setup MTIMECMP through mmio register and loop forever with WFI (RISC-V wait for interrupt instruction).
之后,我通过mmio寄存器设置MTIMECMP,并与WFI永远循环(RISC-V等待中断指令)。 I noticed then that MIP contained 0x8 as expected (which means machine mode timer interrupt pending).
然后我注意到MIP包含了预期的0x8(这意味着机器模式定时器中断待处理)。 The only problem my code did not jump to MTVEC.
我的代码没有跳到MTVEC的唯一问题。 What did I wrong?
我怎么了 Best regards, Serge Teodori
最好的问候,Serge Teodori
source: 资源:
void mtrap(){
uint8_t txt[0x100];
struct uart_t uart = { .reg = (uint32_t*) 0x10013000 };
stringFormat(txt, 0x100, "machine trap\r\n");
uart_write(&uart, txt, 0x100);
}
void main(){
uint8_t txt[0x100];
uint64_t mvendorid, marchid, mimpid, mhartid, mstatus, misa, mtvec, mie, mip, mcause;
struct clint_t clint = { .addr = 0x2000000 };
struct plic_t plic = { .reg = (uint32_t*) 0x0c000000 };
struct uart_t uart = { .reg = (uint32_t*) 0x10013000 };
asm volatile ("csrr %[reg], mvendorid" : [reg] "=r" (mvendorid));
asm volatile ("csrr %[reg], marchid" : [reg] "=r" (marchid));
asm volatile ("csrr %[reg], mimpid" : [reg] "=r" (mimpid));
asm volatile ("csrr %[reg], mhartid" : [reg] "=r" (mhartid));
asm volatile ("csrr %[reg], misa" : [reg] "=r" (misa));
// block all harts except hart 0
if(mhartid)
for(;;){ asm volatile ("wfi"); }
mm_init(0x84000000, 0x1bffe000); // addr: 2GB + 64MB & size: 512MB - 64MB - 8KB
uart_init(&uart);
stringFormat(txt, 0x100, "mvendorid=%x, marchid=%x, mimpid=%x, mhartid=%x, misa=%x\r\n", mvendorid, marchid, mimpid, mhartid, misa);
uart_write(&uart, txt, 0x100);
// check if pending interrupt
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));
stringFormat(txt, 0x100, "mie=%x, mip=%x, mstatus=%x, mcause=%x\r\n", mie, mip, mstatus, mcause);
uart_write(&uart, txt, 0x100);
// set interrupt function or vector
asm volatile ("csrw mtvec, %[reg]" : : [reg] "r" (riscv_mtrap));
asm volatile ("csrr %[reg], mtvec" : [reg] "=r" (mtvec));
stringFormat(txt, 0x100, "mtvec=%x\r\n", mtvec);
uart_write(&uart, txt, 0x100);
// enable machine mode interrupts
asm volatile ("csrs mstatus, 0x8");
// enable interrupts
asm volatile ("csrs mie, 0x8");
// check if pending interrupt
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));
stringFormat(txt, 0x100, "mie=%x, mip=%x, mstatus=%x, mcause=%x\r\n", mie, mip, mstatus, mcause);
uart_write(&uart, txt, 0x100);
// enable timer and wait for x cycles
clint_set_hart_timer(&clint, mhartid, 10);
for(mip = 0; mip < 0x100; mip++){}
// check if pending interrupt
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));
stringFormat(txt, 0x100, "mie=%x, mip=%x, mstatus=%x, mcause=%x\r\n", mie, mip, mstatus, mcause);
uart_write(&uart, txt, 0x100);
for(;;){ asm volatile ("wfi"); }
}
asm: asm:
.align 4
.globl riscv_mtrap
.type riscv_mtrap, @function
riscv_mtrap:
j mtrap
mret
output: 输出:
mvendorid=0, marchid=0, mimpid=0, mhartid=0, misa=800000000014112d
mie=0, mip=0, mstatus=0, mcause=0
mtvec=80000010
mie=8, mip=0, mstatus=8, mcause=0
mie=8, mip=80, mstatus=8, mcause=0
Found the error. 发现错误。
asm volatile ("csrs mie, 0x8");
enables software interrupts. 启用软件中断。 I had to
asm volatile ("csrw mie, 0x80");
我不得不将
asm volatile ("csrw mie, 0x80");
, and now it works. ,现在可以使用了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.