crc32: Abort generic_crc32 with error from target_mem_read

Use larger chunks for hosted to speed up. Send pure NULL as line keep-alive.
This commit is contained in:
Uwe Bonnes 2021-09-06 14:57:59 +02:00 committed by UweBonnes
parent ff79108f66
commit e58b7d623b
4 changed files with 52 additions and 10 deletions

View File

@ -20,6 +20,7 @@
#include "general.h" #include "general.h"
#include "target.h" #include "target.h"
#include "gdb_if.h"
#if !defined(STM32F0) && !defined(STM32F1) && !defined(STM32F2) && \ #if !defined(STM32F0) && !defined(STM32F1) && !defined(STM32F2) && \
!defined(STM32F3) && !defined(STM32F4) && !defined(STM32F7) && \ !defined(STM32F3) && !defined(STM32F4) && !defined(STM32F7) && \
@ -97,14 +98,31 @@ static uint32_t crc32_calc(uint32_t crc, uint8_t data)
return (crc << 8) ^ crc32_table[((crc >> 24) ^ data) & 255]; return (crc << 8) ^ crc32_table[((crc >> 24) ^ data) & 255];
} }
uint32_t generic_crc32(target *t, uint32_t base, size_t len) int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len)
{ {
uint32_t crc = -1; uint32_t crc = -1;
#if PC_HOSTED == 1
/* Reading a 2 MByte on a H743 takes about 80 s@128, 28s @ 1k,
* 22 s @ 4k and 21 s @ 64k
*/
uint8_t bytes[0x1000];
uint32_t start_time = platform_time_ms();
#else
uint8_t bytes[128]; uint8_t bytes[128];
#endif
uint32_t last_time = platform_time_ms();
while (len) { while (len) {
uint32_t actual_time = platform_time_ms();
if ( actual_time > last_time + 1000) {
last_time = actual_time;
gdb_if_putchar(0, true);
}
size_t read_len = MIN(sizeof(bytes), len); size_t read_len = MIN(sizeof(bytes), len);
target_mem_read(t, bytes, base, read_len); if (target_mem_read(t, bytes, base, read_len)) {
DEBUG_WARN("generic_crc32 error around address 0x%08" PRIx32 "\n",
base);
return -1;
}
for (unsigned i = 0; i < read_len; i++) for (unsigned i = 0; i < read_len; i++)
crc = crc32_calc(crc, bytes[i]); crc = crc32_calc(crc, bytes[i]);
@ -112,20 +130,32 @@ uint32_t generic_crc32(target *t, uint32_t base, size_t len)
base += read_len; base += read_len;
len -= read_len; len -= read_len;
} }
return crc; DEBUG_WARN("%d ms\n", platform_time_ms() - start_time);
*crc_res = crc;
return 0;
} }
#else #else
#include <libopencm3/stm32/crc.h> #include <libopencm3/stm32/crc.h>
uint32_t generic_crc32(target *t, uint32_t base, size_t len) int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len)
{ {
uint8_t bytes[128]; uint8_t bytes[128];
uint32_t crc; uint32_t crc;
CRC_CR |= CRC_CR_RESET; CRC_CR |= CRC_CR_RESET;
uint32_t last_time = platform_time_ms();
while (len > 3) { while (len > 3) {
uint32_t actual_time = platform_time_ms();
if ( actual_time > last_time + 1000) {
last_time = actual_time;
gdb_if_putchar(0, true);
}
size_t read_len = MIN(sizeof(bytes), len) & ~3; size_t read_len = MIN(sizeof(bytes), len) & ~3;
target_mem_read(t, bytes, base, read_len); if (target_mem_read(t, bytes, base, read_len)) {
DEBUG_WARN("generic_crc32 error around address 0x%08" PRIx32 "\n",
base);
return -1;
}
for (unsigned i = 0; i < read_len; i += 4) for (unsigned i = 0; i < read_len; i += 4)
CRC_DR = __builtin_bswap32(*(uint32_t*)(bytes+i)); CRC_DR = __builtin_bswap32(*(uint32_t*)(bytes+i));
@ -136,7 +166,11 @@ uint32_t generic_crc32(target *t, uint32_t base, size_t len)
crc = CRC_DR; crc = CRC_DR;
target_mem_read(t, bytes, base, len); if (target_mem_read(t, bytes, base, len)) {
DEBUG_WARN("generic_crc32 error around address 0x%08" PRIx32 "\n",
base);
return -1;
}
uint8_t *data = bytes; uint8_t *data = bytes;
while (len--) { while (len--) {
crc ^= *data++ << 24; crc ^= *data++ << 24;
@ -147,7 +181,8 @@ uint32_t generic_crc32(target *t, uint32_t base, size_t len)
crc <<= 1; crc <<= 1;
} }
} }
return crc; *crc_res = crc;
return 0;
} }
#endif #endif

View File

@ -412,7 +412,12 @@ handle_q_packet(char *packet, int len)
gdb_putpacketz("E01"); gdb_putpacketz("E01");
return; return;
} }
gdb_putpacket_f("C%lx", generic_crc32(cur_target, addr, alen)); uint32_t crc;
int res = generic_crc32(cur_target, &crc, addr, alen);
if (res)
gdb_putpacketz("E03");
else
gdb_putpacket_f("C%lx", crc);
} else { } else {
DEBUG_GDB("*** Unsupported packet: %s\n", packet); DEBUG_GDB("*** Unsupported packet: %s\n", packet);

View File

@ -21,6 +21,6 @@
#ifndef __CRC32_H #ifndef __CRC32_H
#define __CRC32_H #define __CRC32_H
uint32_t generic_crc32(target *t, uint32_t base, int len); int generic_crc32(target *t, uint32_t *crc, uint32_t base, int len);
#endif #endif

View File

@ -29,6 +29,8 @@ void gdb_usb_out_cb(usbd_device *dev, uint8_t ep);
int gdb_if_init(void); int gdb_if_init(void);
unsigned char gdb_if_getchar(void); unsigned char gdb_if_getchar(void);
unsigned char gdb_if_getchar_to(int timeout); unsigned char gdb_if_getchar_to(int timeout);
/* sending gdb_if_putchar(0, true) seems to work as keep alive */
void gdb_if_putchar(unsigned char c, int flush); void gdb_if_putchar(unsigned char c, int flush);
#endif #endif