@@ -3092,36 +3092,48 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
3092
3092
}
3093
3093
}
3094
3094
3095
+ /* TODO: return mem_access_result_t */
3095
3096
static int modify_privilege (struct target * target , uint64_t * mstatus , uint64_t * mstatus_old )
3096
3097
{
3097
- if (riscv_virt2phys_mode_is_hw (target )
3098
- && has_sufficient_progbuf (target , 5 )) {
3099
- /* Read DCSR */
3100
- uint64_t dcsr ;
3101
- if (register_read_direct (target , & dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
3102
- return ERROR_FAIL ;
3098
+ assert (mstatus );
3099
+ assert (mstatus_old );
3100
+ if (!riscv_virt2phys_mode_is_hw (target ))
3101
+ return ERROR_OK ;
3103
3102
3104
- /* Read and save MSTATUS */
3105
- if (register_read_direct (target , mstatus , GDB_REGNO_MSTATUS ) != ERROR_OK )
3106
- return ERROR_FAIL ;
3107
- * mstatus_old = * mstatus ;
3103
+ /* TODO: handle error in this case
3104
+ * modify_privilege function used only for program buffer memory access.
3105
+ * Privilege modification requires progbuf size to be at least 5 */
3106
+ if (!has_sufficient_progbuf (target , 5 )) {
3107
+ LOG_TARGET_WARNING (target , "Can't modify privilege to provide "
3108
+ "hardware translation: program buffer too small." );
3109
+ return ERROR_OK ;
3110
+ }
3111
+
3112
+ /* Read DCSR */
3113
+ riscv_reg_t dcsr ;
3114
+ if (register_read_direct (target , & dcsr , GDB_REGNO_DCSR ) != ERROR_OK )
3115
+ return ERROR_FAIL ;
3108
3116
3109
- /* If we come from m-mode with mprv set, we want to keep mpp */
3110
- if (get_field ( dcsr , CSR_DCSR_PRV ) < 3 ) {
3111
- /* MPP = PRIV */
3112
- * mstatus = set_field ( * mstatus , MSTATUS_MPP , get_field ( dcsr , CSR_DCSR_PRV )) ;
3117
+ /* Read and save MSTATUS */
3118
+ if (register_read_direct ( target , mstatus , GDB_REGNO_MSTATUS ) != ERROR_OK )
3119
+ return ERROR_FAIL ;
3120
+ * mstatus_old = * mstatus ;
3113
3121
3114
- /* MPRV = 1 */
3115
- * mstatus = set_field (* mstatus , MSTATUS_MPRV , 1 );
3122
+ /* If we come from m-mode with mprv set, we want to keep mpp */
3123
+ if (get_field (dcsr , CSR_DCSR_PRV ) == PRV_M )
3124
+ return ERROR_OK ;
3116
3125
3117
- /* Write MSTATUS */
3118
- if (* mstatus != * mstatus_old )
3119
- if (register_write_direct (target , GDB_REGNO_MSTATUS , * mstatus ) != ERROR_OK )
3120
- return ERROR_FAIL ;
3121
- }
3122
- }
3126
+ /* mstatus.mpp <- dcsr.prv */
3127
+ * mstatus = set_field (* mstatus , MSTATUS_MPP , get_field (dcsr , CSR_DCSR_PRV ));
3123
3128
3124
- return ERROR_OK ;
3129
+ /* mstatus.mprv <- 1 */
3130
+ * mstatus = set_field (* mstatus , MSTATUS_MPRV , 1 );
3131
+
3132
+ /* Write MSTATUS */
3133
+ if (* mstatus == * mstatus_old )
3134
+ return ERROR_OK ;
3135
+
3136
+ return register_write_direct (target , GDB_REGNO_MSTATUS , * mstatus );
3125
3137
}
3126
3138
3127
3139
static int read_memory_bus_v0 (struct target * target , target_addr_t address ,
0 commit comments