diff --git a/src/adiv5.c b/src/adiv5.c index 6e0680e..53e453f 100644 --- a/src/adiv5.c +++ b/src/adiv5.c @@ -504,6 +504,9 @@ adiv5_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len) uint32_t osrc = src; enum align align = MIN(ALIGNOF(src), ALIGNOF(len)); + if (len == 0) + return; + len >>= align; ap_mem_access_setup(ap, src, align); adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_AP_DRW, 0); diff --git a/src/crc32.c b/src/crc32.c index 16cc565..881f12d 100644 --- a/src/crc32.c +++ b/src/crc32.c @@ -89,23 +89,21 @@ static const uint32_t crc32_table[] = { 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4, }; -uint32_t crc32_calc(uint32_t crc, uint8_t data) +static uint32_t crc32_calc(uint32_t crc, uint8_t data) { return (crc << 8) ^ crc32_table[((crc >> 24) ^ data) & 255]; } -uint32_t generic_crc32(target *t, uint32_t base, int len) +uint32_t generic_crc32(target *t, uint32_t base, size_t len) { uint32_t crc = -1; - static uint8_t bytes[128]; + uint8_t bytes[128]; while (len) { - uint32_t i; - uint32_t read_len = len >= 128 ? 128 : len; - + size_t read_len = MIN(sizeof(bytes), len); target_mem_read(t, bytes, base, read_len); - for (i=0; i -uint32_t generic_crc32(target *t, uint32_t base, int len) +uint32_t generic_crc32(target *t, uint32_t base, size_t len) { - uint32_t data; + uint8_t bytes[128]; uint32_t crc; - size_t i; CRC_CR |= CRC_CR_RESET; while (len > 3) { - data = target_mem_read32(t, base); + size_t read_len = MIN(sizeof(bytes), len) & ~3; + target_mem_read(t, bytes, base, read_len); - CRC_DR = __builtin_bswap32(data); - base += 4; - len -= 4; + for (unsigned i = 0; i < read_len; i += 4) + CRC_DR = __builtin_bswap32(*(uint32_t*)(bytes+i)); + + base += read_len; + len -= read_len; } crc = CRC_DR; + target_mem_read(t, bytes, base, len); + uint8_t *data = bytes; while (len--) { - data = target_mem_read8(t, base++); - - crc ^= data << 24; - for (i = 0; i < 8; i++) { + crc ^= *data++ << 24; + for (int i = 0; i < 8; i++) { if (crc & 0x80000000) crc = (crc << 1) ^ 0x4C11DB7; else @@ -146,5 +146,5 @@ uint32_t generic_crc32(target *t, uint32_t base, int len) } return crc; } - #endif + diff --git a/src/include/crc32.h b/src/include/crc32.h index bd8d5c4..4e0f729 100644 --- a/src/include/crc32.h +++ b/src/include/crc32.h @@ -21,7 +21,6 @@ #ifndef __CRC32_H #define __CRC32_H -uint32_t crc32_calc(uint32_t crc, uint8_t data); uint32_t generic_crc32(target *t, uint32_t base, int len); #endif diff --git a/src/include/target.h b/src/include/target.h index 16173e9..9436af4 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -53,13 +53,6 @@ bool target_check_error(target *t); void target_mem_read(target *t, void *dest, uint32_t src, size_t len); void target_mem_write(target *t, uint32_t dest, const void *src, size_t len); -uint32_t target_mem_read32(target *t, uint32_t addr); -uint16_t target_mem_read16(target *t, uint32_t addr); -uint8_t target_mem_read8(target *t, uint32_t addr); -void target_mem_write32(target *t, uint32_t addr, uint32_t value); -void target_mem_write16(target *t, uint32_t addr, uint16_t value); -void target_mem_write8(target *t, uint32_t addr, uint8_t value); - /* Register access functions */ void target_regs_read(target *t, void *data); void target_regs_write(target *t, const void *data); diff --git a/src/target_internal.h b/src/target_internal.h index ee5d1be..408056f 100644 --- a/src/target_internal.h +++ b/src/target_internal.h @@ -118,6 +118,14 @@ int target_flash_write_buffered(struct target_flash *f, uint32_t dest, const void *src, size_t len); int target_flash_done_buffered(struct target_flash *f); +/* Convenience function for MMIO access */ +uint32_t target_mem_read32(target *t, uint32_t addr); +uint16_t target_mem_read16(target *t, uint32_t addr); +uint8_t target_mem_read8(target *t, uint32_t addr); +void target_mem_write32(target *t, uint32_t addr, uint32_t value); +void target_mem_write16(target *t, uint32_t addr, uint16_t value); +void target_mem_write8(target *t, uint32_t addr, uint8_t value); + /* Probe for various targets. * Actual functions implemented in their respective drivers. */