diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 7c9fb276..cc106996 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -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', diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 7372fc02..bb203163 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -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 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index b1b36843..4245fa30 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -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 diff --git a/qemu/target/riscv/cpu.h b/qemu/target/riscv/cpu.h index 94b0ffcb..ddc2d54f 100644 --- a/qemu/target/riscv/cpu.h +++ b/qemu/target/riscv/cpu.h @@ -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) diff --git a/qemu/target/riscv/csr.c b/qemu/target/riscv/csr.c index d8b7b84f..dd5c0124 100644 --- a/qemu/target/riscv/csr.c +++ b/qemu/target/riscv/csr.c @@ -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 */