retired reset run_and_init/halt
[openocd.git] / src / target / arm7_9_common.c
index 249d8d4c1cd160d41ec939742d95b8e314a31055..cf5f2b369afba752e62e79a0d3c6d3fd1852d7b0 100644 (file)
@@ -2,6 +2,9 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
+ *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                      *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
@@ -185,7 +188,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                        target->type->read_memory(target, breakpoint->address, 4, 1, (u8 *)&verify);
                        if (verify != arm7_9->arm_bkpt)
                        {
-                               LOG_ERROR("Unable to set 32 bit software breakpoint at address %08x", breakpoint->address);
+                               LOG_ERROR("Unable to set 32 bit software breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
                                return ERROR_OK;
                        }
                }
@@ -200,7 +203,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
                        target->type->read_memory(target, breakpoint->address, 2, 1, (u8 *)&verify);
                        if (verify != arm7_9->thumb_bkpt)
                        {
-                               LOG_ERROR("Unable to set thumb software breakpoint at address %08x", breakpoint->address);
+                               LOG_ERROR("Unable to set thumb software breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
                                return ERROR_OK;
                        }
                }
@@ -559,6 +562,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 +600,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)
@@ -693,10 +704,33 @@ int arm7_9_poll(target_t *target)
                }
                if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
                {
+                       int check_pc=0;
+                       if (target->state == TARGET_RESET)
+                       {
+                               if (target->reset_halt)
+                               {
+                                       if ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0)
+                                       {
+                                               check_pc = 1;
+                                       }
+                               }
+                       }
+                       
                        target->state = TARGET_HALTED;
+                       
                        if ((retval = arm7_9_debug_entry(target)) != ERROR_OK)
                                return retval;
                        
+                       if (check_pc)
+                       {
+                               reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1);
+                               u32 t=*((u32 *)reg->value);
+                               if (t!=0)
+                               {
+                                       LOG_ERROR("PC was not 0. Does this target need srst_pulls_trst?");
+                               }
+                       }
+                       
                        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
                }
                if (target->state == TARGET_DEBUG_RUNNING)
@@ -741,7 +775,7 @@ int arm7_9_assert_reset(target_t *target)
                return ERROR_FAIL;
        }
 
-       if ((target->reset_mode == RESET_HALT) || (target->reset_mode == RESET_INIT))
+       if (target->reset_halt)
        {
                /*
                 * Some targets do not support communication while SRST is asserted. We need to
@@ -758,10 +792,11 @@ int arm7_9_assert_reset(target_t *target)
                else
                {
                        /* program watchpoint unit to match on reset vector address */
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], 0x0);
                        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);
-                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
-                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
-                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
+                       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
                }
        }
 
@@ -824,6 +859,10 @@ int arm7_9_clear_halt(target_t *target)
                         */
                        if (arm7_9->wp0_used)
                        {
+                               if (arm7_9->debug_entry_from_reset)
+                               {
+                                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE]);
+                               }
                                embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
                                embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
                                embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
@@ -949,7 +988,7 @@ int arm7_9_halt(target_t *target)
                else
                {
                        /* we came here in a reset_halt or reset_init sequence
-                        * debug entry was already prepared in arm7_9_prepare_reset_halt()
+                        * debug entry was already prepared in arm7_9_assert_reset()
                         */
                        target->debug_reason = DBG_REASON_DBGRQ;
                        
@@ -961,8 +1000,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
        {
@@ -970,8 +1013,8 @@ int arm7_9_halt(target_t *target)
                 */
                embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
                embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
-               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
        }
 
        target->debug_reason = DBG_REASON_DBGRQ;
@@ -1365,6 +1408,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);
@@ -1551,13 +1598,13 @@ void arm7_9_enable_eice_step(target_t *target)
        * - comparator 0 matches any address, as long as rangein is low */
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
-       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
-       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0x77);
+       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
+       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~(EICE_W_CTRL_RANGE|EICE_W_CTRL_nOPC) & 0xff);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);
        embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
-       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xf7);
+       embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff);
 }
 
 void arm7_9_disable_eice_step(target_t *target)
@@ -2282,6 +2329,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;
@@ -2646,7 +2756,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;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)