Skip to content

Commit eb1ecd7

Browse files
authored
Merge pull request #1170 from fk-sc/fk-sc/priv-mod
target/riscv: decrease modify_privilege function nesting level
2 parents 6587668 + 8b70130 commit eb1ecd7

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

src/target/riscv/riscv-013.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3092,36 +3092,48 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
30923092
}
30933093
}
30943094

3095+
/* TODO: return mem_access_result_t */
30953096
static int modify_privilege(struct target *target, uint64_t *mstatus, uint64_t *mstatus_old)
30963097
{
3097-
if (riscv_virt2phys_mode_is_hw(target)
3098-
&& has_sufficient_progbuf(target, 5)) {
3099-
/* Read DCSR */
3100-
uint64_t dcsr;
3101-
if (register_read_direct(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
3102-
return ERROR_FAIL;
3098+
assert(mstatus);
3099+
assert(mstatus_old);
3100+
if (!riscv_virt2phys_mode_is_hw(target))
3101+
return ERROR_OK;
31033102

3104-
/* Read and save MSTATUS */
3105-
if (register_read_direct(target, mstatus, GDB_REGNO_MSTATUS) != ERROR_OK)
3106-
return ERROR_FAIL;
3107-
*mstatus_old = *mstatus;
3103+
/* TODO: handle error in this case
3104+
* modify_privilege function used only for program buffer memory access.
3105+
* Privilege modification requires progbuf size to be at least 5 */
3106+
if (!has_sufficient_progbuf(target, 5)) {
3107+
LOG_TARGET_WARNING(target, "Can't modify privilege to provide "
3108+
"hardware translation: program buffer too small.");
3109+
return ERROR_OK;
3110+
}
3111+
3112+
/* Read DCSR */
3113+
riscv_reg_t dcsr;
3114+
if (register_read_direct(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
3115+
return ERROR_FAIL;
31083116

3109-
/* If we come from m-mode with mprv set, we want to keep mpp */
3110-
if (get_field(dcsr, CSR_DCSR_PRV) < 3) {
3111-
/* MPP = PRIV */
3112-
*mstatus = set_field(*mstatus, MSTATUS_MPP, get_field(dcsr, CSR_DCSR_PRV));
3117+
/* Read and save MSTATUS */
3118+
if (register_read_direct(target, mstatus, GDB_REGNO_MSTATUS) != ERROR_OK)
3119+
return ERROR_FAIL;
3120+
*mstatus_old = *mstatus;
31133121

3114-
/* MPRV = 1 */
3115-
*mstatus = set_field(*mstatus, MSTATUS_MPRV, 1);
3122+
/* If we come from m-mode with mprv set, we want to keep mpp */
3123+
if (get_field(dcsr, CSR_DCSR_PRV) == PRV_M)
3124+
return ERROR_OK;
31163125

3117-
/* Write MSTATUS */
3118-
if (*mstatus != *mstatus_old)
3119-
if (register_write_direct(target, GDB_REGNO_MSTATUS, *mstatus) != ERROR_OK)
3120-
return ERROR_FAIL;
3121-
}
3122-
}
3126+
/* mstatus.mpp <- dcsr.prv */
3127+
*mstatus = set_field(*mstatus, MSTATUS_MPP, get_field(dcsr, CSR_DCSR_PRV));
31233128

3124-
return ERROR_OK;
3129+
/* mstatus.mprv <- 1 */
3130+
*mstatus = set_field(*mstatus, MSTATUS_MPRV, 1);
3131+
3132+
/* Write MSTATUS */
3133+
if (*mstatus == *mstatus_old)
3134+
return ERROR_OK;
3135+
3136+
return register_write_direct(target, GDB_REGNO_MSTATUS, *mstatus);
31253137
}
31263138

31273139
static int read_memory_bus_v0(struct target *target, target_addr_t address,

0 commit comments

Comments
 (0)