Hazard3/test/sim/sw_testcases/umode_mret.c

49 lines
1.2 KiB
C

#include "tb_cxxrtl_io.h"
#include "hazard3_csr.h"
// Check that U-mode execution of an mret causes an illegal opcode exception.
/*EXPECTED-OUTPUT***************************************************************
-> exception, mcause = 2, mpp = 0 // should indicate U-mode illegal opcode
Excepting instr: 30200073 // mret
*******************************************************************************/
void __attribute__((naked)) do_mret() {
asm ("mret");
}
int main() {
// Give U mode RWX permission on all of memory.
write_csr(pmpcfg0, 0x1fu);
write_csr(pmpaddr0, -1u);
// Jump to do_mret() in U mode
write_csr(mstatus, read_csr(mstatus) & ~0x1800u);
write_csr(mepc, &do_mret);
asm ("mret");
return 0;
}
void __attribute__((interrupt)) handle_exception() {
uint32_t mcause = read_csr(mcause);
tb_printf("-> exception, mcause = %u, mpp = %u\n", mcause, read_csr(mstatus) >> 11 & 0x3u);
write_csr(mcause, 0);
if (mcause == 3) {
// ebreak -> end of test
tb_exit(0);
}
uint32_t mepc = read_csr(mepc);
if (mepc != (uint32_t)&do_mret) {
tb_printf("Bad mepc: %08x\n", mepc);
tb_exit(-1);
}
tb_printf("Excepting instr: %04x%04x\n", *(uint16_t*)(mepc + 2), *(uint16_t*)mepc);
tb_exit(0);
}