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.

Signed-off-by: Jim Wilson <jimw@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20190212230903.9215-1-jimw@sifive.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
This commit is contained in:
Jim Wilson 2019-03-15 03:26:58 -07:00 committed by Palmer Dabbelt
parent 8e73df6aa3
commit 753e3fe207
No known key found for this signature in database
GPG Key ID: EF4CA1502CCBAB41
2 changed files with 30 additions and 7 deletions

View File

@ -172,6 +172,9 @@ struct CPURISCVState {
/* physical memory protection */ /* physical memory protection */
pmp_table_t pmp_state; pmp_table_t pmp_state;
/* True if in debugger mode. */
bool debugger;
#endif #endif
float_status fp_status; float_status fp_status;
@ -293,6 +296,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, int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask); 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, static inline void riscv_csr_write(CPURISCVState *env, int csrno,
target_ulong val) target_ulong val)

View File

@ -46,7 +46,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
static int fs(CPURISCVState *env, int csrno) static int fs(CPURISCVState *env, int csrno)
{ {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
#endif #endif
@ -92,7 +92,7 @@ static int pmp(CPURISCVState *env, int csrno)
static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val) static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
{ {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
#endif #endif
@ -103,7 +103,7 @@ static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
static int write_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 !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
env->mstatus |= MSTATUS_FS; env->mstatus |= MSTATUS_FS;
@ -115,7 +115,7 @@ static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
static int read_frm(CPURISCVState *env, int csrno, target_ulong *val) static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
{ {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
#endif #endif
@ -126,7 +126,7 @@ static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
static int write_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 !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
env->mstatus |= MSTATUS_FS; env->mstatus |= MSTATUS_FS;
@ -138,7 +138,7 @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val) static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
{ {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
#endif #endif
@ -150,7 +150,7 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
static int write_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 !defined(CONFIG_USER_ONLY)
if (!(env->mstatus & MSTATUS_FS)) { if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
return -1; return -1;
} }
env->mstatus |= MSTATUS_FS; env->mstatus |= MSTATUS_FS;
@ -827,6 +827,24 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
return 0; 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 */ /* Control and Status Register function table */
static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
/* User Floating-Point CSRs */ /* User Floating-Point CSRs */