@@ -3092,36 +3092,48 @@ static int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)
30923092 }
30933093}
30943094
3095+ /* TODO: return mem_access_result_t */
30953096static int modify_privilege (struct target * target , uint64_t * mstatus , uint64_t * mstatus_old )
30963097{
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 ;
31033102
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 ;
31083116
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 ;
31133121
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 ;
31163125
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 ));
31233128
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 );
31253137}
31263138
31273139static int read_memory_bus_v0 (struct target * target , target_addr_t address ,
0 commit comments