簡體   English   中英

RISC-V跳轉到中斷處理程序

[英]RISC-V jump to interrupt handler

您好,我在寫一個小的內核,以更好地了解RISC-V。 到目前為止,我設法使用UART並設置了一個簡單的內存管理器。 為了能夠解析用戶輸入,我設置了一個中斷處理程序並將其地址設置為MTVEC。 然后我在MSTATUS和MIE中啟用了中斷。 之后,我通過mmio寄存器設置MTIMECMP,並與WFI永遠循環(RISC-V等待中斷指令)。 然后我注意到MIP包含了預期的0x8(這意味着機器模式定時器中斷待處理)。 我的代碼沒有跳到MTVEC的唯一問題。 我怎么了 最好的問候,Serge Teodori

資源:

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:

    .align 4
    .globl riscv_mtrap
    .type riscv_mtrap, @function
riscv_mtrap:
    j mtrap
    mret

輸出:

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

發現錯誤。 asm volatile ("csrs mie, 0x8"); 啟用軟件中斷。 我不得不將asm volatile ("csrw mie, 0x80"); ,現在可以使用了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM