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 500 ticks..\n");
159 cyg_thread_delay(500);
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 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
332 diag_printf("Formatting JFFS2...\n");
334 cyg_io_handle_t handle
;
337 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
340 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
345 cyg_io_flash_getconfig_devsize_t ds
;
347 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
350 diag_printf("Flash error cyg_io_get_config %d\n", err
);
354 cyg_io_flash_getconfig_erase_t e
;
360 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
361 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
364 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
368 diag_printf("Flash formatted successfully\n");
374 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
375 Jim_Obj
* const *argv
)
387 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
388 Jim_Obj
* const *argv
)
390 cyg_handle_t thread
= 0;
392 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
394 /* Loop over the threads, and generate a table row for
397 while (cyg_thread_get_next(&thread
, &id
))
399 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
401 cyg_thread_info info
;
404 cyg_thread_get_info(thread
, id
, &info
);
406 if (info
.name
== NULL
)
407 info
.name
= "<no name>";
409 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
410 info
.name
, strlen(info
.name
)));
412 /* Translate the state into a string.
415 state_string
= "RUN";
416 else if (info
.state
& 0x04)
417 state_string
= "SUSP";
419 switch (info
.state
& 0x1b)
422 state_string
= "SLEEP";
425 state_string
= "CNTSLEEP";
428 state_string
= "CREATE";
431 state_string
= "EXIT";
434 state_string
= "????";
438 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
439 state_string
, strlen(state_string
)));
441 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
442 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
444 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
447 Jim_ListAppendElement(interp
, threads
, threadObj
);
449 Jim_SetResult(interp
, threads
);
454 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
455 Jim_Obj
* const *argv
)
457 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
459 if (logCount
>= logSize
)
461 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
462 % logSize
, logSize
- logCount
% logSize
);
464 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
466 Jim_SetResult(interp
, tclOutput
);
470 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
471 Jim_Obj
* const *argv
)
478 static void zylinjtag_startNetwork(void)
480 // Bring TCP/IP up immediately before we're ready to accept commands.
482 // That is as soon as a PING responds, we're accepting telnet sessions.
483 #if defined(CYGPKG_NET_FREEBSD_STACK)
484 phi_init_all_network_interfaces();
490 diag_printf("Network not up and running\n");
494 /* very first thing we want is a reboot capability */
497 #if defined(CYGPKG_NET_FREEBSD_STACK)
499 tftpd_start(69, &fileops
);
502 cyg_httpd_init_tcl_interpreter();
504 interp
= httpstate
.jim_interp
;
506 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
508 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
509 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
510 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
511 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
512 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
513 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
519 diag_printf("Web server running\n");
523 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
526 strcpy(ifr
.ifr_name
, "eth0");
528 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
533 diag_printf("Can't obtain MAC address\n");
538 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
544 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
547 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
552 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
557 char *infoStr
= "unknown";
560 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
561 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
562 infoStr
= "undefined instruction";
564 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
565 infoStr
= "software interrupt";
567 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
568 infoStr
= "abort prefetch";
570 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
571 infoStr
= "abort data";
578 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
580 diag_printf("Dumping log\n---\n");
581 if (logCount
>= logSize
)
583 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
585 diag_write(logBuffer
, writePtr
);
587 diag_printf("---\nLogdump complete.\n");
588 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
589 diag_printf("\n---\nRebooting\n");
590 HAL_PLATFORM_RESET();
594 static void setHandler(cyg_code_t exception
)
596 cyg_exception_handler_t
*old_handler
;
597 cyg_addrword_t old_data
;
599 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
600 &old_handler
, &old_data
);
603 static cyg_thread zylinjtag_uart_thread_object
;
604 static cyg_handle_t zylinjtag_uart_thread_handle
;
605 static char uart_stack
[4096];
607 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
608 static char backwardBuffer
[1024];
610 void setNoDelay(int session
, int flag
)
613 // This decreases latency dramatically for e.g. GDB load which
614 // does not have a sliding window protocol
616 // Can cause *lots* of TCP/IP packets to be sent and it would have
617 // to be enabled/disabled on the fly to avoid the CPU being
619 setsockopt(session
, /* socket affected */
620 IPPROTO_TCP
, /* set option at TCP level */
621 TCP_NODELAY
, /* name of option */
622 (char *) &flag
, /* the cast is historical
624 sizeof(int)); /* length of option value */
634 } tcpipSent
[512 * 1024];
637 static void zylinjtag_uart(cyg_addrword_t data
)
639 int so_reuseaddr_option
= 1;
642 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
644 LOG_ERROR("error creating socket: %s", strerror(errno
));
648 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
651 struct sockaddr_in sin
;
652 unsigned int address_size
;
653 address_size
= sizeof(sin
);
654 memset(&sin
, 0, sizeof(sin
));
655 sin
.sin_family
= AF_INET
;
656 sin
.sin_addr
.s_addr
= INADDR_ANY
;
657 sin
.sin_port
= htons(5555);
659 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
661 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
665 if (listen(fd
, 1) == -1)
667 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
670 // socket_nonblock(fd);
675 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
681 setNoDelay(session
, 1);
682 int oldopts
= fcntl(session
, F_GETFL
, 0);
683 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
685 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
692 #ifdef CYGPKG_PROFILE_GPROF
708 FD_SET(session
, &read_fds
);
710 FD_SET(serHandle
, &read_fds
);
711 if (serHandle
> fd_max
)
717 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
718 if ((actual
== 0) && (actual2
== 0))
720 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
729 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
731 t
= read(serHandle
, backwardBuffer
,
732 sizeof(backwardBuffer
));
749 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
757 if (FD_ISSET(session
, &read_fds
)
758 && (sizeof(forwardBuffer
) > actual
))
760 // NB! Here it is important that we empty the TCP/IP read buffer
761 // to make transmission tick right
762 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
765 // this will block if there is no data at all
766 t
= read_socket(session
, forwardBuffer
+ actual
,
767 sizeof(forwardBuffer
) - actual
);
779 /* Do not put things into the serial buffer if it has something to send
780 * as that can cause a single byte to be sent at the time.
784 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
791 // The serial buffer is full
803 tcpipSent
[cur
].req
= x
;
804 tcpipSent
[cur
].actual
= y
;
805 tcpipSent
[cur
].req2
= x2
;
806 tcpipSent
[cur
].actual2
= y2
;
811 closeSession
: close(session
);
815 for (i
= 0; i
< 1024; i
++)
817 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
818 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
828 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
829 (void *) uart_stack
, sizeof(uart_stack
),
830 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
831 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
832 cyg_thread_resume(zylinjtag_uart_thread_handle
);
835 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
836 char **args
, int argc
)
838 static int current_baud
= 38400;
841 command_print(cmd_ctx
, "%d", current_baud
);
846 return ERROR_INVALID_ARGUMENTS
;
849 current_baud
= atol(args
[0]);
852 switch (current_baud
)
855 baud
= CYGNUM_SERIAL_BAUD_9600
;
858 baud
= CYGNUM_SERIAL_BAUD_19200
;
861 baud
= CYGNUM_SERIAL_BAUD_38400
;
864 baud
= CYGNUM_SERIAL_BAUD_57600
;
867 baud
= CYGNUM_SERIAL_BAUD_115200
;
870 baud
= CYGNUM_SERIAL_BAUD_230400
;
873 command_print(cmd_ctx
, "unsupported baudrate");
874 return ERROR_INVALID_ARGUMENTS
;
877 cyg_serial_info_t buf
;
879 //get existing serial configuration
880 len
= sizeof(cyg_serial_info_t
);
882 cyg_io_handle_t serial_handle
;
884 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
887 LOG_ERROR("/dev/ser0 not found\n");
891 err
= cyg_io_get_config(serial_handle
,
892 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
893 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
897 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
902 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
906 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
913 bool logAllToSerial
= false;
916 int boolParam(char *var
);
919 command_context_t
*setup_command_handler(void);
921 static const char *zylin_config_dir
="/config/settings";
923 static int add_default_dirs(void)
925 add_script_search_dir(zylin_config_dir
);
926 add_script_search_dir("/rom/lib/openocd");
927 add_script_search_dir("/rom");
931 int ioutil_init(struct command_context_s
*cmd_ctx
);
933 int main(int argc
, char *argv
[])
935 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
936 * need to allocate towards the end of the heap. */
938 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
939 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
940 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
941 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
946 atexit(keep_webserver
);
948 diag_init_putc(_zylinjtag_diag_write_char
);
949 // We want this in the log.
950 diag_printf("Zylin ZY1000.\n");
952 err
= mount("", "/ram", "ramfs");
955 diag_printf("unable to mount ramfs\n");
960 sprintf(address
, "%p", &filedata
[0]);
961 err
= mount(address
, "/rom", "romfs");
964 diag_printf("unable to mount /rom\n");
967 err
= mount("", "/log", "logfs");
970 diag_printf("unable to mount logfs\n");
973 err
= mount("", "/tftp", "tftpfs");
976 diag_printf("unable to mount logfs\n");
979 log
= fopen("/log/log", "w");
982 diag_printf("Could not open log file /ram/log\n");
987 copydir("/rom", "/ram/cgi");
989 err
= mount("/dev/flash1", "/config", "jffs2");
992 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
993 err
= mount("", "/config", "ramfs");
996 diag_printf("unable to mount /config as ramdisk.\n");
1002 /* are we using a ram disk instead of a flash disk? This is used
1003 * for ZY1000 live demo...
1005 * copy over flash disk to ram block device
1007 if (boolParam("ramdisk"))
1009 diag_printf("Unmounting /config from flash and using ram instead\n");
1010 err
= umount("/config");
1013 diag_printf("unable to unmount jffs\n");
1017 err
= mount("/dev/flash1", "/config2", "jffs2");
1020 diag_printf("unable to mount jffs\n");
1024 err
= mount("", "/config", "ramfs");
1027 diag_printf("unable to mount ram block device\n");
1031 // copydir("/config2", "/config");
1032 copyfile("/config2/ip", "/config/ip");
1033 copydir("/config2/settings", "/config/settings");
1039 mkdir(zylin_config_dir
, 0777);
1040 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1041 mkdir(dirname
, 0777);
1043 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1044 mkdir(dirname
, 0777);
1046 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1047 mkdir(dirname
, 0777);
1050 logAllToSerial
= boolParam("logserial");
1052 // We need the network & web server in case there is something wrong with
1053 // the config files that invoke exit()
1054 zylinjtag_startNetwork();
1056 /* we're going to access the jim interpreter from here on... */
1057 openocd_sleep_postlude();
1062 /* initialize commandline interface */
1063 command_context_t
* cmd_ctx
;
1064 cmd_ctx
= setup_command_handler();
1065 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1066 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1069 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1071 return EXIT_FAILURE
;
1076 #ifdef CYGPKG_PROFILE_GPROF
1077 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1081 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1082 "uart <baud> - forward uart on port 5555");
1085 errVal
= log_init(cmd_ctx
);
1086 if (errVal
!= ERROR_OK
)
1088 diag_printf("log_init() failed %d\n", errVal
);
1092 set_log_output(cmd_ctx
, log
);
1094 LOG_DEBUG("log init complete");
1096 // diag_printf("Executing config files\n");
1101 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1102 command_run_line(cmd_ctx
, "debug_level 3");
1105 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1107 /* we MUST always run the init command as it will launch telnet sessions */
1108 command_run_line(cmd_ctx
, "init");
1111 // diag_printf() is really invoked from many more places than we trust it
1112 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1114 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1115 // fingers that it doesn't cause any crashes.
1116 diag_printf("Init complete, GDB & telnet servers launched.\n");
1117 command_set_output_handler(cmd_ctx
,
1118 zy1000_configuration_output_handler_log
, NULL
);
1119 if (!logAllToSerial
)
1124 /* handle network connections */
1125 server_loop(cmd_ctx
);
1126 openocd_sleep_prelude();
1128 /* shut server down */
1131 /* free commandline interface */
1132 command_done(cmd_ctx
);
1140 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1141 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1143 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1147 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1149 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1150 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1152 #include <pkgconf/system.h>
1153 #include <pkgconf/hal.h>
1154 #include <pkgconf/kernel.h>
1155 #include <pkgconf/io_fileio.h>
1156 #include <pkgconf/fs_rom.h>
1158 #include <cyg/kernel/ktypes.h> // base kernel types
1159 #include <cyg/infra/cyg_trac.h> // tracing macros
1160 #include <cyg/infra/cyg_ass.h> // assertion macros
1161 #include <cyg/fileio/fileio.h>
1162 #include <cyg/kernel/kapi.h>
1163 #include <cyg/infra/diag.h>
1165 //==========================================================================
1166 // Eventually we want to eXecute In Place from the ROM in a protected
1167 // environment, so we'll need executables to be aligned to a boundary
1168 // suitable for MMU protection. A suitable boundary would be the 4k
1169 // boundary in all the CPU architectures I am currently aware of.
1171 // Forward definitions
1173 // Filesystem operations
1174 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1175 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1176 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1177 int mode
, cyg_file
*fte
);
1178 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1179 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1182 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1183 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1184 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1186 //==========================================================================
1187 // Filesystem table entries
1189 // -------------------------------------------------------------------------
1191 // This defines the entry in the filesystem table.
1192 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1193 // we should never block in any filesystem operations.
1195 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1200 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1201 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1202 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1203 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1204 (cyg_fsop_link
*)cyg_fileio_erofs
,
1205 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1206 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1207 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1208 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1209 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1212 // -------------------------------------------------------------------------
1214 // This defines a single ROMFS loaded into ROM at the configured address
1216 // MTAB_ENTRY(rom_mte, // structure name
1217 // "/rom", // mount point
1218 // "romfs", // FIlesystem type
1219 // "", // hardware device
1220 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1224 // -------------------------------------------------------------------------
1226 // This set of file operations are used for normal open files.
1228 static cyg_fileops tftpfs_fileops
=
1229 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1230 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1231 tftpfs_fo_fsync
, tftpfs_fo_close
,
1232 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1233 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1234 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1236 // -------------------------------------------------------------------------
1238 // Process a mount request. This mainly finds root for the
1241 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1246 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1261 static void freeTftp(struct Tftp
*t
)
1274 static const int tftpMaxSize
= 8192 * 1024;
1275 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1276 int mode
, cyg_file
*file
)
1279 tftp
= malloc(sizeof(struct Tftp
));
1282 memset(tftp
, 0, sizeof(struct Tftp
));
1284 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1285 file
->f_type
= CYG_FILE_TYPE_FILE
;
1286 file
->f_ops
= &tftpfs_fileops
;
1291 tftp
->mem
= malloc(tftpMaxSize
);
1292 if (tftp
->mem
== NULL
)
1298 char *server
= strchr(name
, '/');
1305 tftp
->server
= malloc(server
- name
+ 1);
1306 if (tftp
->server
== NULL
)
1311 strncpy(tftp
->server
, name
, server
- name
);
1312 tftp
->server
[server
- name
] = 0;
1314 tftp
->file
= strdup(server
+ 1);
1315 if (tftp
->file
== NULL
)
1321 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1326 static int fetchTftp(struct Tftp
*tftp
)
1328 if (!tftp
->readFile
)
1331 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1332 tftpMaxSize
, TFTP_OCTET
, &err
);
1334 if (tftp
->actual
< 0)
1343 // -------------------------------------------------------------------------
1344 // tftpfs_fo_write()
1345 // Read data from file.
1347 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1349 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1351 if (fetchTftp(tftp
) != ENOERR
)
1355 off_t pos
= fp
->f_offset
;
1357 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1359 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1360 char *buf
= (char *) iov
->iov_base
;
1361 off_t len
= iov
->iov_len
;
1363 if (len
+ pos
> tftp
->actual
)
1365 len
= tftp
->actual
- pos
;
1367 resid
+= iov
->iov_len
- len
;
1369 memcpy(buf
, tftp
->mem
+ pos
, len
);
1373 uio
->uio_resid
= resid
;
1379 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1381 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1384 off_t pos
= fp
->f_offset
;
1386 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1388 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1389 char *buf
= (char *) iov
->iov_base
;
1390 off_t len
= iov
->iov_len
;
1392 if (len
+ pos
> tftpMaxSize
)
1394 len
= tftpMaxSize
- pos
;
1396 resid
+= iov
->iov_len
- len
;
1398 memcpy(tftp
->mem
+ pos
, buf
, len
);
1402 uio
->uio_resid
= resid
;
1410 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1416 // -------------------------------------------------------------------------
1418 // Close a file. We just clear out the data pointer.
1420 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1422 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1427 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1428 TFTP_OCTET
, &error
);
1436 // -------------------------------------------------------------------------
1438 // Seek to a new file position.
1440 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1442 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1445 if (fetchTftp(tftp
) != ENOERR
)
1451 // Pos is already where we want to be.
1455 // Add pos to current offset.
1456 pos
+= fp
->f_offset
;
1460 // Add pos to file size.
1461 pos
+= tftp
->actual
;
1468 // Check that pos is still within current file size, or at the
1470 if (pos
< 0 || pos
> tftp
->actual
)
1473 // All OK, set fp offset and return new position.
1474 *apos
= fp
->f_offset
= pos
;
1482 cyg_thread_delay(us
/ 10000 + 1);
1488 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1490 cyg_httpd_start_chunked("text");
1491 if (logCount
>= logSize
)
1493 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1494 - logCount
% logSize
);
1496 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1497 cyg_httpd_end_chunked();
1501 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1503 // Filesystem operations
1504 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1505 static int logfs_umount(cyg_mtab_entry
*mte
);
1506 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1507 int mode
, cyg_file
*fte
);
1508 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1511 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1512 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1514 #include <cyg/io/devtab.h>
1516 //==========================================================================
1517 // Filesystem table entries
1519 // -------------------------------------------------------------------------
1521 // This defines the entry in the filesystem table.
1522 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1523 // we should never block in any filesystem operations.
1524 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1525 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1529 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1530 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1531 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1532 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1533 (cyg_fsop_link
*)cyg_fileio_erofs
,
1534 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1535 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1536 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1537 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1538 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1540 // -------------------------------------------------------------------------
1542 // This set of file operations are used for normal open files.
1544 static cyg_fileops logfs_fileops
=
1545 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1546 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1547 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1548 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1549 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1550 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1552 // -------------------------------------------------------------------------
1554 // Process a mount request. This mainly finds root for the
1557 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1562 static int logfs_umount(cyg_mtab_entry
*mte
)
1567 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1568 int mode
, cyg_file
*file
)
1570 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1571 file
->f_type
= CYG_FILE_TYPE_FILE
;
1572 file
->f_ops
= &logfs_fileops
;
1579 // -------------------------------------------------------------------------
1581 // Write data to file.
1583 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1586 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1588 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1589 char *buf
= (char *) iov
->iov_base
;
1590 off_t len
= iov
->iov_len
;
1592 diag_write(buf
, len
);
1598 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1603 // -------------------------------------------------------------------------
1605 // Close a file. We just clear out the data pointer.
1607 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1612 int loadFile(const char *fileName
, void **data
, int *len
);
1614 /* boolean parameter stored on config */
1615 int boolParam(char *var
)
1617 bool result
= false;
1618 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1624 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1628 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)