From ffb51c23fdd753ada2554b8b6283533089153b46 Mon Sep 17 00:00:00 2001 From: drath Date: Thu, 21 Jun 2007 13:15:22 +0000 Subject: [PATCH] - added support for Intel/Marvel PXA27x (XScale) targets - added support for scans coming from or ending in Shift-DR or Shift-IR to bitbang code (required for XScale debugging) - cleaned up errror handlers. only use when there's a catchable error - fix segfault when etm was configured without a valid driver git-svn-id: svn://svn.berlios.de/openocd/trunk@176 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/jtag/bitbang.c | 28 ++++++-- src/jtag/jtag.c | 13 ++-- src/jtag/jtag.h | 3 + src/target/arm7_9_common.c | 7 ++ src/target/arm9tdmi.c | 25 ++----- src/target/cortex_swjdp.c | 19 +----- src/target/embeddedice.c | 19 +----- src/target/etm.c | 8 +++ src/target/xscale.c | 130 ++++++++++++++++++++----------------- 9 files changed, 125 insertions(+), 127 deletions(-) diff --git a/src/jtag/bitbang.c b/src/jtag/bitbang.c index 82e92a21..198a741f 100644 --- a/src/jtag/bitbang.c +++ b/src/jtag/bitbang.c @@ -132,21 +132,35 @@ void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) enum tap_state saved_end_state = end_state; int bit_cnt; - if (ir_scan) - bitbang_end_state(TAP_SI); - else - bitbang_end_state(TAP_SD); + if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI)))) + { + if (ir_scan) + bitbang_end_state(TAP_SI); + else + bitbang_end_state(TAP_SD); - bitbang_state_move(); - bitbang_end_state(saved_end_state); + bitbang_state_move(); + bitbang_end_state(saved_end_state); + } for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) { + /* set TMS high on the last bit unless we want to end in TAP_SD/SI */ + int tms; + if ((ir_scan && (end_state == TAP_SI)) || + (!ir_scan && (end_state == TAP_SD))) + { + tms = 0; + } else { + tms = (bit_cnt==scan_size-1) ? 1 : 0; + } + /* if we're just reading the scan, but don't care about the output * default to outputting 'low', this also makes valgrind traces more readable, * as it removes the dependency on an uninitialised value */ - if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1)) { + if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1)) + { bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1); bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1); } else { diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 6dfde760..98919123 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -58,6 +58,8 @@ static cmd_queue_page_t *cmd_queue_pages = NULL; * 3: Pause-DR * 4: Shift-IR * 5: Pause-IR + * + * SD->SD and SI->SI have to be caught in interface specific code */ u8 tap_move[6][6] = { @@ -1086,9 +1088,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) if (compare_failed) { - char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); - char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16); - if (cmd->error_handler) { /* ask the error handler if once has been specified if this is a real problem */ @@ -1109,6 +1108,9 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) */ if (compare_failed) { + char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); + char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16); + if (cmd->fields[i].in_check_mask) { char *in_check_mask_char; @@ -1120,10 +1122,11 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) { WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char); } + + free(captured_char); + free(in_check_value_char); } - free(captured_char); - free(in_check_value_char); } } free(captured); diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 1464a080..1b03d615 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -59,6 +59,9 @@ extern tap_transition_t tap_transitions[16]; /* describe the TAP state diagram * extern enum tap_state end_state; /* finish DR scans in dr_end_state */ extern enum tap_state cur_state; /* current TAP state */ +extern enum tap_state cmd_queue_end_state; /* finish DR scans in dr_end_state */ +extern enum tap_state cmd_queue_cur_state; /* current TAP state */ + #define TAP_MOVE(from, to) tap_move[tap_move_map[from]][tap_move_map[to]] typedef struct error_handler_s diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 77a43fee..cda99d84 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -846,6 +846,13 @@ int arm7_9_prepare_reset_halt(target_t *target) armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; + /* poll the target, and resume if it was currently halted */ + arm7_9_poll(target); + if (target->state == TARGET_HALTED) + { + arm7_9_resume(target, 1, 0x0, 0, 1); + } + if (arm7_9->has_vector_catch) { /* program vector catch register to catch reset vector */ diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 7ecd1f0d..3b06b0e4 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -104,7 +104,7 @@ int arm9tdmi_jtag_error_handler(u8 *in_value, void *priv) DEBUG("caller: %s", caller); - return ERROR_OK; + return ERROR_JTAG_QUEUE_FAILED; } int arm9tdmi_examine_debug_reason(target_t *target) @@ -117,7 +117,6 @@ int arm9tdmi_examine_debug_reason(target_t *target) if ((target->debug_reason != DBG_REASON_DBGRQ) && (target->debug_reason != DBG_REASON_SINGLESTEP)) { - error_handler_t error_handler; scan_field_t fields[3]; u8 databus[4]; u8 instructionbus[4]; @@ -156,9 +155,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) fields[2].in_handler_priv = NULL; arm_jtag_scann(&arm7_9->jtag_info, 0x1); - error_handler.error_handler = arm9tdmi_jtag_error_handler; - error_handler.error_handler_priv = "arm9tdmi_examine_debug_reason"; - arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, &error_handler); + arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL); jtag_add_dr_scan(3, fields, TAP_PD, NULL); jtag_execute_queue(); @@ -187,7 +184,6 @@ int arm9tdmi_examine_debug_reason(target_t *target) /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed) { - error_handler_t error_handler; scan_field_t fields[3]; u8 out_buf[4]; u8 instr_buf[4]; @@ -204,10 +200,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - error_handler.error_handler = arm9tdmi_jtag_error_handler; - error_handler.error_handler_priv = "arm9tdmi_clock_out"; - - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -271,15 +264,11 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) { scan_field_t fields[3]; - error_handler_t error_handler; jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - error_handler.error_handler = arm9tdmi_jtag_error_handler; - error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness"; - - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -340,15 +329,11 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be) { scan_field_t fields[3]; - error_handler_t error_handler; jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - error_handler.error_handler = arm9tdmi_jtag_error_handler; - error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness"; - - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; diff --git a/src/target/cortex_swjdp.c b/src/target/cortex_swjdp.c index 15fc26da..e50c6843 100644 --- a/src/target/cortex_swjdp.c +++ b/src/target/cortex_swjdp.c @@ -54,26 +54,14 @@ are immediatley available. * * ***************************************************************************/ -int swjdp_jtag_error_handler(u8 *in_value, void *priv) -{ - char *caller = priv; - - DEBUG("caller: %s", caller); - - return ERROR_OK; -} - /* Scan out and in from target ordered u8 buffers */ int swjdp_scan(arm_jtag_t *jtag_info, u8 chain, u8 reg_addr, u8 RnW, u8 *outvalue, u8 *invalue, u8 *ack) { scan_field_t fields[2]; u8 out_addr_buf; - error_handler_t error_handler; jtag_add_end_state(TAP_RTI); - error_handler.error_handler = swjdp_jtag_error_handler; - error_handler.error_handler_priv = "swjdp_scan"; - arm_jtag_set_instr(jtag_info, chain, &error_handler); + arm_jtag_set_instr(jtag_info, chain, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 3; @@ -108,12 +96,9 @@ int swjdp_scan_u32(arm_jtag_t *jtag_info, u8 chain, u8 reg_addr, u8 RnW, u32 out scan_field_t fields[2]; u8 out_value_buf[4]; u8 out_addr_buf; - error_handler_t error_handler; jtag_add_end_state(TAP_RTI); - error_handler.error_handler = swjdp_jtag_error_handler; - error_handler.error_handler_priv = "swjdp_scan_u32"; - arm_jtag_set_instr(jtag_info, chain, &error_handler); + arm_jtag_set_instr(jtag_info, chain, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 3; diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index ef38e136..f601c1eb 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -86,15 +86,6 @@ int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf); int embeddedice_write_reg(reg_t *reg, u32 value); int embeddedice_read_reg(reg_t *reg); -int embeddedice_jtag_error_handler(u8 *in_value, void *priv) -{ - char *caller = priv; - - DEBUG("caller: %s", caller); - - return ERROR_OK; -} - reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7_9) { reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t)); @@ -223,17 +214,13 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) embeddedice_reg_t *ice_reg = reg->arch_info; u8 reg_addr = ice_reg->addr & 0x1f; scan_field_t fields[3]; - error_handler_t error_handler; DEBUG("%i", ice_reg->addr); jtag_add_end_state(TAP_RTI); arm_jtag_scann(ice_reg->jtag_info, 0x2); - error_handler.error_handler = embeddedice_jtag_error_handler; - error_handler.error_handler_priv = "embeddedice_read_reg_w_check"; - - arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, &error_handler); + arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL); fields[0].device = ice_reg->jtag_info->chain_pos; fields[0].num_bits = 32; @@ -324,16 +311,12 @@ int embeddedice_write_reg(reg_t *reg, u32 value) embeddedice_reg_t *ice_reg = reg->arch_info; u8 reg_addr = ice_reg->addr & 0x1f; scan_field_t fields[3]; - error_handler_t error_handler; DEBUG("%i: 0x%8.8x", ice_reg->addr, value); jtag_add_end_state(TAP_RTI); arm_jtag_scann(ice_reg->jtag_info, 0x2); - error_handler.error_handler = embeddedice_jtag_error_handler; - error_handler.error_handler_priv = "embeddedice_write_reg"; - arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL); fields[0].device = ice_reg->jtag_info->chain_pos; diff --git a/src/target/etm.c b/src/target/etm.c index dd6e6025..b4c20750 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -1231,6 +1231,14 @@ int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char } } + if (!etm_capture_drivers[i]) + { + /* no supported capture driver found, don't register an ETM */ + free(etm_ctx); + ERROR("trace capture driver '%s' not found", args[4]); + return ERROR_OK; + } + etm_ctx->target = target; etm_ctx->trace_data = NULL; etm_ctx->trace_depth = 0; diff --git a/src/target/xscale.c b/src/target/xscale.c index 311e53bc..2cfc23e7 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * + * Copyright (C) 2006, 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * * * This program is free software; you can redistribute it and/or modify * @@ -34,15 +34,16 @@ #include "binarybuffer.h" #include "time_support.h" #include "breakpoints.h" +#include "fileio.h" #include #include #include -#include #include #include + /* cli handling */ int xscale_register_commands(struct command_context_s *cmd_ctx); @@ -1197,9 +1198,6 @@ int xscale_halt(target_t *target) else if (target->state == TARGET_RESET) { DEBUG("target->state == TARGET_RESET"); - - /* clear TRST */ - jtag_add_reset(0, -1); } else { @@ -1517,22 +1515,32 @@ int xscale_assert_reset(target_t *target) xscale_common_t *xscale = armv4_5->arch_info; DEBUG("target->state: %s", target_state_strings[target->state]); + + /* select DCSR instruction (set endstate to R-T-I to ensure we don't + * end up in T-L-R, which would reset JTAG + */ + jtag_add_end_state(TAP_RTI); + xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr); - /* if the handler isn't installed yet, we have to assert TRST, too */ - if (!xscale->handler_installed) - { - jtag_add_reset(1, 1); - } - else - jtag_add_reset(-1, 1); + /* set Hold reset, Halt mode and Trap Reset */ + buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); + buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); + xscale_write_dcsr(target, 1, 0); + + /* select BYPASS, because having DCSR selected caused problems on the PXA27x */ + xscale_jtag_set_instr(xscale->jtag_info.chain_pos, 0x7f); + jtag_execute_queue(); + + /* assert reset */ + jtag_add_reset(0, 1); /* sleep 1ms, to be sure we fulfill any requirements */ jtag_add_sleep(1000); + jtag_execute_queue(); target->state = TARGET_RESET; return ERROR_OK; - } int xscale_deassert_reset(target_t *target) @@ -1540,17 +1548,18 @@ int xscale_deassert_reset(target_t *target) armv4_5_common_t *armv4_5 = target->arch_info; xscale_common_t *xscale = armv4_5->arch_info; - FILE *binary; + fileio_t debug_handler; u32 address; - struct stat binary_stat; u32 binary_size; - u32 buffer[8]; u32 buf_cnt; int i; + int retval; breakpoint_t *breakpoint = target->breakpoints; + DEBUG("-"); + xscale->ibcr_available = 2; xscale->ibcr0_used = 0; xscale->ibcr1_used = 0; @@ -1571,42 +1580,27 @@ int xscale_deassert_reset(target_t *target) if (!xscale->handler_installed) { - /* release TRST */ - jtag_add_reset(0, -1); - jtag_add_sleep(100000); - - /* set Hold reset, Halt mode and Trap Reset */ - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); - xscale_write_dcsr(target, 1, 0); - jtag_add_runtest(100, TAP_RTI); - jtag_execute_queue(); - /* release SRST */ jtag_add_reset(0, 0); - /* wait 150ms; 100ms were not enough */ - jtag_add_sleep(150000); + + /* wait 300ms; 150 and 100ms were not enough */ + jtag_add_sleep(3000000); jtag_add_runtest(2030, TAP_RTI); jtag_execute_queue(); - + + /* set Hold reset, Halt mode and Trap Reset */ + buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); + buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); xscale_write_dcsr(target, 1, 0); - jtag_execute_queue(); - - /* TODO: load debug handler */ - if (stat("target/xscale/debug_handler.bin", &binary_stat) == -1) - { - ERROR("couldn't stat() target/xscale/debug_handler.bin: %s", strerror(errno)); - return ERROR_OK; - } - - if (!(binary = fopen("target/xscale/debug_handler.bin", "r"))) + + if (fileio_open(&debug_handler, "target/xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK) { - ERROR("couldn't open target/xscale/debug_handler.bin: %s", strerror(errno)); + ERROR("file open error: %s", debug_handler.error_str); return ERROR_OK; } - - if ((binary_size = binary_stat.st_size) % 4) + + if ((binary_size = debug_handler.size) % 4) { ERROR("debug_handler.bin: size not a multiple of 4"); exit(-1); @@ -1623,41 +1617,51 @@ int xscale_deassert_reset(target_t *target) address = xscale->handler_address; while (binary_size > 0) { - buf_cnt = fread(buffer, 4, 8, binary); + u32 cache_line[8]; + u8 buffer[32]; + + if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK) + { + ERROR("reading debug handler failed: %s", debug_handler.error_str); + } - for (i = 0; i < buf_cnt; i++) + for (i = 0; i < buf_cnt; i += 4) { /* convert LE buffer to host-endian u32 */ - buffer[i] = buf_get_u32((u8*)(&buffer[i]), 0, 32); + cache_line[i / 4] = le_to_h_u32(&buffer[i]); } - if (buf_cnt < 8) + for (; buf_cnt < 32; buf_cnt += 4) { - for (; buf_cnt < 8; buf_cnt++) - { - buffer[buf_cnt] = 0xe1a08008; - } + cache_line[buf_cnt / 4] = 0xe1a08008; } /* only load addresses other than the reset vectors */ if ((address % 0x400) != 0x0) { - xscale_load_ic(target, 1, address, buffer); + xscale_load_ic(target, 1, address, cache_line); } - address += buf_cnt * 4; - binary_size -= buf_cnt * 4; + address += buf_cnt; + binary_size -= buf_cnt; }; xscale_load_ic(target, 1, 0x0, xscale->low_vectors); xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors); jtag_add_runtest(30, TAP_RTI); + + jtag_add_sleep(100000); - /* let the target run (should enter debug handler) */ - xscale_write_dcsr(target, 0, 0); + /* set Hold reset, Halt mode and Trap Reset */ + buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); + buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); + xscale_write_dcsr(target, 1, 0); + + /* clear Hold reset to let the target run (should enter debug handler) */ + xscale_write_dcsr(target, 0, 1); target->state = TARGET_RUNNING; - + if ((target->reset_mode != RESET_HALT) && (target->reset_mode != RESET_INIT)) { jtag_add_sleep(10000); @@ -1666,8 +1670,8 @@ int xscale_deassert_reset(target_t *target) xscale_debug_entry(target); target->state = TARGET_HALTED; - /* the PC is now at 0x0 */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0); + /* resume the target */ + xscale_resume(target, 1, 0x0, 1, 0); } } else @@ -1687,7 +1691,9 @@ int xscale_soft_reset_halt(struct target_s *target) int xscale_prepare_reset_halt(struct target_s *target) { - /* nothing to be done for reset_halt on XScale targets */ + /* nothing to be done for reset_halt on XScale targets + * we always halt after a reset to upload the debug handler + */ return ERROR_OK; } @@ -2584,6 +2590,10 @@ int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *targe ERROR("Reset target to enable debug"); } + /* assert TRST once during startup */ + jtag_add_reset(1, 0); + jtag_add_reset(0, 0); + return ERROR_OK; } -- 2.39.5