gaffe in previous commit fixed. "reset run" now works again for arm7/9
[fw/openocd] / src / target / armv7m.c
index 950c5cda78f868be17a3c081ad6cb6aff0fd43dd..b862cf38f1145d0d7446cdbf40103327829ff0b5 100644 (file)
@@ -596,4 +596,64 @@ int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32*
        return ERROR_OK;
 }
 
+int armv7m_blank_check_memory(struct target_s *target, u32 address, u32 count, u32* blank)
+{
+       working_area_t *erase_check_algorithm;
+       reg_param_t reg_params[3];
+       armv7m_algorithm_t armv7m_info;
+       int retval;
+       int i;
+       
+       u16 erase_check_code[] =
+       {
+                                                       /* loop: */
+                0xF810, 0x3B01,        /* ldrb         r3, [r0], #1 */
+                0xEA02, 0x0203,        /* and  r2, r2, r3 */
+                0x3901,                        /* subs         r1, r1, #1 */
+                0xD1F9,                        /* bne          loop */
+                                                       /* end: */
+                0xE7FE,                        /* b            end */
+       };
+
+       /* make sure we have a working area */
+       if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
+       {
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       }
+       
+       /* convert flash writing code into a buffer in target endianness */
+       for (i = 0; i < (sizeof(erase_check_code)/sizeof(u16)); i++)
+               target_write_u16(target, erase_check_algorithm->address + i*sizeof(u16), erase_check_code[i]);
+       
+       armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+       armv7m_info.core_mode = ARMV7M_MODE_ANY;
+
+       init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
+       buf_set_u32(reg_params[0].value, 0, 32, address);
+
+       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+       buf_set_u32(reg_params[1].value, 0, 32, count);
+
+       init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
+       buf_set_u32(reg_params[2].value, 0, 32, 0xff);
 
+       if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, 
+                       erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code)-2), 10000, &armv7m_info)) != ERROR_OK)
+       {
+               destroy_reg_param(&reg_params[0]);
+               destroy_reg_param(&reg_params[1]);
+               destroy_reg_param(&reg_params[2]);
+               target_free_working_area(target, erase_check_algorithm);
+               return 0;
+       }
+       
+       *blank = buf_get_u32(reg_params[2].value, 0, 32);
+       
+       destroy_reg_param(&reg_params[0]);
+       destroy_reg_param(&reg_params[1]);
+       destroy_reg_param(&reg_params[2]);
+       
+       target_free_working_area(target, erase_check_algorithm);
+       
+       return ERROR_OK;
+}