@@ -3083,51 +3083,6 @@ static int riscv_read_phys_memory(struct target *target, target_addr_t phys_addr
30833083 return r -> read_memory (target , phys_address , size , count , buffer , size );
30843084}
30853085
3086- static int riscv_read_memory (struct target * target , target_addr_t address ,
3087- uint32_t size , uint32_t count , uint8_t * buffer )
3088- {
3089- if (count == 0 ) {
3090- LOG_TARGET_WARNING (target , "0-length read from 0x%" TARGET_PRIxADDR , address );
3091- return ERROR_OK ;
3092- }
3093-
3094- int mmu_enabled ;
3095- int result = riscv_mmu (target , & mmu_enabled );
3096- if (result != ERROR_OK )
3097- return result ;
3098-
3099- RISCV_INFO (r );
3100-
3101- if (!mmu_enabled )
3102- return r -> read_memory (target , address , size , count , buffer , size );
3103-
3104- result = check_virt_memory_access (target , address , size , count , false);
3105- if (result != ERROR_OK )
3106- return result ;
3107-
3108- uint32_t current_count = 0 ;
3109- while (current_count < count ) {
3110- target_addr_t physical_addr ;
3111- result = target -> type -> virt2phys (target , address , & physical_addr );
3112- if (result != ERROR_OK ) {
3113- LOG_TARGET_ERROR (target , "Address translation failed." );
3114- return result ;
3115- }
3116-
3117- /* TODO: For simplicity, this algorithm assumes the worst case - the smallest possible page size,
3118- * which is 4 KiB. The algorithm can be improved to detect the real page size, and allow to use larger
3119- * memory transfers and avoid extra unnecessary virt2phys address translations. */
3120- uint32_t chunk_count = MIN (count - current_count , (RISCV_PGSIZE - RISCV_PGOFFSET (address )) / size );
3121- result = r -> read_memory (target , physical_addr , size , chunk_count , buffer + current_count * size , size );
3122- if (result != ERROR_OK )
3123- return result ;
3124-
3125- current_count += chunk_count ;
3126- address += chunk_count * size ;
3127- }
3128- return ERROR_OK ;
3129- }
3130-
31313086static int riscv_write_phys_memory (struct target * target , target_addr_t phys_address ,
31323087 uint32_t size , uint32_t count , const uint8_t * buffer )
31333088{
@@ -3137,11 +3092,16 @@ static int riscv_write_phys_memory(struct target *target, target_addr_t phys_add
31373092 return tt -> write_memory (target , phys_address , size , count , buffer );
31383093}
31393094
3140- static int riscv_write_memory (struct target * target , target_addr_t address ,
3141- uint32_t size , uint32_t count , const uint8_t * buffer )
3095+ static int riscv_rw_memory (struct target * target , target_addr_t address , uint32_t size ,
3096+ uint32_t count , uint8_t * read_buffer , const uint8_t * write_buffer )
31423097{
3098+ /* Exactly one of the buffers must be set, the other must be NULL */
3099+ assert (!!read_buffer != !!write_buffer );
3100+
3101+ const bool is_write = write_buffer ? true : false;
31433102 if (count == 0 ) {
3144- LOG_TARGET_WARNING (target , "0-length write to 0x%" TARGET_PRIxADDR , address );
3103+ LOG_TARGET_WARNING (target , "0-length %s 0x%" TARGET_PRIxADDR ,
3104+ is_write ? "write to" : "read from" , address );
31453105 return ERROR_OK ;
31463106 }
31473107
@@ -3150,14 +3110,19 @@ static int riscv_write_memory(struct target *target, target_addr_t address,
31503110 if (result != ERROR_OK )
31513111 return result ;
31523112
3113+ RISCV_INFO (r );
31533114 struct target_type * tt = get_target_type (target );
31543115 if (!tt )
31553116 return ERROR_FAIL ;
31563117
3157- if (!mmu_enabled )
3158- return tt -> write_memory (target , address , size , count , buffer );
3118+ if (!mmu_enabled ) {
3119+ if (is_write )
3120+ return tt -> write_memory (target , address , size , count , write_buffer );
3121+ else
3122+ return r -> read_memory (target , address , size , count , read_buffer , size );
3123+ }
31593124
3160- result = check_virt_memory_access (target , address , size , count , true );
3125+ result = check_virt_memory_access (target , address , size , count , is_write );
31613126 if (result != ERROR_OK )
31623127 return result ;
31633128
@@ -3170,8 +3135,14 @@ static int riscv_write_memory(struct target *target, target_addr_t address,
31703135 return result ;
31713136 }
31723137
3138+ /* TODO: For simplicity, this algorithm assumes the worst case - the smallest possible page size,
3139+ * which is 4 KiB. The algorithm can be improved to detect the real page size, and allow to use larger
3140+ * memory transfers and avoid extra unnecessary virt2phys address translations. */
31733141 uint32_t chunk_count = MIN (count - current_count , (RISCV_PGSIZE - RISCV_PGOFFSET (address )) / size );
3174- result = tt -> write_memory (target , physical_addr , size , chunk_count , buffer + current_count * size );
3142+ if (is_write )
3143+ result = tt -> write_memory (target , physical_addr , size , chunk_count , write_buffer + current_count * size );
3144+ else
3145+ result = r -> read_memory (target , physical_addr , size , chunk_count , read_buffer + current_count * size , size );
31753146 if (result != ERROR_OK )
31763147 return result ;
31773148
@@ -3181,6 +3152,18 @@ static int riscv_write_memory(struct target *target, target_addr_t address,
31813152 return ERROR_OK ;
31823153}
31833154
3155+ static int riscv_read_memory (struct target * target , target_addr_t address ,
3156+ uint32_t size , uint32_t count , uint8_t * buffer )
3157+ {
3158+ return riscv_rw_memory (target , address , size , count , buffer , NULL );
3159+ }
3160+
3161+ static int riscv_write_memory (struct target * target , target_addr_t address ,
3162+ uint32_t size , uint32_t count , const uint8_t * buffer )
3163+ {
3164+ return riscv_rw_memory (target , address , size , count , NULL , buffer );
3165+ }
3166+
31843167static const char * riscv_get_gdb_arch (const struct target * target )
31853168{
31863169 switch (riscv_xlen (target )) {
0 commit comments