X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fzy1000%2Fzy1000.c;h=22193abd2c74afe84890104e830f1eb27d860220;hp=c8bee2f506292c282f03e4cb1271ebb7712b76fe;hb=4668bd264cfe64c3e3ddd0f75cb5bf2e5e85f717;hpb=6468c593c7ece11aa7735d8d6aa9a546b9505cc3 diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index c8bee2f506..22193abd2c 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -45,6 +45,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -170,6 +172,45 @@ static int zy1000_power_dropout(int *dropout) return ERROR_OK; } +/* Wait for SRST to assert or deassert */ +static void waitSRST(bool asserted) +{ + bool first = true; + long long start = 0; + long total = 0; + const char *mode = asserted ? "assert" : "deassert"; + + for (;;) + { + bool srstAsserted = readSRST(); + if ( (asserted && srstAsserted) || (!asserted && !srstAsserted) ) + { + if (total > 1) + { + LOG_USER("SRST took %dms to %s", (int)total, mode); + } + break; + } + + if (first) + { + first = false; + start = timeval_ms(); + } + + total = timeval_ms() - start; + + keep_alive(); + + if (total > 5000) + { + LOG_ERROR("SRST took too long to %s: %dms", mode, (int)total); + break; + } + } +} + + void zy1000_reset(int trst, int srst) { LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst); @@ -190,6 +231,8 @@ void zy1000_reset(int trst, int srst) * idle in TAP_IDLE, reset halt on str912 will fail. */ ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000001); + + waitSRST(true); } if (!trst) @@ -216,40 +259,7 @@ void zy1000_reset(int trst, int srst) if ((!srst && ((jtag_get_reset_config() & RESET_TRST_PULLS_SRST) == 0))|| (!srst && !trst && (jtag_get_reset_config() & RESET_TRST_PULLS_SRST))) { - bool first = true; - long long start = 0; - long total = 0; - for (;;) - { - // We don't want to sense our own reset, so we clear here. - // There is of course a timing hole where we could loose - // a "real" reset. - if (!readSRST()) - { - if (total > 1) - { - LOG_USER("SRST took %dms to deassert", (int)total); - } - break; - } - - if (first) - { - first = false; - start = timeval_ms(); - } - - total = timeval_ms() - start; - - keep_alive(); - - if (total > 5000) - { - LOG_ERROR("SRST took too long to deassert: %dms", (int)total); - break; - } - } - + waitSRST(false); } } @@ -273,7 +283,7 @@ int zy1000_speed(int speed) { LOG_USER("valid ZY1000 jtag_speed=[8190,2]. With divisor is %dkHz / even values between 8190-2, i.e. min %dHz, max %dMHz", ZYLIN_KHZ, (ZYLIN_KHZ * 1000) / 8190, ZYLIN_KHZ / (2 * 1000)); - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } int khz; @@ -315,7 +325,7 @@ COMMAND_HANDLER(handle_power_command) LOG_INFO("Target power %s", savePower ? "on" : "off"); break; default: - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } return ERROR_OK; @@ -438,24 +448,10 @@ struct cyg_upgrade_info firmware_info = report_info, }; +// File written to /ram/firmware.phi before arriving at this fn static int jim_zy1000_writefirmware(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2) - return JIM_ERR; - - int length; - const char *str = Jim_GetString(argv[1], &length); - - /* */ - int tmpFile; - if ((tmpFile = open(firmware_info.file, O_RDWR | O_CREAT | O_TRUNC)) <= 0) - { - return JIM_ERR; - } - bool success; - success = write(tmpFile, str, length) == length; - close(tmpFile); - if (!success) + if (argc != 1) return JIM_ERR; if (!cyg_firmware_upgrade(NULL, firmware_info)) @@ -622,6 +618,11 @@ int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field assert(scan_size <= 32); shiftValueInner(TAP_IRSHIFT, pause_state, scan_size, 0xffffffff); + /* Optimization code will check what the cur_instr is set to, so + * we must set it to bypass value. + */ + buf_set_ones(tap->cur_instr, tap->ir_length); + tap->bypass = 1; } } @@ -852,7 +853,7 @@ static void jtag_pre_post_bits(struct jtag_tap *tap, int *pre, int *post) TAP_IDLE); */ -void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count) +void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer, int little, int count) { #if 0 int i; @@ -894,7 +895,7 @@ 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) +int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, const uint32_t * data, size_t count) { /* bypass bits before and after */ int pre_bits; @@ -904,7 +905,7 @@ int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opc if ((pre_bits > 32) || (post_bits > 32)) { - int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *, uint32_t, uint32_t *, size_t); + int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *, uint32_t, const uint32_t *, size_t); return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); } else { @@ -1040,7 +1041,8 @@ static const struct command_registration zy1000_commands[] = { }; -#if !BUILD_ZY1000_MASTER || BUILD_ECOSBOARD +#if !BUILD_ZY1000_MASTER + static int tcp_ip = -1; /* Write large packets if we can */ @@ -1077,14 +1079,6 @@ static bool writeLong(uint32_t l) static bool readLong(uint32_t *out_data) { - if (out_pos > 0) - { - if (!flush_writes()) - { - return false; - } - } - uint32_t data = 0; int i; for (i = 0; i < 4; i++) @@ -1092,6 +1086,17 @@ static bool readLong(uint32_t *out_data) uint8_t c; if (in_pos == in_write) { + /* If we have some data that we can send, send them before + * we wait for more data + */ + if (out_pos > 0) + { + if (!flush_writes()) + { + return false; + } + } + /* read more */ int t; t = read(tcp_ip, in_buffer, sizeof(in_buffer)); @@ -1109,7 +1114,6 @@ static bool readLong(uint32_t *out_data) *out_data = data; return true; } -#endif enum ZY1000_CMD { @@ -1119,9 +1123,6 @@ enum ZY1000_CMD ZY1000_CMD_WAITIDLE = 2 }; - -#if !BUILD_ZY1000_MASTER - #include /* for socket(), connect(), send(), and recv() */ #include /* for sockaddr_in and inet_addr() */ @@ -1295,6 +1296,15 @@ void zy1000_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t da callbackqueue[callbackqueue_pos].data2 = data2; callbackqueue[callbackqueue_pos].data3 = data3; callbackqueue_pos++; + + /* KLUDGE! + * make callbacks synchronous for now as minidriver requires callback + * to be synchronous. + * + * We can get away with making read and writes asynchronous so we + * don't completely kill performance. + */ + zy1000_flush_callbackqueue(); } static int zy1000_jtag_convert_to_callback4(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) @@ -1341,6 +1351,9 @@ static void writeShiftValue(uint8_t *data, int bits) readqueue[readqueue_pos].dest = data; readqueue[readqueue_pos].bits = bits; readqueue_pos++; + + /* KLUDGE!!! minidriver requires readqueue to be synchronous */ + zy1000_flush_readqueue(); } #else @@ -1364,129 +1377,13 @@ static void writeShiftValue(uint8_t *data, int bits) #endif -#if BUILD_ECOSBOARD -static char tcpip_stack[2048]; -static cyg_thread tcpip_thread_object; -static cyg_handle_t tcpip_thread_handle; +#if BUILD_ZY1000_MASTER +#if BUILD_ECOSBOARD static char watchdog_stack[2048]; static cyg_thread watchdog_thread_object; static cyg_handle_t watchdog_thread_handle; - -/* Infinite loop peeking & poking */ -static void tcpipserver(void) -{ - for (;;) - { - uint32_t address; - if (!readLong(&address)) - return; - enum ZY1000_CMD c = (address >> 24) & 0xff; - address &= 0xffffff; - switch (c) - { - case ZY1000_CMD_POKE: - { - uint32_t data; - if (!readLong(&data)) - return; - address &= ~0x80000000; - ZY1000_POKE(address + ZY1000_JTAG_BASE, data); - break; - } - case ZY1000_CMD_PEEK: - { - uint32_t data; - ZY1000_PEEK(address + ZY1000_JTAG_BASE, data); - if (!writeLong(data)) - return; - break; - } - case ZY1000_CMD_SLEEP: - { - uint32_t data; - if (!readLong(&data)) - return; - jtag_sleep(data); - break; - } - case ZY1000_CMD_WAITIDLE: - { - waitIdle(); - break; - } - default: - return; - } - } -} - - -static void tcpip_server(cyg_addrword_t data) -{ - int so_reuseaddr_option = 1; - - int fd; - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) - { - LOG_ERROR("error creating socket: %s", strerror(errno)); - exit(-1); - } - - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option, - sizeof(int)); - - struct sockaddr_in sin; - unsigned int address_size; - address_size = sizeof(sin); - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(7777); - - if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1) - { - LOG_ERROR("couldn't bind to socket: %s", strerror(errno)); - exit(-1); - } - - if (listen(fd, 1) == -1) - { - LOG_ERROR("couldn't listen on socket: %s", strerror(errno)); - exit(-1); - } - - - for (;;) - { - tcp_ip = accept(fd, (struct sockaddr *) &sin, &address_size); - if (tcp_ip < 0) - { - continue; - } - - int flag = 1; - setsockopt(tcp_ip, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char *)&flag, /* the cast is historical cruft */ - sizeof(int)); /* length of option value */ - - bool save_poll = jtag_poll_get_enabled(); - - /* polling will screw up the "connection" */ - jtag_poll_set_enabled(false); - - tcpipserver(); - - jtag_poll_set_enabled(save_poll); - - close(tcp_ip); - - } - close(fd); - -} +#endif #ifdef WATCHDOG_BASE /* If we connect to port 8888 we must send a char every 10s or the board resets itself */ @@ -1620,20 +1517,16 @@ int zy1000_init(void) /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */ zy1000_reset(0, 0); - zy1000_speed(jtag_get_speed()); - +#if BUILD_ZY1000_MASTER #if BUILD_ECOSBOARD - cyg_thread_create(1, tcpip_server, (cyg_addrword_t) 0, "tcip/ip server", - (void *) tcpip_stack, sizeof(tcpip_stack), - &tcpip_thread_handle, &tcpip_thread_object); - cyg_thread_resume(tcpip_thread_handle); #ifdef WATCHDOG_BASE cyg_thread_create(1, watchdog_server, (cyg_addrword_t) 0, "watchdog tcip/ip server", (void *) watchdog_stack, sizeof(watchdog_stack), &watchdog_thread_handle, &watchdog_thread_object); cyg_thread_resume(watchdog_thread_handle); #endif +#endif #endif return ERROR_OK;