@@ -2040,53 +2040,13 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
20402040 * Read the requested memory, taking care to execute every read exactly once,
20412041 * even if cmderr=busy is encountered.
20422042 */
2043- static int read_memory_progbuf (struct target * target , target_addr_t address ,
2043+ static int read_memory_progbuf_inner (struct target * target , target_addr_t address ,
20442044 uint32_t size , uint32_t count , uint8_t * buffer )
20452045{
20462046 RISCV013_INFO (info );
20472047
20482048 int result = ERROR_OK ;
20492049
2050- LOG_DEBUG ("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR , count ,
2051- size , address );
2052-
2053- select_dmi (target );
2054-
2055- /* s0 holds the next address to write to
2056- * s1 holds the next data value to write
2057- */
2058- uint64_t s0 , s1 ;
2059- if (register_read (target , & s0 , GDB_REGNO_S0 ) != ERROR_OK )
2060- return ERROR_FAIL ;
2061- if (register_read (target , & s1 , GDB_REGNO_S1 ) != ERROR_OK )
2062- return ERROR_FAIL ;
2063-
2064- if (execute_fence (target ) != ERROR_OK )
2065- return ERROR_FAIL ;
2066-
2067- /* Write the program (load, increment) */
2068- struct riscv_program program ;
2069- riscv_program_init (& program , target );
2070- switch (size ) {
2071- case 1 :
2072- riscv_program_lbr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2073- break ;
2074- case 2 :
2075- riscv_program_lhr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2076- break ;
2077- case 4 :
2078- riscv_program_lwr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2079- break ;
2080- default :
2081- LOG_ERROR ("Unsupported size: %d" , size );
2082- return ERROR_FAIL ;
2083- }
2084- riscv_program_addi (& program , GDB_REGNO_S0 , GDB_REGNO_S0 , size );
2085-
2086- if (riscv_program_ebreak (& program ) != ERROR_OK )
2087- return ERROR_FAIL ;
2088- riscv_program_write (& program );
2089-
20902050 /* Write address to S0, and execute buffer. */
20912051 result = register_write_direct (target , GDB_REGNO_S0 , address );
20922052 if (result != ERROR_OK )
@@ -2214,7 +2174,7 @@ static int read_memory_progbuf(struct target *target, target_addr_t address,
22142174 1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET );
22152175 break ;
22162176 default :
2217- LOG_ERROR ("error when reading memory, abstractcs=0x%08lx" , (long )abstractcs );
2177+ LOG_DEBUG ("error when reading memory, abstractcs=0x%08lx" , (long )abstractcs );
22182178 riscv013_clear_abstract_error (target );
22192179 riscv_batch_free (batch );
22202180 result = ERROR_FAIL ;
@@ -2272,13 +2232,90 @@ static int read_memory_progbuf(struct target *target, target_addr_t address,
22722232 write_to_buf (buffer + receive_addr - address , value , size );
22732233 log_memory_access (receive_addr , value , size , true);
22742234
2275- riscv_set_register (target , GDB_REGNO_S0 , s0 );
2276- riscv_set_register (target , GDB_REGNO_S1 , s1 );
22772235 return ERROR_OK ;
22782236
22792237error :
22802238 dmi_write (target , DMI_ABSTRACTAUTO , 0 );
22812239
2240+ return result ;
2241+ }
2242+
2243+ /**
2244+ * Read the requested memory, silently handling memory access errors.
2245+ */
2246+ static int read_memory_progbuf (struct target * target , target_addr_t address ,
2247+ uint32_t size , uint32_t count , uint8_t * buffer )
2248+ {
2249+ int result = ERROR_OK ;
2250+
2251+ LOG_DEBUG ("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR , count ,
2252+ size , address );
2253+
2254+ select_dmi (target );
2255+
2256+ memset (buffer , 0 , count * size );
2257+
2258+ /* s0 holds the next address to write to
2259+ * s1 holds the next data value to write
2260+ */
2261+ uint64_t s0 , s1 ;
2262+ if (register_read (target , & s0 , GDB_REGNO_S0 ) != ERROR_OK )
2263+ return ERROR_FAIL ;
2264+ if (register_read (target , & s1 , GDB_REGNO_S1 ) != ERROR_OK )
2265+ return ERROR_FAIL ;
2266+
2267+ if (execute_fence (target ) != ERROR_OK )
2268+ return ERROR_FAIL ;
2269+
2270+ /* Write the program (load, increment) */
2271+ struct riscv_program program ;
2272+ riscv_program_init (& program , target );
2273+ switch (size ) {
2274+ case 1 :
2275+ riscv_program_lbr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2276+ break ;
2277+ case 2 :
2278+ riscv_program_lhr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2279+ break ;
2280+ case 4 :
2281+ riscv_program_lwr (& program , GDB_REGNO_S1 , GDB_REGNO_S0 , 0 );
2282+ break ;
2283+ default :
2284+ LOG_ERROR ("Unsupported size: %d" , size );
2285+ return ERROR_FAIL ;
2286+ }
2287+ riscv_program_addi (& program , GDB_REGNO_S0 , GDB_REGNO_S0 , size );
2288+
2289+ if (riscv_program_ebreak (& program ) != ERROR_OK )
2290+ return ERROR_FAIL ;
2291+ riscv_program_write (& program );
2292+
2293+ result = read_memory_progbuf_inner (target , address , size , count , buffer );
2294+
2295+ if (result != ERROR_OK ) {
2296+ /* The full read did not succeed, so we will try to read each word individually. */
2297+ /* This will not be fast, but reading outside actual memory is a special case anyway. */
2298+ /* It will make the toolchain happier, especially Eclipse Memory View as it reads ahead. */
2299+ target_addr_t address_i = address ;
2300+ uint32_t size_i = size ;
2301+ uint32_t count_i = 1 ;
2302+ uint8_t * buffer_i = buffer ;
2303+
2304+ for (uint32_t i = 0 ; i < count ; i ++ , address_i += size_i , buffer_i += size_i ) {
2305+ result = read_memory_progbuf_inner (target , address_i , size_i , count_i , buffer_i );
2306+
2307+ /* The read of a single word failed, so we will just return 0 for that instead */
2308+ if (result != ERROR_OK ) {
2309+ LOG_DEBUG ("error reading single word of %d bytes from 0x%" TARGET_PRIxADDR ,
2310+ size_i , address_i );
2311+
2312+ uint64_t value_i = 0 ;
2313+ write_to_buf (buffer_i , value_i , size_i );
2314+ }
2315+ }
2316+ result = ERROR_OK ;
2317+ }
2318+
22822319 riscv_set_register (target , GDB_REGNO_S0 , s0 );
22832320 riscv_set_register (target , GDB_REGNO_S1 , s1 );
22842321 return result ;
0 commit comments