aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/linux-build.yml2
-rw-r--r--src/target/riscv/riscv-013.c11
-rw-r--r--src/target/riscv/riscv.c23
3 files changed, 14 insertions, 22 deletions
diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml
index 4bcd5bb..c21b364 100644
--- a/.github/workflows/linux-build.yml
+++ b/.github/workflows/linux-build.yml
@@ -5,7 +5,7 @@ name: Linux Build
jobs:
# 32-bit, clang
build32:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
env:
CFLAGS: -m32
CC: clang
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 46c61ca..4fd041f 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -538,6 +538,7 @@ static bool check_dbgbase_exists(struct target *target)
{
uint32_t next_dm = 0;
unsigned int count = 1;
+ riscv013_info_t *info = get_info(target);
LOG_TARGET_DEBUG(target, "Searching for DM with DMI base address (dbgbase) = 0x%x", target->dbgbase);
while (1) {
@@ -552,6 +553,12 @@ static bool check_dbgbase_exists(struct target *target)
LOG_TARGET_ERROR(target, "Reached the end of DM chain (detected %u DMs in total).", count);
break;
}
+ if (next_dm >> info->abits) {
+ LOG_TARGET_ERROR(target, "The address of the next Debug Module does not fit into %u bits, "
+ "which is the width of the DMI bus address. This is a HW bug",
+ info->abits);
+ break;
+ }
/* Safety: Avoid looping forever in case of buggy nextdm values in the hardware. */
if (count++ > RISCV_MAX_DMS) {
LOG_TARGET_ERROR(target, "Supporting no more than %d DMs on a DMI bus. Aborting", RISCV_MAX_DMS);
@@ -2603,8 +2610,8 @@ static int sample_memory_bus_v1(struct target *target,
{
RISCV013_INFO(info);
unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
- if (sbasize > 64) {
- LOG_TARGET_ERROR(target, "Memory sampling is only implemented for sbasize <= 64.");
+ if (sbasize == 0 || sbasize > 64) {
+ LOG_TARGET_ERROR(target, "Memory sampling is only implemented for non-zero sbasize <= 64.");
return ERROR_NOT_IMPLEMENTED;
}
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 3148753..ce0af2a 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -3035,23 +3035,8 @@ static int riscv_mmu(struct target *target, int *enabled)
unsigned int xlen = riscv_xlen(target);
if (v_mode) {
- /* vsatp and hgatp registers are considered active for the
- * purposes of the address-translation algorithm unless the
- * effective privilege mode is U and hstatus.HU=0. */
- if (effective_mode == PRV_U) {
- riscv_reg_t hstatus;
- if (riscv_reg_get(target, &hstatus, GDB_REGNO_HSTATUS) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Failed to read hstatus register.");
- return ERROR_FAIL;
- }
-
- if (get_field(hstatus, HSTATUS_HU) == 0)
- /* In hypervisor mode regular satp translation
- * doesn't happen. */
- return ERROR_OK;
-
- }
-
+ /* In VU or VS mode, MMU is considered enabled when
+ * either hgatp or vsatp mode is not OFF */
riscv_reg_t vsatp;
if (riscv_reg_get(target, &vsatp, GDB_REGNO_VSATP) != ERROR_OK) {
LOG_TARGET_ERROR(target, "Failed to read vsatp register; priv=0x%" PRIx64,
@@ -3059,7 +3044,7 @@ static int riscv_mmu(struct target *target, int *enabled)
return ERROR_FAIL;
}
/* vsatp is identical to satp, so we can use the satp macros. */
- if (RISCV_SATP_MODE(xlen) != SATP_MODE_OFF) {
+ if (get_field(vsatp, RISCV_SATP_MODE(xlen)) != SATP_MODE_OFF) {
LOG_TARGET_DEBUG(target, "VS-stage translation is enabled.");
*enabled = 1;
return ERROR_OK;
@@ -3071,7 +3056,7 @@ static int riscv_mmu(struct target *target, int *enabled)
priv);
return ERROR_FAIL;
}
- if (RISCV_HGATP_MODE(xlen) != HGATP_MODE_OFF) {
+ if (get_field(hgatp, RISCV_HGATP_MODE(xlen)) != HGATP_MODE_OFF) {
LOG_TARGET_DEBUG(target, "G-stage address translation is enabled.");
*enabled = 1;
} else {