Search code examples
operating-systemqemuriscv

Some question about Machine Timer Interrupt and Supervisor Timer Interrupt in riscv


I'm currently working on my OS lab with RISC-V on QEMU, and I've encountered some confusion regarding the behavior when the value of "mtime" exceeds "mtimecmp." Specifically, I'm unsure whether it triggers a Machine Timer Interrupt (MTI) or a Supervisor Timer Interrupt (STI). I've also noticed that even after delegating the STI to S mode, the RISC-V architecture still seems to trap into M mode.

I'm using QEMU emulator version 5.0.0 with the default OpenSBI configuration. I'm curious about the underlying mechanics of how the STI occurs and why the CPU transitions into M mode despite my delegation to S mode.

It appears that when the time interrupt occurs and the value of "mtime" exceeds "mtimecmp," the Machine Timer Interrupt (MTI) is indeed triggered, as evidenced by the fact that the instructions specified in "mtvec" are executed during the interrupt event.


Solution

  • mtimecmp is a M-mode CSR and it is supposed to generate MTI only. STI is a different interrupt.

    Previously there was only mtimecmp CSR and M mode firmware was responsible for providing timer services to S mode. How? Through ecall and interrupt injection.

    • Smode will invoke SBI_EXT_TIME_SET_TIMER ecall and M mode firmware will handle the ecall and program the mtimecmp accordingly.
    • When MTI interrupt is generated (mtime reaches mtimecmp), M-mode firmware will inject that interrupt into S-mode by setting STIP bit in mip.

    Given is the code snippet from openSBI that does the interrupt injection.

    void sbi_timer_process(void)
    {
            csr_clear(CSR_MIE, MIP_MTIP);
            /*  
             * If sstc extension is available, supervisor can receive the timer
             * directly without M-mode come in between. This function should
             * only invoked if M-mode programs the timer for its own purpose.
             */
            if (!sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SSTC))
                    csr_set(CSR_MIP, MIP_STIP);
    }
    

    As of now new extension has been merged in Qemu that adds support for stimecmp. This directly generates STI. Now given you have already delegated STI to S-mode, you should be able to receive it in your S-mode code.