1 /***************************************************************************
2 * Copyright (C) 2007-2009 by Øyvind Harboe *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
26 #include "configuration.h"
33 #include "telnet_server.h"
34 #include "gdb_server.h"
37 #include <time_support.h>
45 #include <cyg/io/flash.h>
46 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
51 #include <cyg/fileio/fileio.h>
53 #include <cyg/athttpd/http.h>
54 #include <cyg/athttpd/socket.h>
55 #include <cyg/athttpd/handler.h>
56 #include <cyg/athttpd/cgi.h>
57 #include <cyg/athttpd/forms.h>
58 #include <cyg/discover/discover.h>
59 #include <cyg/hal/hal_diag.h>
60 #include <cyg/kernel/kapi.h>
61 #include <cyg/io/serialio.h>
62 #include <cyg/io/io.h>
63 #include <netinet/tcp.h>
65 #include <sys/ioctl.h>
66 #include <sys/socket.h>
67 #include <netinet/in.h>
69 #include <arpa/inet.h>
70 #include <sys/types.h>
71 #include <sys/socket.h>
73 #include <netinet/in.h>
75 #include <arpa/inet.h>
85 #ifdef CYGPKG_HAL_NIOS2
86 #define ZY1000_SER_DEV "/dev/uart_0"
88 #define ZY1000_SER_DEV "/dev/ser0"
94 #if defined(CYGPKG_NET_FREEBSD_STACK)
95 #include <tftp_support.h>
96 /* posix compatibility broken*/
97 struct tftpd_fileops fileops
=
99 (int (*)(const char *, int))open
,
101 (int (*)(int, const void *, int))write
,
102 (int (*)(int, void *, int))read
108 void diag_write(char *buf
, int len
)
111 for (j
= 0; j
< len
; j
++)
113 diag_printf("%c", buf
[j
]);
117 static bool serialLog
= true;
118 static bool writeLog
= true;
123 extern struct flash_driver
*flash_drivers
[];
124 extern struct target_type
*target_types
[];
126 #ifdef CYGPKG_PROFILE_GPROF
127 #include <cyg/profile/profile.h>
129 extern char _stext
, _etext
; // Defined by the linker
131 static char *start_of_code
=&_stext
;
132 static char *end_of_code
=&_etext
;
134 void start_profile(void)
136 // This starts up the system-wide profiling, gathering
137 // profile information on all of the code, with a 16 byte
138 // "bucket" size, at a rate of 100us/profile hit.
139 // Note: a bucket size of 16 will give pretty good function
140 // resolution. Much smaller and the buffer becomes
141 // much too large for very little gain.
142 // Note: a timer period of 100us is also a reasonable
143 // compromise. Any smaller and the overhead of
144 // handling the timter (profile) interrupt could
145 // swamp the system. A fast processor might get
146 // by with a smaller value, but a slow one could
147 // even be swamped by this value. If the value is
148 // too large, the usefulness of the profile is reduced.
150 // no more interrupts than 1/10ms.
151 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
152 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
153 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
159 static char reboot_stack
[2048];
161 static void zylinjtag_reboot(cyg_addrword_t data
)
164 diag_printf("Rebooting in 500 ticks..\n");
165 cyg_thread_delay(500);
166 diag_printf("Unmounting /config..\n");
168 diag_printf("Rebooting..\n");
169 HAL_PLATFORM_RESET();
171 static cyg_thread zylinjtag_thread_object
;
172 static cyg_handle_t zylinjtag_thread_handle
;
176 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
177 (void *) reboot_stack
, sizeof(reboot_stack
),
178 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
179 cyg_thread_resume(zylinjtag_thread_handle
);
182 static char zylinjtag_reboot_port_stack
[2048];
183 static cyg_thread zylinjtag_reboot_port_thread_object
;
184 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
186 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
188 int so_reuseaddr_option
= 1;
191 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
193 LOG_ERROR("error creating socket: %s", strerror(errno
));
197 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
200 struct sockaddr_in sin
;
201 unsigned int address_size
;
202 address_size
= sizeof(sin
);
203 memset(&sin
, 0, sizeof(sin
));
204 sin
.sin_family
= AF_INET
;
205 sin
.sin_addr
.s_addr
= INADDR_ANY
;
206 sin
.sin_port
= htons(1234);
208 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
210 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
214 if (listen(fd
, 1) == -1)
216 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
219 // socket_nonblock(fd);
222 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
224 diag_printf("Got reboot signal on port 1234");
230 void reboot_port(void)
232 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
233 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
234 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
235 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
238 int configuration_output_handler(struct command_context
*context
,
241 diag_printf("%s", line
);
246 int zy1000_configuration_output_handler_log(struct command_context
*context
,
249 LOG_USER_N("%s", line
);
254 #ifdef CYGPKG_PROFILE_GPROF
256 int eCosBoard_handle_eCosBoard_profile_command(struct command_context
*cmd_ctx
, char *cmd
, char **args
, int argc
)
258 command_print(cmd_ctx
, "Profiling started");
265 externC
void phi_init_all_network_interfaces(void);
267 struct command_context
*cmd_ctx
;
269 static bool webRunning
= false;
271 void keep_webserver(void)
273 // Target initialisation is only attempted at startup, so we sleep forever and
274 // let the http server bail us out(i.e. get config files set up).
275 diag_printf("OpenOCD has invoked exit().\n"
276 "Use web server to correct any configuration settings and reboot.\n");
280 // exit() will terminate the current thread and we we'll then sleep eternally or
281 // we'll have a reboot scheduled.
284 extern void printDccChar(char c
);
286 static char logBuffer
[128 * 1024];
287 static const int logSize
= sizeof(logBuffer
);
291 void _zylinjtag_diag_write_char(char c
, void **param
)
295 logBuffer
[writePtr
] = c
;
296 writePtr
= (writePtr
+ 1) % logSize
;
303 HAL_DIAG_WRITE_CHAR('\r');
305 HAL_DIAG_WRITE_CHAR(c
);
308 #ifdef CYGPKG_HAL_ZYLIN_PHI
313 void copyfile(char *name2
, char *name1
);
315 void copydir(char *name
, char *destdir
);
318 MTAB_ENTRY(romfs_mte1
,
322 (CYG_ADDRWORD
) &filedata
[0]);
325 void openocd_sleep_prelude(void)
327 cyg_mutex_unlock(&httpstate
.jim_lock
);
330 void openocd_sleep_postlude(void)
332 cyg_mutex_lock(&httpstate
.jim_lock
);
337 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
338 diag_printf("Formatting JFFS2...\n");
340 cyg_io_handle_t handle
;
343 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
346 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
351 cyg_io_flash_getconfig_devsize_t ds
;
353 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
356 diag_printf("Flash error cyg_io_get_config %d\n", err
);
360 cyg_io_flash_getconfig_erase_t e
;
366 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
367 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
370 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
374 diag_printf("Flash formatted successfully\n");
380 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
381 Jim_Obj
* const *argv
)
393 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
394 Jim_Obj
* const *argv
)
396 cyg_handle_t thread
= 0;
398 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
400 /* Loop over the threads, and generate a table row for
403 while (cyg_thread_get_next(&thread
, &id
))
405 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
407 cyg_thread_info info
;
410 cyg_thread_get_info(thread
, id
, &info
);
412 if (info
.name
== NULL
)
413 info
.name
= "<no name>";
415 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
416 info
.name
, strlen(info
.name
)));
418 /* Translate the state into a string.
421 state_string
= "RUN";
422 else if (info
.state
& 0x04)
423 state_string
= "SUSP";
425 switch (info
.state
& 0x1b)
428 state_string
= "SLEEP";
431 state_string
= "CNTSLEEP";
434 state_string
= "CREATE";
437 state_string
= "EXIT";
440 state_string
= "????";
444 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
445 state_string
, strlen(state_string
)));
447 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
448 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
450 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
453 Jim_ListAppendElement(interp
, threads
, threadObj
);
455 Jim_SetResult(interp
, threads
);
460 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
461 Jim_Obj
* const *argv
)
463 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
465 if (logCount
>= logSize
)
467 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
468 % logSize
, logSize
- logCount
% logSize
);
470 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
472 Jim_SetResult(interp
, tclOutput
);
476 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
477 Jim_Obj
* const *argv
)
483 static void zylinjtag_startNetwork(void)
485 // Bring TCP/IP up immediately before we're ready to accept commands.
487 // That is as soon as a PING responds, we're accepting telnet sessions.
488 #if defined(CYGPKG_NET_FREEBSD_STACK)
489 phi_init_all_network_interfaces();
495 diag_printf("Network not up and running\n");
499 /* very first thing we want is a reboot capability */
502 #if defined(CYGPKG_NET_FREEBSD_STACK)
504 tftpd_start(69, &fileops
);
507 cyg_httpd_init_tcl_interpreter();
509 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
511 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
512 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
513 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
514 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
515 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
516 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
522 diag_printf("Web server running\n");
526 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
529 strcpy(ifr
.ifr_name
, "eth0");
531 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
536 diag_printf("Can't obtain MAC address\n");
541 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
544 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
545 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
546 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
547 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
550 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
555 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
560 char *infoStr
= "unknown";
563 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
564 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
565 infoStr
= "undefined instruction";
567 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
568 infoStr
= "software interrupt";
570 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
571 infoStr
= "abort prefetch";
573 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
574 infoStr
= "abort data";
581 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
583 diag_printf("Dumping log\n---\n");
584 if (logCount
>= logSize
)
586 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
588 diag_write(logBuffer
, writePtr
);
590 diag_printf("---\nLogdump complete.\n");
591 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
592 diag_printf("\n---\nRebooting\n");
593 HAL_PLATFORM_RESET();
597 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
598 static void setHandler(cyg_code_t exception
)
600 cyg_exception_handler_t
*old_handler
;
601 cyg_addrword_t old_data
;
603 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
604 &old_handler
, &old_data
);
608 static cyg_thread zylinjtag_uart_thread_object
;
609 static cyg_handle_t zylinjtag_uart_thread_handle
;
610 static char uart_stack
[4096];
612 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
613 static char backwardBuffer
[1024];
615 void setNoDelay(int session
, int flag
)
618 // This decreases latency dramatically for e.g. GDB load which
619 // does not have a sliding window protocol
621 // Can cause *lots* of TCP/IP packets to be sent and it would have
622 // to be enabled/disabled on the fly to avoid the CPU being
624 setsockopt(session
, /* socket affected */
625 IPPROTO_TCP
, /* set option at TCP level */
626 TCP_NODELAY
, /* name of option */
627 (char *) &flag
, /* the cast is historical
629 sizeof(int)); /* length of option value */
633 #define TEST_TCPIP() 0
642 } tcpipSent
[512 * 1024];
646 static void zylinjtag_uart(cyg_addrword_t data
)
648 int so_reuseaddr_option
= 1;
651 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
653 LOG_ERROR("error creating socket: %s", strerror(errno
));
657 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
660 struct sockaddr_in sin
;
661 unsigned int address_size
;
662 address_size
= sizeof(sin
);
663 memset(&sin
, 0, sizeof(sin
));
664 sin
.sin_family
= AF_INET
;
665 sin
.sin_addr
.s_addr
= INADDR_ANY
;
666 sin
.sin_port
= htons(5555);
668 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
670 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
674 if (listen(fd
, 1) == -1)
676 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
679 // socket_nonblock(fd);
684 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
690 setNoDelay(session
, 1);
691 int oldopts
= fcntl(session
, F_GETFL
, 0);
692 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
694 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
701 #ifdef CYGPKG_PROFILE_GPROF
719 FD_SET(session
, &read_fds
);
721 FD_SET(serHandle
, &read_fds
);
722 if (serHandle
> fd_max
)
728 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
729 if ((actual
== 0) && (actual2
== 0))
731 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
740 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
742 t
= read(serHandle
, backwardBuffer
,
743 sizeof(backwardBuffer
));
759 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
767 if (FD_ISSET(session
, &read_fds
)
768 && (sizeof(forwardBuffer
) > actual
))
770 // NB! Here it is important that we empty the TCP/IP read buffer
771 // to make transmission tick right
772 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
775 // this will block if there is no data at all
776 t
= read_socket(session
, forwardBuffer
+ actual
,
777 sizeof(forwardBuffer
) - actual
);
788 /* Do not put things into the serial buffer if it has something to send
789 * as that can cause a single byte to be sent at the time.
793 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
800 // The serial buffer is full
813 tcpipSent
[cur
].req
= x
;
814 tcpipSent
[cur
].actual
= y
;
815 tcpipSent
[cur
].req2
= x2
;
816 tcpipSent
[cur
].actual2
= y2
;
821 closeSession
: close(session
);
826 for (i
= 0; i
< 1024; i
++)
828 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
829 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
840 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
841 (void *) uart_stack
, sizeof(uart_stack
),
842 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
843 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
844 cyg_thread_resume(zylinjtag_uart_thread_handle
);
847 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
848 Jim_Obj
* const *argv
)
850 static int current_baud
= 38400;
853 command_print(cmd_ctx
, "%d", current_baud
);
862 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
865 current_baud
= new_baudrate
;
868 switch (current_baud
)
871 baud
= CYGNUM_SERIAL_BAUD_9600
;
874 baud
= CYGNUM_SERIAL_BAUD_19200
;
877 baud
= CYGNUM_SERIAL_BAUD_38400
;
880 baud
= CYGNUM_SERIAL_BAUD_57600
;
883 baud
= CYGNUM_SERIAL_BAUD_115200
;
886 baud
= CYGNUM_SERIAL_BAUD_230400
;
889 command_print(cmd_ctx
, "unsupported baudrate");
890 return ERROR_INVALID_ARGUMENTS
;
893 cyg_serial_info_t buf
;
895 //get existing serial configuration
896 len
= sizeof(cyg_serial_info_t
);
898 cyg_io_handle_t serial_handle
;
900 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
903 LOG_ERROR("Could not open serial port\n");
907 err
= cyg_io_get_config(serial_handle
,
908 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
909 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
913 LOG_ERROR("Failed to get serial port settings %d", err
);
918 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
922 LOG_ERROR("Failed to set serial port settings %d", err
);
929 bool logAllToSerial
= false;
932 int boolParam(char *var
);
935 static const char *zylin_config_dir
="/config/settings";
937 static int add_default_dirs(void)
939 add_script_search_dir(zylin_config_dir
);
940 add_script_search_dir("/rom/lib/openocd");
941 add_script_search_dir("/rom");
945 int ioutil_init(struct command_context
*cmd_ctx
);
947 int main(int argc
, char *argv
[])
949 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
950 * need to allocate towards the end of the heap. */
952 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
953 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
954 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
955 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
960 atexit(keep_webserver
);
962 diag_init_putc(_zylinjtag_diag_write_char
);
963 // We want this in the log.
964 diag_printf("Zylin ZY1000.\n");
966 err
= mount("", "/ram", "ramfs");
969 diag_printf("unable to mount ramfs\n");
974 sprintf(address
, "%p", &filedata
[0]);
975 err
= mount(address
, "/rom", "romfs");
978 diag_printf("unable to mount /rom\n");
981 err
= mount("", "/log", "logfs");
984 diag_printf("unable to mount logfs\n");
987 err
= mount("", "/tftp", "tftpfs");
990 diag_printf("unable to mount logfs\n");
993 log
= fopen("/log/log", "w");
996 diag_printf("Could not open log file /ram/log\n");
1001 copydir("/rom", "/ram/cgi");
1003 err
= mount("/dev/flash1", "/config", "jffs2");
1006 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1007 err
= mount("", "/config", "ramfs");
1010 diag_printf("unable to mount /config as ramdisk.\n");
1016 /* are we using a ram disk instead of a flash disk? This is used
1017 * for ZY1000 live demo...
1019 * copy over flash disk to ram block device
1021 if (boolParam("ramdisk"))
1023 diag_printf("Unmounting /config from flash and using ram instead\n");
1024 err
= umount("/config");
1027 diag_printf("unable to unmount jffs\n");
1031 err
= mount("/dev/flash1", "/config2", "jffs2");
1034 diag_printf("unable to mount jffs\n");
1038 err
= mount("", "/config", "ramfs");
1041 diag_printf("unable to mount ram block device\n");
1045 // copydir("/config2", "/config");
1046 copyfile("/config2/ip", "/config/ip");
1047 copydir("/config2/settings", "/config/settings");
1053 mkdir(zylin_config_dir
, 0777);
1054 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1055 mkdir(dirname
, 0777);
1057 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1058 mkdir(dirname
, 0777);
1060 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1061 mkdir(dirname
, 0777);
1064 logAllToSerial
= boolParam("logserial");
1066 // We need the network & web server in case there is something wrong with
1067 // the config files that invoke exit()
1068 zylinjtag_startNetwork();
1070 /* we're going to access the jim interpreter from here on... */
1071 openocd_sleep_postlude();
1076 /* initialize commandline interface */
1077 struct command_context
* cmd_ctx
;
1078 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1079 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1080 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1081 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1084 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1086 return EXIT_FAILURE
;
1091 #ifdef CYGPKG_PROFILE_GPROF
1092 COMMAND_REGISTER(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1096 Jim_CreateCommand(httpstate
.jim_interp
, "uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1101 set_log_output(cmd_ctx
, log
);
1103 LOG_DEBUG("log init complete");
1105 // diag_printf("Executing config files\n");
1110 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1111 command_run_line(cmd_ctx
, "debug_level 3");
1114 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1116 /* we MUST always run the init command as it will launch telnet sessions */
1117 command_run_line(cmd_ctx
, "init");
1120 // diag_printf() is really invoked from many more places than we trust it
1121 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1123 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1124 // fingers that it doesn't cause any crashes.
1125 diag_printf("Init complete, GDB & telnet servers launched.\n");
1126 command_set_output_handler(cmd_ctx
,
1127 zy1000_configuration_output_handler_log
, NULL
);
1128 if (!logAllToSerial
)
1133 /* handle network connections */
1134 server_loop(cmd_ctx
);
1135 openocd_sleep_prelude();
1137 /* shut server down */
1140 /* free commandline interface */
1141 command_done(cmd_ctx
);
1149 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1150 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1152 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1156 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1158 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1159 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1161 #include <pkgconf/system.h>
1162 #include <pkgconf/hal.h>
1163 #include <pkgconf/kernel.h>
1164 #include <pkgconf/io_fileio.h>
1165 #include <pkgconf/fs_rom.h>
1167 #include <cyg/kernel/ktypes.h> // base kernel types
1168 #include <cyg/infra/cyg_trac.h> // tracing macros
1169 #include <cyg/infra/cyg_ass.h> // assertion macros
1170 #include <cyg/fileio/fileio.h>
1171 #include <cyg/kernel/kapi.h>
1172 #include <cyg/infra/diag.h>
1174 //==========================================================================
1175 // Eventually we want to eXecute In Place from the ROM in a protected
1176 // environment, so we'll need executables to be aligned to a boundary
1177 // suitable for MMU protection. A suitable boundary would be the 4k
1178 // boundary in all the CPU architectures I am currently aware of.
1180 // Forward definitions
1182 // Filesystem operations
1183 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1184 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1185 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1186 int mode
, cyg_file
*fte
);
1187 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1188 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1191 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1192 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1193 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1195 //==========================================================================
1196 // Filesystem table entries
1198 // -------------------------------------------------------------------------
1200 // This defines the entry in the filesystem table.
1201 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1202 // we should never block in any filesystem operations.
1204 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1209 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1210 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1211 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1212 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1213 (cyg_fsop_link
*)cyg_fileio_erofs
,
1214 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1215 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1216 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1217 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1218 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1221 // -------------------------------------------------------------------------
1223 // This defines a single ROMFS loaded into ROM at the configured address
1225 // MTAB_ENTRY(rom_mte, // structure name
1226 // "/rom", // mount point
1227 // "romfs", // FIlesystem type
1228 // "", // hardware device
1229 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1233 // -------------------------------------------------------------------------
1235 // This set of file operations are used for normal open files.
1237 static cyg_fileops tftpfs_fileops
=
1238 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1239 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1240 tftpfs_fo_fsync
, tftpfs_fo_close
,
1241 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1242 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1243 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1245 // -------------------------------------------------------------------------
1247 // Process a mount request. This mainly finds root for the
1250 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1255 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1270 static void freeTftp(struct Tftp
*t
)
1283 static const int tftpMaxSize
= 8192 * 1024;
1284 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1285 int mode
, cyg_file
*file
)
1288 tftp
= malloc(sizeof(struct Tftp
));
1291 memset(tftp
, 0, sizeof(struct Tftp
));
1293 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1294 file
->f_type
= CYG_FILE_TYPE_FILE
;
1295 file
->f_ops
= &tftpfs_fileops
;
1300 tftp
->mem
= malloc(tftpMaxSize
);
1301 if (tftp
->mem
== NULL
)
1307 char *server
= strchr(name
, '/');
1314 tftp
->server
= malloc(server
- name
+ 1);
1315 if (tftp
->server
== NULL
)
1320 strncpy(tftp
->server
, name
, server
- name
);
1321 tftp
->server
[server
- name
] = 0;
1323 tftp
->file
= strdup(server
+ 1);
1324 if (tftp
->file
== NULL
)
1330 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1335 static int fetchTftp(struct Tftp
*tftp
)
1337 if (!tftp
->readFile
)
1340 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1341 tftpMaxSize
, TFTP_OCTET
, &err
);
1343 if (tftp
->actual
< 0)
1352 // -------------------------------------------------------------------------
1353 // tftpfs_fo_write()
1354 // Read data from file.
1356 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1358 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1360 if (fetchTftp(tftp
) != ENOERR
)
1364 off_t pos
= fp
->f_offset
;
1366 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1368 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1369 char *buf
= (char *) iov
->iov_base
;
1370 off_t len
= iov
->iov_len
;
1372 if (len
+ pos
> tftp
->actual
)
1374 len
= tftp
->actual
- pos
;
1376 resid
+= iov
->iov_len
- len
;
1378 memcpy(buf
, tftp
->mem
+ pos
, len
);
1382 uio
->uio_resid
= resid
;
1388 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1390 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1393 off_t pos
= fp
->f_offset
;
1395 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1397 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1398 char *buf
= (char *) iov
->iov_base
;
1399 off_t len
= iov
->iov_len
;
1401 if (len
+ pos
> tftpMaxSize
)
1403 len
= tftpMaxSize
- pos
;
1405 resid
+= iov
->iov_len
- len
;
1407 memcpy(tftp
->mem
+ pos
, buf
, len
);
1411 uio
->uio_resid
= resid
;
1419 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1425 // -------------------------------------------------------------------------
1427 // Close a file. We just clear out the data pointer.
1429 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1431 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1436 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1437 TFTP_OCTET
, &error
);
1445 // -------------------------------------------------------------------------
1447 // Seek to a new file position.
1449 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1451 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1454 if (fetchTftp(tftp
) != ENOERR
)
1460 // Pos is already where we want to be.
1464 // Add pos to current offset.
1465 pos
+= fp
->f_offset
;
1469 // Add pos to file size.
1470 pos
+= tftp
->actual
;
1477 // Check that pos is still within current file size, or at the
1479 if (pos
< 0 || pos
> tftp
->actual
)
1482 // All OK, set fp offset and return new position.
1483 *apos
= fp
->f_offset
= pos
;
1491 cyg_thread_delay(us
/ 10000 + 1);
1497 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1499 cyg_httpd_start_chunked("text");
1500 if (logCount
>= logSize
)
1502 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1503 - logCount
% logSize
);
1505 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1506 cyg_httpd_end_chunked();
1510 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1512 // Filesystem operations
1513 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1514 static int logfs_umount(cyg_mtab_entry
*mte
);
1515 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1516 int mode
, cyg_file
*fte
);
1517 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1520 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1521 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1523 #include <cyg/io/devtab.h>
1525 //==========================================================================
1526 // Filesystem table entries
1528 // -------------------------------------------------------------------------
1530 // This defines the entry in the filesystem table.
1531 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1532 // we should never block in any filesystem operations.
1533 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1534 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1538 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1539 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1540 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1541 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1542 (cyg_fsop_link
*)cyg_fileio_erofs
,
1543 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1544 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1545 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1546 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1547 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1549 // -------------------------------------------------------------------------
1551 // This set of file operations are used for normal open files.
1553 static cyg_fileops logfs_fileops
=
1554 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1555 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1556 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1557 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1558 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1559 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1561 // -------------------------------------------------------------------------
1563 // Process a mount request. This mainly finds root for the
1566 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1571 static int logfs_umount(cyg_mtab_entry
*mte
)
1576 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1577 int mode
, cyg_file
*file
)
1579 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1580 file
->f_type
= CYG_FILE_TYPE_FILE
;
1581 file
->f_ops
= &logfs_fileops
;
1588 // -------------------------------------------------------------------------
1590 // Write data to file.
1592 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1595 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1597 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1598 char *buf
= (char *) iov
->iov_base
;
1599 off_t len
= iov
->iov_len
;
1601 diag_write(buf
, len
);
1607 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1612 // -------------------------------------------------------------------------
1614 // Close a file. We just clear out the data pointer.
1616 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1621 int loadFile(const char *fileName
, void **data
, int *len
);
1623 /* boolean parameter stored on config */
1624 int boolParam(char *var
)
1626 bool result
= false;
1627 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1633 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1637 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)