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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
20 /* This file supports the zy1000 debugger: http://www.zylin.com/zy1000.html
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.
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).
33 * The zy1000 revc hardware is using an Altera Nios CPU, whereas the
34 * revb is using ARM7 + Xilinx.
36 * See Zylin web pages or contact Zylin for more information.
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
48 #include <target/embeddedice.h>
49 #include <jtag/minidriver.h>
50 #include <jtag/interface.h>
52 #include <helper/time_support.h>
54 #include <netinet/tcp.h>
57 #include "zy1000_version.h"
59 #include <cyg/hal/hal_io.h> // low level i/o
60 #include <cyg/hal/hal_diag.h>
62 #ifdef CYGPKG_HAL_NIOS2
63 #include <cyg/hal/io.h>
64 #include <cyg/firmwareutil/firmwareutil.h>
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
76 /* The software needs to check if it's in RCLK mode or not */
77 static bool zy1000_rclk
= false;
79 static int zy1000_khz(int khz
, int *jtag_speed
)
87 *jtag_speed
= 64000/khz
;
92 static int zy1000_speed_div(int speed
, int *khz
)
106 static bool readPowerDropout(void)
109 // sample and clear power dropout
110 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x80);
111 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0x10, state
);
113 powerDropout
= (state
& 0x80) != 0;
118 static bool readSRST(void)
121 // sample and clear SRST sensing
122 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x00000040);
123 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0x10, state
);
125 srstAsserted
= (state
& 0x40) != 0;
129 static int zy1000_srst_asserted(int *srst_asserted
)
131 *srst_asserted
= readSRST();
135 static int zy1000_power_dropout(int *dropout
)
137 *dropout
= readPowerDropout();
141 void zy1000_reset(int trst
, int srst
)
143 LOG_DEBUG("zy1000 trst=%d, srst=%d", trst
, srst
);
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
153 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x00000001);
157 /* Danger!!! if clk != 0 when in
158 * idle in TAP_IDLE, reset halt on str912 will fail.
160 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x00000001);
165 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x00000002);
170 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x00000002);
173 if (trst
||(srst
&& (jtag_get_reset_config() & RESET_SRST_PULLS_TRST
)))
175 /* we're now in the RESET state until trst is deasserted */
176 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, TAP_RESET
);
179 /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
180 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x400);
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
)))
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
199 LOG_USER("SRST took %dms to deassert", (int)total
);
207 start
= timeval_ms();
210 total
= timeval_ms() - start
;
216 LOG_ERROR("SRST took too long to deassert: %dms", (int)total
);
224 int zy1000_speed(int speed
)
226 /* flush JTAG master FIFO before setting speed */
234 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x100);
236 LOG_DEBUG("jtag_speed using RCLK");
240 if (speed
> 8190 || speed
< 2)
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
;
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);
253 static bool savePower
;
256 static void setPower(bool power
)
261 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x8);
264 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x8);
268 COMMAND_HANDLER(handle_power_command
)
274 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
279 LOG_INFO("Target power %s", savePower
? "on" : "off");
282 return ERROR_INVALID_ARGUMENTS
;
289 static char *tcp_server
= "notspecified";
290 static int jim_zy1000_server(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
295 tcp_server
= strdup(Jim_GetString(argv
[1], NULL
));
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
)
305 if ((argc
< 1) || (argc
> 3))
307 const char *version_str
= NULL
;
311 version_str
= ZYLIN_OPENOCD_VERSION
;
314 const char *str
= Jim_GetString(argv
[1], NULL
);
315 const char *str2
= NULL
;
317 str2
= Jim_GetString(argv
[2], NULL
);
318 if (strcmp("openocd", str
) == 0)
320 version_str
= ZYLIN_OPENOCD
;
322 else if (strcmp("zy1000", str
) == 0)
324 version_str
= ZYLIN_VERSION
;
326 else if (strcmp("date", str
) == 0)
328 version_str
= ZYLIN_DATE
;
330 else if (strcmp("time", str
) == 0)
332 version_str
= ZYLIN_TIME
;
334 else if (strcmp("pcb", str
) == 0)
336 #ifdef CYGPKG_HAL_NIOS2
342 #ifdef CYGPKG_HAL_NIOS2
343 else if (strcmp("fpga", str
) == 0)
346 /* return a list of 32 bit integers to describe the expected
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))
357 time_t last_mod
= timestamp
;
358 char * t
= ctime (&last_mod
) ;
371 Jim_SetResult(interp
, Jim_NewStringObj(interp
, version_str
, -1));
377 #ifdef CYGPKG_HAL_NIOS2
383 struct cyg_upgrade_info
*upgraded_file
;
386 static void report_info(void *data
, const char * format
, va_list args
)
388 char *s
= alloc_vprintf(format
, args
);
393 struct cyg_upgrade_info firmware_info
=
395 (uint8_t *)0x84000000,
401 "ZylinNiosFirmware\n",
405 static int jim_zy1000_writefirmware(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
411 const char *str
= Jim_GetString(argv
[1], &length
);
415 if ((tmpFile
= open(firmware_info
.file
, O_RDWR
| O_CREAT
| O_TRUNC
)) <= 0)
420 success
= write(tmpFile
, str
, length
) == length
;
425 if (!cyg_firmware_upgrade(NULL
, firmware_info
))
433 zylinjtag_Jim_Command_powerstatus(Jim_Interp
*interp
,
435 Jim_Obj
* const *argv
)
439 Jim_WrongNumArgs(interp
, 1, argv
, "powerstatus");
443 bool dropout
= readPowerDropout();
445 Jim_SetResult(interp
, Jim_NewIntObj(interp
, dropout
));
452 int zy1000_quit(void)
460 int interface_jtag_execute_queue(void)
466 /* We must make sure to write data read back to memory location before we return
469 zy1000_flush_readqueue();
473 /* Only check for errors when using RCLK to speed up
476 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0x10, empty
);
477 /* clear JTAG error register */
478 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x14, 0x400);
480 if ((empty
&0x400) != 0)
482 LOG_WARNING("RCLK timeout");
483 /* the error is informative only as we don't want to break the firmware if there
484 * is a false positive.
486 // return ERROR_FAIL;
495 static void writeShiftValue(uint8_t *data
, int bits
);
497 // here we shuffle N bits out/in
498 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
)
500 tap_state_t pause_state
= shiftState
;
501 for (int j
= 0; j
< num_bits
; j
+= 32)
503 int k
= num_bits
- j
;
507 /* we have more to shift out */
508 } else if (pause_now
)
510 /* this was the last to shift out this time */
511 pause_state
= end_state
;
514 // we have (num_bits + 7)/8 bytes of bits to toggle out.
515 // bits are pushed out LSB to MSB
518 if (out_value
!= NULL
)
520 for (int l
= 0; l
< k
; l
+= 8)
522 value
|=out_value
[(j
+ l
)/8]<<l
;
525 /* mask away unused bits for easier debugging */
528 value
&=~(((uint32_t)0xffffffff) << k
);
531 /* Shifting by >= 32 is not defined by the C standard
532 * and will in fact shift by &0x1f bits on nios */
535 shiftValueInner(shiftState
, pause_state
, k
, value
);
537 if (in_value
!= NULL
)
539 writeShiftValue(in_value
+ (j
/8), k
);
544 static __inline
void scanFields(int num_fields
, const struct scan_field
*fields
, tap_state_t shiftState
, tap_state_t end_state
)
546 for (int i
= 0; i
< num_fields
; i
++)
548 scanBits(fields
[i
].out_value
,
557 int interface_jtag_add_ir_scan(struct jtag_tap
*active
, const struct scan_field
*fields
, tap_state_t state
)
560 struct jtag_tap
*tap
, *nextTap
;
561 tap_state_t pause_state
= TAP_IRSHIFT
;
563 for (tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= nextTap
)
565 nextTap
= jtag_tap_next_enabled(tap
);
570 scan_size
= tap
->ir_length
;
572 /* search the list */
575 scanFields(1, fields
, TAP_IRSHIFT
, pause_state
);
576 /* update device information */
577 buf_cpy(fields
[0].out_value
, tap
->cur_instr
, scan_size
);
582 /* if a device isn't listed, set it to BYPASS */
583 assert(scan_size
<= 32);
584 shiftValueInner(TAP_IRSHIFT
, pause_state
, scan_size
, 0xffffffff);
597 int interface_jtag_add_plain_ir_scan(int num_bits
, const uint8_t *out_bits
, uint8_t *in_bits
, tap_state_t state
)
599 scanBits(out_bits
, in_bits
, num_bits
, true, TAP_IRSHIFT
, state
);
603 int interface_jtag_add_dr_scan(struct jtag_tap
*active
, int num_fields
, const struct scan_field
*fields
, tap_state_t state
)
605 struct jtag_tap
*tap
, *nextTap
;
606 tap_state_t pause_state
= TAP_DRSHIFT
;
607 for (tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= nextTap
)
609 nextTap
= jtag_tap_next_enabled(tap
);
615 /* Find a range of fields to write to this tap */
618 assert(!tap
->bypass
);
620 scanFields(num_fields
, fields
, TAP_DRSHIFT
, pause_state
);
623 /* Shift out a 0 for disabled tap's */
625 shiftValueInner(TAP_DRSHIFT
, pause_state
, 1, 0);
631 int interface_jtag_add_plain_dr_scan(int num_bits
, const uint8_t *out_bits
, uint8_t *in_bits
, tap_state_t state
)
633 scanBits(out_bits
, in_bits
, num_bits
, true, TAP_DRSHIFT
, state
);
637 int interface_jtag_add_tlr()
639 setCurrentState(TAP_RESET
);
644 int interface_jtag_add_reset(int req_trst
, int req_srst
)
646 zy1000_reset(req_trst
, req_srst
);
650 static int zy1000_jtag_add_clocks(int num_cycles
, tap_state_t state
, tap_state_t clockstate
)
652 /* num_cycles can be 0 */
653 setCurrentState(clockstate
);
655 /* execute num_cycles, 32 at the time. */
657 for (i
= 0; i
< num_cycles
; i
+= 32)
661 if (num_cycles
-i
< num
)
665 shiftValueInner(clockstate
, clockstate
, num
, 0);
669 /* finish in end_state */
670 setCurrentState(state
);
672 tap_state_t t
= TAP_IDLE
;
673 /* test manual drive code on any target */
675 uint8_t tms_scan
= tap_get_tms_path(t
, state
);
676 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
678 for (i
= 0; i
< tms_count
; i
++)
680 tms
= (tms_scan
>> i
) & 1;
682 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, tms
);
685 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, state
);
691 int interface_jtag_add_runtest(int num_cycles
, tap_state_t state
)
693 return zy1000_jtag_add_clocks(num_cycles
, state
, TAP_IDLE
);
696 int interface_jtag_add_clocks(int num_cycles
)
698 return zy1000_jtag_add_clocks(num_cycles
, cmd_queue_cur_state
, cmd_queue_cur_state
);
701 int interface_add_tms_seq(unsigned num_bits
, const uint8_t *seq
, enum tap_state state
)
703 /*wait for the fifo to be empty*/
706 for (unsigned i
= 0; i
< num_bits
; i
++)
710 if (((seq
[i
/8] >> (i
% 8)) & 1) == 0)
720 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, tms
);
724 if (state
!= TAP_INVALID
)
726 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, state
);
729 /* this would be normal if we are switching to SWD mode */
734 int interface_jtag_add_pathmove(int num_states
, const tap_state_t
*path
)
741 tap_state_t cur_state
= cmd_queue_cur_state
;
744 memset(seq
, 0, sizeof(seq
));
745 assert(num_states
< (int)((sizeof(seq
) * 8)));
749 if (tap_state_transition(cur_state
, false) == path
[state_count
])
753 else if (tap_state_transition(cur_state
, true) == path
[state_count
])
759 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state
), tap_state_name(path
[state_count
]));
763 seq
[state_count
/8] = seq
[state_count
/8] | (tms
<< (state_count
% 8));
765 cur_state
= path
[state_count
];
770 return interface_add_tms_seq(state_count
, seq
, cur_state
);
773 static void jtag_pre_post_bits(struct jtag_tap
*tap
, int *pre
, int *post
)
775 /* bypass bits before and after */
780 struct jtag_tap
*cur_tap
, *nextTap
;
781 for (cur_tap
= jtag_tap_next_enabled(NULL
); cur_tap
!= NULL
; cur_tap
= nextTap
)
783 nextTap
= jtag_tap_next_enabled(cur_tap
);
803 static const int embeddedice_num_bits[] = {32, 6};
807 values[1] = (1 << 5) | reg_addr;
811 embeddedice_num_bits,
816 void embeddedice_write_dcc(struct jtag_tap
*tap
, int reg_addr
, uint8_t *buffer
, int little
, int count
)
820 for (i
= 0; i
< count
; i
++)
822 embeddedice_write_reg_inner(tap
, reg_addr
, fast_target_buffer_get_u32(buffer
, little
));
828 jtag_pre_post_bits(tap
, &pre_bits
, &post_bits
);
830 if ((pre_bits
> 32) || (post_bits
+ 6 > 32))
833 for (i
= 0; i
< count
; i
++)
835 embeddedice_write_reg_inner(tap
, reg_addr
, fast_target_buffer_get_u32(buffer
, little
));
841 for (i
= 0; i
< count
; i
++)
843 /* Fewer pokes means we get to use the FIFO more efficiently */
844 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, pre_bits
, 0);
845 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, 32, fast_target_buffer_get_u32(buffer
, little
));
846 /* Danger! here we need to exit into the TAP_IDLE state to make
847 * DCC pick up this value.
849 shiftValueInner(TAP_DRSHIFT
, TAP_IDLE
, 6 + post_bits
, (reg_addr
| (1 << 5)));
858 int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap
* tap
, uint32_t opcode
, uint32_t * data
, size_t count
)
860 /* bypass bits before and after */
863 jtag_pre_post_bits(tap
, &pre_bits
, &post_bits
);
866 if ((pre_bits
> 32) || (post_bits
> 32))
868 int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap
* tap
, uint32_t opcode
, uint32_t * data
, size_t count
);
869 return arm11_run_instr_data_to_core_noack_inner_default(tap
, opcode
, data
, count
);
872 static const int bits
[] = {32, 2};
873 uint32_t values
[] = {0, 0};
875 /* FIX!!!!!! the target_write_memory() API started this nasty problem
876 * with unaligned uint32_t * pointers... */
877 const uint8_t *t
= (const uint8_t *)data
;
882 /* Danger! This code doesn't update cmd_queue_cur_state, so
883 * invoking jtag_add_pathmove() before jtag_add_dr_out() after
884 * this loop would fail!
886 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, pre_bits
, 0);
894 shiftValueInner(TAP_DRSHIFT
, TAP_DRSHIFT
, 32, value
);
896 shiftValueInner(TAP_DRSHIFT
, TAP_DRPAUSE
, post_bits
, 0);
898 /* copy & paste from arm11_dbgtap.c */
899 //TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT
900 /* KLUDGE! we have to flush the fifo or the Nios CPU locks up.
901 * This is probably a bug in the Avalon bus(cross clocking bridge?)
902 * or in the jtag registers module.
905 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 1);
906 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 1);
907 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
908 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
909 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
910 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 1);
911 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
912 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x28, 0);
913 /* we don't have to wait for the queue to empty here */
914 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x20, TAP_DRSHIFT
);
917 static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay
[] =
919 TAP_DREXIT2
, TAP_DRUPDATE
, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TAP_DRSELECT
, TAP_DRCAPTURE
, TAP_DRSHIFT
923 values
[0] |= (*t
++<<8);
924 values
[0] |= (*t
++<<16);
925 values
[0] |= (*t
++<<24);
933 jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay
),
934 arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay
);
939 values
[0] |= (*t
++<<8);
940 values
[0] |= (*t
++<<16);
941 values
[0] |= (*t
++<<24);
943 /* This will happen on the last iteration updating cmd_queue_cur_state
944 * so we don't have to track it during the common code path
952 return jtag_execute_queue();
957 static const struct command_registration zy1000_commands
[] = {
960 .handler
= handle_power_command
,
962 .help
= "Turn power switch to target on/off. "
963 "With no arguments, prints status.",
964 .usage
= "('on'|'off)",
968 .name
= "zy1000_version",
970 .jim_handler
= jim_zy1000_version
,
971 .help
= "Print version info for zy1000.",
972 .usage
= "['openocd'|'zy1000'|'date'|'time'|'pcb'|'fpga']",
976 .name
= "zy1000_server",
978 .jim_handler
= jim_zy1000_server
,
979 .help
= "Tcpip address for ZY1000 server.",
984 .name
= "powerstatus",
986 .jim_handler
= zylinjtag_Jim_Command_powerstatus
,
987 .help
= "Returns power status of target",
989 #ifdef CYGPKG_HAL_NIOS2
991 .name
= "updatezy1000firmware",
993 .jim_handler
= jim_zy1000_writefirmware
,
994 .help
= "writes firmware to flash",
995 /* .usage = "some_string", */
998 COMMAND_REGISTRATION_DONE
1002 static int tcp_ip
= -1;
1004 /* Write large packets if we can */
1005 static size_t out_pos
;
1006 static uint8_t out_buffer
[16384];
1007 static size_t in_pos
;
1008 static size_t in_write
;
1009 static uint8_t in_buffer
[16384];
1011 static bool flush_writes(void)
1013 bool ok
= (write(tcp_ip
, out_buffer
, out_pos
) == (int)out_pos
);
1018 static bool writeLong(uint32_t l
)
1021 for (i
= 0; i
< 4; i
++)
1023 uint8_t c
= (l
>> (i
*8))&0xff;
1024 out_buffer
[out_pos
++] = c
;
1025 if (out_pos
>= sizeof(out_buffer
))
1027 if (!flush_writes())
1036 static bool readLong(uint32_t *out_data
)
1040 if (!flush_writes())
1048 for (i
= 0; i
< 4; i
++)
1051 if (in_pos
== in_write
)
1055 t
= read(tcp_ip
, in_buffer
, sizeof(in_buffer
));
1060 in_write
= (size_t) t
;
1063 c
= in_buffer
[in_pos
++];
1065 data
|= (c
<< (i
*8));
1073 ZY1000_CMD_POKE
= 0x0,
1074 ZY1000_CMD_PEEK
= 0x8,
1075 ZY1000_CMD_SLEEP
= 0x1,
1076 ZY1000_CMD_WAITIDLE
= 2
1080 #if !BUILD_ECOSBOARD
1082 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
1083 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
1085 /* We initialize this late since we need to know the server address
1088 static void tcpip_open(void)
1093 struct sockaddr_in echoServAddr
; /* Echo server address */
1095 /* Create a reliable, stream socket using TCP */
1096 if ((tcp_ip
= socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
1098 fprintf(stderr
, "Failed to connect to zy1000 server\n");
1102 /* Construct the server address structure */
1103 memset(&echoServAddr
, 0, sizeof(echoServAddr
)); /* Zero out structure */
1104 echoServAddr
.sin_family
= AF_INET
; /* Internet address family */
1105 echoServAddr
.sin_addr
.s_addr
= inet_addr(tcp_server
); /* Server IP address */
1106 echoServAddr
.sin_port
= htons(7777); /* Server port */
1108 /* Establish the connection to the echo server */
1109 if (connect(tcp_ip
, (struct sockaddr
*) &echoServAddr
, sizeof(echoServAddr
)) < 0)
1111 fprintf(stderr
, "Failed to connect to zy1000 server\n");
1116 setsockopt(tcp_ip
, /* socket affected */
1117 IPPROTO_TCP
, /* set option at TCP level */
1118 TCP_NODELAY
, /* name of option */
1119 (char *)&flag
, /* the cast is historical cruft */
1120 sizeof(int)); /* length of option value */
1126 void zy1000_tcpout(uint32_t address
, uint32_t data
)
1129 if (!writeLong((ZY1000_CMD_POKE
<< 24) | address
)||
1132 fprintf(stderr
, "Could not write to zy1000 server\n");
1137 /* By sending the wait to the server, we avoid a readback
1138 * of status. Radically improves performance for this operation
1139 * with long ping times.
1144 if (!writeLong((ZY1000_CMD_WAITIDLE
<< 24)))
1146 fprintf(stderr
, "Could not write to zy1000 server\n");
1151 uint32_t zy1000_tcpin(uint32_t address
)
1155 zy1000_flush_readqueue();
1158 if (!writeLong((ZY1000_CMD_PEEK
<< 24) | address
)||
1161 fprintf(stderr
, "Could not read from zy1000 server\n");
1167 int interface_jtag_add_sleep(uint32_t us
)
1170 if (!writeLong((ZY1000_CMD_SLEEP
<< 24))||
1173 fprintf(stderr
, "Could not read from zy1000 server\n");
1179 /* queue a readback */
1180 #define readqueue_size 16384
1185 } readqueue
[readqueue_size
];
1187 static int readqueue_pos
= 0;
1189 /* flush the readqueue, this means reading any data that
1190 * we're expecting and store them into the final position
1192 void zy1000_flush_readqueue(void)
1194 if (readqueue_pos
== 0)
1196 /* simply debugging by allowing easy breakpoints when there
1197 * is something to do. */
1202 for (i
= 0; i
< readqueue_pos
; i
++)
1205 if (!readLong(&value
))
1207 fprintf(stderr
, "Could not read from zy1000 server\n");
1211 uint8_t *in_value
= readqueue
[i
].dest
;
1212 int k
= readqueue
[i
].bits
;
1214 // we're shifting in data to MSB, shift data to be aligned for returning the value
1217 for (int l
= 0; l
< k
; l
+= 8)
1219 in_value
[l
/8]=(value
>> l
)&0xff;
1225 static void writeShiftValue(uint8_t *data
, int bits
)
1229 if (!writeLong((ZY1000_CMD_PEEK
<< 24) | (ZY1000_JTAG_BASE
+ 0xc)))
1231 fprintf(stderr
, "Could not read from zy1000 server\n");
1235 if (readqueue_pos
>= readqueue_size
)
1237 zy1000_flush_readqueue();
1240 readqueue
[readqueue_pos
].dest
= data
;
1241 readqueue
[readqueue_pos
].bits
= bits
;
1247 static void writeShiftValue(uint8_t *data
, int bits
)
1251 ZY1000_PEEK(ZY1000_JTAG_BASE
+ 0xc, value
);
1252 VERBOSE(LOG_INFO("getShiftValue %08x", value
));
1254 // data in, LSB to MSB
1255 // we're shifting in data to MSB, shift data to be aligned for returning the value
1256 value
>>= 32 - bits
;
1258 for (int l
= 0; l
< bits
; l
+= 8)
1260 data
[l
/8]=(value
>> l
)&0xff;
1267 static char tcpip_stack
[2048];
1268 static cyg_thread tcpip_thread_object
;
1269 static cyg_handle_t tcpip_thread_handle
;
1271 static char watchdog_stack
[2048];
1272 static cyg_thread watchdog_thread_object
;
1273 static cyg_handle_t watchdog_thread_handle
;
1275 /* Infinite loop peeking & poking */
1276 static void tcpipserver(void)
1281 if (!readLong(&address
))
1283 enum ZY1000_CMD c
= (address
>> 24) & 0xff;
1284 address
&= 0xffffff;
1287 case ZY1000_CMD_POKE
:
1290 if (!readLong(&data
))
1292 address
&= ~0x80000000;
1293 ZY1000_POKE(address
+ ZY1000_JTAG_BASE
, data
);
1296 case ZY1000_CMD_PEEK
:
1299 ZY1000_PEEK(address
+ ZY1000_JTAG_BASE
, data
);
1300 if (!writeLong(data
))
1304 case ZY1000_CMD_SLEEP
:
1307 if (!readLong(&data
))
1312 case ZY1000_CMD_WAITIDLE
:
1324 static void tcpip_server(cyg_addrword_t data
)
1326 int so_reuseaddr_option
= 1;
1329 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
1331 LOG_ERROR("error creating socket: %s", strerror(errno
));
1335 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
1338 struct sockaddr_in sin
;
1339 unsigned int address_size
;
1340 address_size
= sizeof(sin
);
1341 memset(&sin
, 0, sizeof(sin
));
1342 sin
.sin_family
= AF_INET
;
1343 sin
.sin_addr
.s_addr
= INADDR_ANY
;
1344 sin
.sin_port
= htons(7777);
1346 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
1348 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
1352 if (listen(fd
, 1) == -1)
1354 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
1361 tcp_ip
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
1368 setsockopt(tcp_ip
, /* socket affected */
1369 IPPROTO_TCP
, /* set option at TCP level */
1370 TCP_NODELAY
, /* name of option */
1371 (char *)&flag
, /* the cast is historical cruft */
1372 sizeof(int)); /* length of option value */
1374 bool save_poll
= jtag_poll_get_enabled();
1376 /* polling will screw up the "connection" */
1377 jtag_poll_set_enabled(false);
1381 jtag_poll_set_enabled(save_poll
);
1390 #ifdef WATCHDOG_BASE
1391 /* If we connect to port 8888 we must send a char every 10s or the board resets itself */
1392 static void watchdog_server(cyg_addrword_t data
)
1394 int so_reuseaddr_option
= 1;
1397 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
1399 LOG_ERROR("error creating socket: %s", strerror(errno
));
1403 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
1406 struct sockaddr_in sin
;
1407 unsigned int address_size
;
1408 address_size
= sizeof(sin
);
1409 memset(&sin
, 0, sizeof(sin
));
1410 sin
.sin_family
= AF_INET
;
1411 sin
.sin_addr
.s_addr
= INADDR_ANY
;
1412 sin
.sin_port
= htons(8888);
1414 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
1416 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
1420 if (listen(fd
, 1) == -1)
1422 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
1429 int watchdog_ip
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
1431 /* Start watchdog, must be reset every 10 seconds. */
1432 HAL_WRITE_UINT32(WATCHDOG_BASE
+ 4, 4);
1434 if (watchdog_ip
< 0)
1436 LOG_ERROR("couldn't open watchdog socket: %s", strerror(errno
));
1441 setsockopt(watchdog_ip
, /* socket affected */
1442 IPPROTO_TCP
, /* set option at TCP level */
1443 TCP_NODELAY
, /* name of option */
1444 (char *)&flag
, /* the cast is historical cruft */
1445 sizeof(int)); /* length of option value */
1451 if (read(watchdog_ip
, &buf
, 1) == 1)
1454 HAL_WRITE_UINT32(WATCHDOG_BASE
+ 8, 0x1234);
1455 /* Echo so we can telnet in and see that resetting works */
1456 write(watchdog_ip
, &buf
, 1);
1459 /* Stop tickling the watchdog, the CPU will reset in < 10 seconds
1472 int interface_jtag_add_sleep(uint32_t us
)
1481 int zy1000_init(void)
1484 LOG_USER("%s", ZYLIN_OPENOCD_VERSION
);
1487 ZY1000_POKE(ZY1000_JTAG_BASE
+ 0x10, 0x30); // Turn on LED1 & LED2
1489 setPower(true); // on by default
1492 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
1494 zy1000_speed(jtag_get_speed());
1498 cyg_thread_create(1, tcpip_server
, (cyg_addrword_t
) 0, "tcip/ip server",
1499 (void *) tcpip_stack
, sizeof(tcpip_stack
),
1500 &tcpip_thread_handle
, &tcpip_thread_object
);
1501 cyg_thread_resume(tcpip_thread_handle
);
1502 #ifdef WATCHDOG_BASE
1503 cyg_thread_create(1, watchdog_server
, (cyg_addrword_t
) 0, "watchdog tcip/ip server",
1504 (void *) watchdog_stack
, sizeof(watchdog_stack
),
1505 &watchdog_thread_handle
, &watchdog_thread_object
);
1506 cyg_thread_resume(watchdog_thread_handle
);
1515 struct jtag_interface zy1000_interface
=
1518 .supported
= DEBUG_CAP_TMS_SEQ
,
1519 .execute_queue
= NULL
,
1520 .speed
= zy1000_speed
,
1521 .commands
= zy1000_commands
,
1522 .init
= zy1000_init
,
1523 .quit
= zy1000_quit
,
1525 .speed_div
= zy1000_speed_div
,
1526 .power_dropout
= zy1000_power_dropout
,
1527 .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)