aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/riscv/riscv.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 4c3f8fd..192b8c5 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -1383,15 +1383,34 @@ static int riscv_mmu(struct target *target, int *enabled)
if (riscv_rtos_enabled(target))
riscv_set_current_hartid(target, target->rtos->current_thread - 1);
- riscv_reg_t value;
- if (riscv_get_register(target, &value, GDB_REGNO_SATP) != ERROR_OK) {
+ /* Don't use MMU in explicit or effective M (machine) mode */
+ riscv_reg_t priv;
+ if (riscv_get_register(target, &priv, GDB_REGNO_PRIV) != ERROR_OK) {
+ LOG_ERROR("Failed to read priv register.");
+ return ERROR_FAIL;
+ }
+
+ riscv_reg_t mstatus;
+ if (riscv_get_register(target, &mstatus, GDB_REGNO_MSTATUS) != ERROR_OK) {
+ LOG_ERROR("Failed to read mstatus register.");
+ return ERROR_FAIL;
+ }
+
+ if ((get_field(mstatus, MSTATUS_MPRV) ? get_field(mstatus, MSTATUS_MPP) : priv) == PRV_M) {
+ LOG_DEBUG("SATP/MMU ignored in Machine mode (mstatus=0x%" PRIx64 ").", mstatus);
+ *enabled = 0;
+ return ERROR_OK;
+ }
+
+ riscv_reg_t satp;
+ if (riscv_get_register(target, &satp, GDB_REGNO_SATP) != ERROR_OK) {
LOG_DEBUG("Couldn't read SATP.");
/* If we can't read SATP, then there must not be an MMU. */
*enabled = 0;
return ERROR_OK;
}
- if (get_field(value, RISCV_SATP_MODE(riscv_xlen(target))) == SATP_MODE_OFF) {
+ if (get_field(satp, RISCV_SATP_MODE(riscv_xlen(target))) == SATP_MODE_OFF) {
LOG_DEBUG("MMU is disabled.");
*enabled = 0;
} else {