Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: qCRC performance uplift #1708

Merged
merged 5 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions src/crc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ bool generic_crc32(target_s *const target, uint32_t *const result, const uint32_
uint8_t bytes[128U];
#endif

#if ENABLE_DEBUG == 1
#ifndef DEBUG_INFO_IS_NOOP
const uint32_t start_time = platform_time_ms();
#endif
uint32_t last_time = platform_time_ms();
Expand All @@ -125,27 +125,43 @@ bool generic_crc32(target_s *const target, uint32_t *const result, const uint32_
}
const size_t read_len = MIN(sizeof(bytes), len - offset);
if (target_mem_read(target, bytes, base + offset, (read_len + 3U) & ~3U)) {
DEBUG_ERROR("generic_crc32 error around address 0x%08" PRIx32 "\n", (uint32_t)(base + offset));
DEBUG_ERROR("%s: error around address 0x%08" PRIx32 "\n", __func__, (uint32_t)(base + offset));
return false;
}

for (size_t i = 0; i < read_len; i++)
crc = crc32_calc(crc, bytes[i]);
}
DEBUG_WARN("%" PRIu32 " ms\n", platform_time_ms() - start_time);
#ifndef DEBUG_INFO_IS_NOOP
/* "generic_crc32: 08000110+75272 -> 1353ms, 54 KiB/s" */
const uint32_t end_time = platform_time_ms();
const uint32_t time_elapsed = end_time - start_time;
DEBUG_INFO("%s: %08" PRIx32 "+%" PRIu32 " -> %" PRIu32 "ms", __func__, base, (uint32_t)len, time_elapsed);
if (len >= 512U) {
const uint32_t speed = len * 1000U / time_elapsed / 1024U;
DEBUG_INFO(", %" PRIu32 " KiB/s", speed);
}
DEBUG_INFO("\n");
#endif
*result = crc;
return true;
}

__attribute__((alias("generic_crc32"))) bool bmd_crc32(
target_s *const target, uint32_t *const result, const uint32_t base, const size_t len);
#else
#include <libopencm3/stm32/crc.h>
#include "buffer_utils.h"

bool generic_crc32(target_s *const target, uint32_t *const result, const uint32_t base, const size_t len)
bool stm32_crc32(target_s *const target, uint32_t *const result, const uint32_t base, const size_t len)
{
uint8_t bytes[128U];
uint8_t bytes[1024U]; /* ADIv5 MEM-AP AutoInc range */
dragonmux marked this conversation as resolved.
Show resolved Hide resolved

CRC_CR |= CRC_CR_RESET;

#ifndef DEBUG_INFO_IS_NOOP
const uint32_t start_time = platform_time_ms();
#endif
uint32_t last_time = platform_time_ms();
const size_t adjusted_len = len & ~3U;
for (size_t offset = 0; offset < adjusted_len; offset += sizeof(bytes)) {
Expand All @@ -156,7 +172,7 @@ bool generic_crc32(target_s *const target, uint32_t *const result, const uint32_
}
const size_t read_len = MIN(sizeof(bytes), adjusted_len - offset);
if (target_mem_read(target, bytes, base + offset, read_len)) {
DEBUG_ERROR("generic_crc32 error around address 0x%08" PRIx32 "\n", (uint32_t)(base + offset));
DEBUG_ERROR("%s: error around address 0x%08" PRIx32 "\n", __func__, (uint32_t)(base + offset));
return false;
}

Expand All @@ -169,7 +185,7 @@ bool generic_crc32(target_s *const target, uint32_t *const result, const uint32_
const size_t remainder = len - adjusted_len;
if (remainder) {
if (target_mem_read(target, bytes, base + adjusted_len, remainder)) {
DEBUG_ERROR("generic_crc32 error around address 0x%08" PRIx32 "\n", (uint32_t)(base + adjusted_len));
DEBUG_ERROR("%s: error around address 0x%08" PRIx32 "\n", __func__, (uint32_t)(base + adjusted_len));
return false;
}
for (size_t offset = 0; offset < remainder; ++offset) {
Expand All @@ -182,7 +198,21 @@ bool generic_crc32(target_s *const target, uint32_t *const result, const uint32_
}
}
}
#ifndef DEBUG_INFO_IS_NOOP
/* "stm32_crc32: 08000110+75272 -> 237ms, 310 KiB/s" */
const uint32_t end_time = platform_time_ms();
const uint32_t time_elapsed = end_time - start_time;
DEBUG_INFO("%s: %08" PRIx32 "+%" PRIu32 " -> %" PRIu32 "ms", __func__, base, (uint32_t)len, time_elapsed);
if (len >= 512U) {
const uint32_t speed = len * 1000U / time_elapsed / 1024U;
DEBUG_INFO(", %" PRIu32 " KiB/s", speed);
}
DEBUG_INFO("\n");
#endif
*result = crc;
return true;
}

__attribute__((alias("stm32_crc32"))) bool bmd_crc32(
target_s *const target, uint32_t *const result, const uint32_t base, const size_t len);
#endif
2 changes: 1 addition & 1 deletion src/gdb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ static void exec_q_crc(const char *packet, const size_t length)
return;
}
uint32_t crc;
if (!generic_crc32(cur_target, &crc, addr, addr_length))
if (!bmd_crc32(cur_target, &crc, addr, addr_length))
gdb_putpacketz("E03");
else
gdb_putpacket_f("C%" PRIx32, crc);
Expand Down
2 changes: 1 addition & 1 deletion src/include/crc32.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
#include <stdint.h>
#include <target.h>

bool generic_crc32(target_s *target, uint32_t *crc, uint32_t base, size_t len);
bool bmd_crc32(target_s *target, uint32_t *crc, uint32_t base, size_t len);

#endif /* INCLUDE_CRC32_H */