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:
parent
8e73df6aa3
commit
753e3fe207
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user