From 95a8cd9b5d07501ac2243c61f331b092b1ea9894 Mon Sep 17 00:00:00 2001 From: Tommy Murphy Date: Tue, 26 May 2020 18:33:30 +0100 Subject: [PATCH] =?UTF-8?q?Don't=20use=20MMU=20in=20M=20mode=20-=20https:/?= =?UTF-8?q?/github.com/riscv/riscv-openocd/issu=E2=80=A6=20(#479)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don't use MMU in M mode - https://github.com/riscv/riscv-openocd/issues/474 * Updated code based on feedback from @timsifive --- src/target/riscv/riscv.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 4c3f8fdf5..192b8c5b6 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 {