X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjtag%2Fzy1000%2Fzy1000.c;h=391d8f2076201d9383aee80dec7a3a1f3c2c7249;hb=57d7743639d5092770d79f7c4b12ae694c482750;hp=2c205b7a5bddbe608a2605665db240092f536c79;hpb=924bf27596f31ab8e79fbb4de702be4a9fa12874;p=fw%2Fopenocd diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 2c205b7a5..391d8f207 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2009 by Øyvind Harboe * + * Copyright (C) 2007-2010 by Øyvind Harboe * * * * 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 * @@ -574,49 +574,31 @@ static __inline void scanFields(int num_fields, const struct scan_field *fields, } } -int interface_jtag_add_ir_scan(int num_fields, const struct scan_field *fields, tap_state_t state) +int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field *fields, tap_state_t state) { - - int j; int scan_size = 0; struct jtag_tap *tap, *nextTap; + for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap) { nextTap = jtag_tap_next_enabled(tap); - int pause = (nextTap==NULL); - - int found = 0; - + bool pause = (nextTap==NULL); scan_size = tap->ir_length; /* search the list */ - for (j = 0; j < num_fields; j++) + if (tap == active) { - if (tap == fields[j].tap) - { - found = 1; - - scanFields(1, fields + j, TAP_IRSHIFT, pause); - /* update device information */ - buf_cpy(fields[j].out_value, tap->cur_instr, scan_size); - - tap->bypass = 0; - break; - } - } + scanFields(1, fields, TAP_IRSHIFT, pause); + /* update device information */ + buf_cpy(fields[0].out_value, tap->cur_instr, scan_size); - if (!found) + tap->bypass = 0; + } else { /* if a device isn't listed, set it to BYPASS */ - uint8_t ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; + assert(scan_size <= 32); + shiftValueInner(TAP_IRSHIFT, pause?TAP_IRPAUSE:TAP_IRSHIFT, scan_size, 0xffffffff); - struct scan_field tmp; - memset(&tmp, 0, sizeof(tmp)); - tmp.out_value = ones; - tmp.num_bits = scan_size; - scanFields(1, &tmp, TAP_IRSHIFT, pause); - /* update device information */ - buf_cpy(tmp.out_value, tap->cur_instr, scan_size); tap->bypass = 1; } } @@ -637,38 +619,25 @@ int interface_jtag_add_plain_ir_scan(int num_fields, const struct scan_field *fi return ERROR_OK; } -int interface_jtag_add_dr_scan(int num_fields, const struct scan_field *fields, tap_state_t state) +int interface_jtag_add_dr_scan(struct jtag_tap *active, int num_fields, const struct scan_field *fields, tap_state_t state) { - - int j; struct jtag_tap *tap, *nextTap; for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap) { nextTap = jtag_tap_next_enabled(tap); - int found = 0; - int pause = (nextTap==NULL); + bool pause = (nextTap==NULL); - for (j = 0; j < num_fields; j++) + /* Find a range of fields to write to this tap */ + if (tap == active) { - if (tap == fields[j].tap) - { - found = 1; + assert(!tap->bypass); - scanFields(1, fields+j, TAP_DRSHIFT, pause); - } - } - if (!found) - { - struct scan_field tmp; - /* program the scan field to 1 bit length, and ignore it's value */ - tmp.num_bits = 1; - tmp.out_value = NULL; - tmp.in_value = NULL; - - scanFields(1, &tmp, TAP_DRSHIFT, pause); - } - else + scanFields(num_fields, fields, TAP_DRSHIFT, pause); + } else { + /* Shift out a 0 for disabled tap's */ + assert(tap->bypass); + shiftValueInner(TAP_DRSHIFT, pause?TAP_DRPAUSE:TAP_DRSHIFT, 1, 0); } } gotoEndState(state); @@ -682,7 +651,6 @@ int interface_jtag_add_plain_dr_scan(int num_fields, const struct scan_field *fi return ERROR_OK; } - int interface_jtag_add_tlr() { setCurrentState(TAP_RESET); @@ -690,8 +658,6 @@ int interface_jtag_add_tlr() } - - int interface_jtag_add_reset(int req_trst, int req_srst) { zy1000_reset(req_trst, req_srst); @@ -736,7 +702,6 @@ static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state); #endif - return ERROR_OK; } @@ -756,18 +721,52 @@ int interface_jtag_add_sleep(uint32_t us) return ERROR_OK; } +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) +{ + /*wait for the fifo to be empty*/ + waitIdle(); + + for (unsigned i = 0; i < num_bits; i++) + { + int tms; + + if (((seq[i/8] >> (i % 8)) & 1) == 0) + { + tms = 0; + } + else + { + tms = 1; + } + + waitIdle(); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms); + } + + waitIdle(); + if (state != TAP_INVALID) + { + ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state); + } else + { + /* this would be normal if we are switching to SWD mode */ + } + return ERROR_OK; +} + int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { int state_count; int tms = 0; - /*wait for the fifo to be empty*/ - waitIdle(); - state_count = 0; tap_state_t cur_state = cmd_queue_cur_state; + uint8_t seq[16]; + memset(seq, 0, sizeof(seq)); + assert(num_states < (sizeof(seq) * 8)); + while (num_states) { if (tap_state_transition(cur_state, false) == path[state_count]) @@ -784,21 +783,16 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) exit(-1); } - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms); + seq[state_count/8] = seq[state_count/8] | (tms << (state_count % 8)); cur_state = path[state_count]; state_count++; num_states--; } - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, cur_state); - return ERROR_OK; + return interface_add_tms_seq(state_count, seq, cur_state); } - - void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count) { // static int const reg_addr = 0x5; @@ -838,6 +832,105 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, } + +int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count) +{ +#if 0 + int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count); + return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); +#else + static const int bits[] = {32, 2}; + uint32_t values[] = {0, 0}; + + /* FIX!!!!!! the target_write_memory() API started this nasty problem + * with unaligned uint32_t * pointers... */ + const uint8_t *t = (const uint8_t *)data; + + + /* bypass bits before and after */ + int pre_bits = 0; + int post_bits = 0; + + bool found = false; + struct jtag_tap *cur_tap, *nextTap; + for (cur_tap = jtag_tap_next_enabled(NULL); cur_tap!= NULL; cur_tap = nextTap) + { + nextTap = jtag_tap_next_enabled(cur_tap); + if (cur_tap == tap) + { + found = true; + } else + { + if (found) + { + post_bits++; + } else + { + pre_bits++; + } + } + } + + post_bits+=2; + + + while (--count > 0) + { + shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0); + + uint32_t value; + value = *t++; + value |= (*t++<<8); + value |= (*t++<<16); + value |= (*t++<<24); + + shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, value); + shiftValueInner(TAP_DRSHIFT, TAP_DRPAUSE, post_bits, 0); + +#if 1 + /* copy & paste from arm11_dbgtap.c */ + //TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT + + waitIdle(); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + /* we don't have to wait for the queue to empty here. waitIdle(); */ + ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); +#else + static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = + { + TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT + }; + + jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), + arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); +#endif + } + + values[0] = *t++; + values[0] |= (*t++<<8); + values[0] |= (*t++<<16); + values[0] |= (*t++<<24); + + /* This will happen on the last iteration updating the current tap state + * so we don't have to track it during the common code path */ + jtag_add_dr_out(tap, + 2, + bits, + values, + TAP_IDLE); + + return jtag_execute_queue(); +#endif +} + + static const struct command_registration zy1000_commands[] = { { .name = "power", @@ -877,6 +970,7 @@ static const struct command_registration zy1000_commands[] = { struct jtag_interface zy1000_interface = { .name = "ZY1000", + .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = NULL, .speed = zy1000_speed, .commands = zy1000_commands,