@@ -2036,53 +2036,13 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
20362036 * Read the requested memory, taking care to execute every read exactly once,
20372037 * even if cmderr=busy is encountered.
20382038 */
2039- static int read_memory_progbuf (struct target * target , target_addr_t address ,
2039+ static int read_memory_progbuf_inner (struct target * target , target_addr_t address ,
20402040 uint32_t size , uint32_t count , uint8_t * buffer )
20412041{
20422042 RISCV013_INFO (info );
20432043
20442044 int result = ERROR_OK ;
20452045
2046- LOG_DEBUG ("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR , count ,
2047- size , address );
2048-
2049- select_dmi (target );
2050-
2051- /* s0 holds the next address to write to
2052- * s1 holds the next data value to write
2053- */
2054- uint64_t s0 , s1 ;
2055- if (register_read (target , & s0 , GDB_REGNO_S0 ) != ERROR_OK )
2056- return ERROR_FAIL ;
2057- if (register_read (target , & s1 , GDB_REGNO_S1 ) != ERROR_OK )
2058- return ERROR_FAIL ;
2059-
2060- if (execute_fence (target ) != ERROR_OK )
2061- return ERROR_FAIL ;
2062-
2063- /* Write the program (load, increment) */
2064- struct riscv_program program ;
2065- riscv_program_init (& program , target );
2066- switch (size ) {
2067- case 1 :
2068- riscv_program_lbr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2069- break ;
2070- case 2 :
2071- riscv_program_lhr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2072- break ;
2073- case 4 :
2074- riscv_program_lwr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2075- break ;
2076- default :
2077- LOG_ERROR ("Unsupported size: %d" , size );
2078- return ERROR_FAIL ;
2079- }
2080- riscv_program_addi (& program , GDB_REGNO_S0 , GDB_REGNO_S0 , size );
2081-
2082- if (riscv_program_ebreak (& program ) != ERROR_OK )
2083- return ERROR_FAIL ;
2084- riscv_program_write (& program );
2085-
20862046 /* Write address to S0, and execute buffer. */
20872047 result = register_write_direct (target , GDB_REGNO_S0 , address );
20882048 if (result != ERROR_OK )
@@ -2210,7 +2170,7 @@ static int read_memory_progbuf(struct target *target, target_addr_t address,
22102170 1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET );
22112171 break ;
22122172 default :
2213- LOG_ERROR ("error when reading memory, abstractcs=0x%08lx" , (long )abstractcs );
2173+ LOG_DEBUG ("error when reading memory, abstractcs=0x%08lx" , (long )abstractcs );
22142174 riscv013_clear_abstract_error (target );
22152175 riscv_batch_free (batch );
22162176 result = ERROR_FAIL ;
@@ -2268,13 +2228,88 @@ static int read_memory_progbuf(struct target *target, target_addr_t address,
22682228 write_to_buf (buffer + receive_addr - address , value , size );
22692229 log_memory_access (receive_addr , value , size , true);
22702230
2271- riscv_set_register (target , GDB_REGNO_S0 , s0 );
2272- riscv_set_register (target , GDB_REGNO_S1 , s1 );
22732231 return ERROR_OK ;
22742232
22752233error :
22762234 dmi_write (target , DMI_ABSTRACTAUTO , 0 );
22772235
2236+ return result ;
2237+ }
2238+
2239+ /**
2240+ * Read the requested memory, silently handling memory access errors.
2241+ */
2242+ static int read_memory_progbuf (struct target * target , target_addr_t address ,
2243+ uint32_t size , uint32_t count , uint8_t * buffer )
2244+ {
2245+ int result = ERROR_OK ;
2246+
2247+ LOG_DEBUG ("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR , count ,
2248+ size , address );
2249+
2250+ select_dmi (target );
2251+
2252+ /* s0 holds the next address to write to
2253+ * s1 holds the next data value to write
2254+ */
2255+ uint64_t s0 , s1 ;
2256+ if (register_read (target , & s0 , GDB_REGNO_S0 ) != ERROR_OK )
2257+ return ERROR_FAIL ;
2258+ if (register_read (target , & s1 , GDB_REGNO_S1 ) != ERROR_OK )
2259+ return ERROR_FAIL ;
2260+
2261+ if (execute_fence (target ) != ERROR_OK )
2262+ return ERROR_FAIL ;
2263+
2264+ /* Write the program (load, increment) */
2265+ struct riscv_program program ;
2266+ riscv_program_init (& program , target );
2267+ switch (size ) {
2268+ case 1 :
2269+ riscv_program_lbr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2270+ break ;
2271+ case 2 :
2272+ riscv_program_lhr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2273+ break ;
2274+ case 4 :
2275+ riscv_program_lwr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2276+ break ;
2277+ default :
2278+ LOG_ERROR ("Unsupported size: %d" , size );
2279+ return ERROR_FAIL ;
2280+ }
2281+ riscv_program_addi (& program , GDB_REGNO_S0 , GDB_REGNO_S0 , size );
2282+
2283+ if (riscv_program_ebreak (& program ) != ERROR_OK )
2284+ return ERROR_FAIL ;
2285+ riscv_program_write (& program );
2286+
2287+ result = read_memory_progbuf_inner (target , address , size , count , buffer );
2288+
2289+ /* The full read did not succeed, so we will try to read each word individually. */
2290+ /* This will not be fast, but reading outside actual memory is a special case anyway. */
2291+ /* It will make the toolchain happier, especially Eclipse Memory View as it reads ahead. */
2292+ if (result != ERROR_OK ) {
2293+ target_addr_t address_i = address ;
2294+ uint32_t size_i = size ;
2295+ uint32_t count_i = 1 ;
2296+ uint8_t * buffer_i = buffer ;
2297+
2298+ for (uint32_t i = 0 ; i < count ; i ++ , address_i += size_i , buffer_i += size_i ) {
2299+ result = read_memory_progbuf_inner (target , address_i , size_i , count_i , buffer_i );
2300+
2301+ /* The read of a single word failed, so we will just return 0 for that instead */
2302+ if (result != ERROR_OK ) {
2303+ LOG_DEBUG ("error reading single word of %d bytes from 0x%" TARGET_PRIxADDR ,
2304+ size_i , address_i );
2305+
2306+ uint64_t value_i = 0 ;
2307+ write_to_buf (buffer_i , value_i , size_i );
2308+ }
2309+ }
2310+ result = ERROR_OK ;
2311+ }
2312+
22782313 riscv_set_register (target , GDB_REGNO_S0 , s0 );
22792314 riscv_set_register (target , GDB_REGNO_S1 , s1 );
22802315 return result ;
0 commit comments