X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fxscale.c;h=8d97a89fbed059e8391820f358d464ed254b5618;hp=5e9c598234234280d933cd75e224d21ef9cdcee0;hb=3160c66408af858c3064e54fb14f074e54ac6701;hpb=4315142ea0d7035fe117b9e344beaf98c91ee35c diff --git a/src/target/xscale.c b/src/target/xscale.c index 5e9c598234..8d97a89fbe 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -73,16 +73,12 @@ static int xscale_read_trace(struct target *); /* This XScale "debug handler" is loaded into the processor's * mini-ICache, which is 2K of code writable only via JTAG. - * - * FIXME the OpenOCD "bin2char" utility currently doesn't handle - * binary files cleanly. It's string oriented, and terminates them - * with a NUL character. Better would be to generate the constants - * and let other code decide names, scoping, and other housekeeping. */ -static /* unsigned const char xscale_debug_handler[] = ... */ -#include "xscale_debug.h" +static const uint8_t xscale_debug_handler[] = { +#include "xscale_debug.inc" +}; -static char *const xscale_reg_list[] = { +static const char *const xscale_reg_list[] = { "XSCALE_MAINID", /* 0 */ "XSCALE_CACHETYPE", "XSCALE_CTRL", @@ -513,8 +509,6 @@ done: static int xscale_send(struct target *target, const uint8_t *buffer, int count, int size) { struct xscale_common *xscale = target_to_xscale(target); - uint32_t t[3]; - int bits[3]; int retval; int done_count = 0; @@ -522,37 +516,45 @@ static int xscale_send(struct target *target, const uint8_t *buffer, int count, XSCALE_DBGRX << xscale->xscale_variant, TAP_IDLE); - bits[0] = 3; - t[0] = 0; - bits[1] = 32; - t[2] = 1; - bits[2] = 1; + static const uint8_t t0; + uint8_t t1[4]; + static const uint8_t t2 = 1; + struct scan_field fields[3] = { + { .num_bits = 3, .out_value = &t0 }, + { .num_bits = 32, .out_value = t1 }, + { .num_bits = 1, .out_value = &t2 }, + }; + int endianness = target->endianness; while (done_count++ < count) { + uint32_t t; + switch (size) { case 4: if (endianness == TARGET_LITTLE_ENDIAN) - t[1] = le_to_h_u32(buffer); + t = le_to_h_u32(buffer); else - t[1] = be_to_h_u32(buffer); + t = be_to_h_u32(buffer); break; case 2: if (endianness == TARGET_LITTLE_ENDIAN) - t[1] = le_to_h_u16(buffer); + t = le_to_h_u16(buffer); else - t[1] = be_to_h_u16(buffer); + t = be_to_h_u16(buffer); break; case 1: - t[1] = buffer[0]; + t = buffer[0]; break; default: LOG_ERROR("BUG: size neither 4, 2 nor 1"); return ERROR_COMMAND_SYNTAX_ERROR; } - jtag_add_dr_out(target->tap, + + buf_set_u32(t1, 0, 32, t); + + jtag_add_dr_scan(target->tap, 3, - bits, - t, + fields, TAP_IDLE); buffer += size; } @@ -1447,6 +1449,13 @@ static int xscale_assert_reset(struct target *target) LOG_DEBUG("target->state: %s", target_state_name(target)); + /* assert reset */ + jtag_add_reset(0, 1); + + /* sleep 1ms, to be sure we fulfill any requirements */ + jtag_add_sleep(1000); + jtag_execute_queue(); + /* select DCSR instruction (set endstate to R-T-I to ensure we don't * end up in T-L-R, which would reset JTAG */ @@ -1463,13 +1472,6 @@ static int xscale_assert_reset(struct target *target) xscale_jtag_set_instr(target->tap, ~0, TAP_IDLE); 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; if (target->reset_halt) { @@ -1543,7 +1545,7 @@ static int xscale_deassert_reset(struct target *target) * coprocessors, trace data, etc. */ address = xscale->handler_address; - for (unsigned binary_size = sizeof xscale_debug_handler - 1; + for (unsigned binary_size = sizeof xscale_debug_handler; binary_size > 0; binary_size -= buf_cnt, buffer += buf_cnt) { uint32_t cache_line[8]; @@ -1815,8 +1817,10 @@ static int xscale_read_memory(struct target *target, uint32_t address, /* receive data from target (count times 32-bit words in host endianness) */ buf32 = malloc(4 * count); retval = xscale_receive(target, buf32, count); - if (retval != ERROR_OK) + if (retval != ERROR_OK) { + free(buf32); return retval; + } /* extract data from host-endian buffer into byte stream */ for (i = 0; i < count; i++) { @@ -2901,7 +2905,7 @@ static int xscale_init_target(struct command_context *cmd_ctx, } static int xscale_init_arch_info(struct target *target, - struct xscale_common *xscale, struct jtag_tap *tap, const char *variant) + struct xscale_common *xscale, struct jtag_tap *tap) { struct arm *arm; uint32_t high_reset_branch, low_reset_branch; @@ -2912,33 +2916,7 @@ static int xscale_init_arch_info(struct target *target, /* store architecture specfic data */ xscale->common_magic = XSCALE_COMMON_MAGIC; - /* we don't really *need* a variant param ... */ - if (variant) { - int ir_length = 0; - - if (strcmp(variant, "pxa250") == 0 - || strcmp(variant, "pxa255") == 0 - || strcmp(variant, "pxa26x") == 0) - ir_length = 5; - else if (strcmp(variant, "pxa27x") == 0 - || strcmp(variant, "ixp42x") == 0 - || strcmp(variant, "ixp45x") == 0 - || strcmp(variant, "ixp46x") == 0) - ir_length = 7; - else if (strcmp(variant, "pxa3xx") == 0) - ir_length = 11; - else - LOG_WARNING("%s: unrecognized variant %s", - tap->dotted_name, variant); - - if (ir_length && ir_length != tap->ir_length) { - LOG_WARNING("%s: IR length for %s is %d; fixing", - tap->dotted_name, variant, ir_length); - tap->ir_length = ir_length; - } - } - - /* PXA3xx shifts the JTAG instructions */ + /* PXA3xx with 11 bit IR shifts the JTAG instructions */ if (tap->ir_length == 11) xscale->xscale_variant = XSCALE_PXA3XX; else @@ -2997,6 +2975,7 @@ static int xscale_init_arch_info(struct target *target, /* prepare ARMv4/5 specific information */ arm->arch_info = xscale; + arm->core_type = ARM_MODE_ANY; arm->read_core_reg = xscale_read_core_reg; arm->write_core_reg = xscale_write_core_reg; arm->full_context = xscale_full_context; @@ -3019,7 +2998,7 @@ static int xscale_target_create(struct target *target, Jim_Interp *interp) { struct xscale_common *xscale; - if (sizeof xscale_debug_handler - 1 > 0x800) { + if (sizeof xscale_debug_handler > 0x800) { LOG_ERROR("debug_handler.bin: larger than 2kb"); return ERROR_FAIL; } @@ -3028,8 +3007,7 @@ static int xscale_target_create(struct target *target, Jim_Interp *interp) if (!xscale) return ERROR_FAIL; - return xscale_init_arch_info(target, xscale, target->tap, - target->variant); + return xscale_init_arch_info(target, xscale, target->tap); } COMMAND_HANDLER(xscale_handle_debug_handler_command) @@ -3217,28 +3195,66 @@ COMMAND_HANDLER(xscale_handle_idcache_command) return ERROR_OK; } +static const struct { + char name[15]; + unsigned mask; +} vec_ids[] = { + { "fiq", DCSR_TF, }, + { "irq", DCSR_TI, }, + { "dabt", DCSR_TD, }, + { "pabt", DCSR_TA, }, + { "swi", DCSR_TS, }, + { "undef", DCSR_TU, }, + { "reset", DCSR_TR, }, +}; + COMMAND_HANDLER(xscale_handle_vector_catch_command) { struct target *target = get_current_target(CMD_CTX); struct xscale_common *xscale = target_to_xscale(target); int retval; + uint32_t dcsr_value; + uint32_t catch = 0; + struct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR]; retval = xscale_verify_pointer(CMD_CTX, xscale); if (retval != ERROR_OK) return retval; - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - else { - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], xscale->vector_catch); - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, - 16, - 8, - xscale->vector_catch); + dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32); + if (CMD_ARGC > 0) { + if (CMD_ARGC == 1) { + if (strcmp(CMD_ARGV[0], "all") == 0) { + catch = DCSR_TRAP_MASK; + CMD_ARGC--; + } else if (strcmp(CMD_ARGV[0], "none") == 0) { + catch = 0; + CMD_ARGC--; + } + } + while (CMD_ARGC-- > 0) { + unsigned i; + for (i = 0; i < ARRAY_SIZE(vec_ids); i++) { + if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name)) + continue; + catch |= vec_ids[i].mask; + break; + } + if (i == ARRAY_SIZE(vec_ids)) { + LOG_ERROR("No vector '%s'", CMD_ARGV[CMD_ARGC]); + return ERROR_COMMAND_SYNTAX_ERROR; + } + } + *(uint32_t *)(dcsr_reg->value) &= ~DCSR_TRAP_MASK; + *(uint32_t *)(dcsr_reg->value) |= catch; xscale_write_dcsr(target, -1, -1); } - command_print(CMD_CTX, "vector catch mask: 0x%2.2x", xscale->vector_catch); + dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32); + for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) { + command_print(CMD_CTX, "%15s: %s", vec_ids[i].name, + (dcsr_value & vec_ids[i].mask) ? "catch" : "ignore"); + } return ERROR_OK; } @@ -3349,7 +3365,7 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command) if (xscale->trace.mode != XSCALE_TRACE_DISABLED) { char fill_string[12]; - sprintf(fill_string, "fill %" PRId32, xscale->trace.buffer_fill); + sprintf(fill_string, "fill %d", xscale->trace.buffer_fill); command_print(CMD_CTX, "trace buffer enabled (%s)", (xscale->trace.mode == XSCALE_TRACE_FILL) ? fill_string : "wrap"); @@ -3584,9 +3600,9 @@ static const struct command_registration xscale_exec_command_handlers[] = { .name = "vector_catch", .handler = xscale_handle_vector_catch_command, .mode = COMMAND_EXEC, - .help = "set or display 8-bit mask of vectors " + .help = "set or display mask of vectors " "that should trigger debug entry", - .usage = "[mask]", + .usage = "['all'|'none'|'fiq'|'irq'|'dabt'|'pabt'|'swi'|'undef'|'reset']", }, { .name = "vector_table", @@ -3674,15 +3690,12 @@ struct target_type xscale_target = { .poll = xscale_poll, .arch_state = xscale_arch_state, - .target_request_data = NULL, - .halt = xscale_halt, .resume = xscale_resume, .step = xscale_step, .assert_reset = xscale_assert_reset, .deassert_reset = xscale_deassert_reset, - .soft_reset_halt = NULL, /* REVISIT on some cores, allow exporting iwmmxt registers ... */ .get_gdb_reg_list = arm_get_gdb_reg_list,