1 /***************************************************************************
2 * Copyright (C) 2007-2010 by Øyvind Harboe *
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. *
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. *
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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
18 ***************************************************************************/
20 /* This file supports the zy1000 debugger:
22 * http://www.ultsol.com/index.php/component/content/article/8/33-zylin-zy1000-jtag-probe
24 * The zy1000 is a standalone debugger that has a web interface and
25 * requires no drivers on the developer host as all communication
26 * is via TCP/IP. The zy1000 gets it performance(~400-700kBytes/s
27 * DCC downloads @ 16MHz target) as it has an FPGA to hardware
28 * accelerate the JTAG commands, while offering *very* low latency
29 * between OpenOCD and the FPGA registers.
31 * The disadvantage of the zy1000 is that it has a feeble CPU compared to
32 * a PC(ca. 50-500 DMIPS depending on how one counts it), whereas a PC
33 * is on the order of 10000 DMIPS(i.e. at a factor of 20-200).
35 * The zy1000 revc hardware is using an Altera Nios CPU, whereas the
36 * revb is using ARM7 + Xilinx.
38 * See Zylin web pages or contact Zylin for more information.
40 * The reason this code is in OpenOCD rather than OpenOCD linked with the
41 * ZY1000 code is that OpenOCD is the long road towards getting
42 * libopenocd into place. libopenocd will support both low performance,
43 * low latency systems(embedded) and high performance high latency
52 #include <target/embeddedice.h>
53 #include <jtag/minidriver.h>
54 #include <jtag/interface.h>
56 #include <helper/time_support.h>
58 #include <netinet/tcp.h>
60 /* Assume we're connecting to a revc w/60MHz clock. */
61 #define ZYLIN_KHZ 60000
63 /* The software needs to check if it's in RCLK mode or not */
64 static bool zy1000_rclk
;
66 static int zy1000_khz(int khz
, int *jtag_speed
)
72 /* Round speed up to nearest divisor.
75 * (64000 + 15999) / 16000 = 4
82 * (64000 + 15998) / 15999 = 5
89 speed
= (ZYLIN_KHZ
+ (khz
- 1)) / khz
;
90 speed
= (speed
+ 1) / 2;
93 /* maximum dividend */
101 static int zy1000_speed_div(int speed
, int *khz
)
106 *khz
= ZYLIN_KHZ
/ speed
;
111 static bool readPowerDropout(void)
114 /* sample and clear power dropout */
115 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x80);
116 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0x10, state
);
118 powerDropout
= (state
& 0x80) != 0;
123 static bool readSRST(void)
126 /* sample and clear SRST sensing */
127 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x00000040);
128 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0x10, state
);
130 srstAsserted
= (state
& 0x40) != 0;
134 static int zy1000_srst_asserted(int *srst_asserted
)
136 *srst_asserted
= readSRST();
140 static int zy1000_power_dropout(int *dropout
)
142 *dropout
= readPowerDropout();
146 /* Wait for SRST to assert or deassert */
147 static void waitSRST(bool asserted
)
152 const char *mode
= asserted
? "assert" : "deassert";
155 bool srstAsserted
= readSRST();
156 if ((asserted
&& srstAsserted
) || (!asserted
&& !srstAsserted
)) {
158 LOG_USER("SRST took %dms to %s", (int)total
, mode
);
164 start
= timeval_ms();
167 total
= timeval_ms() - start
;
172 LOG_ERROR("SRST took too long to %s: %dms", mode
, (int)total
);
178 void zy1000_reset(int trst
, int srst
)
180 LOG_DEBUG("zy1000 trst=%d, srst=%d", trst
, srst
);
182 /* flush the JTAG FIFO. Not flushing the queue before messing with
183 * reset has such interesting bugs as causing hard to reproduce
184 * RCLK bugs as RCLK will stop responding when TRST is asserted
189 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x00000001);
191 /* Danger!!! if clk != 0 when in
192 * idle in TAP_IDLE, reset halt on str912 will fail.
194 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x00000001);
200 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x00000002);
203 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x00000002);
206 if (trst
|| (srst
&& (jtag_get_reset_config() & RESET_SRST_PULLS_TRST
))) {
207 /* we're now in the RESET state until trst is deasserted */
208 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, TAP_RESET
);
210 /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
211 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x400);
214 /* wait for srst to float back up */
215 if ((!srst
&& ((jtag_get_reset_config() & RESET_TRST_PULLS_SRST
) == 0)) ||
216 (!srst
&& !trst
&& (jtag_get_reset_config() & RESET_TRST_PULLS_SRST
)))
220 int zy1000_speed(int speed
)
222 /* flush JTAG master FIFO before setting speed */
229 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x100);
231 LOG_DEBUG("jtag_speed using RCLK");
233 if (speed
> 8190 || speed
< 2) {
235 "valid ZY1000 jtag_speed=[8190,2]. With divisor is %dkHz / even values between 8190-2, i.e. min %dHz, max %dMHz",
237 (ZYLIN_KHZ
* 1000) / 8190,
238 ZYLIN_KHZ
/ (2 * 1000));
239 return ERROR_COMMAND_SYNTAX_ERROR
;
244 zy1000_speed_div(speed
, &khz
);
245 LOG_USER("jtag_speed %d => JTAG clk=%d kHz", speed
, khz
);
246 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x100);
247 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x1c, speed
);
252 static bool savePower
;
254 static void setPower(bool power
)
258 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x8);
260 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x8);
263 COMMAND_HANDLER(handle_power_command
)
268 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
273 LOG_INFO("Target power %s", savePower
? "on" : "off");
276 return ERROR_COMMAND_SYNTAX_ERROR
;
282 #if !BUILD_ZY1000_MASTER
283 static char *tcp_server
= "notspecified";
284 static int jim_zy1000_server(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
289 tcp_server
= strdup(Jim_GetString(argv
[1], NULL
));
295 static int zylinjtag_Jim_Command_powerstatus(Jim_Interp
*interp
,
297 Jim_Obj
* const *argv
)
300 Jim_WrongNumArgs(interp
, 1, argv
, "powerstatus");
304 bool dropout
= readPowerDropout();
306 Jim_SetResult(interp
, Jim_NewIntObj(interp
, dropout
));
311 int zy1000_quit(void)
317 int interface_jtag_execute_queue(void)
323 /* We must make sure to write data read back to memory location before we return
326 zy1000_flush_readqueue();
328 /* and handle any callbacks... */
329 zy1000_flush_callbackqueue();
332 /* Only check for errors when using RCLK to speed up
335 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0x10, empty
);
336 /* clear JTAG error register */
337 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x400);
339 if ((empty
&0x400) != 0) {
340 LOG_WARNING("RCLK timeout");
341 /* the error is informative only as we don't want to break the firmware if there
342 * is a false positive.
344 /* return ERROR_FAIL; */
350 static void writeShiftValue(uint8_t *data
, int bits
);
352 /* here we shuffle N bits out/in */
353 static inline void scanBits(const uint8_t *out_value
,
357 tap_state_t shiftState
,
358 tap_state_t end_state
)
360 tap_state_t pause_state
= shiftState
;
361 for (int j
= 0; j
< num_bits
; j
+= 32) {
362 int k
= num_bits
- j
;
365 /* we have more to shift out */
366 } else if (pause_now
) {
367 /* this was the last to shift out this time */
368 pause_state
= end_state
;
371 /* we have (num_bits + 7)/8 bytes of bits to toggle out. */
372 /* bits are pushed out LSB to MSB */
375 if (out_value
!= NULL
) {
376 for (int l
= 0; l
< k
; l
+= 8)
377 value
|= out_value
[(j
+ l
)/8]<<l
;
379 /* mask away unused bits for easier debugging */
381 value
&= ~(((uint32_t)0xffffffff) << k
);
383 /* Shifting by >= 32 is not defined by the C standard
384 * and will in fact shift by &0x1f bits on nios */
387 shiftValueInner(shiftState
, pause_state
, k
, value
);
389 if (in_value
!= NULL
)
390 writeShiftValue(in_value
+ (j
/8), k
);
394 static inline void scanFields(int num_fields
,
395 const struct scan_field
*fields
,
396 tap_state_t shiftState
,
397 tap_state_t end_state
)
399 for (int i
= 0; i
< num_fields
; i
++) {
400 scanBits(fields
[i
].out_value
,
409 int interface_jtag_add_ir_scan(struct jtag_tap
*active
,
410 const struct scan_field
*fields
,
414 struct jtag_tap
*tap
, *nextTap
;
415 tap_state_t pause_state
= TAP_IRSHIFT
;
417 for (tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= nextTap
) {
418 nextTap
= jtag_tap_next_enabled(tap
);
421 scan_size
= tap
->ir_length
;
423 /* search the list */
425 scanFields(1, fields
, TAP_IRSHIFT
, pause_state
);
426 /* update device information */
427 buf_cpy(fields
[0].out_value
, tap
->cur_instr
, scan_size
);
431 /* if a device isn't listed, set it to BYPASS */
432 assert(scan_size
<= 32);
433 shiftValueInner(TAP_IRSHIFT
, pause_state
, scan_size
, 0xffffffff);
435 /* Optimization code will check what the cur_instr is set to, so
436 * we must set it to bypass value.
438 buf_set_ones(tap
->cur_instr
, tap
->ir_length
);
447 int interface_jtag_add_plain_ir_scan(int num_bits
,
448 const uint8_t *out_bits
,
452 scanBits(out_bits
, in_bits
, num_bits
, true, TAP_IRSHIFT
, state
);
456 int interface_jtag_add_dr_scan(struct jtag_tap
*active
,
458 const struct scan_field
*fields
,
461 struct jtag_tap
*tap
, *nextTap
;
462 tap_state_t pause_state
= TAP_DRSHIFT
;
463 for (tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= nextTap
) {
464 nextTap
= jtag_tap_next_enabled(tap
);
468 /* Find a range of fields to write to this tap */
470 assert(!tap
->bypass
);
472 scanFields(num_fields
, fields
, TAP_DRSHIFT
, pause_state
);
474 /* Shift out a 0 for disabled tap's */
476 shiftValueInner(TAP_DRSHIFT
, pause_state
, 1, 0);
482 int interface_jtag_add_plain_dr_scan(int num_bits
,
483 const uint8_t *out_bits
,
487 scanBits(out_bits
, in_bits
, num_bits
, true, TAP_DRSHIFT
, state
);
491 int interface_jtag_add_tlr()
493 setCurrentState(TAP_RESET
);
497 int interface_jtag_add_reset(int req_trst
, int req_srst
)
499 zy1000_reset(req_trst
, req_srst
);
503 static int zy1000_jtag_add_clocks(int num_cycles
, tap_state_t state
, tap_state_t clockstate
)
505 /* num_cycles can be 0 */
506 setCurrentState(clockstate
);
508 /* execute num_cycles, 32 at the time. */
510 for (i
= 0; i
< num_cycles
; i
+= 32) {
513 if (num_cycles
-i
< num
)
515 shiftValueInner(clockstate
, clockstate
, num
, 0);
519 /* finish in end_state */
520 setCurrentState(state
);
522 tap_state_t t
= TAP_IDLE
;
523 /* test manual drive code on any target */
525 uint8_t tms_scan
= tap_get_tms_path(t
, state
);
526 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
528 for (i
= 0; i
< tms_count
; i
++) {
529 tms
= (tms_scan
>> i
) & 1;
531 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, tms
);
534 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, state
);
540 int interface_jtag_add_runtest(int num_cycles
, tap_state_t state
)
542 return zy1000_jtag_add_clocks(num_cycles
, state
, TAP_IDLE
);
545 int interface_jtag_add_clocks(int num_cycles
)
547 return zy1000_jtag_add_clocks(num_cycles
, cmd_queue_cur_state
, cmd_queue_cur_state
);
550 int interface_add_tms_seq(unsigned num_bits
, const uint8_t *seq
, enum tap_state state
)
552 /*wait for the fifo to be empty*/
555 for (unsigned i
= 0; i
< num_bits
; i
++) {
558 if (((seq
[i
/8] >> (i
% 8)) & 1) == 0)
564 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, tms
);
568 if (state
!= TAP_INVALID
)
569 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, state
);
571 /* this would be normal if
572 * we are switching to SWD mode */
577 int interface_jtag_add_pathmove(int num_states
, const tap_state_t
*path
)
584 tap_state_t cur_state
= cmd_queue_cur_state
;
587 memset(seq
, 0, sizeof(seq
));
588 assert(num_states
< (int)((sizeof(seq
) * 8)));
591 if (tap_state_transition(cur_state
, false) == path
[state_count
])
593 else if (tap_state_transition(cur_state
, true) == path
[state_count
])
596 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
597 tap_state_name(cur_state
), tap_state_name(path
[state_count
]));
601 seq
[state_count
/8] = seq
[state_count
/8] | (tms
<< (state_count
% 8));
603 cur_state
= path
[state_count
];
608 return interface_add_tms_seq(state_count
, seq
, cur_state
);
611 static void jtag_pre_post_bits(struct jtag_tap
*tap
, int *pre
, int *post
)
613 /* bypass bits before and after */
618 struct jtag_tap
*cur_tap
, *nextTap
;
619 for (cur_tap
= jtag_tap_next_enabled(NULL
); cur_tap
!= NULL
; cur_tap
= nextTap
) {
620 nextTap
= jtag_tap_next_enabled(cur_tap
);
634 void embeddedice_write_dcc(struct jtag_tap
*tap
,
636 const uint8_t *buffer
,
642 for (i
= 0; i
< count
; i
++) {
643 embeddedice_write_reg_inner(tap
, reg_addr
, fast_target_buffer_get_u32(buffer
,
650 jtag_pre_post_bits(tap
, &pre_bits
, &post_bits
);
652 if ((pre_bits
> 32) || (post_bits
+ 6 > 32)) {
654 for (i
= 0; i
< count
; i
++) {
655 embeddedice_write_reg_inner(tap
, reg_addr
,
656 fast_target_buffer_get_u32(buffer
, little
));
661 for (i
= 0; i
< count
; i
++) {
662 /* Fewer pokes means we get to use the FIFO more efficiently */
663 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, pre_bits
, 0);
664 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, 32,
665 fast_target_buffer_get_u32(buffer
, little
));
666 /* Danger! here we need to exit into the TAP_IDLE state to make
667 * DCC pick up this value.
669 shiftValueInner(TAP_DRSHIFT
, TAP_IDLE
, 6 + post_bits
,
670 (reg_addr
| (1 << 5)));
677 int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap
*tap
,
679 const uint32_t *data
,
682 /* bypass bits before and after */
685 jtag_pre_post_bits(tap
, &pre_bits
, &post_bits
);
688 if ((pre_bits
> 32) || (post_bits
> 32)) {
689 int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap
*,
690 uint32_t, const uint32_t *, size_t);
691 return arm11_run_instr_data_to_core_noack_inner_default(tap
, opcode
, data
, count
);
693 static const uint8_t zero
;
695 /* FIX!!!!!! the target_write_memory() API started this nasty problem
696 * with unaligned uint32_t * pointers... */
697 const uint8_t *t
= (const uint8_t *)data
;
699 while (--count
> 0) {
701 /* Danger! This code doesn't update cmd_queue_cur_state, so
702 * invoking jtag_add_pathmove() before jtag_add_dr_scan() after
703 * this loop would fail!
705 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, pre_bits
, 0);
713 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, 32, value
);
715 shiftValueInner(TAP_DRSHIFT
, TAP_DRPAUSE
, post_bits
, 0);
717 /* copy & paste from arm11_dbgtap.c */
718 /* TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT,
719 * TAP_DRCAPTURE, TAP_DRSHIFT */
720 /* KLUDGE! we have to flush the fifo or the Nios CPU locks up.
721 * This is probably a bug in the Avalon bus(cross clocking bridge?)
722 * or in the jtag registers module.
725 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 1);
726 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 1);
727 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
728 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
729 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
730 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 1);
731 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
732 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
733 /* we don't have to wait for the queue to empty here */
734 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, TAP_DRSHIFT
);
737 static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay
[] = {
738 TAP_DREXIT2
, TAP_DRUPDATE
, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
,
739 TAP_DRSELECT
, TAP_DRCAPTURE
, TAP_DRSHIFT
742 struct scan_field fields
[2] = {
743 { .num_bits
= 32, .out_value
= t
},
744 { .num_bits
= 2, .out_value
= &zero
},
748 jtag_add_dr_scan(tap
,
753 jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay
),
754 arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay
);
758 struct scan_field fields
[2] = {
759 { .num_bits
= 32, .out_value
= t
},
760 { .num_bits
= 2, .out_value
= &zero
},
763 /* This will happen on the last iteration updating cmd_queue_cur_state
764 * so we don't have to track it during the common code path
766 jtag_add_dr_scan(tap
,
771 return jtag_execute_queue();
775 static const struct command_registration zy1000_commands
[] = {
778 .handler
= handle_power_command
,
780 .help
= "Turn power switch to target on/off. "
781 "With no arguments, prints status.",
782 .usage
= "('on'|'off)",
784 #if !BUILD_ZY1000_MASTER
786 .name
= "zy1000_server",
788 .jim_handler
= jim_zy1000_server
,
789 .help
= "Tcpip address for ZY1000 server.",
794 .name
= "powerstatus",
796 .jim_handler
= zylinjtag_Jim_Command_powerstatus
,
797 .help
= "Returns power status of target",
799 COMMAND_REGISTRATION_DONE
802 #if !BUILD_ZY1000_MASTER
804 static int tcp_ip
= -1;
806 /* Write large packets if we can */
807 static size_t out_pos
;
808 static uint8_t out_buffer
[16384];
809 static size_t in_pos
;
810 static size_t in_write
;
811 static uint8_t in_buffer
[16384];
813 static bool flush_writes(void)
815 bool ok
= (write(tcp_ip
, out_buffer
, out_pos
) == (int)out_pos
);
820 static bool writeLong(uint32_t l
)
823 for (i
= 0; i
< 4; i
++) {
824 uint8_t c
= (l
>> (i
*8))&0xff;
825 out_buffer
[out_pos
++] = c
;
826 if (out_pos
>= sizeof(out_buffer
)) {
834 static bool readLong(uint32_t *out_data
)
838 for (i
= 0; i
< 4; i
++) {
840 if (in_pos
== in_write
) {
841 /* If we have some data that we can send, send them before
842 * we wait for more data
851 t
= read(tcp_ip
, in_buffer
, sizeof(in_buffer
));
854 in_write
= (size_t) t
;
857 c
= in_buffer
[in_pos
++];
859 data
|= (c
<< (i
*8));
866 ZY1000_CMD_POKE
= 0x0,
867 ZY1000_CMD_PEEK
= 0x8,
868 ZY1000_CMD_SLEEP
= 0x1,
869 ZY1000_CMD_WAITIDLE
= 2
872 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
873 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
875 /* We initialize this late since we need to know the server address
878 static void tcpip_open(void)
883 struct sockaddr_in echoServAddr
;/* Echo server address */
885 /* Create a reliable, stream socket using TCP */
886 tcp_ip
= socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
888 fprintf(stderr
, "Failed to connect to zy1000 server\n");
892 /* Construct the server address structure */
893 memset(&echoServAddr
, 0, sizeof(echoServAddr
)); /* Zero out structure */
894 echoServAddr
.sin_family
= AF_INET
; /* Internet address family */
895 echoServAddr
.sin_addr
.s_addr
= inet_addr(tcp_server
); /* Server IP address */
896 echoServAddr
.sin_port
= htons(7777); /* Server port */
898 /* Establish the connection to the echo server */
899 if (connect(tcp_ip
, (struct sockaddr
*) &echoServAddr
, sizeof(echoServAddr
)) < 0) {
900 fprintf(stderr
, "Failed to connect to zy1000 server\n");
905 setsockopt(tcp_ip
, /* socket affected */
906 IPPROTO_TCP
, /* set option at TCP level */
907 TCP_NODELAY
, /* name of option */
908 (char *)&flag
, /* the cast is historical cruft */
909 sizeof(int)); /* length of option value */
914 void zy1000_tcpout(uint32_t address
, uint32_t data
)
917 if (!writeLong((ZY1000_CMD_POKE
<< 24) | address
) || !writeLong(data
)) {
918 fprintf(stderr
, "Could not write to zy1000 server\n");
923 /* By sending the wait to the server, we avoid a readback
924 * of status. Radically improves performance for this operation
925 * with long ping times.
930 if (!writeLong((ZY1000_CMD_WAITIDLE
<< 24))) {
931 fprintf(stderr
, "Could not write to zy1000 server\n");
936 uint32_t zy1000_tcpin(uint32_t address
)
940 zy1000_flush_readqueue();
943 if (!writeLong((ZY1000_CMD_PEEK
<< 24) | address
) || !readLong(&data
)) {
944 fprintf(stderr
, "Could not read from zy1000 server\n");
950 int interface_jtag_add_sleep(uint32_t us
)
953 if (!writeLong((ZY1000_CMD_SLEEP
<< 24)) || !writeLong(us
)) {
954 fprintf(stderr
, "Could not read from zy1000 server\n");
960 /* queue a readback */
961 #define readqueue_size 16384
965 } readqueue
[readqueue_size
];
967 static int readqueue_pos
;
969 /* flush the readqueue, this means reading any data that
970 * we're expecting and store them into the final position
972 void zy1000_flush_readqueue(void)
974 if (readqueue_pos
== 0) {
975 /* simply debugging by allowing easy breakpoints when there
976 * is something to do. */
981 for (i
= 0; i
< readqueue_pos
; i
++) {
983 if (!readLong(&value
)) {
984 fprintf(stderr
, "Could not read from zy1000 server\n");
988 uint8_t *in_value
= readqueue
[i
].dest
;
989 int k
= readqueue
[i
].bits
;
991 /* we're shifting in data to MSB, shift data to be aligned for returning the value */
994 for (int l
= 0; l
< k
; l
+= 8)
995 in_value
[l
/8] = (value
>> l
)&0xff;
1000 /* By queuing the callback's we avoid flushing the
1001 * read queue until jtag_execute_queue(). This can
1002 * reduce latency dramatically for cases where
1003 * callbacks are used extensively.
1005 #define callbackqueue_size 128
1006 static struct callbackentry
{
1007 jtag_callback_t callback
;
1008 jtag_callback_data_t data0
;
1009 jtag_callback_data_t data1
;
1010 jtag_callback_data_t data2
;
1011 jtag_callback_data_t data3
;
1012 } callbackqueue
[callbackqueue_size
];
1014 static int callbackqueue_pos
;
1016 void zy1000_jtag_add_callback4(jtag_callback_t callback
,
1017 jtag_callback_data_t data0
,
1018 jtag_callback_data_t data1
,
1019 jtag_callback_data_t data2
,
1020 jtag_callback_data_t data3
)
1022 if (callbackqueue_pos
>= callbackqueue_size
)
1023 zy1000_flush_callbackqueue();
1025 callbackqueue
[callbackqueue_pos
].callback
= callback
;
1026 callbackqueue
[callbackqueue_pos
].data0
= data0
;
1027 callbackqueue
[callbackqueue_pos
].data1
= data1
;
1028 callbackqueue
[callbackqueue_pos
].data2
= data2
;
1029 callbackqueue
[callbackqueue_pos
].data3
= data3
;
1030 callbackqueue_pos
++;
1033 * make callbacks synchronous for now as minidriver requires callback
1034 * to be synchronous.
1036 * We can get away with making read and writes asynchronous so we
1037 * don't completely kill performance.
1039 zy1000_flush_callbackqueue();
1042 static int zy1000_jtag_convert_to_callback4(jtag_callback_data_t data0
,
1043 jtag_callback_data_t data1
,
1044 jtag_callback_data_t data2
,
1045 jtag_callback_data_t data3
)
1047 ((jtag_callback1_t
)data1
)(data0
);
1051 void zy1000_jtag_add_callback(jtag_callback1_t callback
, jtag_callback_data_t data0
)
1053 zy1000_jtag_add_callback4(zy1000_jtag_convert_to_callback4
,
1055 (jtag_callback_data_t
)callback
,
1060 void zy1000_flush_callbackqueue(void)
1062 /* we have to flush the read queue so we have access to
1063 the data the callbacks will use
1065 zy1000_flush_readqueue();
1067 for (i
= 0; i
< callbackqueue_pos
; i
++) {
1068 struct callbackentry
*entry
= &callbackqueue
[i
];
1069 jtag_set_error(entry
->callback(entry
->data0
, entry
->data1
, entry
->data2
,
1072 callbackqueue_pos
= 0;
1075 static void writeShiftValue(uint8_t *data
, int bits
)
1079 if (!writeLong((ZY1000_CMD_PEEK
<< 24) | (ZY1000_JTAG_BASE
+ 0xc))) {
1080 fprintf(stderr
, "Could not read from zy1000 server\n");
1084 if (readqueue_pos
>= readqueue_size
)
1085 zy1000_flush_readqueue();
1087 readqueue
[readqueue_pos
].dest
= data
;
1088 readqueue
[readqueue_pos
].bits
= bits
;
1091 /* KLUDGE!!! minidriver requires readqueue to be synchronous */
1092 zy1000_flush_readqueue();
1097 static void writeShiftValue(uint8_t *data
, int bits
)
1101 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0xc, value
);
1102 VERBOSE(LOG_INFO("getShiftValue %08x", value
));
1104 /* data in, LSB to MSB */
1105 /* we're shifting in data to MSB, shift data to be aligned for returning the value */
1106 value
>>= 32 - bits
;
1108 for (int l
= 0; l
< bits
; l
+= 8)
1109 data
[l
/8] = (value
>> l
)&0xff;
1114 #if BUILD_ZY1000_MASTER
1116 #ifdef WATCHDOG_BASE
1117 /* If we connect to port 8888 we must send a char every 10s or the board resets itself */
1118 static void watchdog_server(cyg_addrword_t data
)
1120 int so_reuseaddr_option
= 1;
1122 int fd
= socket(AF_INET
, SOCK_STREAM
, 0);
1124 LOG_ERROR("error creating socket: %s", strerror(errno
));
1128 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void *) &so_reuseaddr_option
,
1131 struct sockaddr_in sin
;
1132 unsigned int address_size
;
1133 address_size
= sizeof(sin
);
1134 memset(&sin
, 0, sizeof(sin
));
1135 sin
.sin_family
= AF_INET
;
1136 sin
.sin_addr
.s_addr
= INADDR_ANY
;
1137 sin
.sin_port
= htons(8888);
1139 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1) {
1140 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
1144 if (listen(fd
, 1) == -1) {
1145 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
1151 int watchdog_ip
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
1153 /* Start watchdog, must be reset every 10 seconds. */
1154 HAL_WRITE_UINT32(WATCHDOG_BASE
+ 4, 4);
1156 if (watchdog_ip
< 0) {
1157 LOG_ERROR("couldn't open watchdog socket: %s", strerror(errno
));
1162 setsockopt(watchdog_ip
, /* socket affected */
1163 IPPROTO_TCP
, /* set option at TCP level */
1164 TCP_NODELAY
, /* name of option */
1165 (char *)&flag
, /* the cast is historical cruft */
1166 sizeof(int)); /* length of option value */
1171 if (read(watchdog_ip
, &buf
, 1) == 1) {
1173 HAL_WRITE_UINT32(WATCHDOG_BASE
+ 8, 0x1234);
1174 /* Echo so we can telnet in and see that resetting works */
1175 write(watchdog_ip
, &buf
, 1);
1177 /* Stop tickling the watchdog, the CPU will reset in < 10 seconds
1192 #if BUILD_ZY1000_MASTER
1193 int interface_jtag_add_sleep(uint32_t us
)
1200 #if BUILD_ZY1000_MASTER
1201 volatile void *zy1000_jtag_master
;
1202 #include <sys/mman.h>
1205 int zy1000_init(void)
1207 #if BUILD_ZY1000_MASTER
1208 int fd
= open("/dev/mem", O_RDWR
| O_SYNC
);
1210 LOG_ERROR("No access to /dev/mem");
1213 #ifndef REGISTERS_BASE
1214 #define REGISTERS_BASE 0x9002000
1215 #define REGISTERS_SPAN 128
1218 zy1000_jtag_master
= mmap(0,
1220 PROT_READ
| PROT_WRITE
,
1225 if (zy1000_jtag_master
== (void *) -1) {
1227 LOG_ERROR("No access to /dev/mem");
1232 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x30); /* Turn on LED1 & LED2 */
1234 setPower(true); /* on by default */
1236 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
1242 struct jtag_interface zy1000_interface
= {
1244 .supported
= DEBUG_CAP_TMS_SEQ
,
1245 .execute_queue
= NULL
,
1246 .speed
= zy1000_speed
,
1247 .commands
= zy1000_commands
,
1248 .init
= zy1000_init
,
1249 .quit
= zy1000_quit
,
1251 .speed_div
= zy1000_speed_div
,
1252 .power_dropout
= zy1000_power_dropout
,
1253 .srst_asserted
= zy1000_srst_asserted
,
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)