From b930514e2f3e2a83e075e8c19ae0d38bbd2b27dc Mon Sep 17 00:00:00 2001 From: drath Date: Sat, 25 Aug 2007 09:59:42 +0000 Subject: [PATCH] - added support for setting JTAG frequency on ASIX PRESTO (thanks to Pavel Chromy) - usbprog update (thanks to Benedikt Sauter) - added embeddedice_send and _handshake functions (thanks to Pavel Chromy) - added support for 4, 8 and 16 bit ports to etb.c git-svn-id: svn://svn.berlios.de/openocd/trunk@203 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/jtag/presto.c | 20 +- src/jtag/usbprog.c | 403 +++++++++++++++++++++------------------ src/openocd.c | 5 +- src/target/embeddedice.c | 173 ++++++++++++++--- src/target/embeddedice.h | 4 +- src/target/etb.c | 61 +++++- 6 files changed, 445 insertions(+), 221 deletions(-) diff --git a/src/jtag/presto.c b/src/jtag/presto.c index 084ae91799..62a9746b2f 100644 --- a/src/jtag/presto.c +++ b/src/jtag/presto.c @@ -656,11 +656,26 @@ int presto_bitq_reset(int trst, int srst) /* -------------------------------------------------------------------------- */ +char *presto_speed_text[4] = +{ + "3 MHz", + "1.5 MHz", + "750 kHz", + "93.75 kHz" +}; int presto_jtag_speed(int speed) { + + if ((speed < 0) || (speed > 3)) + { + INFO("valid speed values: 0 (3 MHz), 1 (1.5 MHz), 2 (750 kHz) and 3 (93.75 kHz)"); + return ERROR_INVALID_ARGUMENTS; + } + jtag_speed = speed; - return ERROR_OK; + INFO("setting speed to %d, max. TCK freq. is %s", speed, presto_speed_text[speed]); + return presto_sendbyte(0xA8 | speed); } @@ -704,6 +719,9 @@ int presto_jtag_init(void) } INFO("PRESTO open, serial number '%s'", presto->serial); + /* use JTAG speed setting from configuration file */ + presto_jtag_speed(jtag_speed); + bitq_interface = &presto_bitq; return ERROR_OK; } diff --git a/src/jtag/usbprog.c b/src/jtag/usbprog.c index 4c39a8ff4d..94be877774 100644 --- a/src/jtag/usbprog.c +++ b/src/jtag/usbprog.c @@ -40,7 +40,7 @@ #include "log.h" #define VID 0x1781 -#define PID 0x0c62 +#define PID 0x0c63 // Pins at usbprog #define TDO_BIT 0 @@ -129,83 +129,83 @@ int usbprog_register_commands(struct command_context_s *cmd_ctx) int usbprog_execute_queue(void) { - jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - u8 *buffer; - - while (cmd) - { - switch (cmd->type) - { - case JTAG_END_STATE: + jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ + int scan_size; + enum scan_type type; + u8 *buffer; + + while (cmd) + { + switch (cmd->type) + { + case JTAG_END_STATE: #ifdef _DEBUG_JTAG_IO_ -DEBUG("end_state: %i", cmd->cmd.end_state->end_state); + DEBUG("end_state: %i", cmd->cmd.end_state->end_state); #endif -if (cmd->cmd.end_state->end_state != -1) - usbprog_end_state(cmd->cmd.end_state->end_state); -break; - case JTAG_RESET: + if (cmd->cmd.end_state->end_state != -1) + usbprog_end_state(cmd->cmd.end_state->end_state); + break; + case JTAG_RESET: #ifdef _DEBUG_JTAG_IO_ - DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); + DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); #endif - if (cmd->cmd.reset->trst == 1) - { - cur_state = TAP_TLR; - } - usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: + if (cmd->cmd.reset->trst == 1) + { + cur_state = TAP_TLR; + } + usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); + break; + case JTAG_RUNTEST: #ifdef _DEBUG_JTAG_IO_ - DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); + DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); #endif - if (cmd->cmd.runtest->end_state != -1) - usbprog_end_state(cmd->cmd.runtest->end_state); - usbprog_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_STATEMOVE: + if (cmd->cmd.runtest->end_state != -1) + usbprog_end_state(cmd->cmd.runtest->end_state); + usbprog_runtest(cmd->cmd.runtest->num_cycles); + break; + case JTAG_STATEMOVE: #ifdef _DEBUG_JTAG_IO_ - DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); + DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); #endif - if (cmd->cmd.statemove->end_state != -1) - usbprog_end_state(cmd->cmd.statemove->end_state); - usbprog_state_move(); - break; - case JTAG_PATHMOVE: + if (cmd->cmd.statemove->end_state != -1) + usbprog_end_state(cmd->cmd.statemove->end_state); + usbprog_state_move(); + break; + case JTAG_PATHMOVE: #ifdef _DEBUG_JTAG_IO_ - DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); + DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, + cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); #endif - usbprog_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: + usbprog_path_move(cmd->cmd.pathmove); + break; + case JTAG_SCAN: #ifdef _DEBUG_JTAG_IO_ - DEBUG("scan end in %i", cmd->cmd.scan->end_state); + DEBUG("scan end in %i", cmd->cmd.scan->end_state); #endif - if (cmd->cmd.scan->end_state != -1) - usbprog_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - return ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: + if (cmd->cmd.scan->end_state != -1) + usbprog_end_state(cmd->cmd.scan->end_state); + scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); + type = jtag_scan_type(cmd->cmd.scan); + usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); + if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) + return ERROR_JTAG_QUEUE_FAILED; + if (buffer) + free(buffer); + break; + case JTAG_SLEEP: #ifdef _DEBUG_JTAG_IO_ - DEBUG("sleep %i", cmd->cmd.sleep->us); + DEBUG("sleep %i", cmd->cmd.sleep->us); #endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return ERROR_OK; + jtag_sleep(cmd->cmd.sleep->us); + break; + default: + ERROR("BUG: unknown JTAG command type encountered"); + exit(-1); + } + cmd = cmd->next; + } + + return ERROR_OK; } @@ -218,9 +218,9 @@ int usbprog_init(void) ERROR("Can't find USB JTAG Interface! Please check connection and permissions."); return ERROR_JTAG_INIT_FAILED; } - + INFO("USB JTAG Interface ready!"); - + usbprog_jtag_init(usbprog_jtag_handle); usbprog_reset(0, 0); usbprog_write(0, 0, 0); @@ -230,7 +230,7 @@ int usbprog_init(void) int usbprog_quit(void) { - + return ERROR_OK; } @@ -249,157 +249,161 @@ void usbprog_end_state(enum tap_state state) void usbprog_state_move(void) { - int i=0, tms=0; - u8 tms_scan = TAP_MOVE(cur_state, end_state); + int i=0, tms=0; + u8 tms_scan = TAP_MOVE(cur_state, end_state); - usbprog_jtag_write_tms(usbprog_jtag_handle,(char)tms_scan); - for (i = 0; i < 7; i++) - { - tms = (tms_scan >> i) & 1; - } - - cur_state = end_state; + usbprog_jtag_write_tms(usbprog_jtag_handle,(char)tms_scan); + for (i = 0; i < 7; i++) + { + tms = (tms_scan >> i) & 1; + } + + cur_state = end_state; } void usbprog_path_move(pathmove_command_t *cmd) { - int num_states = cmd->num_states; - int state_count; - - state_count = 0; - while (num_states) - { - if (tap_transitions[cur_state].low == cmd->path[state_count]) - { - INFO("1"); - usbprog_write(0, 0, 0); - usbprog_write(1, 0, 0); - } - else if (tap_transitions[cur_state].high == cmd->path[state_count]) - { - INFO("2"); - usbprog_write(0, 1, 0); - usbprog_write(1, 1, 0); - } - else - { - ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]); - exit(-1); - } - - cur_state = cmd->path[state_count]; - state_count++; - num_states--; - } - - end_state = cur_state; + int num_states = cmd->num_states; + int state_count; + + state_count = 0; + while (num_states) + { + if (tap_transitions[cur_state].low == cmd->path[state_count]) + { + //INFO("1"); + usbprog_write(0, 0, 0); + usbprog_write(1, 0, 0); + } + else if (tap_transitions[cur_state].high == cmd->path[state_count]) + { + //INFO("2"); + usbprog_write(0, 1, 0); + usbprog_write(1, 1, 0); + } + else + { + ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]); + exit(-1); + } + + cur_state = cmd->path[state_count]; + state_count++; + num_states--; + } + + end_state = cur_state; } void usbprog_runtest(int num_cycles) { - int i; + int i; + + enum tap_state saved_end_state = end_state; - /* - enum tap_state saved_end_state = end_state; - */ /* only do a state_move when we're not already in RTI */ - if (cur_state != TAP_RTI) - { - usbprog_end_state(TAP_RTI); - usbprog_state_move(); - } + if (cur_state != TAP_RTI) + { + usbprog_end_state(TAP_RTI); + usbprog_state_move(); + } - /* execute num_cycles */ + /* execute num_cycles */ if(num_cycles>0) { + usbprog_jtag_tms_send(usbprog_jtag_handle); usbprog_write(0, 0, 0); } else { usbprog_jtag_tms_send(usbprog_jtag_handle); + //INFO("NUM CYCLES %i",num_cycles); } - for (i = 0; i < num_cycles; i++) - { - usbprog_write(1, 0, 0); - usbprog_write(0, 0, 0); - } + for (i = 0; i < num_cycles; i++) + { + usbprog_write(1, 0, 0); + usbprog_write(0, 0, 0); + } - /* finish in end_state */ + /* finish in end_state */ /* usbprog_end_state(saved_end_state); if (cur_state != end_state) usbprog_state_move(); - */ + */ } void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) { - enum tap_state saved_end_state = end_state; + enum tap_state saved_end_state = end_state; + int bit_cnt; - if (ir_scan) - usbprog_end_state(TAP_SI); - else - usbprog_end_state(TAP_SD); + if (ir_scan) + usbprog_end_state(TAP_SI); + else + usbprog_end_state(TAP_SD); - usbprog_state_move(); - usbprog_end_state(saved_end_state); + //usbprog_jtag_tms_send(usbprog_jtag_handle); - usbprog_jtag_tms_send(usbprog_jtag_handle); + usbprog_state_move(); + usbprog_end_state(saved_end_state); - if (type == SCAN_OUT) { - usbprog_jtag_write_tdi(usbprog_jtag_handle, (char*)buffer, scan_size); - } - if (type == SCAN_IN) { - usbprog_jtag_read_tdo(usbprog_jtag_handle, (char*)buffer, scan_size); - } - if (type == SCAN_IO) { - usbprog_jtag_write_and_read(usbprog_jtag_handle, (char*)buffer, scan_size); - } + usbprog_jtag_tms_send(usbprog_jtag_handle); - if (ir_scan) - cur_state = TAP_PI; - else - cur_state = TAP_PD; + if (type == SCAN_OUT) { + usbprog_jtag_write_tdi(usbprog_jtag_handle,buffer, scan_size); + } + if (type == SCAN_IN) { + usbprog_jtag_read_tdo(usbprog_jtag_handle,buffer, scan_size); + } + if (type == SCAN_IO) { + usbprog_jtag_write_and_read(usbprog_jtag_handle,buffer, scan_size); + } + + if (ir_scan) + cur_state = TAP_PI; + else + cur_state = TAP_PD; - if (cur_state != end_state) - usbprog_state_move(); + if (cur_state != end_state) + usbprog_state_move(); } /*************** jtag wrapper functions *********************/ void usbprog_write(int tck, int tms, int tdi) { - unsigned char output_value=0x00; + unsigned char output_value=0x00; - if (tms) - output_value |= (1<descriptor.idVendor == VID && dev->descriptor.idProduct == PID) { tmp->usb_handle = usb_open(dev); - usb_set_configuration (tmp->usb_handle,dev->config[0].bConfigurationValue); + usb_set_configuration (tmp->usb_handle,1); usb_claim_interface(tmp->usb_handle, 0); usb_set_altinterface(tmp->usb_handle,0); return tmp; @@ -452,9 +458,10 @@ void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag) unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen) { int res = usb_bulk_write(usbprog_jtag->usb_handle,3,msg,msglen,100); - if(msg[0]==2) + if(msg[0]==2||msg[0]==1||msg[0]==4||msg[0]==0||msg[0]==6||msg[0]==0x0A||msg[0]==9) return 1; if(res == msglen) { + //INFO("HALLLLOOO %i",(int)msg[0]); res = usb_bulk_read(usbprog_jtag->usb_handle,0x82, msg, 2, 100); if (res > 0) return (unsigned char)msg[1]; @@ -475,11 +482,11 @@ void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag) void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size) { char tmp[64]; // fastes packet size for usb controller - int send_bits, bufindex = 0, fillindex = 0, i, loops; + int send_bits,bufindex=0,fillindex=0,i,j,complete=size,loops; char swap; // 61 byte can be transfered (488 bit) - + while(size > 0) { if(size > 488) { send_bits = 488; @@ -500,15 +507,23 @@ void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffe tmp[3+i]=buffer[bufindex]; bufindex++; } - - usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,64,1000); - - while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 1000) < 1); - - for(i=0;iusb_handle,3,tmp,64,1000)==64) + { + //INFO("HALLLLOOO2 %i",(int)tmp[0]); + usleep(1); + int timeout=0; + while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 1000) < 1){ + timeout++; + if(timeout>10) + break; + } + + for(i=0;i 0) { if(size > 488) { send_bits = 488; @@ -535,10 +550,17 @@ void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int tmp[0] = WRITE_AND_READ; tmp[1] = (char)(send_bits>>8); // high tmp[2] = (char)(send_bits); // low - + usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,3,1000); - - while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 10) < 1); + + //INFO("HALLLLOOO3 %i",(int)tmp[0]); + int timeout=0; + usleep(1); + while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 10) < 1){ + timeout++; + if(timeout>10) + break; + } for(i=0;i 0) { if(size > 488) { send_bits = 488; @@ -561,13 +583,13 @@ void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, in } else { send_bits = size; loops = size/8; - /*if(loops==0)*/ + //if(loops==0) loops++; size = 0; } tmp[0] = WRITE_TDI; - tmp[1] = (char)(send_bits>>8); /* high */ - tmp[2] = (char)(send_bits); /* low */ + tmp[1] = (char)(send_bits>>8); // high + tmp[2] = (char)(send_bits); // low i=0; for(i=0;i < loops ;i++) { @@ -641,6 +663,7 @@ void usbprog_jtag_tms_collect(char tms_scan){ void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag){ int i; + //INFO("TMS SEND"); if(tms_chain_index>0) { char tmp[tms_chain_index+2]; tmp[0] = WRITE_TMS_CHAIN; diff --git a/src/openocd.c b/src/openocd.c index 94dfa8ad6b..26a218b9d1 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -18,7 +18,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#define OPENOCD_VERSION "Open On-Chip Debugger (2007-08-21 18:30 CEST)" +#define OPENOCD_VERSION "Open On-Chip Debugger (2007-08-25 12:00 CEST)" #ifdef HAVE_CONFIG_H #include "config.h" @@ -60,7 +60,8 @@ int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char ** void exit_handler(void) { /* close JTAG interface */ - if (jtag && jtag->quit) jtag->quit(); + if (jtag && jtag->quit) + jtag->quit(); } int main(int argc, char *argv[]) diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index e86a81cd43..4d76bcaf1f 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -214,7 +214,9 @@ 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]; - + u8 field1_out[1]; + u8 field2_out[1]; + DEBUG("%i", ice_reg->addr); jtag_add_end_state(TAP_RTI); @@ -234,7 +236,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) fields[1].device = ice_reg->jtag_info->chain_pos; fields[1].num_bits = 5; - fields[1].out_value = malloc(1); + fields[1].out_value = field1_out; buf_set_u32(fields[1].out_value, 0, 5, reg_addr); fields[1].out_mask = NULL; fields[1].in_value = NULL; @@ -245,7 +247,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) fields[2].device = ice_reg->jtag_info->chain_pos; fields[2].num_bits = 1; - fields[2].out_value = malloc(1); + fields[2].out_value = field2_out; buf_set_u32(fields[2].out_value, 0, 1, 0); fields[2].out_mask = NULL; fields[2].in_value = NULL; @@ -268,9 +270,6 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) jtag_add_dr_scan(3, fields, -1, NULL); - free(fields[1].out_value); - free(fields[2].out_value); - return ERROR_OK; } @@ -280,9 +279,10 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) */ int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size) { - u8 reg_addr = 0x5; scan_field_t fields[3]; - + u8 field1_out[1]; + u8 field2_out[1]; + jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0x2); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); @@ -299,8 +299,8 @@ int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size) fields[1].device = jtag_info->chain_pos; fields[1].num_bits = 5; - fields[1].out_value = malloc(1); - buf_set_u32(fields[1].out_value, 0, 5, reg_addr); + fields[1].out_value = field1_out; + buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_DATA]); fields[1].out_mask = NULL; fields[1].in_value = NULL; fields[1].in_check_value = NULL; @@ -310,7 +310,7 @@ int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size) fields[2].device = jtag_info->chain_pos; fields[2].num_bits = 1; - fields[2].out_value = malloc(1); + fields[2].out_value = field2_out; buf_set_u32(fields[2].out_value, 0, 1, 0); fields[2].out_mask = NULL; fields[2].in_value = NULL; @@ -337,9 +337,6 @@ int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size) size--; } - free(fields[1].out_value); - free(fields[2].out_value); - return jtag_execute_queue(); } @@ -380,7 +377,10 @@ 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]; - + u8 field0_out[4]; + u8 field1_out[1]; + u8 field2_out[1]; + DEBUG("%i: 0x%8.8x", ice_reg->addr, value); jtag_add_end_state(TAP_RTI); @@ -390,7 +390,7 @@ int embeddedice_write_reg(reg_t *reg, u32 value) fields[0].device = ice_reg->jtag_info->chain_pos; fields[0].num_bits = 32; - fields[0].out_value = malloc(4); + fields[0].out_value = field0_out; buf_set_u32(fields[0].out_value, 0, 32, value); fields[0].out_mask = NULL; fields[0].in_value = NULL; @@ -401,7 +401,7 @@ int embeddedice_write_reg(reg_t *reg, u32 value) fields[1].device = ice_reg->jtag_info->chain_pos; fields[1].num_bits = 5; - fields[1].out_value = malloc(1); + fields[1].out_value = field1_out; buf_set_u32(fields[1].out_value, 0, 5, reg_addr); fields[1].out_mask = NULL; fields[1].in_value = NULL; @@ -412,7 +412,7 @@ int embeddedice_write_reg(reg_t *reg, u32 value) fields[2].device = ice_reg->jtag_info->chain_pos; fields[2].num_bits = 1; - fields[2].out_value = malloc(1); + fields[2].out_value = field2_out; buf_set_u32(fields[2].out_value, 0, 1, 1); fields[2].out_mask = NULL; fields[2].in_value = NULL; @@ -423,10 +423,6 @@ int embeddedice_write_reg(reg_t *reg, u32 value) jtag_add_dr_scan(3, fields, -1, NULL); - free(fields[0].out_value); - free(fields[1].out_value); - free(fields[2].out_value); - return ERROR_OK; } @@ -435,3 +431,136 @@ int embeddedice_store_reg(reg_t *reg) return embeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); } +/* send words of 32 bit to the DCC + * we pretend the target is always going to be fast enough + * (relative to the JTAG clock), so we don't need to handshake + */ +int embeddedice_send(arm_jtag_t *jtag_info, u32 *data, u32 size) +{ + scan_field_t fields[3]; + u8 field0_out[4]; + u8 field1_out[1]; + u8 field2_out[1]; + + jtag_add_end_state(TAP_RTI); + arm_jtag_scann(jtag_info, 0x2); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); + + fields[0].device = jtag_info->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = field0_out; + fields[0].out_mask = NULL; + fields[0].in_value = NULL; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = jtag_info->chain_pos; + fields[1].num_bits = 5; + fields[1].out_value = field1_out; + buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_DATA]); + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = jtag_info->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = field2_out; + buf_set_u32(fields[2].out_value, 0, 1, 1); + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + while (size > 0) + { + buf_set_u32(fields[0].out_value, 0, 32, *data); + jtag_add_dr_scan(3, fields, -1, NULL); + + data++; + size--; + } + + /* call to jtag_execute_queue() intentionally omitted */ + return ERROR_OK; +} + +/* wait for DCC control register R/W handshake bit to become active + */ +int embeddedice_handshake(arm_jtag_t *jtag_info, int hsbit, u32 timeout) +{ + scan_field_t fields[3]; + u8 field0_in[4]; + u8 field1_out[1]; + u8 field2_out[1]; + int retval; + int hsact; + struct timeval lap; + struct timeval now; + + if (hsbit == EICE_COMM_CTRL_WBIT) + hsact = 1; + else if (hsbit != EICE_COMM_CTRL_RBIT) + hsact = 0; + else + return ERROR_INVALID_ARGUMENTS; + + jtag_add_end_state(TAP_RTI); + arm_jtag_scann(jtag_info, 0x2); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); + + fields[0].device = jtag_info->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = NULL; + fields[0].out_mask = NULL; + fields[0].in_value = field0_in; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = jtag_info->chain_pos; + fields[1].num_bits = 5; + fields[1].out_value = field1_out; + buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]); + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = jtag_info->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = field2_out; + buf_set_u32(fields[2].out_value, 0, 1, 0); + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + jtag_add_dr_scan(3, fields, -1, NULL); + gettimeofday(&lap, NULL); + do + { + jtag_add_dr_scan(3, fields, -1, NULL); + if ((retval = jtag_execute_queue()) != ERROR_OK) + return retval; + + if (buf_get_u32(field0_in, hsbit, 1) == hsact) + return ERROR_OK; + + gettimeofday(&now, NULL); + } + while ((now.tv_sec-lap.tv_sec)*1000 + (now.tv_usec-lap.tv_usec)/1000 <= timeout); + + return ERROR_TARGET_TIMEOUT; +} diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h index 466854f9d4..9915e49b27 100644 --- a/src/target/embeddedice.h +++ b/src/target/embeddedice.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005, 2006 by Dominic Rath * + * Copyright (C) 2005, 2006 by Dominic Rath * * Dominic.Rath@gmx.de * * * * This program is free software; you can redistribute it and/or modify * @@ -98,5 +98,7 @@ extern int embeddedice_store_reg(reg_t *reg); extern int embeddedice_set_reg(reg_t *reg, u32 value); extern int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf); extern int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size); +extern int embeddedice_send(arm_jtag_t *jtag_info, u32 *data, u32 size); +extern int embeddedice_handshake(arm_jtag_t *jtag_info, int hsbit, u32 timeout); #endif /* EMBEDDED_ICE_H */ diff --git a/src/target/etb.c b/src/target/etb.c index f145f3021b..53f9f30e6d 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -569,17 +569,66 @@ int etb_read_trace(etm_context_t *etm_ctx) free(etm_ctx->trace_data); } - if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) + if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) + etm_ctx->trace_depth = num_frames * 3; + else if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) etm_ctx->trace_depth = num_frames * 2; else etm_ctx->trace_depth = num_frames; - etm_ctx->trace_data= malloc(sizeof(etmv1_trace_data_t) * etm_ctx->trace_depth); + etm_ctx->trace_data = malloc(sizeof(etmv1_trace_data_t) * etm_ctx->trace_depth); for (i = 0, j = 0; i < num_frames; i++) { - if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) + if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) + { + /* trace word j */ + etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; + etm_ctx->trace_data[j].packet = (trace_data[i] & 0x78) >> 3; + etm_ctx->trace_data[j].flags = 0; + if ((trace_data[i] & 0x80) >> 7) + { + etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; + } + if (etm_ctx->trace_data[j].pipestat == STAT_TR) + { + etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7; + etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; + } + + /* trace word j+1 */ + etm_ctx->trace_data[j+1].pipestat = (trace_data[i] & 0x100) >> 8; + etm_ctx->trace_data[j+1].packet = (trace_data[i] & 0x7800) >> 11; + etm_ctx->trace_data[j+1].flags = 0; + if ((trace_data[i] & 0x8000) >> 15) + { + etm_ctx->trace_data[j+1].flags |= ETMV1_TRACESYNC_CYCLE; + } + if (etm_ctx->trace_data[j+1].pipestat == STAT_TR) + { + etm_ctx->trace_data[j+1].pipestat = etm_ctx->trace_data[j+1].packet & 0x7; + etm_ctx->trace_data[j+1].flags |= ETMV1_TRIGGER_CYCLE; + } + + /* trace word j+2 */ + etm_ctx->trace_data[j+2].pipestat = (trace_data[i] & 0x10000) >> 16; + etm_ctx->trace_data[j+2].packet = (trace_data[i] & 0x780000) >> 19; + etm_ctx->trace_data[j+2].flags = 0; + if ((trace_data[i] & 0x800000) >> 23) + { + etm_ctx->trace_data[j+2].flags |= ETMV1_TRACESYNC_CYCLE; + } + if (etm_ctx->trace_data[j+2].pipestat == STAT_TR) + { + etm_ctx->trace_data[j+2].pipestat = etm_ctx->trace_data[j+2].packet & 0x7; + etm_ctx->trace_data[j+2].flags |= ETMV1_TRIGGER_CYCLE; + } + + j += 3; + } + else if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) { + /* trace word j */ etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7f8) >> 3; etm_ctx->trace_data[j].flags = 0; @@ -593,6 +642,7 @@ int etb_read_trace(etm_context_t *etm_ctx) etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; } + /* trace word j+1 */ etm_ctx->trace_data[j+1].pipestat = (trace_data[i] & 0x7000) >> 12; etm_ctx->trace_data[j+1].packet = (trace_data[i] & 0x7f8000) >> 15; etm_ctx->trace_data[j+1].flags = 0; @@ -610,6 +660,7 @@ int etb_read_trace(etm_context_t *etm_ctx) } else { + /* trace word j */ etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7fff8) >> 3; etm_ctx->trace_data[j].flags = 0; @@ -640,9 +691,9 @@ int etb_start_capture(etm_context_t *etm_ctx) if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) { - if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_16BIT) + if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) != ETM_PORT_8BIT) { - DEBUG("ETB can't run in demultiplexed mode with a 16-bit port"); + ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port"); return ERROR_ETM_PORTMODE_NOT_SUPPORTED; } etb_ctrl_value |= 0x2; -- 2.30.2