This is an automated email from Gerrit. "Gaetan Perrot <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9024
-- gerrit commit 1137dfae956cb785669018b262137362adef0886 Author: Gaetan Perrot <[email protected]> Date: Fri Jun 27 16:16:06 2025 +0900 flash: scqspi: Add support for verify in SC-QSPI driver This commit adds a verify function to the SC-QSPI flash driver for the SC-OBC Module A1. The verify routine reads back data from the flash and compares it against a provided buffer, allowing validation of programmed contents. This is useful during firmware updates, flash self-tests, and development. The implementation leverages the previously added read functionality and performs a byte-wise comparison between flash and memory data. Change-Id: Ibe84080df3af59cdd469ee5e8b8231e4b49b39aa Signed-off-by: Gaetan Perrot <[email protected]> diff --git a/src/flash/nor/scqspi.c b/src/flash/nor/scqspi.c index a5109e19f2..12efb76378 100644 --- a/src/flash/nor/scqspi.c +++ b/src/flash/nor/scqspi.c @@ -11,6 +11,7 @@ #include "imp.h" #include "spi.h" #include <helper/bits.h> +#include <helper/crc32.h> #include <helper/time_support.h> #include <target/image.h> @@ -86,9 +87,9 @@ static bool verify(struct target *target, uint32_t addr, uint32_t exp, uint32_t uint32_t retry) { uint32_t val; - int32_t ret; + int ret; - for (uint32_t i = 0; i <= retry; i++) { + for (int i = 0; i <= retry; i++) { ret = target_read_u32(target, addr, &val); if (ret != ERROR_OK) { LOG_ERROR("Faild to read the register value: %d", ret); @@ -877,6 +878,73 @@ end: return ret; } +static uint32_t calculate_image_crc32(const uint8_t *data, size_t len) +{ + uint32_t crc = SCQSPI_CRC32_INIT; + + while (len > 0) { + size_t chunk = len > SCQSPI_VERIFY_CHUNK_SIZE ? SCQSPI_VERIFY_CHUNK_SIZE : len; + crc = crc32_le(CRC32_POLY_LE, crc, data, chunk); + data += chunk; + len -= chunk; + } + + return SCQSPI_CRC32_FINAL(crc); +} + +static int calculate_flash_crc32(struct flash_bank *bank, uint32_t offset, size_t len, + uint32_t *crc_out) +{ + uint8_t block_buf[SCQSPI_VERIFY_CHUNK_SIZE]; + uint32_t crc = SCQSPI_CRC32_INIT; + int ret; + + while (len > 0) { + size_t chunk = len > SCQSPI_VERIFY_CHUNK_SIZE ? SCQSPI_VERIFY_CHUNK_SIZE : len; + + ret = scqspi_nor_quad_read(bank, block_buf, offset, chunk); + if (ret != ERROR_OK) { + LOG_ERROR("Failed to read flash at offset 0x%08" PRIx32, offset); + goto end; + } + + crc = crc32_le(CRC32_POLY_LE, crc, block_buf, chunk); + offset += chunk; + len -= chunk; + } + + *crc_out = SCQSPI_CRC32_FINAL(crc); + +end: + return ret; +} + +static int scqspi_nor_verify(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, + uint32_t count) +{ + struct scqspi_flash_bank *scqspi_info = bank->driver_priv; + uint32_t expected_crc = calculate_image_crc32(buffer, count); + uint32_t actual_crc; + int ret; + + LOG_DEBUG("Verify %d bytes from 0x%08x", count, (scqspi_info->flash_addr + offset)); + + ret = calculate_flash_crc32(bank, offset, count, &actual_crc); + if (ret != ERROR_OK) + goto end; + + if (actual_crc == expected_crc) + ret = ERROR_OK; + else { + LOG_ERROR("CRC mismatch : expected 0x%08" PRIx32 ", got 0x%08" PRIx32, expected_crc, + actual_crc); + ret = ERROR_FAIL; + } + +end: + return ret; +} + /* ------------------------------------------------------------------------- * Command handler functions * -------------------------------------------------------------------------*/ @@ -1186,10 +1254,39 @@ static int scqspi_protect(struct flash_bank *bank, int set, unsigned int first, } static int scqspi_verify(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, - uint32_t count) + uint32_t count) { - /* Not implemented */ - return ERROR_OK; + struct target *target = bank->target; + struct scqspi_flash_bank *scqspi_info = bank->driver_priv; + + int ret; + + LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32, __func__, offset, count); + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + ret = ERROR_TARGET_NOT_HALTED; + goto end; + } + + if (!(scqspi_info->probed)) { + LOG_ERROR("Flash bank not probed"); + ret = ERROR_FLASH_BANK_NOT_PROBED; + goto end; + } + + if (offset + count > bank->size) { + LOG_ERROR("Flash access out of range: offset=%u, count=%u, bank_size=%u", offset, + count, bank->size); + return ERROR_FLASH_DST_OUT_OF_BANK; + } + + ret = scqspi_nor_verify(bank, buffer, offset, count); + if (ret != ERROR_OK) + LOG_ERROR("Failed to read data on flash : %d", ret); + +end: + return ret; } static const struct command_registration scqspi_command_handlers[] = { --
