Support trap handling during block emulation
Trap might occurs during block emulation, for example, page fault. In order to handle trap, we have to temporarily escape from block and jump to the trap handler to handle the trap PC by PC. Once trap is handled, resume the previous execution flow where cause the trap. To support this, we leverage setjmp function to store the state and a flag called is_trapped to indicate the emulation is in a trap handling mode currently. The sret and mret implementation are refactored to control the corresponding CSR before get out from trap.
Some S-mode CSRs are added to riscv_internal to support S-mode. S-mode, and M-mode CSR helper macros are also introduced, so that the CSR can be manipulated in an easier manner.
Related: #310
For nested traps concern, I think before entering critical part of kernel control path, the contents of the CSR registers could be saved in the Kernel Mode stack, then restore the contents of the CSR registers when exiting the kernel control path. This way is considered as a software manner.
please do not merge yet
You can simply convert this pull request to draft, so that it will not be merged.
According to the "The RISC-V Instruction Set Manual ( Volume I: Unprivileged ISA Document Version 20191213 )", the execution environment interface ( EEI ) may or may NOT guarantee that misaligned loads and stores are fully supported. Thus, I think the emulator maybe no need handling misalignment in hardware manner and just let Linux handle it through exception. In other words, ensuring the emulator set the PC to correct address that stored in stvec CSR.
According to the "The RISC-V Instruction Set Manual ( Volume I: Unprivileged ISA Document Version 20191213 )", the execution environment interface ( EEI ) may or may NOT guarantee that misaligned loads and stores are fully supported. Thus, I think the emulator maybe no need handling misalignment in hardware manner and just let Linux handle it through exception. In other words, ensuring the emulator set the PC to correct address that stored in stvec CSR.
The reason rv32emu includes an option for misalignment handling is to align its behavior with Spike, allowing the two implementations to be compared. You should evaluate the minimal and necessary changes.
According to the "The RISC-V Instruction Set Manual ( Volume I: Unprivileged ISA Document Version 20191213 )", the execution environment interface ( EEI ) may or may NOT guarantee that misaligned loads and stores are fully supported. Thus, I think the emulator maybe no need handling misalignment in hardware manner and just let Linux handle it through exception. In other words, ensuring the emulator set the PC to correct address that stored in stvec CSR.
The reason rv32emu includes an option for misalignment handling is to align its behavior with Spike, allowing the two implementations to be compared. You should evaluate the minimal and necessary changes.
Got it. The current implementation of misaligned handling is through trap and set PC according to the stvec or mtvec CSR which in my expectation instead of handled by rv32emu itself. So that, the handling of misaligned behavior whether it results in a fatal error or is manageable depends on the implementation of the handler. Some simple test suites will be introduced to test the changes in this PR.
As I realizes that we may not need to enable exception or interrupt delegation from M-mode software to S-mode software since we do not tend to leverage the M-mode software ( such as OpenSBI ) to boot Linux kernel. Nonetheless, I would still like to include the medeleg and mideleg CSRs in the changes for a more comprehensive implementation. They are not entirely useless, as the test suite has utilized them from the very beginning of its design.
Any idea for this? @jserv
Nonetheless, I would still like to include the
medelegandmidelegCSRs in the changes for a more comprehensive implementation. They are not entirely useless, as the test suite has utilized them from the very beginning of its design.
I am afraid of the lack of proper test suite from CSR operations, meaning that we can have limited coverage. Meanwhile, I don't have explicit idea to escape from the chicken and egg problem.
According to the "The RISC-V Instruction Set Manual ( Volume I: Unprivileged ISA Document Version 20191213 )", the execution environment interface ( EEI ) may or may NOT guarantee that misaligned loads and stores are fully supported. Thus, I think the emulator maybe no need handling misalignment in hardware manner and just let Linux handle it through exception. In other words, ensuring the emulator set the PC to correct address that stored in stvec CSR.
The reason rv32emu includes an option for misalignment handling is to align its behavior with Spike, allowing the two implementations to be compared. You should evaluate the minimal and necessary changes.
The rv->is_trapped is compiled only when SYSTEM build flag is enabled. Thus, when comparing the misalignment handling between rv32emu and Spike during ISA simulation, the original behavior is maintained.
Nonetheless, I would still like to include the
medelegandmidelegCSRs in the changes for a more comprehensive implementation. They are not entirely useless, as the test suite has utilized them from the very beginning of its design.I am afraid of the lack of proper test suite from CSR operations, meaning that we can have limited coverage. Meanwhile, I don't have explicit idea to escape from the chicken and egg problem.
I intend to remove the exception and interrupt delegation logic for now. We can add it back later if needed.
#498 must be merged first for this PR to pass the CI.
The commits are reordered and squashed.
To handle a trap, we temporarily exit the block and transfer control to the trap handler, processing each instruction by stepping.
Does this change explicitly break the chained block? or just trap into the interrupt service routine and go back to the current when it done?
To handle a trap, we temporarily exit the block and transfer control to the trap handler, processing each instruction by stepping.
Does this change explicitly break the chained block? or just trap into the interrupt service routine and go back to the current when it done?
The latter.