Merge pull request #1170 from fk-sc/fk-sc/priv-mod

target/riscv: decrease modify_privilege function nesting level
This commit is contained in:
Evgeniy Naydanov 2024-11-26 17:26:49 +03:00 committed by GitHub
commit eb1ecd7d10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 37 additions and 25 deletions

View File

@ -3092,12 +3092,25 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
} }
} }
/* TODO: return mem_access_result_t */
static int modify_privilege(struct target *target, uint64_t *mstatus, uint64_t *mstatus_old) static int modify_privilege(struct target *target, uint64_t *mstatus, uint64_t *mstatus_old)
{ {
if (riscv_virt2phys_mode_is_hw(target) assert(mstatus);
&& has_sufficient_progbuf(target, 5)) { assert(mstatus_old);
if (!riscv_virt2phys_mode_is_hw(target))
return ERROR_OK;
/* TODO: handle error in this case
* modify_privilege function used only for program buffer memory access.
* Privilege modification requires progbuf size to be at least 5 */
if (!has_sufficient_progbuf(target, 5)) {
LOG_TARGET_WARNING(target, "Can't modify privilege to provide "
"hardware translation: program buffer too small.");
return ERROR_OK;
}
/* Read DCSR */ /* Read DCSR */
uint64_t dcsr; riscv_reg_t dcsr;
if (register_read_direct(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK) if (register_read_direct(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
@ -3107,21 +3120,20 @@ static int modify_privilege(struct target *target, uint64_t *mstatus, uint64_t *
*mstatus_old = *mstatus; *mstatus_old = *mstatus;
/* If we come from m-mode with mprv set, we want to keep mpp */ /* If we come from m-mode with mprv set, we want to keep mpp */
if (get_field(dcsr, CSR_DCSR_PRV) < 3) { if (get_field(dcsr, CSR_DCSR_PRV) == PRV_M)
/* MPP = PRIV */ return ERROR_OK;
/* mstatus.mpp <- dcsr.prv */
*mstatus = set_field(*mstatus, MSTATUS_MPP, get_field(dcsr, CSR_DCSR_PRV)); *mstatus = set_field(*mstatus, MSTATUS_MPP, get_field(dcsr, CSR_DCSR_PRV));
/* MPRV = 1 */ /* mstatus.mprv <- 1 */
*mstatus = set_field(*mstatus, MSTATUS_MPRV, 1); *mstatus = set_field(*mstatus, MSTATUS_MPRV, 1);
/* Write MSTATUS */ /* Write MSTATUS */
if (*mstatus != *mstatus_old) if (*mstatus == *mstatus_old)
if (register_write_direct(target, GDB_REGNO_MSTATUS, *mstatus) != ERROR_OK)
return ERROR_FAIL;
}
}
return ERROR_OK; return ERROR_OK;
return register_write_direct(target, GDB_REGNO_MSTATUS, *mstatus);
} }
static int read_memory_bus_v0(struct target *target, target_addr_t address, static int read_memory_bus_v0(struct target *target, target_addr_t address,