diff options
author | Andrew Waterman <andrew@sifive.com> | 2017-03-29 16:27:11 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2017-03-29 16:27:11 -0700 |
commit | 6f407a8d549620be5cfbdaa0b9fda967d633d736 (patch) | |
tree | 0af94c561a63d5f1026511b47c99ea387426504f | |
parent | 75f1854cd9d665dd6a7ed3bff7556b98e5a4a26c (diff) | |
download | pk-6f407a8d549620be5cfbdaa0b9fda967d633d736.zip pk-6f407a8d549620be5cfbdaa0b9fda967d633d736.tar.gz pk-6f407a8d549620be5cfbdaa0b9fda967d633d736.tar.bz2 |
Attempt to read instruction from mbadaddr
-rw-r--r-- | machine/emulation.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/machine/emulation.c b/machine/emulation.c index 25b39af..b5d3410 100644 --- a/machine/emulation.c +++ b/machine/emulation.c @@ -128,11 +128,15 @@ void illegal_insn_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) " .word truly_illegal_insn\n" " .popsection"); - uintptr_t mstatus; - insn_t insn = get_insn(mepc, &mstatus); - - if ((insn & 3) != 3) - return emulate_rvc(regs, mcause, mepc, mstatus, insn); + uintptr_t mstatus = read_csr(mstatus); + insn_t insn = read_csr(mbadaddr); + + if (unlikely((insn & 3) != 3)) { + if (insn == 0) + insn = get_insn(mepc, &mstatus); + if ((insn & 3) != 3) + return emulate_rvc(regs, mcause, mepc, mstatus, insn); + } write_csr(mepc, mepc + 4); |