debug-feature: jtagtcpip, improve jtag performance
[openocd.git] / src / jtag / zy1000 / zy1000.c
1 /***************************************************************************
2 * Copyright (C) 2007-2010 by Øyvind Harboe *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 /* This file supports the zy1000 debugger: http://www.zylin.com/zy1000.html
21 *
22 * The zy1000 is a standalone debugger that has a web interface and
23 * requires no drivers on the developer host as all communication
24 * is via TCP/IP. The zy1000 gets it performance(~400-700kBytes/s
25 * DCC downloads @ 16MHz target) as it has an FPGA to hardware
26 * accelerate the JTAG commands, while offering *very* low latency
27 * between OpenOCD and the FPGA registers.
28 *
29 * The disadvantage of the zy1000 is that it has a feeble CPU compared to
30 * a PC(ca. 50-500 DMIPS depending on how one counts it), whereas a PC
31 * is on the order of 10000 DMIPS(i.e. at a factor of 20-200).
32 *
33 * The zy1000 revc hardware is using an Altera Nios CPU, whereas the
34 * revb is using ARM7 + Xilinx.
35 *
36 * See Zylin web pages or contact Zylin for more information.
37 *
38 * The reason this code is in OpenOCD rather than OpenOCD linked with the
39 * ZY1000 code is that OpenOCD is the long road towards getting
40 * libopenocd into place. libopenocd will support both low performance,
41 * low latency systems(embedded) and high performance high latency
42 * systems(PCs).
43 */
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47
48 #include <target/embeddedice.h>
49 #include <jtag/minidriver.h>
50 #include <jtag/interface.h>
51 #include <time.h>
52 #include <helper/time_support.h>
53
54 #include <netinet/tcp.h>
55
56 #if BUILD_ECOSBOARD
57 #include "zy1000_version.h"
58
59 #include <cyg/hal/hal_io.h> // low level i/o
60 #include <cyg/hal/hal_diag.h>
61
62 #ifdef CYGPKG_HAL_NIOS2
63 #include <cyg/hal/io.h>
64 #include <cyg/firmwareutil/firmwareutil.h>
65 #endif
66
67 #define ZYLIN_VERSION GIT_ZY1000_VERSION
68 #define ZYLIN_DATE __DATE__
69 #define ZYLIN_TIME __TIME__
70 #define ZYLIN_OPENOCD GIT_OPENOCD_VERSION
71 #define ZYLIN_OPENOCD_VERSION "ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE
72
73 #endif
74
75
76 /* The software needs to check if it's in RCLK mode or not */
77 static bool zy1000_rclk = false;
78
79 static int zy1000_khz(int khz, int *jtag_speed)
80 {
81 if (khz == 0)
82 {
83 *jtag_speed = 0;
84 }
85 else
86 {
87 *jtag_speed = 64000/khz;
88 }
89 return ERROR_OK;
90 }
91
92 static int zy1000_speed_div(int speed, int *khz)
93 {
94 if (speed == 0)
95 {
96 *khz = 0;
97 }
98 else
99 {
100 *khz = 64000/speed;
101 }
102
103 return ERROR_OK;
104 }
105
106 static bool readPowerDropout(void)
107 {
108 uint32_t state;
109 // sample and clear power dropout
110 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x80);
111 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state);
112 bool powerDropout;
113 powerDropout = (state & 0x80) != 0;
114 return powerDropout;
115 }
116
117
118 static bool readSRST(void)
119 {
120 uint32_t state;
121 // sample and clear SRST sensing
122 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000040);
123 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state);
124 bool srstAsserted;
125 srstAsserted = (state & 0x40) != 0;
126 return srstAsserted;
127 }
128
129 static int zy1000_srst_asserted(int *srst_asserted)
130 {
131 *srst_asserted = readSRST();
132 return ERROR_OK;
133 }
134
135 static int zy1000_power_dropout(int *dropout)
136 {
137 *dropout = readPowerDropout();
138 return ERROR_OK;
139 }
140
141 void zy1000_reset(int trst, int srst)
142 {
143 LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
144
145 /* flush the JTAG FIFO. Not flushing the queue before messing with
146 * reset has such interesting bugs as causing hard to reproduce
147 * RCLK bugs as RCLK will stop responding when TRST is asserted
148 */
149 waitIdle();
150
151 if (!srst)
152 {
153 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000001);
154 }
155 else
156 {
157 /* Danger!!! if clk != 0 when in
158 * idle in TAP_IDLE, reset halt on str912 will fail.
159 */
160 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000001);
161 }
162
163 if (!trst)
164 {
165 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000002);
166 }
167 else
168 {
169 /* assert reset */
170 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000002);
171 }
172
173 if (trst||(srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
174 {
175 /* we're now in the RESET state until trst is deasserted */
176 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_RESET);
177 } else
178 {
179 /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
180 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400);
181 }
182
183 /* wait for srst to float back up */
184 if ((!srst && ((jtag_get_reset_config() & RESET_TRST_PULLS_SRST) == 0))||
185 (!srst && !trst && (jtag_get_reset_config() & RESET_TRST_PULLS_SRST)))
186 {
187 bool first = true;
188 long long start = 0;
189 long total = 0;
190 for (;;)
191 {
192 // We don't want to sense our own reset, so we clear here.
193 // There is of course a timing hole where we could loose
194 // a "real" reset.
195 if (!readSRST())
196 {
197 if (total > 1)
198 {
199 LOG_USER("SRST took %dms to deassert", (int)total);
200 }
201 break;
202 }
203
204 if (first)
205 {
206 first = false;
207 start = timeval_ms();
208 }
209
210 total = timeval_ms() - start;
211
212 keep_alive();
213
214 if (total > 5000)
215 {
216 LOG_ERROR("SRST took too long to deassert: %dms", (int)total);
217 break;
218 }
219 }
220
221 }
222 }
223
224 int zy1000_speed(int speed)
225 {
226 /* flush JTAG master FIFO before setting speed */
227 waitIdle();
228
229 zy1000_rclk = false;
230
231 if (speed == 0)
232 {
233 /*0 means RCLK*/
234 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x100);
235 zy1000_rclk = true;
236 LOG_DEBUG("jtag_speed using RCLK");
237 }
238 else
239 {
240 if (speed > 8190 || speed < 2)
241 {
242 LOG_USER("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");
243 return ERROR_INVALID_ARGUMENTS;
244 }
245
246 LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);
247 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x100);
248 ZY1000_POKE(ZY1000_JTAG_BASE + 0x1c, speed&~1);
249 }
250 return ERROR_OK;
251 }
252
253 static bool savePower;
254
255
256 static void setPower(bool power)
257 {
258 savePower = power;
259 if (power)
260 {
261 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x8);
262 } else
263 {
264 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x8);
265 }
266 }
267
268 COMMAND_HANDLER(handle_power_command)
269 {
270 switch (CMD_ARGC)
271 {
272 case 1: {
273 bool enable;
274 COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
275 setPower(enable);
276 // fall through
277 }
278 case 0:
279 LOG_INFO("Target power %s", savePower ? "on" : "off");
280 break;
281 default:
282 return ERROR_INVALID_ARGUMENTS;
283 }
284
285 return ERROR_OK;
286 }
287
288 #if !BUILD_ECOSBOARD
289 static char *tcp_server = "notspecified";
290 static int jim_zy1000_server(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
291 {
292 if (argc != 2)
293 return JIM_ERR;
294
295 tcp_server = strdup(Jim_GetString(argv[1], NULL));
296
297 return JIM_OK;
298 }
299 #endif
300
301 #if BUILD_ECOSBOARD
302 /* Give TELNET a way to find out what version this is */
303 static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
304 {
305 if ((argc < 1) || (argc > 3))
306 return JIM_ERR;
307 const char *version_str = NULL;
308
309 if (argc == 1)
310 {
311 version_str = ZYLIN_OPENOCD_VERSION;
312 } else
313 {
314 const char *str = Jim_GetString(argv[1], NULL);
315 const char *str2 = NULL;
316 if (argc > 2)
317 str2 = Jim_GetString(argv[2], NULL);
318 if (strcmp("openocd", str) == 0)
319 {
320 version_str = ZYLIN_OPENOCD;
321 }
322 else if (strcmp("zy1000", str) == 0)
323 {
324 version_str = ZYLIN_VERSION;
325 }
326 else if (strcmp("date", str) == 0)
327 {
328 version_str = ZYLIN_DATE;
329 }
330 else if (strcmp("time", str) == 0)
331 {
332 version_str = ZYLIN_TIME;
333 }
334 else if (strcmp("pcb", str) == 0)
335 {
336 #ifdef CYGPKG_HAL_NIOS2
337 version_str="c";
338 #else
339 version_str="b";
340 #endif
341 }
342 #ifdef CYGPKG_HAL_NIOS2
343 else if (strcmp("fpga", str) == 0)
344 {
345
346 /* return a list of 32 bit integers to describe the expected
347 * and actual FPGA
348 */
349 static char *fpga_id = "0x12345678 0x12345678 0x12345678 0x12345678";
350 uint32_t id, timestamp;
351 HAL_READ_UINT32(SYSID_BASE, id);
352 HAL_READ_UINT32(SYSID_BASE+4, timestamp);
353 sprintf(fpga_id, "0x%08x 0x%08x 0x%08x 0x%08x", id, timestamp, SYSID_ID, SYSID_TIMESTAMP);
354 version_str = fpga_id;
355 if ((argc>2) && (strcmp("time", str2) == 0))
356 {
357 time_t last_mod = timestamp;
358 char * t = ctime (&last_mod) ;
359 t[strlen(t)-1] = 0;
360 version_str = t;
361 }
362 }
363 #endif
364
365 else
366 {
367 return JIM_ERR;
368 }
369 }
370
371 Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1));
372
373 return JIM_OK;
374 }
375 #endif
376
377 #ifdef CYGPKG_HAL_NIOS2
378
379
380 struct info_forward
381 {
382 void *data;
383 struct cyg_upgrade_info *upgraded_file;
384 };
385
386 static void report_info(void *data, const char * format, va_list args)
387 {
388 char *s = alloc_vprintf(format, args);
389 LOG_USER_N("%s", s);
390 free(s);
391 }
392
393 struct cyg_upgrade_info firmware_info =
394 {
395 (uint8_t *)0x84000000,
396 "/ram/firmware.phi",
397 "Firmware",
398 0x0300000,
399 0x1f00000 -
400 0x0300000,
401 "ZylinNiosFirmware\n",
402 report_info,
403 };
404
405 static int jim_zy1000_writefirmware(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
406 {
407 if (argc != 2)
408 return JIM_ERR;
409
410 int length;
411 const char *str = Jim_GetString(argv[1], &length);
412
413 /* */
414 int tmpFile;
415 if ((tmpFile = open(firmware_info.file, O_RDWR | O_CREAT | O_TRUNC)) <= 0)
416 {
417 return JIM_ERR;
418 }
419 bool success;
420 success = write(tmpFile, str, length) == length;
421 close(tmpFile);
422 if (!success)
423 return JIM_ERR;
424
425 if (!cyg_firmware_upgrade(NULL, firmware_info))
426 return JIM_ERR;
427
428 return JIM_OK;
429 }
430 #endif
431
432 static int
433 zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp,
434 int argc,
435 Jim_Obj * const *argv)
436 {
437 if (argc != 1)
438 {
439 Jim_WrongNumArgs(interp, 1, argv, "powerstatus");
440 return JIM_ERR;
441 }
442
443 bool dropout = readPowerDropout();
444
445 Jim_SetResult(interp, Jim_NewIntObj(interp, dropout));
446
447 return JIM_OK;
448 }
449
450
451
452 int zy1000_quit(void)
453 {
454
455 return ERROR_OK;
456 }
457
458
459
460 int interface_jtag_execute_queue(void)
461 {
462 uint32_t empty;
463
464 waitIdle();
465
466 /* We must make sure to write data read back to memory location before we return
467 * from this fn
468 */
469 zy1000_flush_readqueue();
470
471 /* and handle any callbacks... */
472 zy1000_flush_callbackqueue();
473
474 if (zy1000_rclk)
475 {
476 /* Only check for errors when using RCLK to speed up
477 * jtag over TCP/IP
478 */
479 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
480 /* clear JTAG error register */
481 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400);
482
483 if ((empty&0x400) != 0)
484 {
485 LOG_WARNING("RCLK timeout");
486 /* the error is informative only as we don't want to break the firmware if there
487 * is a false positive.
488 */
489 // return ERROR_FAIL;
490 }
491 }
492 return ERROR_OK;
493 }
494
495
496
497
498 static void writeShiftValue(uint8_t *data, int bits);
499
500 // here we shuffle N bits out/in
501 static __inline void scanBits(const uint8_t *out_value, uint8_t *in_value, int num_bits, bool pause_now, tap_state_t shiftState, tap_state_t end_state)
502 {
503 tap_state_t pause_state = shiftState;
504 for (int j = 0; j < num_bits; j += 32)
505 {
506 int k = num_bits - j;
507 if (k > 32)
508 {
509 k = 32;
510 /* we have more to shift out */
511 } else if (pause_now)
512 {
513 /* this was the last to shift out this time */
514 pause_state = end_state;
515 }
516
517 // we have (num_bits + 7)/8 bytes of bits to toggle out.
518 // bits are pushed out LSB to MSB
519 uint32_t value;
520 value = 0;
521 if (out_value != NULL)
522 {
523 for (int l = 0; l < k; l += 8)
524 {
525 value|=out_value[(j + l)/8]<<l;
526 }
527 }
528 /* mask away unused bits for easier debugging */
529 if (k < 32)
530 {
531 value&=~(((uint32_t)0xffffffff) << k);
532 } else
533 {
534 /* Shifting by >= 32 is not defined by the C standard
535 * and will in fact shift by &0x1f bits on nios */
536 }
537
538 shiftValueInner(shiftState, pause_state, k, value);
539
540 if (in_value != NULL)
541 {
542 writeShiftValue(in_value + (j/8), k);
543 }
544 }
545 }
546
547 static __inline void scanFields(int num_fields, const struct scan_field *fields, tap_state_t shiftState, tap_state_t end_state)
548 {
549 for (int i = 0; i < num_fields; i++)
550 {
551 scanBits(fields[i].out_value,
552 fields[i].in_value,
553 fields[i].num_bits,
554 (i == num_fields-1),
555 shiftState,
556 end_state);
557 }
558 }
559
560 int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field *fields, tap_state_t state)
561 {
562 int scan_size = 0;
563 struct jtag_tap *tap, *nextTap;
564 tap_state_t pause_state = TAP_IRSHIFT;
565
566 for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
567 {
568 nextTap = jtag_tap_next_enabled(tap);
569 if (nextTap==NULL)
570 {
571 pause_state = state;
572 }
573 scan_size = tap->ir_length;
574
575 /* search the list */
576 if (tap == active)
577 {
578 scanFields(1, fields, TAP_IRSHIFT, pause_state);
579 /* update device information */
580 buf_cpy(fields[0].out_value, tap->cur_instr, scan_size);
581
582 tap->bypass = 0;
583 } else
584 {
585 /* if a device isn't listed, set it to BYPASS */
586 assert(scan_size <= 32);
587 shiftValueInner(TAP_IRSHIFT, pause_state, scan_size, 0xffffffff);
588
589 tap->bypass = 1;
590 }
591 }
592
593 return ERROR_OK;
594 }
595
596
597
598
599
600 int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
601 {
602 scanBits(out_bits, in_bits, num_bits, true, TAP_IRSHIFT, state);
603 return ERROR_OK;
604 }
605
606 int interface_jtag_add_dr_scan(struct jtag_tap *active, int num_fields, const struct scan_field *fields, tap_state_t state)
607 {
608 struct jtag_tap *tap, *nextTap;
609 tap_state_t pause_state = TAP_DRSHIFT;
610 for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
611 {
612 nextTap = jtag_tap_next_enabled(tap);
613 if (nextTap==NULL)
614 {
615 pause_state = state;
616 }
617
618 /* Find a range of fields to write to this tap */
619 if (tap == active)
620 {
621 assert(!tap->bypass);
622
623 scanFields(num_fields, fields, TAP_DRSHIFT, pause_state);
624 } else
625 {
626 /* Shift out a 0 for disabled tap's */
627 assert(tap->bypass);
628 shiftValueInner(TAP_DRSHIFT, pause_state, 1, 0);
629 }
630 }
631 return ERROR_OK;
632 }
633
634 int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)
635 {
636 scanBits(out_bits, in_bits, num_bits, true, TAP_DRSHIFT, state);
637 return ERROR_OK;
638 }
639
640 int interface_jtag_add_tlr()
641 {
642 setCurrentState(TAP_RESET);
643 return ERROR_OK;
644 }
645
646
647 int interface_jtag_add_reset(int req_trst, int req_srst)
648 {
649 zy1000_reset(req_trst, req_srst);
650 return ERROR_OK;
651 }
652
653 static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate)
654 {
655 /* num_cycles can be 0 */
656 setCurrentState(clockstate);
657
658 /* execute num_cycles, 32 at the time. */
659 int i;
660 for (i = 0; i < num_cycles; i += 32)
661 {
662 int num;
663 num = 32;
664 if (num_cycles-i < num)
665 {
666 num = num_cycles-i;
667 }
668 shiftValueInner(clockstate, clockstate, num, 0);
669 }
670
671 #if !TEST_MANUAL()
672 /* finish in end_state */
673 setCurrentState(state);
674 #else
675 tap_state_t t = TAP_IDLE;
676 /* test manual drive code on any target */
677 int tms;
678 uint8_t tms_scan = tap_get_tms_path(t, state);
679 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
680
681 for (i = 0; i < tms_count; i++)
682 {
683 tms = (tms_scan >> i) & 1;
684 waitIdle();
685 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms);
686 }
687 waitIdle();
688 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state);
689 #endif
690
691 return ERROR_OK;
692 }
693
694 int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
695 {
696 return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE);
697 }
698
699 int interface_jtag_add_clocks(int num_cycles)
700 {
701 return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_cur_state);
702 }
703
704 int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
705 {
706 /*wait for the fifo to be empty*/
707 waitIdle();
708
709 for (unsigned i = 0; i < num_bits; i++)
710 {
711 int tms;
712
713 if (((seq[i/8] >> (i % 8)) & 1) == 0)
714 {
715 tms = 0;
716 }
717 else
718 {
719 tms = 1;
720 }
721
722 waitIdle();
723 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms);
724 }
725
726 waitIdle();
727 if (state != TAP_INVALID)
728 {
729 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state);
730 } else
731 {
732 /* this would be normal if we are switching to SWD mode */
733 }
734 return ERROR_OK;
735 }
736
737 int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
738 {
739 int state_count;
740 int tms = 0;
741
742 state_count = 0;
743
744 tap_state_t cur_state = cmd_queue_cur_state;
745
746 uint8_t seq[16];
747 memset(seq, 0, sizeof(seq));
748 assert(num_states < (int)((sizeof(seq) * 8)));
749
750 while (num_states)
751 {
752 if (tap_state_transition(cur_state, false) == path[state_count])
753 {
754 tms = 0;
755 }
756 else if (tap_state_transition(cur_state, true) == path[state_count])
757 {
758 tms = 1;
759 }
760 else
761 {
762 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[state_count]));
763 exit(-1);
764 }
765
766 seq[state_count/8] = seq[state_count/8] | (tms << (state_count % 8));
767
768 cur_state = path[state_count];
769 state_count++;
770 num_states--;
771 }
772
773 return interface_add_tms_seq(state_count, seq, cur_state);
774 }
775
776 static void jtag_pre_post_bits(struct jtag_tap *tap, int *pre, int *post)
777 {
778 /* bypass bits before and after */
779 int pre_bits = 0;
780 int post_bits = 0;
781
782 bool found = false;
783 struct jtag_tap *cur_tap, *nextTap;
784 for (cur_tap = jtag_tap_next_enabled(NULL); cur_tap!= NULL; cur_tap = nextTap)
785 {
786 nextTap = jtag_tap_next_enabled(cur_tap);
787 if (cur_tap == tap)
788 {
789 found = true;
790 } else
791 {
792 if (found)
793 {
794 post_bits++;
795 } else
796 {
797 pre_bits++;
798 }
799 }
800 }
801 *pre = pre_bits;
802 *post = post_bits;
803 }
804
805 /*
806 static const int embeddedice_num_bits[] = {32, 6};
807 uint32_t values[2];
808
809 values[0] = value;
810 values[1] = (1 << 5) | reg_addr;
811
812 jtag_add_dr_out(tap,
813 2,
814 embeddedice_num_bits,
815 values,
816 TAP_IDLE);
817 */
818
819 void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
820 {
821 #if 0
822 int i;
823 for (i = 0; i < count; i++)
824 {
825 embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little));
826 buffer += 4;
827 }
828 #else
829 int pre_bits;
830 int post_bits;
831 jtag_pre_post_bits(tap, &pre_bits, &post_bits);
832
833 if ((pre_bits > 32) || (post_bits + 6 > 32))
834 {
835 int i;
836 for (i = 0; i < count; i++)
837 {
838 embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little));
839 buffer += 4;
840 }
841 } else
842 {
843 int i;
844 for (i = 0; i < count; i++)
845 {
846 /* Fewer pokes means we get to use the FIFO more efficiently */
847 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0);
848 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, little));
849 /* Danger! here we need to exit into the TAP_IDLE state to make
850 * DCC pick up this value.
851 */
852 shiftValueInner(TAP_DRSHIFT, TAP_IDLE, 6 + post_bits, (reg_addr | (1 << 5)));
853 buffer += 4;
854 }
855 }
856 #endif
857 }
858
859
860
861 int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count)
862 {
863 /* bypass bits before and after */
864 int pre_bits;
865 int post_bits;
866 jtag_pre_post_bits(tap, &pre_bits, &post_bits);
867 post_bits+=2;
868
869 if ((pre_bits > 32) || (post_bits > 32))
870 {
871 int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *, uint32_t, uint32_t *, size_t);
872 return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count);
873 } else
874 {
875 static const int bits[] = {32, 2};
876 uint32_t values[] = {0, 0};
877
878 /* FIX!!!!!! the target_write_memory() API started this nasty problem
879 * with unaligned uint32_t * pointers... */
880 const uint8_t *t = (const uint8_t *)data;
881
882 while (--count > 0)
883 {
884 #if 1
885 /* Danger! This code doesn't update cmd_queue_cur_state, so
886 * invoking jtag_add_pathmove() before jtag_add_dr_out() after
887 * this loop would fail!
888 */
889 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0);
890
891 uint32_t value;
892 value = *t++;
893 value |= (*t++<<8);
894 value |= (*t++<<16);
895 value |= (*t++<<24);
896
897 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, value);
898 /* minimum 2 bits */
899 shiftValueInner(TAP_DRSHIFT, TAP_DRPAUSE, post_bits, 0);
900
901 /* copy & paste from arm11_dbgtap.c */
902 //TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
903 /* KLUDGE! we have to flush the fifo or the Nios CPU locks up.
904 * This is probably a bug in the Avalon bus(cross clocking bridge?)
905 * or in the jtag registers module.
906 */
907 waitIdle();
908 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1);
909 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1);
910 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
911 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
912 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
913 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1);
914 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
915 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0);
916 /* we don't have to wait for the queue to empty here */
917 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT);
918 waitIdle();
919 #else
920 static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] =
921 {
922 TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
923 };
924
925 values[0] = *t++;
926 values[0] |= (*t++<<8);
927 values[0] |= (*t++<<16);
928 values[0] |= (*t++<<24);
929
930 jtag_add_dr_out(tap,
931 2,
932 bits,
933 values,
934 TAP_IDLE);
935
936 jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay),
937 arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay);
938 #endif
939 }
940
941 values[0] = *t++;
942 values[0] |= (*t++<<8);
943 values[0] |= (*t++<<16);
944 values[0] |= (*t++<<24);
945
946 /* This will happen on the last iteration updating cmd_queue_cur_state
947 * so we don't have to track it during the common code path
948 */
949 jtag_add_dr_out(tap,
950 2,
951 bits,
952 values,
953 TAP_IDLE);
954
955 return jtag_execute_queue();
956 }
957 }
958
959
960 static const struct command_registration zy1000_commands[] = {
961 {
962 .name = "power",
963 .handler = handle_power_command,
964 .mode = COMMAND_ANY,
965 .help = "Turn power switch to target on/off. "
966 "With no arguments, prints status.",
967 .usage = "('on'|'off)",
968 },
969 #if BUILD_ECOSBOARD
970 {
971 .name = "zy1000_version",
972 .mode = COMMAND_ANY,
973 .jim_handler = jim_zy1000_version,
974 .help = "Print version info for zy1000.",
975 .usage = "['openocd'|'zy1000'|'date'|'time'|'pcb'|'fpga']",
976 },
977 #else
978 {
979 .name = "zy1000_server",
980 .mode = COMMAND_ANY,
981 .jim_handler = jim_zy1000_server,
982 .help = "Tcpip address for ZY1000 server.",
983 .usage = "address",
984 },
985 #endif
986 {
987 .name = "powerstatus",
988 .mode = COMMAND_ANY,
989 .jim_handler = zylinjtag_Jim_Command_powerstatus,
990 .help = "Returns power status of target",
991 },
992 #ifdef CYGPKG_HAL_NIOS2
993 {
994 .name = "updatezy1000firmware",
995 .mode = COMMAND_ANY,
996 .jim_handler = jim_zy1000_writefirmware,
997 .help = "writes firmware to flash",
998 /* .usage = "some_string", */
999 },
1000 #endif
1001 COMMAND_REGISTRATION_DONE
1002 };
1003
1004
1005 static int tcp_ip = -1;
1006
1007 /* Write large packets if we can */
1008 static size_t out_pos;
1009 static uint8_t out_buffer[16384];
1010 static size_t in_pos;
1011 static size_t in_write;
1012 static uint8_t in_buffer[16384];
1013
1014 static bool flush_writes(void)
1015 {
1016 bool ok = (write(tcp_ip, out_buffer, out_pos) == (int)out_pos);
1017 out_pos = 0;
1018 return ok;
1019 }
1020
1021 static bool writeLong(uint32_t l)
1022 {
1023 int i;
1024 for (i = 0; i < 4; i++)
1025 {
1026 uint8_t c = (l >> (i*8))&0xff;
1027 out_buffer[out_pos++] = c;
1028 if (out_pos >= sizeof(out_buffer))
1029 {
1030 if (!flush_writes())
1031 {
1032 return false;
1033 }
1034 }
1035 }
1036 return true;
1037 }
1038
1039 static bool readLong(uint32_t *out_data)
1040 {
1041 if (out_pos > 0)
1042 {
1043 if (!flush_writes())
1044 {
1045 return false;
1046 }
1047 }
1048
1049 uint32_t data = 0;
1050 int i;
1051 for (i = 0; i < 4; i++)
1052 {
1053 uint8_t c;
1054 if (in_pos == in_write)
1055 {
1056 /* read more */
1057 int t;
1058 t = read(tcp_ip, in_buffer, sizeof(in_buffer));
1059 if (t < 1)
1060 {
1061 return false;
1062 }
1063 in_write = (size_t) t;
1064 in_pos = 0;
1065 }
1066 c = in_buffer[in_pos++];
1067
1068 data |= (c << (i*8));
1069 }
1070 *out_data = data;
1071 return true;
1072 }
1073
1074 enum ZY1000_CMD
1075 {
1076 ZY1000_CMD_POKE = 0x0,
1077 ZY1000_CMD_PEEK = 0x8,
1078 ZY1000_CMD_SLEEP = 0x1,
1079 ZY1000_CMD_WAITIDLE = 2
1080 };
1081
1082
1083 #if !BUILD_ECOSBOARD
1084
1085 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
1086 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
1087
1088 /* We initialize this late since we need to know the server address
1089 * first.
1090 */
1091 static void tcpip_open(void)
1092 {
1093 if (tcp_ip >= 0)
1094 return;
1095
1096 struct sockaddr_in echoServAddr; /* Echo server address */
1097
1098 /* Create a reliable, stream socket using TCP */
1099 if ((tcp_ip = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
1100 {
1101 fprintf(stderr, "Failed to connect to zy1000 server\n");
1102 exit(-1);
1103 }
1104
1105 /* Construct the server address structure */
1106 memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
1107 echoServAddr.sin_family = AF_INET; /* Internet address family */
1108 echoServAddr.sin_addr.s_addr = inet_addr(tcp_server); /* Server IP address */
1109 echoServAddr.sin_port = htons(7777); /* Server port */
1110
1111 /* Establish the connection to the echo server */
1112 if (connect(tcp_ip, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
1113 {
1114 fprintf(stderr, "Failed to connect to zy1000 server\n");
1115 exit(-1);
1116 }
1117
1118 int flag = 1;
1119 setsockopt(tcp_ip, /* socket affected */
1120 IPPROTO_TCP, /* set option at TCP level */
1121 TCP_NODELAY, /* name of option */
1122 (char *)&flag, /* the cast is historical cruft */
1123 sizeof(int)); /* length of option value */
1124
1125 }
1126
1127
1128 /* send a poke */
1129 void zy1000_tcpout(uint32_t address, uint32_t data)
1130 {
1131 tcpip_open();
1132 if (!writeLong((ZY1000_CMD_POKE << 24) | address)||
1133 !writeLong(data))
1134 {
1135 fprintf(stderr, "Could not write to zy1000 server\n");
1136 exit(-1);
1137 }
1138 }
1139
1140 /* By sending the wait to the server, we avoid a readback
1141 * of status. Radically improves performance for this operation
1142 * with long ping times.
1143 */
1144 void waitIdle(void)
1145 {
1146 tcpip_open();
1147 if (!writeLong((ZY1000_CMD_WAITIDLE << 24)))
1148 {
1149 fprintf(stderr, "Could not write to zy1000 server\n");
1150 exit(-1);
1151 }
1152 }
1153
1154 uint32_t zy1000_tcpin(uint32_t address)
1155 {
1156 tcpip_open();
1157
1158 zy1000_flush_readqueue();
1159
1160 uint32_t data;
1161 if (!writeLong((ZY1000_CMD_PEEK << 24) | address)||
1162 !readLong(&data))
1163 {
1164 fprintf(stderr, "Could not read from zy1000 server\n");
1165 exit(-1);
1166 }
1167 return data;
1168 }
1169
1170 int interface_jtag_add_sleep(uint32_t us)
1171 {
1172 tcpip_open();
1173 if (!writeLong((ZY1000_CMD_SLEEP << 24))||
1174 !writeLong(us))
1175 {
1176 fprintf(stderr, "Could not read from zy1000 server\n");
1177 exit(-1);
1178 }
1179 return ERROR_OK;
1180 }
1181
1182 /* queue a readback */
1183 #define readqueue_size 16384
1184 static struct
1185 {
1186 uint8_t *dest;
1187 int bits;
1188 } readqueue[readqueue_size];
1189
1190 static int readqueue_pos = 0;
1191
1192 /* flush the readqueue, this means reading any data that
1193 * we're expecting and store them into the final position
1194 */
1195 void zy1000_flush_readqueue(void)
1196 {
1197 if (readqueue_pos == 0)
1198 {
1199 /* simply debugging by allowing easy breakpoints when there
1200 * is something to do. */
1201 return;
1202 }
1203 int i;
1204 tcpip_open();
1205 for (i = 0; i < readqueue_pos; i++)
1206 {
1207 uint32_t value;
1208 if (!readLong(&value))
1209 {
1210 fprintf(stderr, "Could not read from zy1000 server\n");
1211 exit(-1);
1212 }
1213
1214 uint8_t *in_value = readqueue[i].dest;
1215 int k = readqueue[i].bits;
1216
1217 // we're shifting in data to MSB, shift data to be aligned for returning the value
1218 value >>= 32-k;
1219
1220 for (int l = 0; l < k; l += 8)
1221 {
1222 in_value[l/8]=(value >> l)&0xff;
1223 }
1224 }
1225 readqueue_pos = 0;
1226 }
1227
1228 /* By queuing the callback's we avoid flushing the
1229 read queue until jtag_execute_queue(). This can
1230 reduce latency dramatically for cases where
1231 callbacks are used extensively.
1232 */
1233 #define callbackqueue_size 128
1234 static struct callbackentry
1235 {
1236 jtag_callback_t callback;
1237 jtag_callback_data_t data0;
1238 jtag_callback_data_t data1;
1239 jtag_callback_data_t data2;
1240 jtag_callback_data_t data3;
1241 } callbackqueue[callbackqueue_size];
1242
1243 static int callbackqueue_pos = 0;
1244
1245 void zy1000_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
1246 {
1247 if (callbackqueue_pos >= callbackqueue_size)
1248 {
1249 zy1000_flush_callbackqueue();
1250 }
1251
1252 callbackqueue[callbackqueue_pos].callback = callback;
1253 callbackqueue[callbackqueue_pos].data0 = data0;
1254 callbackqueue[callbackqueue_pos].data1 = data1;
1255 callbackqueue[callbackqueue_pos].data2 = data2;
1256 callbackqueue[callbackqueue_pos].data3 = data3;
1257 callbackqueue_pos++;
1258 }
1259
1260 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)
1261 {
1262 ((jtag_callback1_t)data1)(data0);
1263 return ERROR_OK;
1264 }
1265
1266 void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)
1267 {
1268 zy1000_jtag_add_callback4(zy1000_jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
1269 }
1270
1271 void zy1000_flush_callbackqueue(void)
1272 {
1273 /* we have to flush the read queue so we have access to
1274 the data the callbacks will use
1275 */
1276 zy1000_flush_readqueue();
1277 int i;
1278 for (i = 0; i < callbackqueue_pos; i++)
1279 {
1280 struct callbackentry *entry = &callbackqueue[i];
1281 jtag_set_error(entry->callback(entry->data0, entry->data1, entry->data2, entry->data3));
1282 }
1283 callbackqueue_pos = 0;
1284 }
1285
1286 static void writeShiftValue(uint8_t *data, int bits)
1287 {
1288 waitIdle();
1289
1290 if (!writeLong((ZY1000_CMD_PEEK << 24) | (ZY1000_JTAG_BASE + 0xc)))
1291 {
1292 fprintf(stderr, "Could not read from zy1000 server\n");
1293 exit(-1);
1294 }
1295
1296 if (readqueue_pos >= readqueue_size)
1297 {
1298 zy1000_flush_readqueue();
1299 }
1300
1301 readqueue[readqueue_pos].dest = data;
1302 readqueue[readqueue_pos].bits = bits;
1303 readqueue_pos++;
1304 }
1305
1306 #else
1307
1308 static void writeShiftValue(uint8_t *data, int bits)
1309 {
1310 uint32_t value;
1311 waitIdle();
1312 ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, value);
1313 VERBOSE(LOG_INFO("getShiftValue %08x", value));
1314
1315 // data in, LSB to MSB
1316 // we're shifting in data to MSB, shift data to be aligned for returning the value
1317 value >>= 32 - bits;
1318
1319 for (int l = 0; l < bits; l += 8)
1320 {
1321 data[l/8]=(value >> l)&0xff;
1322 }
1323 }
1324
1325 #endif
1326
1327 #if BUILD_ECOSBOARD
1328 static char tcpip_stack[2048];
1329 static cyg_thread tcpip_thread_object;
1330 static cyg_handle_t tcpip_thread_handle;
1331
1332 static char watchdog_stack[2048];
1333 static cyg_thread watchdog_thread_object;
1334 static cyg_handle_t watchdog_thread_handle;
1335
1336 /* Infinite loop peeking & poking */
1337 static void tcpipserver(void)
1338 {
1339 for (;;)
1340 {
1341 uint32_t address;
1342 if (!readLong(&address))
1343 return;
1344 enum ZY1000_CMD c = (address >> 24) & 0xff;
1345 address &= 0xffffff;
1346 switch (c)
1347 {
1348 case ZY1000_CMD_POKE:
1349 {
1350 uint32_t data;
1351 if (!readLong(&data))
1352 return;
1353 address &= ~0x80000000;
1354 ZY1000_POKE(address + ZY1000_JTAG_BASE, data);
1355 break;
1356 }
1357 case ZY1000_CMD_PEEK:
1358 {
1359 uint32_t data;
1360 ZY1000_PEEK(address + ZY1000_JTAG_BASE, data);
1361 if (!writeLong(data))
1362 return;
1363 break;
1364 }
1365 case ZY1000_CMD_SLEEP:
1366 {
1367 uint32_t data;
1368 if (!readLong(&data))
1369 return;
1370 jtag_sleep(data);
1371 break;
1372 }
1373 case ZY1000_CMD_WAITIDLE:
1374 {
1375 waitIdle();
1376 break;
1377 }
1378 default:
1379 return;
1380 }
1381 }
1382 }
1383
1384
1385 static void tcpip_server(cyg_addrword_t data)
1386 {
1387 int so_reuseaddr_option = 1;
1388
1389 int fd;
1390 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1391 {
1392 LOG_ERROR("error creating socket: %s", strerror(errno));
1393 exit(-1);
1394 }
1395
1396 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option,
1397 sizeof(int));
1398
1399 struct sockaddr_in sin;
1400 unsigned int address_size;
1401 address_size = sizeof(sin);
1402 memset(&sin, 0, sizeof(sin));
1403 sin.sin_family = AF_INET;
1404 sin.sin_addr.s_addr = INADDR_ANY;
1405 sin.sin_port = htons(7777);
1406
1407 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
1408 {
1409 LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
1410 exit(-1);
1411 }
1412
1413 if (listen(fd, 1) == -1)
1414 {
1415 LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
1416 exit(-1);
1417 }
1418
1419
1420 for (;;)
1421 {
1422 tcp_ip = accept(fd, (struct sockaddr *) &sin, &address_size);
1423 if (tcp_ip < 0)
1424 {
1425 continue;
1426 }
1427
1428 int flag = 1;
1429 setsockopt(tcp_ip, /* socket affected */
1430 IPPROTO_TCP, /* set option at TCP level */
1431 TCP_NODELAY, /* name of option */
1432 (char *)&flag, /* the cast is historical cruft */
1433 sizeof(int)); /* length of option value */
1434
1435 bool save_poll = jtag_poll_get_enabled();
1436
1437 /* polling will screw up the "connection" */
1438 jtag_poll_set_enabled(false);
1439
1440 tcpipserver();
1441
1442 jtag_poll_set_enabled(save_poll);
1443
1444 close(tcp_ip);
1445
1446 }
1447 close(fd);
1448
1449 }
1450
1451 #ifdef WATCHDOG_BASE
1452 /* If we connect to port 8888 we must send a char every 10s or the board resets itself */
1453 static void watchdog_server(cyg_addrword_t data)
1454 {
1455 int so_reuseaddr_option = 1;
1456
1457 int fd;
1458 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1459 {
1460 LOG_ERROR("error creating socket: %s", strerror(errno));
1461 exit(-1);
1462 }
1463
1464 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option,
1465 sizeof(int));
1466
1467 struct sockaddr_in sin;
1468 unsigned int address_size;
1469 address_size = sizeof(sin);
1470 memset(&sin, 0, sizeof(sin));
1471 sin.sin_family = AF_INET;
1472 sin.sin_addr.s_addr = INADDR_ANY;
1473 sin.sin_port = htons(8888);
1474
1475 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
1476 {
1477 LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
1478 exit(-1);
1479 }
1480
1481 if (listen(fd, 1) == -1)
1482 {
1483 LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
1484 exit(-1);
1485 }
1486
1487
1488 for (;;)
1489 {
1490 int watchdog_ip = accept(fd, (struct sockaddr *) &sin, &address_size);
1491
1492 /* Start watchdog, must be reset every 10 seconds. */
1493 HAL_WRITE_UINT32(WATCHDOG_BASE + 4, 4);
1494
1495 if (watchdog_ip < 0)
1496 {
1497 LOG_ERROR("couldn't open watchdog socket: %s", strerror(errno));
1498 exit(-1);
1499 }
1500
1501 int flag = 1;
1502 setsockopt(watchdog_ip, /* socket affected */
1503 IPPROTO_TCP, /* set option at TCP level */
1504 TCP_NODELAY, /* name of option */
1505 (char *)&flag, /* the cast is historical cruft */
1506 sizeof(int)); /* length of option value */
1507
1508
1509 char buf;
1510 for (;;)
1511 {
1512 if (read(watchdog_ip, &buf, 1) == 1)
1513 {
1514 /* Reset timer */
1515 HAL_WRITE_UINT32(WATCHDOG_BASE + 8, 0x1234);
1516 /* Echo so we can telnet in and see that resetting works */
1517 write(watchdog_ip, &buf, 1);
1518 } else
1519 {
1520 /* Stop tickling the watchdog, the CPU will reset in < 10 seconds
1521 * now.
1522 */
1523 return;
1524 }
1525
1526 }
1527
1528 /* Never reached */
1529 }
1530 }
1531 #endif
1532
1533 int interface_jtag_add_sleep(uint32_t us)
1534 {
1535 jtag_sleep(us);
1536 return ERROR_OK;
1537 }
1538
1539 #endif
1540
1541
1542 int zy1000_init(void)
1543 {
1544 #if BUILD_ECOSBOARD
1545 LOG_USER("%s", ZYLIN_OPENOCD_VERSION);
1546 #endif
1547
1548 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x30); // Turn on LED1 & LED2
1549
1550 setPower(true); // on by default
1551
1552
1553 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
1554 zy1000_reset(0, 0);
1555 zy1000_speed(jtag_get_speed());
1556
1557
1558 #if BUILD_ECOSBOARD
1559 cyg_thread_create(1, tcpip_server, (cyg_addrword_t) 0, "tcip/ip server",
1560 (void *) tcpip_stack, sizeof(tcpip_stack),
1561 &tcpip_thread_handle, &tcpip_thread_object);
1562 cyg_thread_resume(tcpip_thread_handle);
1563 #ifdef WATCHDOG_BASE
1564 cyg_thread_create(1, watchdog_server, (cyg_addrword_t) 0, "watchdog tcip/ip server",
1565 (void *) watchdog_stack, sizeof(watchdog_stack),
1566 &watchdog_thread_handle, &watchdog_thread_object);
1567 cyg_thread_resume(watchdog_thread_handle);
1568 #endif
1569 #endif
1570
1571 return ERROR_OK;
1572 }
1573
1574
1575
1576 struct jtag_interface zy1000_interface =
1577 {
1578 .name = "ZY1000",
1579 .supported = DEBUG_CAP_TMS_SEQ,
1580 .execute_queue = NULL,
1581 .speed = zy1000_speed,
1582 .commands = zy1000_commands,
1583 .init = zy1000_init,
1584 .quit = zy1000_quit,
1585 .khz = zy1000_khz,
1586 .speed_div = zy1000_speed_div,
1587 .power_dropout = zy1000_power_dropout,
1588 .srst_asserted = zy1000_srst_asserted,
1589 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)