@@ -2005,13 +2005,6 @@ static int examine(struct target *target)
20052005 info -> impebreak );
20062006 }
20072007
2008- if (info -> progbufsize < 4 && riscv_virt2phys_mode_is_hw (target )) {
2009- LOG_TARGET_ERROR (target , "software address translation "
2010- "is not available on this target. It requires a "
2011- "program buffer size of at least 4. (progbufsize=%d) "
2012- "Use `riscv set_enable_virtual off` to continue." , info -> progbufsize );
2013- }
2014-
20152008 /* Don't call any riscv_* functions until after we've counted the number of
20162009 * cores and initialized registers. */
20172010
@@ -3109,47 +3102,69 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
31093102}
31103103
31113104/* TODO: return mem_access_result_t */
3112- static int modify_privilege (struct target * target , uint64_t * mstatus , uint64_t * mstatus_old )
3105+ static int modify_privilege_for_virt2phys_mode (struct target * target , riscv_reg_t * mstatus , riscv_reg_t * mstatus_old ,
3106+ riscv_reg_t * dcsr , riscv_reg_t * dcsr_old )
31133107{
31143108 assert (mstatus );
31153109 assert (mstatus_old );
3110+ assert (dcsr );
3111+ assert (dcsr_old );
31163112 if (!riscv_virt2phys_mode_is_hw (target ))
31173113 return ERROR_OK ;
31183114
3119- /* TODO: handle error in this case
3120- * modify_privilege function used only for program buffer memory access.
3121- * Privilege modification requires progbuf size to be at least 5 */
3122- if (!has_sufficient_progbuf (target , 5 )) {
3123- LOG_TARGET_WARNING (target , "Can't modify privilege to provide "
3124- "hardware translation: program buffer too small." );
3125- return ERROR_OK ;
3126- }
3127-
3128- /* Read DCSR */
3129- riscv_reg_t dcsr ;
3130- if (register_read_direct (target , & dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
3115+ /* Read and save DCSR */
3116+ if (riscv_reg_get (target , dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
31313117 return ERROR_FAIL ;
3118+ * dcsr_old = * dcsr ;
31323119
31333120 /* Read and save MSTATUS */
3134- if (register_read_direct (target , mstatus , GDB_REGNO_MSTATUS ) != ERROR_OK )
3121+ if (riscv_reg_get (target , mstatus , GDB_REGNO_MSTATUS ) != ERROR_OK )
31353122 return ERROR_FAIL ;
31363123 * mstatus_old = * mstatus ;
31373124
31383125 /* If we come from m-mode with mprv set, we want to keep mpp */
3139- if (get_field (dcsr , CSR_DCSR_PRV ) == PRV_M )
3126+ if (get_field (* dcsr , CSR_DCSR_PRV ) == PRV_M )
31403127 return ERROR_OK ;
31413128
31423129 /* mstatus.mpp <- dcsr.prv */
3143- * mstatus = set_field (* mstatus , MSTATUS_MPP , get_field (dcsr , CSR_DCSR_PRV ));
3130+ * mstatus = set_field (* mstatus , MSTATUS_MPP , get_field (* dcsr , CSR_DCSR_PRV ));
31443131
31453132 /* mstatus.mprv <- 1 */
31463133 * mstatus = set_field (* mstatus , MSTATUS_MPRV , 1 );
31473134
31483135 /* Write MSTATUS */
3149- if (* mstatus == * mstatus_old )
3136+ if (* mstatus != * mstatus_old &&
3137+ riscv_reg_set (target , GDB_REGNO_MSTATUS , * mstatus ) != ERROR_OK )
3138+ return ERROR_FAIL ;
3139+
3140+ /* dcsr.mprven <- 1 */
3141+ * dcsr = set_field (* dcsr , CSR_DCSR_MPRVEN , CSR_DCSR_MPRVEN_ENABLED );
3142+
3143+ /* Write DCSR */
3144+ if (* dcsr != * dcsr_old &&
3145+ riscv_reg_set (target , GDB_REGNO_DCSR , * dcsr ) != ERROR_OK )
3146+ return ERROR_FAIL ;
3147+
3148+ return ERROR_OK ;
3149+ }
3150+
3151+ static int restore_privilege_from_virt2phys_mode (struct target * target , riscv_reg_t mstatus , riscv_reg_t mstatus_old ,
3152+ riscv_reg_t dcsr , riscv_reg_t dcsr_old )
3153+ {
3154+ if (!riscv_virt2phys_mode_is_hw (target ))
31503155 return ERROR_OK ;
31513156
3152- return register_write_direct (target , GDB_REGNO_MSTATUS , * mstatus );
3157+ /* Restore MSTATUS */
3158+ if (mstatus != mstatus_old &&
3159+ riscv_reg_set (target , GDB_REGNO_MSTATUS , mstatus_old ) != ERROR_OK )
3160+ return ERROR_FAIL ;
3161+
3162+ /* Restore DCSR */
3163+ if (dcsr != dcsr_old &&
3164+ riscv_reg_set (target , GDB_REGNO_DCSR , dcsr_old ) != ERROR_OK )
3165+ return ERROR_FAIL ;
3166+
3167+ return ERROR_OK ;
31533168}
31543169
31553170static int read_memory_bus_v0 (struct target * target , const riscv_mem_access_args_t args )
@@ -4188,25 +4203,8 @@ static int read_word_from_s1(struct target *target,
41884203 return ERROR_OK ;
41894204}
41904205
4191- static int riscv_program_load_mprv (struct riscv_program * p , enum gdb_regno d ,
4192- enum gdb_regno b , int offset , unsigned int size , bool mprven )
4193- {
4194- if (mprven && riscv_program_csrrsi (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4195- GDB_REGNO_DCSR ) != ERROR_OK )
4196- return ERROR_FAIL ;
4197-
4198- if (riscv_program_load (p , d , b , offset , size ) != ERROR_OK )
4199- return ERROR_FAIL ;
4200-
4201- if (mprven && riscv_program_csrrci (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4202- GDB_REGNO_DCSR ) != ERROR_OK )
4203- return ERROR_FAIL ;
4204-
4205- return ERROR_OK ;
4206- }
4207-
42084206static int read_memory_progbuf_inner_fill_progbuf (struct target * target ,
4209- uint32_t increment , uint32_t size , bool mprven )
4207+ uint32_t increment , uint32_t size )
42104208{
42114209 const bool is_repeated_read = increment == 0 ;
42124210
@@ -4220,8 +4218,7 @@ static int read_memory_progbuf_inner_fill_progbuf(struct target *target,
42204218 struct riscv_program program ;
42214219
42224220 riscv_program_init (& program , target );
4223- if (riscv_program_load_mprv (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ,
4224- mprven ) != ERROR_OK )
4221+ if (riscv_program_load (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ) != ERROR_OK )
42254222 return ERROR_FAIL ;
42264223 if (is_repeated_read ) {
42274224 if (riscv_program_addi (& program , GDB_REGNO_A0 , GDB_REGNO_A0 , 1 )
@@ -4246,14 +4243,12 @@ static int read_memory_progbuf_inner_fill_progbuf(struct target *target,
42464243 * re-read the data only if `abstract command busy` or `DMI busy`
42474244 * is encountered in the process.
42484245 */
4249- static int read_memory_progbuf_inner (struct target * target ,
4250- const riscv_mem_access_args_t args , bool mprven )
4246+ static int read_memory_progbuf_inner (struct target * target , const riscv_mem_access_args_t args )
42514247{
42524248 assert (riscv_mem_access_is_read (args ));
42534249 assert (args .count > 1 && "If count == 1, read_memory_progbuf_inner_one must be called" );
42544250
4255- if (read_memory_progbuf_inner_fill_progbuf (target , args .increment ,
4256- args .size , mprven ) != ERROR_OK )
4251+ if (read_memory_progbuf_inner_fill_progbuf (target , args .increment , args .size ) != ERROR_OK )
42574252 return ERROR_FAIL ;
42584253
42594254 if (read_memory_progbuf_inner_startup (target , args .address ,
@@ -4305,8 +4300,7 @@ static int read_memory_progbuf_inner(struct target *target,
43054300 * Only need to save/restore one GPR to read a single word, and the progbuf
43064301 * program doesn't need to increment.
43074302 */
4308- static int read_memory_progbuf_inner_one (struct target * target ,
4309- const riscv_mem_access_args_t args , bool mprven )
4303+ static int read_memory_progbuf_inner_one (struct target * target , const riscv_mem_access_args_t args )
43104304{
43114305 assert (riscv_mem_access_is_read (args ));
43124306
@@ -4316,8 +4310,7 @@ static int read_memory_progbuf_inner_one(struct target *target,
43164310 struct riscv_program program ;
43174311
43184312 riscv_program_init (& program , target );
4319- if (riscv_program_load_mprv (& program , GDB_REGNO_S1 , GDB_REGNO_S1 , 0 ,
4320- args .size , mprven ) != ERROR_OK )
4313+ if (riscv_program_load (& program , GDB_REGNO_S1 , GDB_REGNO_S1 , 0 , args .size ) != ERROR_OK )
43214314 return ERROR_FAIL ;
43224315 if (riscv_program_ebreak (& program ) != ERROR_OK )
43234316 return ERROR_FAIL ;
@@ -4363,19 +4356,18 @@ read_memory_progbuf(struct target *target, const riscv_mem_access_args_t args)
43634356 if (execute_autofence (target ) != ERROR_OK )
43644357 return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED ;
43654358
4366- uint64_t mstatus = 0 ;
4367- uint64_t mstatus_old = 0 ;
4368- if (modify_privilege (target , & mstatus , & mstatus_old ) != ERROR_OK )
4359+ riscv_reg_t mstatus = 0 ;
4360+ riscv_reg_t mstatus_old = 0 ;
4361+ riscv_reg_t dcsr = 0 ;
4362+ riscv_reg_t dcsr_old = 0 ;
4363+ if (modify_privilege_for_virt2phys_mode (target , & mstatus , & mstatus_old , & dcsr , & dcsr_old ) != ERROR_OK )
43694364 return MEM_ACCESS_FAILED_PRIV_MOD_FAILED ;
43704365
4371- const bool mprven = riscv_virt2phys_mode_is_hw (target )
4372- && get_field (mstatus , MSTATUS_MPRV );
43734366 int result = (args .count == 1 ) ?
4374- read_memory_progbuf_inner_one (target , args , mprven ) :
4375- read_memory_progbuf_inner (target , args , mprven );
4367+ read_memory_progbuf_inner_one (target , args ) :
4368+ read_memory_progbuf_inner (target , args );
43764369
4377- if (mstatus != mstatus_old &&
4378- register_write_direct (target , GDB_REGNO_MSTATUS , mstatus_old ) != ERROR_OK )
4370+ if (restore_privilege_from_virt2phys_mode (target , mstatus , mstatus_old , dcsr , dcsr_old ) != ERROR_OK )
43794371 return MEM_ACCESS_FAILED ;
43804372
43814373 return (result == ERROR_OK ) ? MEM_ACCESS_OK : MEM_ACCESS_FAILED ;
@@ -4833,25 +4825,7 @@ static int write_memory_progbuf_try_to_write(struct target *target,
48334825 return result ;
48344826}
48354827
4836- static int riscv_program_store_mprv (struct riscv_program * p , enum gdb_regno d ,
4837- enum gdb_regno b , int offset , unsigned int size , bool mprven )
4838- {
4839- if (mprven && riscv_program_csrrsi (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4840- GDB_REGNO_DCSR ) != ERROR_OK )
4841- return ERROR_FAIL ;
4842-
4843- if (riscv_program_store (p , d , b , offset , size ) != ERROR_OK )
4844- return ERROR_FAIL ;
4845-
4846- if (mprven && riscv_program_csrrci (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4847- GDB_REGNO_DCSR ) != ERROR_OK )
4848- return ERROR_FAIL ;
4849-
4850- return ERROR_OK ;
4851- }
4852-
4853- static int write_memory_progbuf_fill_progbuf (struct target * target ,
4854- uint32_t size , bool mprven )
4828+ static int write_memory_progbuf_fill_progbuf (struct target * target , uint32_t size )
48554829{
48564830 if (riscv013_reg_save (target , GDB_REGNO_S0 ) != ERROR_OK )
48574831 return ERROR_FAIL ;
@@ -4861,8 +4835,7 @@ static int write_memory_progbuf_fill_progbuf(struct target *target,
48614835 struct riscv_program program ;
48624836
48634837 riscv_program_init (& program , target );
4864- if (riscv_program_store_mprv (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ,
4865- mprven ) != ERROR_OK )
4838+ if (riscv_program_store (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ) != ERROR_OK )
48664839 return ERROR_FAIL ;
48674840
48684841 if (riscv_program_addi (& program , GDB_REGNO_S0 , GDB_REGNO_S0 , size ) != ERROR_OK )
@@ -4874,12 +4847,11 @@ static int write_memory_progbuf_fill_progbuf(struct target *target,
48744847 return riscv_program_write (& program );
48754848}
48764849
4877- static int write_memory_progbuf_inner (struct target * target , const riscv_mem_access_args_t args , bool mprven )
4850+ static int write_memory_progbuf_inner (struct target * target , const riscv_mem_access_args_t args )
48784851{
48794852 assert (riscv_mem_access_is_write (args ));
48804853
4881- if (write_memory_progbuf_fill_progbuf (target , args .size ,
4882- mprven ) != ERROR_OK )
4854+ if (write_memory_progbuf_fill_progbuf (target , args .size ) != ERROR_OK )
48834855 return ERROR_FAIL ;
48844856
48854857 target_addr_t addr_on_target = args .address ;
@@ -4923,18 +4895,15 @@ write_memory_progbuf(struct target *target, const riscv_mem_access_args_t args)
49234895
49244896 uint64_t mstatus = 0 ;
49254897 uint64_t mstatus_old = 0 ;
4926- if (modify_privilege (target , & mstatus , & mstatus_old ) != ERROR_OK )
4898+ uint64_t dcsr = 0 ;
4899+ uint64_t dcsr_old = 0 ;
4900+ if (modify_privilege_for_virt2phys_mode (target , & mstatus , & mstatus_old , & dcsr , & dcsr_old ) != ERROR_OK )
49274901 return MEM_ACCESS_FAILED_PRIV_MOD_FAILED ;
49284902
4929- const bool mprven = riscv_virt2phys_mode_is_hw (target )
4930- && get_field (mstatus , MSTATUS_MPRV );
4903+ int result = write_memory_progbuf_inner (target , args );
49314904
4932- int result = write_memory_progbuf_inner (target , args , mprven );
4933-
4934- /* Restore MSTATUS */
4935- if (mstatus != mstatus_old )
4936- if (register_write_direct (target , GDB_REGNO_MSTATUS , mstatus_old ))
4937- return MEM_ACCESS_FAILED ;
4905+ if (restore_privilege_from_virt2phys_mode (target , mstatus , mstatus_old , dcsr , dcsr_old ) != ERROR_OK )
4906+ return MEM_ACCESS_FAILED ;
49384907
49394908 if (execute_autofence (target ) != ERROR_OK )
49404909 return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED ;
0 commit comments