1 /***************************************************************************
2 * Copyright (C) 2007-2009 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 ***************************************************************************/
24 #include <helper/types.h>
25 #include <jtag/jtag.h>
26 #include <helper/ioutil.h>
27 #include <helper/configuration.h>
29 #include <server/server.h>
30 #include <server/telnet_server.h>
31 #include <server/gdb_server.h>
34 #include <helper/time_support.h>
42 #include <cyg/io/flash.h>
43 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
48 #include <cyg/fileio/fileio.h>
50 #include <cyg/athttpd/http.h>
51 #include <cyg/athttpd/socket.h>
52 #include <cyg/athttpd/handler.h>
53 #include <cyg/athttpd/cgi.h>
54 #include <cyg/athttpd/forms.h>
55 #include <cyg/discover/discover.h>
56 #include <cyg/hal/hal_diag.h>
57 #include <cyg/kernel/kapi.h>
58 #include <cyg/io/serialio.h>
59 #include <cyg/io/io.h>
60 #include <netinet/tcp.h>
62 #include <sys/ioctl.h>
63 #include <sys/socket.h>
64 #include <netinet/in.h>
66 #include <arpa/inet.h>
67 #include <sys/types.h>
68 #include <sys/socket.h>
70 #include <netinet/in.h>
72 #include <arpa/inet.h>
82 #ifdef CYGPKG_HAL_NIOS2
83 #define ZY1000_SER_DEV "/dev/uart_0"
85 #define ZY1000_SER_DEV "/dev/ser0"
91 #if defined(CYGPKG_NET_FREEBSD_STACK)
92 #include <tftp_support.h>
93 /* posix compatibility broken*/
94 struct tftpd_fileops fileops
=
96 (int (*)(const char *, int))open
,
98 (int (*)(int, const void *, int))write
,
99 (int (*)(int, void *, int))read
105 void diag_write(char *buf
, int len
)
108 for (j
= 0; j
< len
; j
++)
110 diag_printf("%c", buf
[j
]);
114 static bool serialLog
= true;
115 static bool writeLog
= true;
120 extern struct flash_driver
*flash_drivers
[];
121 extern struct target_type
*target_types
[];
123 #ifdef CYGPKG_PROFILE_GPROF
124 #include <cyg/profile/profile.h>
126 extern char _stext
, _etext
; // Defined by the linker
128 static char *start_of_code
=&_stext
;
129 static char *end_of_code
=&_etext
;
131 void start_profile(void)
133 // This starts up the system-wide profiling, gathering
134 // profile information on all of the code, with a 16 byte
135 // "bucket" size, at a rate of 100us/profile hit.
136 // Note: a bucket size of 16 will give pretty good function
137 // resolution. Much smaller and the buffer becomes
138 // much too large for very little gain.
139 // Note: a timer period of 100us is also a reasonable
140 // compromise. Any smaller and the overhead of
141 // handling the timter (profile) interrupt could
142 // swamp the system. A fast processor might get
143 // by with a smaller value, but a slow one could
144 // even be swamped by this value. If the value is
145 // too large, the usefulness of the profile is reduced.
147 // no more interrupts than 1/10ms.
148 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
149 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
150 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
156 static char reboot_stack
[2048];
158 static void zylinjtag_reboot(cyg_addrword_t data
)
161 diag_printf("Rebooting in 500 ticks..\n");
162 cyg_thread_delay(500);
163 diag_printf("Unmounting /config..\n");
165 diag_printf("Rebooting..\n");
166 HAL_PLATFORM_RESET();
168 static cyg_thread zylinjtag_thread_object
;
169 static cyg_handle_t zylinjtag_thread_handle
;
173 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
174 (void *) reboot_stack
, sizeof(reboot_stack
),
175 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
176 cyg_thread_resume(zylinjtag_thread_handle
);
179 static char zylinjtag_reboot_port_stack
[2048];
180 static cyg_thread zylinjtag_reboot_port_thread_object
;
181 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
183 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
185 int so_reuseaddr_option
= 1;
188 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
190 LOG_ERROR("error creating socket: %s", strerror(errno
));
194 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
197 struct sockaddr_in sin
;
198 unsigned int address_size
;
199 address_size
= sizeof(sin
);
200 memset(&sin
, 0, sizeof(sin
));
201 sin
.sin_family
= AF_INET
;
202 sin
.sin_addr
.s_addr
= INADDR_ANY
;
203 sin
.sin_port
= htons(1234);
205 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
207 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
211 if (listen(fd
, 1) == -1)
213 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
216 // socket_nonblock(fd);
219 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
221 diag_printf("Got reboot signal on port 1234");
227 void reboot_port(void)
229 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
230 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
231 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
232 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
235 int configuration_output_handler(struct command_context
*context
,
238 diag_printf("%s", line
);
243 int zy1000_configuration_output_handler_log(struct command_context
*context
,
246 LOG_USER_N("%s", line
);
251 #ifdef CYGPKG_PROFILE_GPROF
252 //extern int64_t totaltime;
254 static int zylinjtag_Jim_Command_profile(Jim_Interp
*interp
, int argc
,
255 Jim_Obj
* const *argv
)
257 if ((argc
== 2) && (strcmp(Jim_GetString(argv
[1], NULL
), "stats")==0))
260 //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
263 LOG_USER("Profiling started");
272 externC
void phi_init_all_network_interfaces(void);
274 struct command_context
*cmd_ctx
;
276 static bool webRunning
= false;
278 void keep_webserver(void)
280 // Target initialisation is only attempted at startup, so we sleep forever and
281 // let the http server bail us out(i.e. get config files set up).
282 diag_printf("OpenOCD has invoked exit().\n"
283 "Use web server to correct any configuration settings and reboot.\n");
287 // exit() will terminate the current thread and we we'll then sleep eternally or
288 // we'll have a reboot scheduled.
291 extern void printDccChar(char c
);
293 static char logBuffer
[128 * 1024];
294 static const int logSize
= sizeof(logBuffer
);
298 void _zylinjtag_diag_write_char(char c
, void **param
)
302 logBuffer
[writePtr
] = c
;
303 writePtr
= (writePtr
+ 1) % logSize
;
310 HAL_DIAG_WRITE_CHAR('\r');
312 HAL_DIAG_WRITE_CHAR(c
);
315 #ifdef CYGPKG_HAL_ZYLIN_PHI
320 void copyfile(char *name2
, char *name1
);
322 void copydir(char *name
, char *destdir
);
325 MTAB_ENTRY(romfs_mte1
,
329 (CYG_ADDRWORD
) &filedata
[0]);
332 void openocd_sleep_prelude(void)
334 cyg_mutex_unlock(&httpstate
.jim_lock
);
337 void openocd_sleep_postlude(void)
339 cyg_mutex_lock(&httpstate
.jim_lock
);
344 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
345 diag_printf("Formatting JFFS2...\n");
347 cyg_io_handle_t handle
;
350 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
353 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
358 cyg_io_flash_getconfig_devsize_t ds
;
360 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
363 diag_printf("Flash error cyg_io_get_config %d\n", err
);
367 cyg_io_flash_getconfig_erase_t e
;
373 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
374 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
377 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
381 diag_printf("Flash formatted successfully\n");
387 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
388 Jim_Obj
* const *argv
)
400 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
401 Jim_Obj
* const *argv
)
403 cyg_handle_t thread
= 0;
405 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
407 /* Loop over the threads, and generate a table row for
410 while (cyg_thread_get_next(&thread
, &id
))
412 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
414 cyg_thread_info info
;
417 cyg_thread_get_info(thread
, id
, &info
);
419 if (info
.name
== NULL
)
420 info
.name
= "<no name>";
422 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
423 info
.name
, strlen(info
.name
)));
425 /* Translate the state into a string.
428 state_string
= "RUN";
429 else if (info
.state
& 0x04)
430 state_string
= "SUSP";
432 switch (info
.state
& 0x1b)
435 state_string
= "SLEEP";
438 state_string
= "CNTSLEEP";
441 state_string
= "CREATE";
444 state_string
= "EXIT";
447 state_string
= "????";
451 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
452 state_string
, strlen(state_string
)));
454 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
455 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
457 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
460 Jim_ListAppendElement(interp
, threads
, threadObj
);
462 Jim_SetResult(interp
, threads
);
467 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
468 Jim_Obj
* const *argv
)
470 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
472 if (logCount
>= logSize
)
474 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
475 % logSize
, logSize
- logCount
% logSize
);
477 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
479 Jim_SetResult(interp
, tclOutput
);
483 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
484 Jim_Obj
* const *argv
)
490 static void zylinjtag_startNetwork(void)
492 // Bring TCP/IP up immediately before we're ready to accept commands.
494 // That is as soon as a PING responds, we're accepting telnet sessions.
495 #if defined(CYGPKG_NET_FREEBSD_STACK)
496 phi_init_all_network_interfaces();
502 diag_printf("Network not up and running\n");
506 /* very first thing we want is a reboot capability */
509 #if defined(CYGPKG_NET_FREEBSD_STACK)
511 tftpd_start(69, &fileops
);
514 cyg_httpd_init_tcl_interpreter();
516 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
518 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
519 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
520 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
521 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
522 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
523 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
529 diag_printf("Web server running\n");
533 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
536 strcpy(ifr
.ifr_name
, "eth0");
538 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
543 diag_printf("Can't obtain MAC address\n");
548 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
549 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
550 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
551 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
552 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
553 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
554 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
557 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
562 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
567 char *infoStr
= "unknown";
570 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
571 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
572 infoStr
= "undefined instruction";
574 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
575 infoStr
= "software interrupt";
577 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
578 infoStr
= "abort prefetch";
580 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
581 infoStr
= "abort data";
588 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
590 diag_printf("Dumping log\n---\n");
591 if (logCount
>= logSize
)
593 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
595 diag_write(logBuffer
, writePtr
);
597 diag_printf("---\nLogdump complete.\n");
598 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
599 diag_printf("\n---\nRebooting\n");
600 HAL_PLATFORM_RESET();
604 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
605 static void setHandler(cyg_code_t exception
)
607 cyg_exception_handler_t
*old_handler
;
608 cyg_addrword_t old_data
;
610 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
611 &old_handler
, &old_data
);
615 static cyg_thread zylinjtag_uart_thread_object
;
616 static cyg_handle_t zylinjtag_uart_thread_handle
;
617 static char uart_stack
[4096];
619 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
620 static char backwardBuffer
[1024];
622 void setNoDelay(int session
, int flag
)
625 // This decreases latency dramatically for e.g. GDB load which
626 // does not have a sliding window protocol
628 // Can cause *lots* of TCP/IP packets to be sent and it would have
629 // to be enabled/disabled on the fly to avoid the CPU being
631 setsockopt(session
, /* socket affected */
632 IPPROTO_TCP
, /* set option at TCP level */
633 TCP_NODELAY
, /* name of option */
634 (char *) &flag
, /* the cast is historical
636 sizeof(int)); /* length of option value */
640 #define TEST_TCPIP() 0
649 } tcpipSent
[512 * 1024];
653 static void zylinjtag_uart(cyg_addrword_t data
)
655 int so_reuseaddr_option
= 1;
658 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
660 LOG_ERROR("error creating socket: %s", strerror(errno
));
664 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
667 struct sockaddr_in sin
;
668 unsigned int address_size
;
669 address_size
= sizeof(sin
);
670 memset(&sin
, 0, sizeof(sin
));
671 sin
.sin_family
= AF_INET
;
672 sin
.sin_addr
.s_addr
= INADDR_ANY
;
673 sin
.sin_port
= htons(5555);
675 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
677 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
681 if (listen(fd
, 1) == -1)
683 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
686 // socket_nonblock(fd);
691 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
697 setNoDelay(session
, 1);
698 int oldopts
= fcntl(session
, F_GETFL
, 0);
699 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
701 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
708 #ifdef CYGPKG_PROFILE_GPROF
726 FD_SET(session
, &read_fds
);
728 FD_SET(serHandle
, &read_fds
);
729 if (serHandle
> fd_max
)
735 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
736 if ((actual
== 0) && (actual2
== 0))
738 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
747 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
749 t
= read(serHandle
, backwardBuffer
,
750 sizeof(backwardBuffer
));
766 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
774 if (FD_ISSET(session
, &read_fds
)
775 && (sizeof(forwardBuffer
) > actual
))
777 // NB! Here it is important that we empty the TCP/IP read buffer
778 // to make transmission tick right
779 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
782 // this will block if there is no data at all
783 t
= read_socket(session
, forwardBuffer
+ actual
,
784 sizeof(forwardBuffer
) - actual
);
795 /* Do not put things into the serial buffer if it has something to send
796 * as that can cause a single byte to be sent at the time.
800 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
807 // The serial buffer is full
820 tcpipSent
[cur
].req
= x
;
821 tcpipSent
[cur
].actual
= y
;
822 tcpipSent
[cur
].req2
= x2
;
823 tcpipSent
[cur
].actual2
= y2
;
828 closeSession
: close(session
);
833 for (i
= 0; i
< 1024; i
++)
835 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
836 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
847 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
848 (void *) uart_stack
, sizeof(uart_stack
),
849 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
850 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
851 cyg_thread_resume(zylinjtag_uart_thread_handle
);
854 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
855 Jim_Obj
* const *argv
)
857 static int current_baud
= 38400;
860 command_print(cmd_ctx
, "%d", current_baud
);
869 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
872 current_baud
= new_baudrate
;
875 switch (current_baud
)
878 baud
= CYGNUM_SERIAL_BAUD_9600
;
881 baud
= CYGNUM_SERIAL_BAUD_19200
;
884 baud
= CYGNUM_SERIAL_BAUD_38400
;
887 baud
= CYGNUM_SERIAL_BAUD_57600
;
890 baud
= CYGNUM_SERIAL_BAUD_115200
;
893 baud
= CYGNUM_SERIAL_BAUD_230400
;
896 command_print(cmd_ctx
, "unsupported baudrate");
897 return ERROR_INVALID_ARGUMENTS
;
900 cyg_serial_info_t buf
;
902 //get existing serial configuration
903 len
= sizeof(cyg_serial_info_t
);
905 cyg_io_handle_t serial_handle
;
907 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
910 LOG_ERROR("Could not open serial port\n");
914 err
= cyg_io_get_config(serial_handle
,
915 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
916 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
920 LOG_ERROR("Failed to get serial port settings %d", err
);
925 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
929 LOG_ERROR("Failed to set serial port settings %d", err
);
936 bool logAllToSerial
= false;
939 int boolParam(char *var
);
942 static const char *zylin_config_dir
="/config/settings";
944 static int add_default_dirs(void)
946 add_script_search_dir(zylin_config_dir
);
947 add_script_search_dir("/rom/lib/openocd");
948 add_script_search_dir("/rom");
952 int main(int argc
, char *argv
[])
954 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
955 * need to allocate towards the end of the heap. */
957 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
958 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
959 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
960 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
965 atexit(keep_webserver
);
967 diag_init_putc(_zylinjtag_diag_write_char
);
968 // We want this in the log.
969 diag_printf("Zylin ZY1000.\n");
971 err
= mount("", "/ram", "ramfs");
974 diag_printf("unable to mount ramfs\n");
979 sprintf(address
, "%p", &filedata
[0]);
980 err
= mount(address
, "/rom", "romfs");
983 diag_printf("unable to mount /rom\n");
986 err
= mount("", "/log", "logfs");
989 diag_printf("unable to mount logfs\n");
992 err
= mount("", "/tftp", "tftpfs");
995 diag_printf("unable to mount logfs\n");
998 log
= fopen("/log/log", "w");
1001 diag_printf("Could not open log file /ram/log\n");
1006 copydir("/rom", "/ram/cgi");
1008 err
= mount("/dev/flash1", "/config", "jffs2");
1011 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1012 err
= mount("", "/config", "ramfs");
1015 diag_printf("unable to mount /config as ramdisk.\n");
1021 /* are we using a ram disk instead of a flash disk? This is used
1022 * for ZY1000 live demo...
1024 * copy over flash disk to ram block device
1026 if (boolParam("ramdisk"))
1028 diag_printf("Unmounting /config from flash and using ram instead\n");
1029 err
= umount("/config");
1032 diag_printf("unable to unmount jffs\n");
1036 err
= mount("/dev/flash1", "/config2", "jffs2");
1039 diag_printf("unable to mount jffs\n");
1043 err
= mount("", "/config", "ramfs");
1046 diag_printf("unable to mount ram block device\n");
1050 // copydir("/config2", "/config");
1051 copyfile("/config2/ip", "/config/ip");
1052 copydir("/config2/settings", "/config/settings");
1058 mkdir(zylin_config_dir
, 0777);
1059 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1060 mkdir(dirname
, 0777);
1062 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1063 mkdir(dirname
, 0777);
1065 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1066 mkdir(dirname
, 0777);
1069 logAllToSerial
= boolParam("logserial");
1071 // We need the network & web server in case there is something wrong with
1072 // the config files that invoke exit()
1073 zylinjtag_startNetwork();
1075 /* we're going to access the jim interpreter from here on... */
1076 openocd_sleep_postlude();
1081 /* initialize commandline interface */
1082 struct command_context
* cmd_ctx
;
1083 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1084 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1085 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1086 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1088 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1089 return EXIT_FAILURE
;
1091 #ifdef CYGPKG_PROFILE_GPROF
1092 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_profile", zylinjtag_Jim_Command_profile
,
1096 Jim_CreateCommand(httpstate
.jim_interp
, "uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1101 set_log_output(cmd_ctx
, log
);
1103 LOG_DEBUG("log init complete");
1105 // diag_printf("Executing config files\n");
1110 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1111 command_run_line(cmd_ctx
, "debug_level 3");
1114 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1117 ret
= server_init(cmd_ctx
);
1118 if (ERROR_OK
!= ret
)
1119 return EXIT_FAILURE
;
1121 /* we MUST always run the init command as it will launch telnet sessions */
1122 command_run_line(cmd_ctx
, "init");
1125 // diag_printf() is really invoked from many more places than we trust it
1126 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1128 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1129 // fingers that it doesn't cause any crashes.
1130 diag_printf("Init complete, GDB & telnet servers launched.\n");
1131 command_set_output_handler(cmd_ctx
,
1132 zy1000_configuration_output_handler_log
, NULL
);
1133 if (!logAllToSerial
)
1138 /* handle network connections */
1139 server_loop(cmd_ctx
);
1140 openocd_sleep_prelude();
1142 /* shut server down */
1145 /* free commandline interface */
1146 command_done(cmd_ctx
);
1154 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1155 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1157 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1161 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1163 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1164 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1166 #include <pkgconf/system.h>
1167 #include <pkgconf/hal.h>
1168 #include <pkgconf/kernel.h>
1169 #include <pkgconf/io_fileio.h>
1170 #include <pkgconf/fs_rom.h>
1172 #include <cyg/kernel/ktypes.h> // base kernel types
1173 #include <cyg/infra/cyg_trac.h> // tracing macros
1174 #include <cyg/infra/cyg_ass.h> // assertion macros
1175 #include <cyg/fileio/fileio.h>
1176 #include <cyg/kernel/kapi.h>
1177 #include <cyg/infra/diag.h>
1179 //==========================================================================
1180 // Eventually we want to eXecute In Place from the ROM in a protected
1181 // environment, so we'll need executables to be aligned to a boundary
1182 // suitable for MMU protection. A suitable boundary would be the 4k
1183 // boundary in all the CPU architectures I am currently aware of.
1185 // Forward definitions
1187 // Filesystem operations
1188 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1189 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1190 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1191 int mode
, cyg_file
*fte
);
1192 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1193 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1196 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1197 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1198 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1200 //==========================================================================
1201 // Filesystem table entries
1203 // -------------------------------------------------------------------------
1205 // This defines the entry in the filesystem table.
1206 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1207 // we should never block in any filesystem operations.
1209 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1214 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1215 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1216 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1217 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1218 (cyg_fsop_link
*)cyg_fileio_erofs
,
1219 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1220 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1221 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1222 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1223 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1226 // -------------------------------------------------------------------------
1228 // This defines a single ROMFS loaded into ROM at the configured address
1230 // MTAB_ENTRY(rom_mte, // structure name
1231 // "/rom", // mount point
1232 // "romfs", // FIlesystem type
1233 // "", // hardware device
1234 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1238 // -------------------------------------------------------------------------
1240 // This set of file operations are used for normal open files.
1242 static cyg_fileops tftpfs_fileops
=
1243 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1244 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1245 tftpfs_fo_fsync
, tftpfs_fo_close
,
1246 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1247 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1248 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1250 // -------------------------------------------------------------------------
1252 // Process a mount request. This mainly finds root for the
1255 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1260 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1275 static void freeTftp(struct Tftp
*t
)
1288 static const int tftpMaxSize
= 8192 * 1024;
1289 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1290 int mode
, cyg_file
*file
)
1293 tftp
= malloc(sizeof(struct Tftp
));
1296 memset(tftp
, 0, sizeof(struct Tftp
));
1298 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1299 file
->f_type
= CYG_FILE_TYPE_FILE
;
1300 file
->f_ops
= &tftpfs_fileops
;
1305 tftp
->mem
= malloc(tftpMaxSize
);
1306 if (tftp
->mem
== NULL
)
1312 char *server
= strchr(name
, '/');
1319 tftp
->server
= malloc(server
- name
+ 1);
1320 if (tftp
->server
== NULL
)
1325 strncpy(tftp
->server
, name
, server
- name
);
1326 tftp
->server
[server
- name
] = 0;
1328 tftp
->file
= strdup(server
+ 1);
1329 if (tftp
->file
== NULL
)
1335 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1340 static int fetchTftp(struct Tftp
*tftp
)
1342 if (!tftp
->readFile
)
1345 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1346 tftpMaxSize
, TFTP_OCTET
, &err
);
1348 if (tftp
->actual
< 0)
1357 // -------------------------------------------------------------------------
1358 // tftpfs_fo_write()
1359 // Read data from file.
1361 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1363 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1365 if (fetchTftp(tftp
) != ENOERR
)
1369 off_t pos
= fp
->f_offset
;
1371 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1373 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1374 char *buf
= (char *) iov
->iov_base
;
1375 off_t len
= iov
->iov_len
;
1377 if (len
+ pos
> tftp
->actual
)
1379 len
= tftp
->actual
- pos
;
1381 resid
+= iov
->iov_len
- len
;
1383 memcpy(buf
, tftp
->mem
+ pos
, len
);
1387 uio
->uio_resid
= resid
;
1393 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1395 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1398 off_t pos
= fp
->f_offset
;
1400 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1402 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1403 char *buf
= (char *) iov
->iov_base
;
1404 off_t len
= iov
->iov_len
;
1406 if (len
+ pos
> tftpMaxSize
)
1408 len
= tftpMaxSize
- pos
;
1410 resid
+= iov
->iov_len
- len
;
1412 memcpy(tftp
->mem
+ pos
, buf
, len
);
1416 uio
->uio_resid
= resid
;
1424 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1430 // -------------------------------------------------------------------------
1432 // Close a file. We just clear out the data pointer.
1434 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1436 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1441 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1442 TFTP_OCTET
, &error
);
1450 // -------------------------------------------------------------------------
1452 // Seek to a new file position.
1454 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1456 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1459 if (fetchTftp(tftp
) != ENOERR
)
1465 // Pos is already where we want to be.
1469 // Add pos to current offset.
1470 pos
+= fp
->f_offset
;
1474 // Add pos to file size.
1475 pos
+= tftp
->actual
;
1482 // Check that pos is still within current file size, or at the
1484 if (pos
< 0 || pos
> tftp
->actual
)
1487 // All OK, set fp offset and return new position.
1488 *apos
= fp
->f_offset
= pos
;
1496 cyg_thread_delay(us
/ 10000 + 1);
1502 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1504 cyg_httpd_start_chunked("text");
1505 if (logCount
>= logSize
)
1507 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1508 - logCount
% logSize
);
1510 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1511 cyg_httpd_end_chunked();
1515 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1517 // Filesystem operations
1518 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1519 static int logfs_umount(cyg_mtab_entry
*mte
);
1520 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1521 int mode
, cyg_file
*fte
);
1522 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1525 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1526 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1528 #include <cyg/io/devtab.h>
1530 //==========================================================================
1531 // Filesystem table entries
1533 // -------------------------------------------------------------------------
1535 // This defines the entry in the filesystem table.
1536 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1537 // we should never block in any filesystem operations.
1538 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1539 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1543 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1544 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1545 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1546 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1547 (cyg_fsop_link
*)cyg_fileio_erofs
,
1548 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1549 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1550 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1551 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1552 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1554 // -------------------------------------------------------------------------
1556 // This set of file operations are used for normal open files.
1558 static cyg_fileops logfs_fileops
=
1559 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1560 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1561 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1562 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1563 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1564 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1566 // -------------------------------------------------------------------------
1568 // Process a mount request. This mainly finds root for the
1571 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1576 static int logfs_umount(cyg_mtab_entry
*mte
)
1581 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1582 int mode
, cyg_file
*file
)
1584 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1585 file
->f_type
= CYG_FILE_TYPE_FILE
;
1586 file
->f_ops
= &logfs_fileops
;
1593 // -------------------------------------------------------------------------
1595 // Write data to file.
1597 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1600 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1602 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1603 char *buf
= (char *) iov
->iov_base
;
1604 off_t len
= iov
->iov_len
;
1606 diag_write(buf
, len
);
1612 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1617 // -------------------------------------------------------------------------
1619 // Close a file. We just clear out the data pointer.
1621 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1626 int loadFile(const char *fileName
, void **data
, int *len
);
1628 /* boolean parameter stored on config */
1629 int boolParam(char *var
)
1631 bool result
= false;
1632 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1638 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1642 result
= strncmp((char *) data
, "1", len
) == 0;
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)