@@ -2005,13 +2005,6 @@ static int examine(struct target *target)
2005
2005
info -> impebreak );
2006
2006
}
2007
2007
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
-
2015
2008
/* Don't call any riscv_* functions until after we've counted the number of
2016
2009
* cores and initialized registers. */
2017
2010
@@ -3109,47 +3102,69 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
3109
3102
}
3110
3103
3111
3104
/* 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 )
3113
3107
{
3114
3108
assert (mstatus );
3115
3109
assert (mstatus_old );
3110
+ assert (dcsr );
3111
+ assert (dcsr_old );
3116
3112
if (!riscv_virt2phys_mode_is_hw (target ))
3117
3113
return ERROR_OK ;
3118
3114
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 )
3131
3117
return ERROR_FAIL ;
3118
+ * dcsr_old = * dcsr ;
3132
3119
3133
3120
/* 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 )
3135
3122
return ERROR_FAIL ;
3136
3123
* mstatus_old = * mstatus ;
3137
3124
3138
3125
/* 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 )
3140
3127
return ERROR_OK ;
3141
3128
3142
3129
/* 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 ));
3144
3131
3145
3132
/* mstatus.mprv <- 1 */
3146
3133
* mstatus = set_field (* mstatus , MSTATUS_MPRV , 1 );
3147
3134
3148
3135
/* 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 ))
3150
3155
return ERROR_OK ;
3151
3156
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 ;
3153
3168
}
3154
3169
3155
3170
static 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,
4188
4203
return ERROR_OK ;
4189
4204
}
4190
4205
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
-
4208
4206
static 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 )
4210
4208
{
4211
4209
const bool is_repeated_read = increment == 0 ;
4212
4210
@@ -4220,8 +4218,7 @@ static int read_memory_progbuf_inner_fill_progbuf(struct target *target,
4220
4218
struct riscv_program program ;
4221
4219
4222
4220
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 )
4225
4222
return ERROR_FAIL ;
4226
4223
if (is_repeated_read ) {
4227
4224
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,
4246
4243
* re-read the data only if `abstract command busy` or `DMI busy`
4247
4244
* is encountered in the process.
4248
4245
*/
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 )
4251
4247
{
4252
4248
assert (riscv_mem_access_is_read (args ));
4253
4249
assert (args .count > 1 && "If count == 1, read_memory_progbuf_inner_one must be called" );
4254
4250
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 )
4257
4252
return ERROR_FAIL ;
4258
4253
4259
4254
if (read_memory_progbuf_inner_startup (target , args .address ,
@@ -4305,8 +4300,7 @@ static int read_memory_progbuf_inner(struct target *target,
4305
4300
* Only need to save/restore one GPR to read a single word, and the progbuf
4306
4301
* program doesn't need to increment.
4307
4302
*/
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 )
4310
4304
{
4311
4305
assert (riscv_mem_access_is_read (args ));
4312
4306
@@ -4316,8 +4310,7 @@ static int read_memory_progbuf_inner_one(struct target *target,
4316
4310
struct riscv_program program ;
4317
4311
4318
4312
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 )
4321
4314
return ERROR_FAIL ;
4322
4315
if (riscv_program_ebreak (& program ) != ERROR_OK )
4323
4316
return ERROR_FAIL ;
@@ -4363,19 +4356,18 @@ read_memory_progbuf(struct target *target, const riscv_mem_access_args_t args)
4363
4356
if (execute_autofence (target ) != ERROR_OK )
4364
4357
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED ;
4365
4358
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 )
4369
4364
return MEM_ACCESS_FAILED_PRIV_MOD_FAILED ;
4370
4365
4371
- const bool mprven = riscv_virt2phys_mode_is_hw (target )
4372
- && get_field (mstatus , MSTATUS_MPRV );
4373
4366
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 );
4376
4369
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 )
4379
4371
return MEM_ACCESS_FAILED ;
4380
4372
4381
4373
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,
4833
4825
return result ;
4834
4826
}
4835
4827
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 )
4855
4829
{
4856
4830
if (riscv013_reg_save (target , GDB_REGNO_S0 ) != ERROR_OK )
4857
4831
return ERROR_FAIL ;
@@ -4861,8 +4835,7 @@ static int write_memory_progbuf_fill_progbuf(struct target *target,
4861
4835
struct riscv_program program ;
4862
4836
4863
4837
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 )
4866
4839
return ERROR_FAIL ;
4867
4840
4868
4841
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,
4874
4847
return riscv_program_write (& program );
4875
4848
}
4876
4849
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 )
4878
4851
{
4879
4852
assert (riscv_mem_access_is_write (args ));
4880
4853
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 )
4883
4855
return ERROR_FAIL ;
4884
4856
4885
4857
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)
4923
4895
4924
4896
uint64_t mstatus = 0 ;
4925
4897
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 )
4927
4901
return MEM_ACCESS_FAILED_PRIV_MOD_FAILED ;
4928
4902
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 );
4931
4904
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 ;
4938
4907
4939
4908
if (execute_autofence (target ) != ERROR_OK )
4940
4909
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED ;
0 commit comments