added pre/post_reset scripts based on Pieter Conradie's ideas.
[fw/openocd] / src / target / arm7_9_common.c
index 517badfdf79383f20fa66676b362062393eb5475..9da9c5a4d76f44dfc01dce7d2b465c2089dfed50 100644 (file)
@@ -559,6 +559,10 @@ int arm7_9_execute_sys_speed(struct target_s *target)
                                
        /* set RESTART instruction */
        jtag_add_end_state(TAP_RTI);
+       if (arm7_9->need_bypass_before_restart) {
+               arm7_9->need_bypass_before_restart = 0;
+               arm_jtag_set_instr(jtag_info, 0xf, NULL);
+       }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
        
        for (timeout=0; timeout<50; timeout++)
@@ -593,6 +597,10 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target)
                                
        /* set RESTART instruction */
        jtag_add_end_state(TAP_RTI);
+       if (arm7_9->need_bypass_before_restart) {
+               arm7_9->need_bypass_before_restart = 0;
+               arm_jtag_set_instr(jtag_info, 0xf, NULL);
+       }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
        
        if (!set)
@@ -694,8 +702,6 @@ int arm7_9_poll(target_t *target)
                if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
                {
                        int check_pc=0;
-                       target->state = TARGET_HALTED;
-                       
                        if (target->state == TARGET_RESET)
                        {
                                if ((target->reset_mode == RESET_HALT) || (target->reset_mode == RESET_INIT))
@@ -707,6 +713,8 @@ int arm7_9_poll(target_t *target)
                                }
                        }
                        
+                       target->state = TARGET_HALTED;
+                       
                        if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
                                return retval;
                        
@@ -716,7 +724,7 @@ int arm7_9_poll(target_t *target)
                                u32 t=*((u32 *)reg->value);
                                if (t!=0)
                                {
-                                       LOG_ERROR("PC was not 0. Does this target does target need srst_pulls_trst?");
+                                       LOG_ERROR("PC was not 0. Does this target need srst_pulls_trst?");
                                }
                        }
                        
@@ -984,8 +992,12 @@ int arm7_9_halt(target_t *target)
        {
                /* program EmbeddedICE Debug Control Register to assert DBGRQ
                 */
-               buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);     
-               embeddedice_store_reg(dbg_ctrl);
+               if (arm7_9->set_special_dbgrq) {
+                       arm7_9->set_special_dbgrq(target);
+               } else {
+                       buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);     
+                       embeddedice_store_reg(dbg_ctrl);
+               }
        }
        else
        {
@@ -1388,6 +1400,10 @@ int arm7_9_restart_core(struct target_s *target)
        
        /* set RESTART instruction */
        jtag_add_end_state(TAP_RTI);
+       if (arm7_9->need_bypass_before_restart) {
+               arm7_9->need_bypass_before_restart = 0;
+               arm_jtag_set_instr(jtag_info, 0xf, NULL);
+       }
        arm_jtag_set_instr(jtag_info, 0x4, NULL);
        
        jtag_add_runtest(1, TAP_RTI);
@@ -2305,6 +2321,69 @@ int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32*
        return ERROR_OK;
 }
 
+int arm7_9_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];
+       armv4_5_algorithm_t armv4_5_info;
+       int retval;
+       int i;
+       
+       u32 erase_check_code[] =
+       {
+                                               /* loop: */
+               0xe4d03001,             /* ldrb r3, [r0], #1    */
+               0xe0022003,             /* and r2, r2, r3               */
+               0xe2511001,     /* subs r1, r1, #1              */
+               0x1afffffb,             /* bne loop                             */
+                                               /* end: */
+               0xeafffffe              /* 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(u32)); i++)
+               target_write_u32(target, erase_check_algorithm->address + i*sizeof(u32), erase_check_code[i]);
+       
+       armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+       armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+       armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+
+       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) - 4), 10000, &armv4_5_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;
+}
+
 int arm7_9_register_commands(struct command_context_s *cmd_ctx)
 {
        command_t *arm7_9_cmd;
@@ -2669,7 +2748,9 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
        
        arm7_9->fast_memory_access = fast_and_dangerous;
        arm7_9->dcc_downloads = fast_and_dangerous;
-
+       
+       arm7_9->need_bypass_before_restart = 0;
+       
        armv4_5->arch_info = arm7_9;
        armv4_5->read_core_reg = arm7_9_read_core_reg;
        armv4_5->write_core_reg = arm7_9_write_core_reg;