X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm7_9_common.c;h=563f470159682725ed59be87f5980a19c1e6d63a;hp=d77f2000279abbd6e619bf472062b80dfddf0f77;hb=dfbb9f3e89ae;hpb=2b7504c27947a139473986fa65d977701addb88d diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index d77f200027..563f470159 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -84,27 +84,17 @@ int arm7_9_reinit_embeddedice(target_t *target) arm7_9_enable_sw_bkpts(target); } - arm7_9->reinit_embeddedice = 0; - return ERROR_OK; } -int arm7_9_jtag_callback(enum jtag_event event, void *priv) +/* set things up after a reset / on startup */ +int arm7_9_setup(target_t *target) { - target_t *target = priv; - armv4_5_common_t *armv4_5 = target->arch_info; - arm7_9_common_t *arm7_9 = armv4_5->arch_info; - - /* a test-logic reset occured + /* a test-logic reset have occured * the EmbeddedICE registers have been reset * hardware breakpoints have been cleared */ - if (event == JTAG_TRST_ASSERTED) - { - arm7_9->reinit_embeddedice = 1; - } - - return ERROR_OK; + return arm7_9_reinit_embeddedice(target); } int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p) @@ -195,7 +185,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; } } @@ -210,7 +200,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; } } @@ -569,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++) @@ -603,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) @@ -649,11 +647,14 @@ int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer) int arm7_9_handle_target_request(void *priv) { target_t *target = priv; + if (!target->type->examined) + return ERROR_OK; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; arm_jtag_t *jtag_info = &arm7_9->jtag_info; reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL]; + if (!target->dbg_msg_enabled) return ERROR_OK; @@ -683,11 +684,6 @@ int arm7_9_poll(target_t *target) arm7_9_common_t *arm7_9 = armv4_5->arch_info; reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - if (arm7_9->reinit_embeddedice) - { - arm7_9_reinit_embeddedice(target); - } - /* read debug status register */ embeddedice_read_reg(dbg_stat); if ((retval = jtag_execute_queue()) != ERROR_OK) @@ -697,7 +693,7 @@ int arm7_9_poll(target_t *target) if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1)) { - LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32)); +/* LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));*/ if (target->state == TARGET_UNKNOWN) { target->state = TARGET_RUNNING; @@ -705,10 +701,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) @@ -753,7 +772,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 @@ -770,23 +789,14 @@ 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); } } - /* we can't know what state the target is in as we might e.g. - * be resetting after a power dropout, so we need to issue a tms/srst - */ - - /* assert SRST and TRST */ - /* system would get ouf sync if we didn't reset test-logic, too */ - jtag_add_reset(1, 1); - - jtag_add_sleep(5000); - /* here we should issue a srst only, but we may have to assert trst as well */ if (jtag_reset_config & RESET_SRST_PULLS_TRST) { @@ -846,6 +856,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]); @@ -869,7 +883,7 @@ int arm7_9_soft_reset_halt(struct target_s *target) int i; int retval; - if ((retval=target->type->halt(target))!=ERROR_OK) + if ((retval=target_halt(target))!=ERROR_OK) return retval; for (i=0; i<10; i++) @@ -925,6 +939,9 @@ int arm7_9_soft_reset_halt(struct target_s *target) armv4_5->core_mode = ARMV4_5_MODE_SVC; armv4_5->core_state = ARMV4_5_STATE_ARM; + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; /* reset registers */ for (i = 0; i <= 14; i++) @@ -965,14 +982,27 @@ int arm7_9_halt(target_t *target) LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); return ERROR_TARGET_FAILURE; } + else + { + /* we came here in a reset_halt or reset_init sequence + * debug entry was already prepared in arm7_9_assert_reset() + */ + target->debug_reason = DBG_REASON_DBGRQ; + + return ERROR_OK; + } } if (arm7_9->use_dbgrq) { /* 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 { @@ -980,8 +1010,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; @@ -1022,15 +1052,7 @@ int arm7_9_debug_entry(target_t *target) if ((retval = jtag_execute_queue()) != ERROR_OK) { - switch (retval) - { - case ERROR_JTAG_QUEUE_FAILED: - LOG_ERROR("JTAG queue failed while writing EmbeddedICE control register"); - exit(-1); - break; - default: - break; - } + return retval; } if ((retval = arm7_9->examine_debug_reason(target)) != ERROR_OK) @@ -1112,6 +1134,8 @@ int arm7_9_debug_entry(target_t *target) LOG_ERROR("unknown debug reason: %i", target->debug_reason); } + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; for (i=0; i<=15; i++) { @@ -1122,9 +1146,12 @@ int arm7_9_debug_entry(target_t *target) } LOG_DEBUG("entered debug state at PC 0x%x", context[15]); + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; /* exceptions other than USR & SYS have a saved program status register */ - if ((armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_USR) && (armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_SYS)) + if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS)) { u32 spsr; arm7_9->read_xpsr(target, &spsr, 1); @@ -1161,6 +1188,9 @@ int arm7_9_full_context(target_t *target) LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND) * SYS shares registers with User, so we don't touch SYS @@ -1247,6 +1277,9 @@ int arm7_9_restore_context(target_t *target) if (arm7_9->pre_restore_context) arm7_9->pre_restore_context(target); + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND) * SYS shares registers with User, so we don't touch SYS */ @@ -1372,6 +1405,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); @@ -1558,13 +1595,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) @@ -1656,6 +1693,10 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod int retval; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode; if ((num < 0) || (num > 16)) @@ -1717,6 +1758,10 @@ int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mo u32 reg[16]; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode; if ((num < 0) || (num > 16)) @@ -1892,6 +1937,9 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count break; } + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + for (i=0; i<=last_reg; i++) ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid; @@ -2059,6 +2107,9 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1); embeddedice_store_reg(dbg_ctrl); + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + for (i=0; i<=last_reg; i++) ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid; @@ -2081,6 +2132,12 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun return ERROR_OK; } +static const u32 dcc_code[] = +{ + /* MRC TST BNE MRC STR B */ + 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9 +}; + int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer) { armv4_5_common_t *armv4_5 = target->arch_info; @@ -2091,12 +2148,6 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); int i; - u32 dcc_code[] = - { - /* MRC TST BNE MRC STR B */ - 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9 - }; - if (!arm7_9->dcc_downloads) return target->type->write_memory(target, address, 4, count, buffer); @@ -2169,11 +2220,11 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe } } - target->type->halt(target); + target_halt(target); for (i=0; i<100; i++) { - target->type->poll(target); + target_poll(target); if (target->state == TARGET_HALTED) break; usleep(1000); /* sleep 1ms */ @@ -2275,6 +2326,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(®_params[0], "r0", 32, PARAM_OUT); + buf_set_u32(reg_params[0].value, 0, 32, address); + + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); + buf_set_u32(reg_params[1].value, 0, 32, count); + + init_reg_param(®_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(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_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(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_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; @@ -2432,6 +2546,12 @@ int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, armv4_5_common_t *armv4_5; arm7_9_common_t *arm7_9; + if (target->state != TARGET_HALTED) + { + LOG_ERROR("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) { command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); @@ -2627,17 +2747,15 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9) arm7_9->has_monitor_mode = 0; arm7_9->has_vector_catch = 0; - arm7_9->reinit_embeddedice = 0; - arm7_9->debug_entry_from_reset = 0; arm7_9->dcc_working_area = NULL; - arm7_9->fast_memory_access = 0; - arm7_9->dcc_downloads = 0; - - jtag_register_event_callback(arm7_9_jtag_callback, target); - + 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;