RISC-V: Add debug support for accessing CSRs.

Add a debugger field to CPURISCVState. Add riscv_csrrw_debug function
to set it. Disable mode checks when debugger field true.

Backports commit 753e3fe207db08ce0ef0405e8452c3397c9b9308 from qemu
This commit is contained in:
Jim Wilson 2019-03-19 23:42:44 -04:00 committed by Lioncash
parent 30ab335bb3
commit 65903cf9a4
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
5 changed files with 33 additions and 7 deletions

View file

@ -5480,6 +5480,7 @@ riscv_symbols = (
'riscv_cpu_set_mode',
'riscv_cpu_update_mip',
'riscv_csrrw',
'riscv_csrrw_debug',
'riscv_excp_names',
'riscv_fpr_regnames',
'riscv_get_csr_ops',

View file

@ -3401,6 +3401,7 @@
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv32
#define riscv_cpu_update_mip riscv_cpu_update_mip_riscv32
#define riscv_csrrw riscv_csrrw_riscv32
#define riscv_csrrw_debug riscv_csrrw_debug_riscv32
#define riscv_excp_names riscv_excp_names_riscv32
#define riscv_fpr_regnames riscv_fpr_regnames_riscv32
#define riscv_get_csr_ops riscv_get_csr_ops_riscv32

View file

@ -3401,6 +3401,7 @@
#define riscv_cpu_set_mode riscv_cpu_set_mode_riscv64
#define riscv_cpu_update_mip riscv_cpu_update_mip_riscv64
#define riscv_csrrw riscv_csrrw_riscv64
#define riscv_csrrw_debug riscv_csrrw_debug_riscv64
#define riscv_excp_names riscv_excp_names_riscv64
#define riscv_fpr_regnames riscv_fpr_regnames_riscv64
#define riscv_get_csr_ops riscv_get_csr_ops_riscv64

View file

@ -174,6 +174,9 @@ struct CPURISCVState {
/* physical memory protection */
pmp_table_t pmp_state;
/* True if in debugger mode. */
bool debugger;
#endif
float_status fp_status;
@ -298,6 +301,8 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask);
int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask);
static inline void riscv_csr_write(CPURISCVState *env, int csrno,
target_ulong val)

View file

@ -45,7 +45,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
static int fs(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
#endif
@ -91,7 +91,7 @@ static int pmp(CPURISCVState *env, int csrno)
static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
#endif
@ -102,7 +102,7 @@ static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
env->mstatus |= MSTATUS_FS;
@ -114,7 +114,7 @@ static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
#endif
@ -125,7 +125,7 @@ static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
env->mstatus |= MSTATUS_FS;
@ -137,7 +137,7 @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
#endif
@ -149,7 +149,7 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
{
#if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) {
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1;
}
env->mstatus |= MSTATUS_FS;
@ -835,6 +835,24 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
return 0;
}
/*
* Debugger support. If not in user mode, set env->debugger before the
* riscv_csrrw call and clear it after the call.
*/
int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask)
{
int ret;
#if !defined(CONFIG_USER_ONLY)
env->debugger = true;
#endif
ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
#if !defined(CONFIG_USER_ONLY)
env->debugger = false;
#endif
return ret;
}
/* Control and Status Register function table */
static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
/* User Floating-Point CSRs */