1 /***************************************************************************
2 * Copyright (C) 2007-2008 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 ***************************************************************************/
27 #include "configuration.h"
37 #include "telnet_server.h"
38 #include "gdb_server.h"
40 #include <time_support.h>
48 #include <cyg/io/flash.h>
49 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
54 #include <cyg/fileio/fileio.h>
56 #include <cyg/athttpd/http.h>
57 #include <cyg/athttpd/socket.h>
58 #include <cyg/athttpd/handler.h>
59 #include <cyg/athttpd/cgi.h>
60 #include <cyg/athttpd/forms.h>
61 #include <cyg/discover/discover.h>
62 #include <cyg/hal/hal_diag.h>
63 #include <cyg/kernel/kapi.h>
64 #include <cyg/io/serialio.h>
65 #include <cyg/io/io.h>
66 #include <netinet/tcp.h>
68 #include <sys/ioctl.h>
69 #include <sys/socket.h>
70 #include <netinet/in.h>
72 #include <arpa/inet.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
76 #include <netinet/in.h>
78 #include <arpa/inet.h>
88 #if defined(CYGPKG_NET_FREEBSD_STACK)
89 #include <tftp_support.h>
90 /* posix compatibility broken*/
91 struct tftpd_fileops fileops
=
93 (int (*)(const char *, int))open
,
95 (int (*)(int, const void *, int))write
,
96 (int (*)(int, void *, int))read
102 void diag_write(char *buf
, int len
)
105 for (j
= 0; j
< len
; j
++)
107 diag_printf("%c", buf
[j
]);
111 static bool serialLog
= true;
112 static bool writeLog
= true;
117 extern flash_driver_t
*flash_drivers
[];
118 extern target_type_t
*target_types
[];
120 #ifdef CYGPKG_PROFILE_GPROF
121 #include <cyg/profile/profile.h>
123 extern char _stext
, _etext
; // Defined by the linker
125 static char *start_of_code
=&_stext
;
126 static char *end_of_code
=&_etext
;
128 void start_profile(void)
130 // This starts up the system-wide profiling, gathering
131 // profile information on all of the code, with a 16 byte
132 // "bucket" size, at a rate of 100us/profile hit.
133 // Note: a bucket size of 16 will give pretty good function
134 // resolution. Much smaller and the buffer becomes
135 // much too large for very little gain.
136 // Note: a timer period of 100us is also a reasonable
137 // compromise. Any smaller and the overhead of
138 // handling the timter (profile) interrupt could
139 // swamp the system. A fast processor might get
140 // by with a smaller value, but a slow one could
141 // even be swamped by this value. If the value is
142 // too large, the usefulness of the profile is reduced.
144 // no more interrupts than 1/10ms.
145 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
146 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
147 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
153 static char reboot_stack
[2048];
155 static void zylinjtag_reboot(cyg_addrword_t data
)
158 diag_printf("Rebooting in 100 ticks..\n");
159 cyg_thread_delay(100);
160 diag_printf("Unmounting /config..\n");
162 diag_printf("Rebooting..\n");
163 HAL_PLATFORM_RESET();
165 static cyg_thread zylinjtag_thread_object
;
166 static cyg_handle_t zylinjtag_thread_handle
;
170 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
171 (void *) reboot_stack
, sizeof(reboot_stack
),
172 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
173 cyg_thread_resume(zylinjtag_thread_handle
);
176 static char zylinjtag_reboot_port_stack
[2048];
177 static cyg_thread zylinjtag_reboot_port_thread_object
;
178 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
180 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
182 int so_reuseaddr_option
= 1;
185 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
187 LOG_ERROR("error creating socket: %s", strerror(errno
));
191 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
194 struct sockaddr_in sin
;
195 unsigned int address_size
;
196 address_size
= sizeof(sin
);
197 memset(&sin
, 0, sizeof(sin
));
198 sin
.sin_family
= AF_INET
;
199 sin
.sin_addr
.s_addr
= INADDR_ANY
;
200 sin
.sin_port
= htons(1234);
202 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
204 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
208 if (listen(fd
, 1) == -1)
210 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
213 // socket_nonblock(fd);
216 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
218 diag_printf("Got reboot signal on port 1234");
224 void reboot_port(void)
226 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
227 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
228 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
229 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
232 int configuration_output_handler(struct command_context_s
*context
,
235 diag_printf("%s", line
);
240 int zy1000_configuration_output_handler_log(struct command_context_s
*context
,
243 LOG_USER_N("%s", line
);
248 #ifdef CYGPKG_PROFILE_GPROF
250 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
252 command_print(cmd_ctx
, "Profiling started");
259 externC
void phi_init_all_network_interfaces(void);
261 command_context_t
*cmd_ctx
;
263 static bool webRunning
= false;
265 void keep_webserver(void)
267 // Target initialisation is only attempted at startup, so we sleep forever and
268 // let the http server bail us out(i.e. get config files set up).
269 diag_printf("OpenOCD has invoked exit().\n"
270 "Use web server to correct any configuration settings and reboot.\n");
274 // exit() will terminate the current thread and we we'll then sleep eternally or
275 // we'll have a reboot scheduled.
278 extern void printDccChar(char c
);
280 static char logBuffer
[128 * 1024];
281 static const int logSize
= sizeof(logBuffer
);
285 void _zylinjtag_diag_write_char(char c
, void **param
)
289 logBuffer
[writePtr
] = c
;
290 writePtr
= (writePtr
+ 1) % logSize
;
297 HAL_DIAG_WRITE_CHAR('\r');
299 HAL_DIAG_WRITE_CHAR(c
);
302 #ifdef CYGPKG_HAL_ZYLIN_PHI
307 void copyfile(char *name2
, char *name1
);
309 void copydir(char *name
, char *destdir
);
312 MTAB_ENTRY(romfs_mte1
,
316 (CYG_ADDRWORD
) &filedata
[0]);
319 void openocd_sleep_prelude(void)
321 cyg_mutex_unlock(&httpstate
.jim_lock
);
324 void openocd_sleep_postlude(void)
326 cyg_mutex_lock(&httpstate
.jim_lock
);
331 diag_printf("Formatting JFFS2...\n");
333 cyg_io_handle_t handle
;
336 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
339 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
344 cyg_io_flash_getconfig_devsize_t ds
;
346 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
349 diag_printf("Flash error cyg_io_get_config %d\n", err
);
353 cyg_io_flash_getconfig_erase_t e
;
359 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
360 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
363 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
367 diag_printf("Flash formatted successfully\n");
372 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
373 Jim_Obj
* const *argv
)
385 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
386 Jim_Obj
* const *argv
)
388 cyg_handle_t thread
= 0;
390 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
392 /* Loop over the threads, and generate a table row for
395 while (cyg_thread_get_next(&thread
, &id
))
397 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
399 cyg_thread_info info
;
402 cyg_thread_get_info(thread
, id
, &info
);
404 if (info
.name
== NULL
)
405 info
.name
= "<no name>";
407 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
408 info
.name
, strlen(info
.name
)));
410 /* Translate the state into a string.
413 state_string
= "RUN";
414 else if (info
.state
& 0x04)
415 state_string
= "SUSP";
417 switch (info
.state
& 0x1b)
420 state_string
= "SLEEP";
423 state_string
= "CNTSLEEP";
426 state_string
= "CREATE";
429 state_string
= "EXIT";
432 state_string
= "????";
436 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
437 state_string
, strlen(state_string
)));
439 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
440 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
442 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
445 Jim_ListAppendElement(interp
, threads
, threadObj
);
447 Jim_SetResult(interp
, threads
);
452 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
453 Jim_Obj
* const *argv
)
455 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
457 if (logCount
>= logSize
)
459 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
460 % logSize
, logSize
- logCount
% logSize
);
462 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
464 Jim_SetResult(interp
, tclOutput
);
468 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
469 Jim_Obj
* const *argv
)
476 static void zylinjtag_startNetwork(void)
478 // Bring TCP/IP up immediately before we're ready to accept commands.
480 // That is as soon as a PING responds, we're accepting telnet sessions.
481 #if defined(CYGPKG_NET_FREEBSD_STACK)
482 phi_init_all_network_interfaces();
488 diag_printf("Network not up and running\n");
492 /* very first thing we want is a reboot capability */
495 #if defined(CYGPKG_NET_FREEBSD_STACK)
497 tftpd_start(69, &fileops
);
500 cyg_httpd_init_tcl_interpreter();
502 interp
= httpstate
.jim_interp
;
504 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
506 Jim_CreateCommand(httpstate
.jim_interp
, "reboot",
507 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
508 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
509 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
510 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
511 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
517 diag_printf("Web server running\n");
521 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
524 strcpy(ifr
.ifr_name
, "eth0");
526 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
531 diag_printf("Can't obtain MAC address\n");
536 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
537 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
538 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
545 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
550 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
555 char *infoStr
= "unknown";
558 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
559 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
560 infoStr
= "undefined instruction";
562 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
563 infoStr
= "software interrupt";
565 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
566 infoStr
= "abort prefetch";
568 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
569 infoStr
= "abort data";
576 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
578 diag_printf("Dumping log\n---\n");
579 if (logCount
>= logSize
)
581 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
583 diag_write(logBuffer
, writePtr
);
585 diag_printf("---\nLogdump complete.\n");
586 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
587 diag_printf("\n---\nRebooting\n");
588 HAL_PLATFORM_RESET();
592 static void setHandler(cyg_code_t exception
)
594 cyg_exception_handler_t
*old_handler
;
595 cyg_addrword_t old_data
;
597 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
598 &old_handler
, &old_data
);
601 static cyg_thread zylinjtag_uart_thread_object
;
602 static cyg_handle_t zylinjtag_uart_thread_handle
;
603 static char uart_stack
[4096];
605 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
606 static char backwardBuffer
[1024];
608 void setNoDelay(int session
, int flag
)
611 // This decreases latency dramatically for e.g. GDB load which
612 // does not have a sliding window protocol
614 // Can cause *lots* of TCP/IP packets to be sent and it would have
615 // to be enabled/disabled on the fly to avoid the CPU being
617 setsockopt(session
, /* socket affected */
618 IPPROTO_TCP
, /* set option at TCP level */
619 TCP_NODELAY
, /* name of option */
620 (char *) &flag
, /* the cast is historical
622 sizeof(int)); /* length of option value */
632 } tcpipSent
[512 * 1024];
635 static void zylinjtag_uart(cyg_addrword_t data
)
637 int so_reuseaddr_option
= 1;
640 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
642 LOG_ERROR("error creating socket: %s", strerror(errno
));
646 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
649 struct sockaddr_in sin
;
650 unsigned int address_size
;
651 address_size
= sizeof(sin
);
652 memset(&sin
, 0, sizeof(sin
));
653 sin
.sin_family
= AF_INET
;
654 sin
.sin_addr
.s_addr
= INADDR_ANY
;
655 sin
.sin_port
= htons(5555);
657 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
659 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
663 if (listen(fd
, 1) == -1)
665 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
668 // socket_nonblock(fd);
673 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
679 setNoDelay(session
, 1);
680 int oldopts
= fcntl(session
, F_GETFL
, 0);
681 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
683 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
690 #ifdef CYGPKG_PROFILE_GPROF
706 FD_SET(session
, &read_fds
);
708 FD_SET(serHandle
, &read_fds
);
709 if (serHandle
> fd_max
)
715 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
716 if ((actual
== 0) && (actual2
== 0))
718 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
727 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
729 t
= read(serHandle
, backwardBuffer
,
730 sizeof(backwardBuffer
));
747 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
755 if (FD_ISSET(session
, &read_fds
)
756 && (sizeof(forwardBuffer
) > actual
))
758 // NB! Here it is important that we empty the TCP/IP read buffer
759 // to make transmission tick right
760 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
763 // this will block if there is no data at all
764 t
= read_socket(session
, forwardBuffer
+ actual
,
765 sizeof(forwardBuffer
) - actual
);
777 /* Do not put things into the serial buffer if it has something to send
778 * as that can cause a single byte to be sent at the time.
782 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
789 // The serial buffer is full
801 tcpipSent
[cur
].req
= x
;
802 tcpipSent
[cur
].actual
= y
;
803 tcpipSent
[cur
].req2
= x2
;
804 tcpipSent
[cur
].actual2
= y2
;
809 closeSession
: close(session
);
813 for (i
= 0; i
< 1024; i
++)
815 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
816 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
826 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
827 (void *) uart_stack
, sizeof(uart_stack
),
828 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
829 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
830 cyg_thread_resume(zylinjtag_uart_thread_handle
);
833 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
834 char **args
, int argc
)
836 static int current_baud
= 38400;
839 command_print(cmd_ctx
, "%d", current_baud
);
844 return ERROR_INVALID_ARGUMENTS
;
847 current_baud
= atol(args
[0]);
850 switch (current_baud
)
853 baud
= CYGNUM_SERIAL_BAUD_9600
;
856 baud
= CYGNUM_SERIAL_BAUD_19200
;
859 baud
= CYGNUM_SERIAL_BAUD_38400
;
862 baud
= CYGNUM_SERIAL_BAUD_57600
;
865 baud
= CYGNUM_SERIAL_BAUD_115200
;
868 baud
= CYGNUM_SERIAL_BAUD_230400
;
871 command_print(cmd_ctx
, "unsupported baudrate");
872 return ERROR_INVALID_ARGUMENTS
;
875 cyg_serial_info_t buf
;
877 //get existing serial configuration
878 len
= sizeof(cyg_serial_info_t
);
880 cyg_io_handle_t serial_handle
;
882 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
885 LOG_ERROR("/dev/ser0 not found\n");
889 err
= cyg_io_get_config(serial_handle
,
890 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
891 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
895 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
900 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
904 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
911 bool logAllToSerial
= false;
914 int boolParam(char *var
);
917 command_context_t
*setup_command_handler(void);
919 static const char *zylin_config_dir
="/config/settings";
921 int add_default_dirs(void)
923 add_script_search_dir(zylin_config_dir
);
924 add_script_search_dir("/rom/lib/openocd");
925 add_script_search_dir("/rom");
929 int ioutil_init(struct command_context_s
*cmd_ctx
);
931 int main(int argc
, char *argv
[])
933 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
934 * need to allocate towards the end of the heap. */
936 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
937 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
938 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
939 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
944 atexit(keep_webserver
);
946 diag_init_putc(_zylinjtag_diag_write_char
);
947 // We want this in the log.
948 diag_printf("Zylin ZY1000.\n");
950 err
= mount("", "/ram", "ramfs");
953 diag_printf("unable to mount ramfs\n");
958 sprintf(address
, "%p", &filedata
[0]);
959 err
= mount(address
, "/rom", "romfs");
962 diag_printf("unable to mount /rom\n");
965 err
= mount("", "/log", "logfs");
968 diag_printf("unable to mount logfs\n");
971 err
= mount("", "/tftp", "tftpfs");
974 diag_printf("unable to mount logfs\n");
977 log
= fopen("/log/log", "w");
980 diag_printf("Could not open log file /ram/log\n");
985 copydir("/rom", "/ram/cgi");
987 err
= mount("/dev/flash1", "/config", "jffs2");
990 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
991 err
= mount("", "/config", "ramfs");
994 diag_printf("unable to mount /config as ramdisk.\n");
1000 /* are we using a ram disk instead of a flash disk? This is used
1001 * for ZY1000 live demo...
1003 * copy over flash disk to ram block device
1005 if (boolParam("ramdisk"))
1007 diag_printf("Unmounting /config from flash and using ram instead\n");
1008 err
= umount("/config");
1011 diag_printf("unable to unmount jffs\n");
1015 err
= mount("/dev/flash1", "/config2", "jffs2");
1018 diag_printf("unable to mount jffs\n");
1022 err
= mount("", "/config", "ramfs");
1025 diag_printf("unable to mount ram block device\n");
1029 // copydir("/config2", "/config");
1030 copyfile("/config2/ip", "/config/ip");
1031 copydir("/config2/settings", "/config/settings");
1037 mkdir(zylin_config_dir
, 0777);
1038 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1039 mkdir(dirname
, 0777);
1041 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1042 mkdir(dirname
, 0777);
1044 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1045 mkdir(dirname
, 0777);
1048 logAllToSerial
= boolParam("logserial");
1050 // We need the network & web server in case there is something wrong with
1051 // the config files that invoke exit()
1052 zylinjtag_startNetwork();
1054 /* we're going to access the jim interpreter from here on... */
1055 openocd_sleep_postlude();
1060 /* initialize commandline interface */
1061 command_context_t
* cmd_ctx
;
1062 cmd_ctx
= setup_command_handler();
1063 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1064 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1067 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1069 return EXIT_FAILURE
;
1074 #ifdef CYGPKG_PROFILE_GPROF
1075 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1079 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1080 "uart <baud> - forward uart on port 5555");
1083 errVal
= log_init(cmd_ctx
);
1084 if (errVal
!= ERROR_OK
)
1086 diag_printf("log_init() failed %d\n", errVal
);
1090 set_log_output(cmd_ctx
, log
);
1092 LOG_DEBUG("log init complete");
1094 // diag_printf("Executing config files\n");
1099 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1100 command_run_line(cmd_ctx
, "debug_level 3");
1103 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1105 /* we MUST always run the init command as it will launch telnet sessions */
1106 command_run_line(cmd_ctx
, "init");
1109 // diag_printf() is really invoked from many more places than we trust it
1110 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1112 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1113 // fingers that it doesn't cause any crashes.
1114 diag_printf("Init complete, GDB & telnet servers launched.\n");
1115 command_set_output_handler(cmd_ctx
,
1116 zy1000_configuration_output_handler_log
, NULL
);
1117 if (!logAllToSerial
)
1122 /* handle network connections */
1123 server_loop(cmd_ctx
);
1124 openocd_sleep_prelude();
1126 /* shut server down */
1129 /* free commandline interface */
1130 command_done(cmd_ctx
);
1138 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1139 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1141 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1145 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1147 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1148 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1150 #include <pkgconf/system.h>
1151 #include <pkgconf/hal.h>
1152 #include <pkgconf/kernel.h>
1153 #include <pkgconf/io_fileio.h>
1154 #include <pkgconf/fs_rom.h>
1156 #include <cyg/kernel/ktypes.h> // base kernel types
1157 #include <cyg/infra/cyg_trac.h> // tracing macros
1158 #include <cyg/infra/cyg_ass.h> // assertion macros
1159 #include <cyg/fileio/fileio.h>
1160 #include <cyg/kernel/kapi.h>
1161 #include <cyg/infra/diag.h>
1163 //==========================================================================
1164 // Eventually we want to eXecute In Place from the ROM in a protected
1165 // environment, so we'll need executables to be aligned to a boundary
1166 // suitable for MMU protection. A suitable boundary would be the 4k
1167 // boundary in all the CPU architectures I am currently aware of.
1169 // Forward definitions
1171 // Filesystem operations
1172 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1173 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1174 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1175 int mode
, cyg_file
*fte
);
1176 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1177 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1180 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1181 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1182 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1184 //==========================================================================
1185 // Filesystem table entries
1187 // -------------------------------------------------------------------------
1189 // This defines the entry in the filesystem table.
1190 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1191 // we should never block in any filesystem operations.
1193 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1198 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1199 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1200 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1201 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1202 (cyg_fsop_link
*)cyg_fileio_erofs
,
1203 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1204 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1205 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1206 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1207 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1210 // -------------------------------------------------------------------------
1212 // This defines a single ROMFS loaded into ROM at the configured address
1214 // MTAB_ENTRY(rom_mte, // structure name
1215 // "/rom", // mount point
1216 // "romfs", // FIlesystem type
1217 // "", // hardware device
1218 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1222 // -------------------------------------------------------------------------
1224 // This set of file operations are used for normal open files.
1226 static cyg_fileops tftpfs_fileops
=
1227 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1228 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1229 tftpfs_fo_fsync
, tftpfs_fo_close
,
1230 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1231 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1232 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1234 // -------------------------------------------------------------------------
1236 // Process a mount request. This mainly finds root for the
1239 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1244 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1259 static void freeTftp(struct Tftp
*t
)
1272 static const int tftpMaxSize
= 8192 * 1024;
1273 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1274 int mode
, cyg_file
*file
)
1277 tftp
= malloc(sizeof(struct Tftp
));
1280 memset(tftp
, 0, sizeof(struct Tftp
));
1282 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1283 file
->f_type
= CYG_FILE_TYPE_FILE
;
1284 file
->f_ops
= &tftpfs_fileops
;
1289 tftp
->mem
= malloc(tftpMaxSize
);
1290 if (tftp
->mem
== NULL
)
1296 char *server
= strchr(name
, '/');
1303 tftp
->server
= malloc(server
- name
+ 1);
1304 if (tftp
->server
== NULL
)
1309 strncpy(tftp
->server
, name
, server
- name
);
1310 tftp
->server
[server
- name
] = 0;
1312 tftp
->file
= strdup(server
+ 1);
1313 if (tftp
->file
== NULL
)
1319 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1324 static int fetchTftp(struct Tftp
*tftp
)
1326 if (!tftp
->readFile
)
1329 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1330 tftpMaxSize
, TFTP_OCTET
, &err
);
1332 if (tftp
->actual
< 0)
1341 // -------------------------------------------------------------------------
1342 // tftpfs_fo_write()
1343 // Read data from file.
1345 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1347 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1349 if (fetchTftp(tftp
) != ENOERR
)
1353 off_t pos
= fp
->f_offset
;
1355 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1357 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1358 char *buf
= (char *) iov
->iov_base
;
1359 off_t len
= iov
->iov_len
;
1361 if (len
+ pos
> tftp
->actual
)
1363 len
= tftp
->actual
- pos
;
1365 resid
+= iov
->iov_len
- len
;
1367 memcpy(buf
, tftp
->mem
+ pos
, len
);
1371 uio
->uio_resid
= resid
;
1377 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1379 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1382 off_t pos
= fp
->f_offset
;
1384 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1386 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1387 char *buf
= (char *) iov
->iov_base
;
1388 off_t len
= iov
->iov_len
;
1390 if (len
+ pos
> tftpMaxSize
)
1392 len
= tftpMaxSize
- pos
;
1394 resid
+= iov
->iov_len
- len
;
1396 memcpy(tftp
->mem
+ pos
, buf
, len
);
1400 uio
->uio_resid
= resid
;
1408 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1414 // -------------------------------------------------------------------------
1416 // Close a file. We just clear out the data pointer.
1418 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1420 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1425 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1426 TFTP_OCTET
, &error
);
1434 // -------------------------------------------------------------------------
1436 // Seek to a new file position.
1438 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1440 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1443 if (fetchTftp(tftp
) != ENOERR
)
1449 // Pos is already where we want to be.
1453 // Add pos to current offset.
1454 pos
+= fp
->f_offset
;
1458 // Add pos to file size.
1459 pos
+= tftp
->actual
;
1466 // Check that pos is still within current file size, or at the
1468 if (pos
< 0 || pos
> tftp
->actual
)
1471 // All OK, set fp offset and return new position.
1472 *apos
= fp
->f_offset
= pos
;
1480 cyg_thread_delay(us
/ 10000 + 1);
1486 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1488 cyg_httpd_start_chunked("text");
1489 if (logCount
>= logSize
)
1491 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1492 - logCount
% logSize
);
1494 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1495 cyg_httpd_end_chunked();
1499 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1501 // Filesystem operations
1502 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1503 static int logfs_umount(cyg_mtab_entry
*mte
);
1504 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1505 int mode
, cyg_file
*fte
);
1506 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1509 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1510 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1512 #include <cyg/io/devtab.h>
1514 //==========================================================================
1515 // Filesystem table entries
1517 // -------------------------------------------------------------------------
1519 // This defines the entry in the filesystem table.
1520 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1521 // we should never block in any filesystem operations.
1522 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1523 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1527 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1528 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1529 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1530 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1531 (cyg_fsop_link
*)cyg_fileio_erofs
,
1532 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1533 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1534 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1535 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1536 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1538 // -------------------------------------------------------------------------
1540 // This set of file operations are used for normal open files.
1542 static cyg_fileops logfs_fileops
=
1543 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1544 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1545 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1546 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1547 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1548 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1550 // -------------------------------------------------------------------------
1552 // Process a mount request. This mainly finds root for the
1555 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1560 static int logfs_umount(cyg_mtab_entry
*mte
)
1565 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1566 int mode
, cyg_file
*file
)
1568 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1569 file
->f_type
= CYG_FILE_TYPE_FILE
;
1570 file
->f_ops
= &logfs_fileops
;
1577 // -------------------------------------------------------------------------
1579 // Write data to file.
1581 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1584 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1586 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1587 char *buf
= (char *) iov
->iov_base
;
1588 off_t len
= iov
->iov_len
;
1590 diag_write(buf
, len
);
1596 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1601 // -------------------------------------------------------------------------
1603 // Close a file. We just clear out the data pointer.
1605 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1610 int loadFile(const char *fileName
, void **data
, int *len
);
1612 /* boolean parameter stored on config */
1613 int boolParam(char *var
)
1615 bool result
= false;
1616 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1622 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1626 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)