@@ -2036,13 +2036,6 @@ static int examine(struct target *target)
2036
2036
info -> impebreak );
2037
2037
}
2038
2038
2039
- if (info -> progbufsize < 4 && riscv_virt2phys_mode_is_hw (target )) {
2040
- LOG_TARGET_ERROR (target , "software address translation "
2041
- "is not available on this target. It requires a "
2042
- "program buffer size of at least 4. (progbufsize=%d) "
2043
- "Use `riscv set_enable_virtual off` to continue." , info -> progbufsize );
2044
- }
2045
-
2046
2039
/* Don't call any riscv_* functions until after we've counted the number of
2047
2040
* cores and initialized registers. */
2048
2041
@@ -3143,47 +3136,69 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
3143
3136
}
3144
3137
3145
3138
/* TODO: return mem_access_result_t */
3146
- static int modify_privilege (struct target * target , uint64_t * mstatus , uint64_t * mstatus_old )
3139
+ static int modify_privilege_for_virt2phys_mode (struct target * target , riscv_reg_t * mstatus , riscv_reg_t * mstatus_old ,
3140
+ riscv_reg_t * dcsr , riscv_reg_t * dcsr_old )
3147
3141
{
3148
3142
assert (mstatus );
3149
3143
assert (mstatus_old );
3144
+ assert (dcsr );
3145
+ assert (dcsr_old );
3150
3146
if (!riscv_virt2phys_mode_is_hw (target ))
3151
3147
return ERROR_OK ;
3152
3148
3153
- /* TODO: handle error in this case
3154
- * modify_privilege function used only for program buffer memory access.
3155
- * Privilege modification requires progbuf size to be at least 5 */
3156
- if (!has_sufficient_progbuf (target , 5 )) {
3157
- LOG_TARGET_WARNING (target , "Can't modify privilege to provide "
3158
- "hardware translation: program buffer too small." );
3159
- return ERROR_OK ;
3160
- }
3161
-
3162
- /* Read DCSR */
3163
- riscv_reg_t dcsr ;
3164
- if (register_read_direct (target , & dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
3149
+ /* Read and save DCSR */
3150
+ if (riscv_reg_get (target , dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
3165
3151
return ERROR_FAIL ;
3152
+ * dcsr_old = * dcsr ;
3166
3153
3167
3154
/* Read and save MSTATUS */
3168
- if (register_read_direct (target , mstatus , GDB_REGNO_MSTATUS ) != ERROR_OK )
3155
+ if (riscv_reg_get (target , mstatus , GDB_REGNO_MSTATUS ) != ERROR_OK )
3169
3156
return ERROR_FAIL ;
3170
3157
* mstatus_old = * mstatus ;
3171
3158
3172
3159
/* If we come from m-mode with mprv set, we want to keep mpp */
3173
- if (get_field (dcsr , CSR_DCSR_PRV ) == PRV_M )
3160
+ if (get_field (* dcsr , CSR_DCSR_PRV ) == PRV_M )
3174
3161
return ERROR_OK ;
3175
3162
3176
3163
/* mstatus.mpp <- dcsr.prv */
3177
- * mstatus = set_field (* mstatus , MSTATUS_MPP , get_field (dcsr , CSR_DCSR_PRV ));
3164
+ * mstatus = set_field (* mstatus , MSTATUS_MPP , get_field (* dcsr , CSR_DCSR_PRV ));
3178
3165
3179
3166
/* mstatus.mprv <- 1 */
3180
3167
* mstatus = set_field (* mstatus , MSTATUS_MPRV , 1 );
3181
3168
3182
3169
/* Write MSTATUS */
3183
- if (* mstatus == * mstatus_old )
3170
+ if (* mstatus != * mstatus_old &&
3171
+ riscv_reg_set (target , GDB_REGNO_MSTATUS , * mstatus ) != ERROR_OK )
3172
+ return ERROR_FAIL ;
3173
+
3174
+ /* dcsr.mprven <- 1 */
3175
+ * dcsr = set_field (* dcsr , CSR_DCSR_MPRVEN , CSR_DCSR_MPRVEN_ENABLED );
3176
+
3177
+ /* Write DCSR */
3178
+ if (* dcsr != * dcsr_old &&
3179
+ riscv_reg_set (target , GDB_REGNO_DCSR , * dcsr ) != ERROR_OK )
3180
+ return ERROR_FAIL ;
3181
+
3182
+ return ERROR_OK ;
3183
+ }
3184
+
3185
+ static int restore_privilege_from_virt2phys_mode (struct target * target , riscv_reg_t mstatus , riscv_reg_t mstatus_old ,
3186
+ riscv_reg_t dcsr , riscv_reg_t dcsr_old )
3187
+ {
3188
+ if (!riscv_virt2phys_mode_is_hw (target ))
3184
3189
return ERROR_OK ;
3185
3190
3186
- return register_write_direct (target , GDB_REGNO_MSTATUS , * mstatus );
3191
+ /* Restore MSTATUS */
3192
+ if (mstatus != mstatus_old &&
3193
+ riscv_reg_set (target , GDB_REGNO_MSTATUS , mstatus_old ) != ERROR_OK )
3194
+ return ERROR_FAIL ;
3195
+
3196
+ /* Restore DCSR */
3197
+ if (dcsr != dcsr_old &&
3198
+ riscv_reg_set (target , GDB_REGNO_DCSR , dcsr_old ) != ERROR_OK )
3199
+ return ERROR_FAIL ;
3200
+
3201
+ return ERROR_OK ;
3187
3202
}
3188
3203
3189
3204
static int read_memory_bus_v0 (struct target * target , const riscv_mem_access_args_t args )
@@ -4222,25 +4237,8 @@ static int read_word_from_s1(struct target *target,
4222
4237
return ERROR_OK ;
4223
4238
}
4224
4239
4225
- static int riscv_program_load_mprv (struct riscv_program * p , enum gdb_regno d ,
4226
- enum gdb_regno b , int offset , unsigned int size , bool mprven )
4227
- {
4228
- if (mprven && riscv_program_csrrsi (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4229
- GDB_REGNO_DCSR ) != ERROR_OK )
4230
- return ERROR_FAIL ;
4231
-
4232
- if (riscv_program_load (p , d , b , offset , size ) != ERROR_OK )
4233
- return ERROR_FAIL ;
4234
-
4235
- if (mprven && riscv_program_csrrci (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4236
- GDB_REGNO_DCSR ) != ERROR_OK )
4237
- return ERROR_FAIL ;
4238
-
4239
- return ERROR_OK ;
4240
- }
4241
-
4242
4240
static int read_memory_progbuf_inner_fill_progbuf (struct target * target ,
4243
- uint32_t increment , uint32_t size , bool mprven )
4241
+ uint32_t increment , uint32_t size )
4244
4242
{
4245
4243
const bool is_repeated_read = increment == 0 ;
4246
4244
@@ -4254,8 +4252,7 @@ static int read_memory_progbuf_inner_fill_progbuf(struct target *target,
4254
4252
struct riscv_program program ;
4255
4253
4256
4254
riscv_program_init (& program , target );
4257
- if (riscv_program_load_mprv (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ,
4258
- mprven ) != ERROR_OK )
4255
+ if (riscv_program_load (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ) != ERROR_OK )
4259
4256
return ERROR_FAIL ;
4260
4257
if (is_repeated_read ) {
4261
4258
if (riscv_program_addi (& program , GDB_REGNO_A0 , GDB_REGNO_A0 , 1 )
@@ -4280,14 +4277,12 @@ static int read_memory_progbuf_inner_fill_progbuf(struct target *target,
4280
4277
* re-read the data only if `abstract command busy` or `DMI busy`
4281
4278
* is encountered in the process.
4282
4279
*/
4283
- static int read_memory_progbuf_inner (struct target * target ,
4284
- const riscv_mem_access_args_t args , bool mprven )
4280
+ static int read_memory_progbuf_inner (struct target * target , const riscv_mem_access_args_t args )
4285
4281
{
4286
4282
assert (riscv_mem_access_is_read (args ));
4287
4283
assert (args .count > 1 && "If count == 1, read_memory_progbuf_inner_one must be called" );
4288
4284
4289
- if (read_memory_progbuf_inner_fill_progbuf (target , args .increment ,
4290
- args .size , mprven ) != ERROR_OK )
4285
+ if (read_memory_progbuf_inner_fill_progbuf (target , args .increment , args .size ) != ERROR_OK )
4291
4286
return ERROR_FAIL ;
4292
4287
4293
4288
if (read_memory_progbuf_inner_startup (target , args .address ,
@@ -4339,8 +4334,7 @@ static int read_memory_progbuf_inner(struct target *target,
4339
4334
* Only need to save/restore one GPR to read a single word, and the progbuf
4340
4335
* program doesn't need to increment.
4341
4336
*/
4342
- static int read_memory_progbuf_inner_one (struct target * target ,
4343
- const riscv_mem_access_args_t args , bool mprven )
4337
+ static int read_memory_progbuf_inner_one (struct target * target , const riscv_mem_access_args_t args )
4344
4338
{
4345
4339
assert (riscv_mem_access_is_read (args ));
4346
4340
@@ -4350,8 +4344,7 @@ static int read_memory_progbuf_inner_one(struct target *target,
4350
4344
struct riscv_program program ;
4351
4345
4352
4346
riscv_program_init (& program , target );
4353
- if (riscv_program_load_mprv (& program , GDB_REGNO_S1 , GDB_REGNO_S1 , 0 ,
4354
- args .size , mprven ) != ERROR_OK )
4347
+ if (riscv_program_load (& program , GDB_REGNO_S1 , GDB_REGNO_S1 , 0 , args .size ) != ERROR_OK )
4355
4348
return ERROR_FAIL ;
4356
4349
if (riscv_program_ebreak (& program ) != ERROR_OK )
4357
4350
return ERROR_FAIL ;
@@ -4397,19 +4390,18 @@ read_memory_progbuf(struct target *target, const riscv_mem_access_args_t args)
4397
4390
if (execute_autofence (target ) != ERROR_OK )
4398
4391
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED ;
4399
4392
4400
- uint64_t mstatus = 0 ;
4401
- uint64_t mstatus_old = 0 ;
4402
- if (modify_privilege (target , & mstatus , & mstatus_old ) != ERROR_OK )
4393
+ riscv_reg_t mstatus = 0 ;
4394
+ riscv_reg_t mstatus_old = 0 ;
4395
+ riscv_reg_t dcsr = 0 ;
4396
+ riscv_reg_t dcsr_old = 0 ;
4397
+ if (modify_privilege_for_virt2phys_mode (target , & mstatus , & mstatus_old , & dcsr , & dcsr_old ) != ERROR_OK )
4403
4398
return MEM_ACCESS_FAILED_PRIV_MOD_FAILED ;
4404
4399
4405
- const bool mprven = riscv_virt2phys_mode_is_hw (target )
4406
- && get_field (mstatus , MSTATUS_MPRV );
4407
4400
int result = (args .count == 1 ) ?
4408
- read_memory_progbuf_inner_one (target , args , mprven ) :
4409
- read_memory_progbuf_inner (target , args , mprven );
4401
+ read_memory_progbuf_inner_one (target , args ) :
4402
+ read_memory_progbuf_inner (target , args );
4410
4403
4411
- if (mstatus != mstatus_old &&
4412
- register_write_direct (target , GDB_REGNO_MSTATUS , mstatus_old ) != ERROR_OK )
4404
+ if (restore_privilege_from_virt2phys_mode (target , mstatus , mstatus_old , dcsr , dcsr_old ) != ERROR_OK )
4413
4405
return MEM_ACCESS_FAILED ;
4414
4406
4415
4407
return (result == ERROR_OK ) ? MEM_ACCESS_OK : MEM_ACCESS_FAILED ;
@@ -4867,25 +4859,7 @@ static int write_memory_progbuf_try_to_write(struct target *target,
4867
4859
return result ;
4868
4860
}
4869
4861
4870
- static int riscv_program_store_mprv (struct riscv_program * p , enum gdb_regno d ,
4871
- enum gdb_regno b , int offset , unsigned int size , bool mprven )
4872
- {
4873
- if (mprven && riscv_program_csrrsi (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4874
- GDB_REGNO_DCSR ) != ERROR_OK )
4875
- return ERROR_FAIL ;
4876
-
4877
- if (riscv_program_store (p , d , b , offset , size ) != ERROR_OK )
4878
- return ERROR_FAIL ;
4879
-
4880
- if (mprven && riscv_program_csrrci (p , GDB_REGNO_ZERO , CSR_DCSR_MPRVEN ,
4881
- GDB_REGNO_DCSR ) != ERROR_OK )
4882
- return ERROR_FAIL ;
4883
-
4884
- return ERROR_OK ;
4885
- }
4886
-
4887
- static int write_memory_progbuf_fill_progbuf (struct target * target ,
4888
- uint32_t size , bool mprven )
4862
+ static int write_memory_progbuf_fill_progbuf (struct target * target , uint32_t size )
4889
4863
{
4890
4864
if (riscv013_reg_save (target , GDB_REGNO_S0 ) != ERROR_OK )
4891
4865
return ERROR_FAIL ;
@@ -4895,8 +4869,7 @@ static int write_memory_progbuf_fill_progbuf(struct target *target,
4895
4869
struct riscv_program program ;
4896
4870
4897
4871
riscv_program_init (& program , target );
4898
- if (riscv_program_store_mprv (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ,
4899
- mprven ) != ERROR_OK )
4872
+ if (riscv_program_store (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 , size ) != ERROR_OK )
4900
4873
return ERROR_FAIL ;
4901
4874
4902
4875
if (riscv_program_addi (& program , GDB_REGNO_S0 , GDB_REGNO_S0 , size ) != ERROR_OK )
@@ -4908,12 +4881,11 @@ static int write_memory_progbuf_fill_progbuf(struct target *target,
4908
4881
return riscv_program_write (& program );
4909
4882
}
4910
4883
4911
- static int write_memory_progbuf_inner (struct target * target , const riscv_mem_access_args_t args , bool mprven )
4884
+ static int write_memory_progbuf_inner (struct target * target , const riscv_mem_access_args_t args )
4912
4885
{
4913
4886
assert (riscv_mem_access_is_write (args ));
4914
4887
4915
- if (write_memory_progbuf_fill_progbuf (target , args .size ,
4916
- mprven ) != ERROR_OK )
4888
+ if (write_memory_progbuf_fill_progbuf (target , args .size ) != ERROR_OK )
4917
4889
return ERROR_FAIL ;
4918
4890
4919
4891
target_addr_t addr_on_target = args .address ;
@@ -4957,18 +4929,15 @@ write_memory_progbuf(struct target *target, const riscv_mem_access_args_t args)
4957
4929
4958
4930
uint64_t mstatus = 0 ;
4959
4931
uint64_t mstatus_old = 0 ;
4960
- if (modify_privilege (target , & mstatus , & mstatus_old ) != ERROR_OK )
4932
+ uint64_t dcsr = 0 ;
4933
+ uint64_t dcsr_old = 0 ;
4934
+ if (modify_privilege_for_virt2phys_mode (target , & mstatus , & mstatus_old , & dcsr , & dcsr_old ) != ERROR_OK )
4961
4935
return MEM_ACCESS_FAILED_PRIV_MOD_FAILED ;
4962
4936
4963
- const bool mprven = riscv_virt2phys_mode_is_hw (target )
4964
- && get_field (mstatus , MSTATUS_MPRV );
4937
+ int result = write_memory_progbuf_inner (target , args );
4965
4938
4966
- int result = write_memory_progbuf_inner (target , args , mprven );
4967
-
4968
- /* Restore MSTATUS */
4969
- if (mstatus != mstatus_old )
4970
- if (register_write_direct (target , GDB_REGNO_MSTATUS , mstatus_old ))
4971
- return MEM_ACCESS_FAILED ;
4939
+ if (restore_privilege_from_virt2phys_mode (target , mstatus , mstatus_old , dcsr , dcsr_old ) != ERROR_OK )
4940
+ return MEM_ACCESS_FAILED ;
4972
4941
4973
4942
if (execute_autofence (target ) != ERROR_OK )
4974
4943
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED ;
0 commit comments