+
+ return arm_init_arch_info(target, arm);
+}
+
+/** Generates a CRC32 checksum of a memory region. */
+int armv7m_checksum_memory(struct target *target,
+ uint32_t address, uint32_t count, uint32_t *checksum)
+{
+ struct working_area *crc_algorithm;
+ struct armv7m_algorithm armv7m_info;
+ struct reg_param reg_params[2];
+ int retval;
+
+ /* see contrib/loaders/checksum/armv7m_crc.s for src */
+
+ static const uint8_t cortex_m3_crc_code[] = {
+ /* main: */
+ 0x02, 0x46, /* mov r2, r0 */
+ 0x00, 0x20, /* movs r0, #0 */
+ 0xC0, 0x43, /* mvns r0, r0 */
+ 0x0A, 0x4E, /* ldr r6, CRC32XOR */
+ 0x0B, 0x46, /* mov r3, r1 */
+ 0x00, 0x24, /* movs r4, #0 */
+ 0x0D, 0xE0, /* b ncomp */
+ /* nbyte: */
+ 0x11, 0x5D, /* ldrb r1, [r2, r4] */
+ 0x09, 0x06, /* lsls r1, r1, #24 */
+ 0x48, 0x40, /* eors r0, r0, r1 */
+ 0x00, 0x25, /* movs r5, #0 */
+ /* loop: */
+ 0x00, 0x28, /* cmp r0, #0 */
+ 0x02, 0xDA, /* bge notset */
+ 0x40, 0x00, /* lsls r0, r0, #1 */
+ 0x70, 0x40, /* eors r0, r0, r6 */
+ 0x00, 0xE0, /* b cont */
+ /* notset: */
+ 0x40, 0x00, /* lsls r0, r0, #1 */
+ /* cont: */
+ 0x01, 0x35, /* adds r5, r5, #1 */
+ 0x08, 0x2D, /* cmp r5, #8 */
+ 0xF6, 0xD1, /* bne loop */
+ 0x01, 0x34, /* adds r4, r4, #1 */
+ /* ncomp: */
+ 0x9C, 0x42, /* cmp r4, r3 */
+ 0xEF, 0xD1, /* bne nbyte */
+ 0x00, 0xBE, /* bkpt #0 */
+ 0xB7, 0x1D, 0xC1, 0x04 /* CRC32XOR: .word 0x04c11db7 */
+ };
+
+ retval = target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_buffer(target, crc_algorithm->address,
+ sizeof(cortex_m3_crc_code), (uint8_t *)cortex_m3_crc_code);
+ if (retval != ERROR_OK)
+ goto cleanup;
+
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_ANY;
+
+ init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
+
+ buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[1].value, 0, 32, count);
+
+ int timeout = 20000 * (1 + (count / (1024 * 1024)));
+
+ retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
+ crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6),
+ timeout, &armv7m_info);
+
+ if (retval == ERROR_OK)
+ *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+ else
+ LOG_ERROR("error executing cortex_m3 crc algorithm");
+
+ destroy_reg_param(®_params[0]);
+ destroy_reg_param(®_params[1]);
+
+cleanup:
+ target_free_working_area(target, crc_algorithm);
+
+ return retval;