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"
36 #include "telnet_server.h"
37 #include "gdb_server.h"
39 #include <time_support.h>
41 #include <sys/types.h>
49 #include <cyg/io/flash.h>
50 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
55 #include <cyg/fileio/fileio.h>
57 #include <cyg/athttpd/http.h>
58 #include <cyg/athttpd/socket.h>
59 #include <cyg/athttpd/handler.h>
60 #include <cyg/athttpd/cgi.h>
61 #include <cyg/athttpd/forms.h>
62 #include <cyg/discover/discover.h>
63 #include <cyg/hal/hal_diag.h>
64 #include <cyg/kernel/kapi.h>
65 #include <cyg/io/serialio.h>
66 #include <cyg/io/io.h>
67 #include <netinet/tcp.h>
69 #include <sys/ioctl.h>
70 #include <sys/socket.h>
71 #include <netinet/in.h>
73 #include <arpa/inet.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
77 #include <netinet/in.h>
79 #include <arpa/inet.h>
87 #if defined(CYGPKG_NET_FREEBSD_STACK)
88 #include <tftp_support.h>
89 /* posix compatibility broken*/
90 struct tftpd_fileops fileops
=
92 (int (*)(const char *, int))open
,
94 (int (*)(int, const void *, int))write
,
95 ( int (*)(int, void *, int))read
101 void diag_write(char *buf
, int len
)
104 for (j
= 0; j
< len
; j
++)
106 diag_printf("%c", buf
[j
]);
110 static bool serialLog
= true;
111 static bool writeLog
= true;
116 extern flash_driver_t
*flash_drivers
[];
117 extern target_type_t
*target_types
[];
119 #ifdef CYGPKG_PROFILE_GPROF
120 #include <cyg/profile/profile.h>
122 extern char _stext
, _etext
; // Defined by the linker
124 static char *start_of_code
=&_stext
;
125 static char *end_of_code
=&_etext
;
127 void start_profile(void)
129 // This starts up the system-wide profiling, gathering
130 // profile information on all of the code, with a 16 byte
131 // "bucket" size, at a rate of 100us/profile hit.
132 // Note: a bucket size of 16 will give pretty good function
133 // resolution. Much smaller and the buffer becomes
134 // much too large for very little gain.
135 // Note: a timer period of 100us is also a reasonable
136 // compromise. Any smaller and the overhead of
137 // handling the timter (profile) interrupt could
138 // swamp the system. A fast processor might get
139 // by with a smaller value, but a slow one could
140 // even be swamped by this value. If the value is
141 // too large, the usefulness of the profile is reduced.
143 // no more interrupts than 1/10ms.
144 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
145 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
146 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 int configuration_output_handler(struct command_context_s
*context
,
179 diag_printf("%s", line
);
184 int zy1000_configuration_output_handler_log(struct command_context_s
*context
,
187 LOG_USER_N("%s", line
);
192 #ifdef CYGPKG_PROFILE_GPROF
193 extern void start_profile();
195 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
197 command_print(cmd_ctx
, "Profiling started");
204 externC
void phi_init_all_network_interfaces();
206 command_context_t
*cmd_ctx
;
208 static bool webRunning
= false;
210 void keep_webserver()
212 // Target initialisation is only attempted at startup, so we sleep forever and
213 // let the http server bail us out(i.e. get config files set up).
214 diag_printf("OpenOCD has invoked exit().\n"
215 "Use web server to correct any configuration settings and reboot.\n");
219 // exit() will terminate the current thread and we we'll then sleep eternally or
220 // we'll have a reboot scheduled.
223 extern void printDccChar(char c
);
225 static char logBuffer
[128 * 1024];
226 static const int logSize
= sizeof(logBuffer
);
230 void _zylinjtag_diag_write_char(char c
, void **param
)
234 logBuffer
[writePtr
] = c
;
235 writePtr
= (writePtr
+ 1) % logSize
;
242 HAL_DIAG_WRITE_CHAR('\r');
244 HAL_DIAG_WRITE_CHAR(c
);
247 #ifdef CYGPKG_HAL_ZYLIN_PHI
252 void copyfile(char *name2
, char *name1
);
254 void copydir(char *name
, char *destdir
);
257 MTAB_ENTRY( romfs_mte1
,
261 (CYG_ADDRWORD
) &filedata
[0] );
264 void openocd_sleep_prelude()
266 cyg_mutex_unlock(&httpstate
.jim_lock
);
269 void openocd_sleep_postlude()
271 cyg_mutex_lock(&httpstate
.jim_lock
);
276 diag_printf("Formatting JFFS2...\n");
278 cyg_io_handle_t handle
;
281 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
284 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
289 cyg_io_flash_getconfig_devsize_t ds
;
291 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
294 diag_printf("Flash error cyg_io_get_config %d\n", err
);
298 cyg_io_flash_getconfig_erase_t e
;
304 e
.err_address
= &err_addr
;
306 diag_printf("Formatting 0x%08x bytes\n", ds
.dev_size
);
307 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
310 diag_printf("Flash erase error %d offset 0x%p\n", err
, err_addr
);
314 diag_printf("Flash formatted successfully\n");
319 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
320 Jim_Obj
* const *argv
)
332 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
333 Jim_Obj
* const *argv
)
335 cyg_handle_t thread
= 0;
337 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
339 /* Loop over the threads, and generate a table row for
342 while (cyg_thread_get_next(&thread
, &id
))
344 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
346 cyg_thread_info info
;
349 cyg_thread_get_info(thread
, id
, &info
);
351 if (info
.name
== NULL
)
352 info
.name
= "<no name>";
354 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
355 info
.name
, strlen(info
.name
)));
357 /* Translate the state into a string.
360 state_string
= "RUN";
361 else if (info
.state
& 0x04)
362 state_string
= "SUSP";
364 switch (info
.state
& 0x1b)
367 state_string
= "SLEEP";
370 state_string
= "CNTSLEEP";
373 state_string
= "CREATE";
376 state_string
= "EXIT";
379 state_string
= "????";
383 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
384 state_string
, strlen(state_string
)));
386 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
387 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
389 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
392 Jim_ListAppendElement(interp
, threads
, threadObj
);
394 Jim_SetResult(interp
, threads
);
399 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
400 Jim_Obj
* const *argv
)
402 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
404 if (logCount
>= logSize
)
406 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
407 % logSize
, logSize
- logCount
% logSize
);
409 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
411 Jim_SetResult(interp
, tclOutput
);
415 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
416 Jim_Obj
* const *argv
)
422 static int zylinjtag_Jim_Command_mac(Jim_Interp
*interp
, int argc
,
423 Jim_Obj
* const *argv
)
426 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
428 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, hwaddr
, strlen(hwaddr
));
430 Jim_SetResult(interp
, tclOutput
);
435 static int zylinjtag_Jim_Command_ip(Jim_Interp
*interp
, int argc
,
436 Jim_Obj
* const *argv
)
438 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
440 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
442 if (getifaddrs(&ifp
) < 0)
447 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
452 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
453 salen
= sizeof(struct sockaddr_in
);
454 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
455 salen
= sizeof(struct sockaddr_in6
);
459 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
465 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, ip
, strlen(ip
));
472 Jim_SetResult(interp
, tclOutput
);
477 extern Jim_Interp
*interp
;
479 static void zylinjtag_startNetwork()
481 // Bring TCP/IP up immediately before we're ready to accept commands.
483 // That is as soon as a PING responds, we're accepting telnet sessions.
484 #if defined(CYGPKG_NET_FREEBSD_STACK)
485 phi_init_all_network_interfaces();
491 diag_printf("Network not up and running\n");
494 #if defined(CYGPKG_NET_FREEBSD_STACK)
496 tftpd_start(69, &fileops
);
499 cyg_httpd_init_tcl_interpreter();
501 interp
= httpstate
.jim_interp
;
503 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
505 Jim_CreateCommand(httpstate
.jim_interp
, "reboot",
506 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
507 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
508 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
509 Jim_CreateCommand(httpstate
.jim_interp
, "mac", zylinjtag_Jim_Command_mac
,
511 Jim_CreateCommand(httpstate
.jim_interp
, "ip", zylinjtag_Jim_Command_ip
,
513 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
514 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
520 diag_printf("Web server running\n");
524 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
527 strcpy(ifr
.ifr_name
, "eth0");
529 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
534 diag_printf("Can't obtain MAC address\n");
539 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
544 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
545 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
548 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
553 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
558 char *infoStr
= "unknown";
561 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
562 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
563 infoStr
= "undefined instruction";
565 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
566 infoStr
= "software interrupt";
568 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
569 infoStr
= "abort prefetch";
571 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
572 infoStr
= "abort data";
579 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
581 diag_printf("Dumping log\n---\n");
582 if (logCount
>= logSize
)
584 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
586 diag_write(logBuffer
, writePtr
);
588 diag_printf("---\nLogdump complete.\n");
589 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
590 diag_printf("\n---\nRebooting\n");
591 HAL_PLATFORM_RESET();
595 static void setHandler(cyg_code_t exception
)
597 cyg_exception_handler_t
*old_handler
;
598 cyg_addrword_t old_data
;
600 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
601 &old_handler
, &old_data
);
604 static cyg_thread zylinjtag_uart_thread_object
;
605 static cyg_handle_t zylinjtag_uart_thread_handle
;
606 static char uart_stack
[4096];
608 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
609 static char backwardBuffer
[1024];
611 void setNoDelay(int session
, int flag
)
614 // This decreases latency dramatically for e.g. GDB load which
615 // does not have a sliding window protocol
617 // Can cause *lots* of TCP/IP packets to be sent and it would have
618 // to be enabled/disabled on the fly to avoid the CPU being
620 setsockopt(session
, /* socket affected */
621 IPPROTO_TCP
, /* set option at TCP level */
622 TCP_NODELAY
, /* name of option */
623 (char *) &flag
, /* the cast is historical
625 sizeof(int)); /* length of option value */
635 } tcpipSent
[512 * 1024];
638 static void zylinjtag_uart(cyg_addrword_t data
)
640 int so_reuseaddr_option
= 1;
643 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
645 LOG_ERROR("error creating socket: %s", strerror(errno
));
649 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
652 struct sockaddr_in sin
;
653 unsigned int address_size
;
654 address_size
= sizeof(sin
);
655 memset(&sin
, 0, sizeof(sin
));
656 sin
.sin_family
= AF_INET
;
657 sin
.sin_addr
.s_addr
= INADDR_ANY
;
658 sin
.sin_port
= htons(5555);
660 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
662 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
666 if (listen(fd
, 1) == -1)
668 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
671 // socket_nonblock(fd);
676 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
682 setNoDelay(session
, 1);
683 int oldopts
= fcntl(session
, F_GETFL
, 0);
684 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
686 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
693 #ifdef CYGPKG_PROFILE_GPROF
709 FD_SET(session
, &read_fds
);
711 FD_SET(serHandle
, &read_fds
);
712 if (serHandle
> fd_max
)
718 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
719 if ((actual
== 0) && (actual2
== 0))
721 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
730 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
731 actual2
= read(serHandle
, backwardBuffer
,
732 sizeof(backwardBuffer
));
748 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
756 if (FD_ISSET(session
, &read_fds
)
757 && (sizeof(forwardBuffer
) > actual
))
759 // NB! Here it is important that we empty the TCP/IP read buffer
760 // to make transmission tick right
761 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
764 // this will block if there is no data at all
765 t
= read_socket(session
, forwardBuffer
+ actual
,
766 sizeof(forwardBuffer
) - actual
);
778 /* Do not put things into the serial buffer if it has something to send
779 * as that can cause a single byte to be sent at the time.
783 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
790 // The serial buffer is full
802 tcpipSent
[cur
].req
= x
;
803 tcpipSent
[cur
].actual
= y
;
804 tcpipSent
[cur
].req2
= x2
;
805 tcpipSent
[cur
].actual2
= y2
;
810 closeSession
: close(session
);
814 for (i
= 0; i
< 1024; i
++)
816 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
817 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
827 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
828 (void *) uart_stack
, sizeof(uart_stack
),
829 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
830 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
831 cyg_thread_resume(zylinjtag_uart_thread_handle
);
834 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
835 char **args
, int argc
)
837 static int current_baud
= 38400;
840 command_print(cmd_ctx
, "%d", current_baud
);
845 return ERROR_INVALID_ARGUMENTS
;
848 current_baud
= atol(args
[0]);
851 switch (current_baud
)
854 baud
= CYGNUM_SERIAL_BAUD_9600
;
857 baud
= CYGNUM_SERIAL_BAUD_19200
;
860 baud
= CYGNUM_SERIAL_BAUD_38400
;
863 baud
= CYGNUM_SERIAL_BAUD_57600
;
866 baud
= CYGNUM_SERIAL_BAUD_115200
;
869 baud
= CYGNUM_SERIAL_BAUD_230400
;
872 command_print(cmd_ctx
, "unsupported baudrate");
873 return ERROR_INVALID_ARGUMENTS
;
876 cyg_serial_info_t buf
;
878 //get existing serial configuration
879 len
= sizeof(cyg_serial_info_t
);
881 cyg_io_handle_t serial_handle
;
883 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
886 LOG_ERROR("/dev/ser0 not found\n");
890 err
= cyg_io_get_config(serial_handle
,
891 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
892 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
896 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
901 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
905 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
912 bool logAllToSerial
= false;
915 int boolParam(char *var
);
918 command_context_t
*setup_command_handler();
920 extern const char *zylin_config_dir
;
922 int add_default_dirs(void)
924 add_script_search_dir(zylin_config_dir
);
925 add_script_search_dir("/rom/lib/openocd");
926 add_script_search_dir("/rom");
930 int main(int argc
, char *argv
[])
932 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
933 * need to allocate towards the end of the heap. */
935 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
936 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
937 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
938 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
943 atexit(keep_webserver
);
945 diag_init_putc(_zylinjtag_diag_write_char
);
946 // We want this in the log.
947 diag_printf("Zylin ZY1000.\n");
949 err
= mount("", "/ram", "ramfs");
952 diag_printf("unable to mount ramfs\n");
957 sprintf(address
, "%p", &filedata
[0]);
958 err
= mount(address
, "/rom", "romfs");
961 diag_printf("unable to mount /rom\n");
964 err
= mount("", "/log", "logfs");
967 diag_printf("unable to mount logfs\n");
970 err
= mount("", "/tftp", "tftpfs");
973 diag_printf("unable to mount logfs\n");
976 log
= fopen("/log/log", "w");
979 diag_printf("Could not open log file /ram/log\n");
984 copydir("/rom", "/ram/cgi");
986 err
= mount("/dev/flash1", "/config", "jffs2");
989 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
990 err
= mount("", "/config", "ramfs");
993 diag_printf("unable to mount /config as ramdisk.\n");
999 /* are we using a ram disk instead of a flash disk? This is used
1000 * for ZY1000 live demo...
1002 * copy over flash disk to ram block device
1004 if (boolParam("ramdisk"))
1006 diag_printf("Unmounting /config from flash and using ram instead\n");
1007 err
= umount("/config");
1010 diag_printf("unable to unmount jffs\n");
1014 err
= mount("/dev/flash1", "/config2", "jffs2");
1017 diag_printf("unable to mount jffs\n");
1021 err
= mount("", "/config", "ramfs");
1024 diag_printf("unable to mount ram block device\n");
1028 // copydir("/config2", "/config");
1029 copyfile("/config2/ip", "/config/ip");
1030 copydir("/config2/settings", "/config/settings");
1036 mkdir(zylin_config_dir
, 0777);
1037 char *dirname
=alloc_printf("%s/target", zylin_config_dir
);
1038 mkdir(dirname
, 0777);
1040 dirname
=alloc_printf("%s/event", zylin_config_dir
);
1041 mkdir(dirname
, 0777);
1044 logAllToSerial
= boolParam("logserial");
1046 // We need the network & web server in case there is something wrong with
1047 // the config files that invoke exit()
1048 zylinjtag_startNetwork();
1050 /* we're going to access the jim interpreter from here on... */
1051 openocd_sleep_postlude();
1056 /* initialize commandline interface */
1057 command_context_t
* cmd_ctx
;
1058 cmd_ctx
= setup_command_handler();
1059 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1060 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1062 #ifdef CYGPKG_PROFILE_GPROF
1063 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1067 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1068 "uart <baud> - forward uart on port 5555");
1071 errVal
= log_init(cmd_ctx
);
1072 if (errVal
!= ERROR_OK
)
1074 diag_printf("log_init() failed %d\n", errVal
);
1078 set_log_output(cmd_ctx
, log
);
1080 LOG_DEBUG("log init complete");
1082 // diag_printf("Executing config files\n");
1087 "%s/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1088 command_run_line(cmd_ctx
, "debug_level 3");
1091 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1094 // diag_printf() is really invoked from many more places than we trust it
1095 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1097 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1098 // fingers that it doesn't cause any crashes.
1099 diag_printf("Init complete, GDB & telnet servers launched.\n");
1100 command_set_output_handler(cmd_ctx
,
1101 zy1000_configuration_output_handler_log
, NULL
);
1102 if (!logAllToSerial
)
1107 /* handle network connections */
1108 server_loop(cmd_ctx
);
1109 openocd_sleep_prelude();
1111 /* shut server down */
1114 /* free commandline interface */
1115 command_done(cmd_ctx
);
1123 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1124 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1126 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1130 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1132 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1133 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1135 #include <pkgconf/system.h>
1136 #include <pkgconf/hal.h>
1137 #include <pkgconf/kernel.h>
1138 #include <pkgconf/io_fileio.h>
1139 #include <pkgconf/fs_rom.h>
1141 #include <cyg/kernel/ktypes.h> // base kernel types
1142 #include <cyg/infra/cyg_trac.h> // tracing macros
1143 #include <cyg/infra/cyg_ass.h> // assertion macros
1145 #include <sys/types.h>
1147 #include <sys/stat.h>
1156 #include <cyg/fileio/fileio.h>
1158 #include <cyg/kernel/kapi.h>
1159 #include <cyg/infra/diag.h>
1161 //==========================================================================
1162 // Eventually we want to eXecute In Place from the ROM in a protected
1163 // environment, so we'll need executables to be aligned to a boundary
1164 // suitable for MMU protection. A suitable boundary would be the 4k
1165 // boundary in all the CPU architectures I am currently aware of.
1167 // Forward definitions
1169 // Filesystem operations
1170 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1171 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1172 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1173 int mode
, cyg_file
*fte
);
1174 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1175 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1178 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1179 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1180 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1182 //==========================================================================
1183 // Filesystem table entries
1185 // -------------------------------------------------------------------------
1187 // This defines the entry in the filesystem table.
1188 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1189 // we should never block in any filesystem operations.
1191 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
1196 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1197 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1198 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1199 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1200 (cyg_fsop_link
*)cyg_fileio_erofs
,
1201 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1202 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1203 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1204 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1205 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1208 // -------------------------------------------------------------------------
1210 // This defines a single ROMFS loaded into ROM at the configured address
1212 // MTAB_ENTRY( rom_mte, // structure name
1213 // "/rom", // mount point
1214 // "romfs", // FIlesystem type
1215 // "", // hardware device
1216 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1220 // -------------------------------------------------------------------------
1222 // This set of file operations are used for normal open files.
1224 static cyg_fileops tftpfs_fileops
=
1225 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1226 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1227 tftpfs_fo_fsync
, tftpfs_fo_close
,
1228 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1229 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1230 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1232 // -------------------------------------------------------------------------
1234 // Process a mount request. This mainly finds root for the
1237 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1242 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1257 static void freeTftp(struct Tftp
*t
)
1270 static const int tftpMaxSize
= 8192 * 1024;
1271 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1272 int mode
, cyg_file
*file
)
1275 tftp
= malloc(sizeof(struct Tftp
));
1278 memset(tftp
, 0, sizeof(struct Tftp
));
1280 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1281 file
->f_type
= CYG_FILE_TYPE_FILE
;
1282 file
->f_ops
= &tftpfs_fileops
;
1287 tftp
->mem
= malloc(tftpMaxSize
);
1288 if (tftp
->mem
== NULL
)
1294 char *server
= strchr(name
, '/');
1301 tftp
->server
= malloc(server
- name
+ 1);
1302 if (tftp
->server
== NULL
)
1307 strncpy(tftp
->server
, name
, server
- name
);
1308 tftp
->server
[server
- name
] = 0;
1310 tftp
->file
= strdup(server
+ 1);
1311 if (tftp
->file
== NULL
)
1317 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1322 static int fetchTftp(struct Tftp
*tftp
)
1324 if (!tftp
->readFile
)
1327 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1328 tftpMaxSize
, TFTP_OCTET
, &err
);
1330 if (tftp
->actual
< 0)
1339 // -------------------------------------------------------------------------
1340 // tftpfs_fo_write()
1341 // Read data from file.
1343 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1345 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1347 if (fetchTftp(tftp
) != ENOERR
)
1351 off_t pos
= fp
->f_offset
;
1353 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1355 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1356 char *buf
= (char *) iov
->iov_base
;
1357 off_t len
= iov
->iov_len
;
1359 if (len
+ pos
> tftp
->actual
)
1361 len
= tftp
->actual
- pos
;
1363 resid
+= iov
->iov_len
- len
;
1365 memcpy(buf
, tftp
->mem
+ pos
, len
);
1369 uio
->uio_resid
= resid
;
1375 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1377 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1380 off_t pos
= fp
->f_offset
;
1382 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1384 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1385 char *buf
= (char *) iov
->iov_base
;
1386 off_t len
= iov
->iov_len
;
1388 if (len
+ pos
> tftpMaxSize
)
1390 len
= tftpMaxSize
- pos
;
1392 resid
+= iov
->iov_len
- len
;
1394 memcpy(tftp
->mem
+ pos
, buf
, len
);
1398 uio
->uio_resid
= resid
;
1406 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1412 // -------------------------------------------------------------------------
1414 // Close a file. We just clear out the data pointer.
1416 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1418 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1423 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1424 TFTP_OCTET
, &error
);
1432 // -------------------------------------------------------------------------
1434 // Seek to a new file position.
1436 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1438 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1441 if (fetchTftp(tftp
) != ENOERR
)
1447 // Pos is already where we want to be.
1451 // Add pos to current offset.
1452 pos
+= fp
->f_offset
;
1456 // Add pos to file size.
1457 pos
+= tftp
->actual
;
1464 // Check that pos is still within current file size, or at the
1466 if (pos
< 0 || pos
> tftp
->actual
)
1469 // All OK, set fp offset and return new position.
1470 *apos
= fp
->f_offset
= pos
;
1478 cyg_thread_delay(us
/ 10000 + 1);
1484 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1486 cyg_httpd_start_chunked("text");
1487 if (logCount
>= logSize
)
1489 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1490 - logCount
% logSize
);
1492 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1493 cyg_httpd_end_chunked();
1497 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1499 // Filesystem operations
1500 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1501 static int logfs_umount(cyg_mtab_entry
*mte
);
1502 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1503 int mode
, cyg_file
*fte
);
1504 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1507 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1508 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1510 #include <cyg/io/devtab.h>
1512 //==========================================================================
1513 // Filesystem table entries
1515 // -------------------------------------------------------------------------
1517 // This defines the entry in the filesystem table.
1518 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1519 // we should never block in any filesystem operations.
1520 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
1521 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
1525 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1526 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1527 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1528 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1529 (cyg_fsop_link
*)cyg_fileio_erofs
,
1530 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1531 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1532 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1533 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1534 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1536 // -------------------------------------------------------------------------
1538 // This set of file operations are used for normal open files.
1540 static cyg_fileops logfs_fileops
=
1541 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1542 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1543 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1544 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1545 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1546 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1548 // -------------------------------------------------------------------------
1550 // Process a mount request. This mainly finds root for the
1553 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1558 static int logfs_umount(cyg_mtab_entry
*mte
)
1563 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1564 int mode
, cyg_file
*file
)
1566 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1567 file
->f_type
= CYG_FILE_TYPE_FILE
;
1568 file
->f_ops
= &logfs_fileops
;
1575 // -------------------------------------------------------------------------
1577 // Write data to file.
1579 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1582 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1584 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1585 char *buf
= (char *) iov
->iov_base
;
1586 off_t len
= iov
->iov_len
;
1588 diag_write(buf
, len
);
1594 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1599 // -------------------------------------------------------------------------
1601 // Close a file. We just clear out the data pointer.
1603 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
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)