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 ***************************************************************************/
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 #if defined(CYGPKG_NET_FREEBSD_STACK)
86 #include <tftp_support.h>
87 /* posix compatibility broken*/
88 struct tftpd_fileops fileops
=
90 (int (*)(const char *, int))open
,
92 (int (*)(int, const void *, int))write
,
93 (int (*)(int, void *, int))read
99 void diag_write(char *buf
, int len
)
102 for (j
= 0; j
< len
; j
++)
104 diag_printf("%c", buf
[j
]);
108 static bool serialLog
= true;
109 static bool writeLog
= true;
114 extern struct flash_driver
*flash_drivers
[];
115 extern struct target_type
*target_types
[];
117 #ifdef CYGPKG_PROFILE_GPROF
118 #include <cyg/profile/profile.h>
120 extern char _stext
, _etext
; // Defined by the linker
122 static char *start_of_code
=&_stext
;
123 static char *end_of_code
=&_etext
;
125 void start_profile(void)
127 // This starts up the system-wide profiling, gathering
128 // profile information on all of the code, with a 16 byte
129 // "bucket" size, at a rate of 100us/profile hit.
130 // Note: a bucket size of 16 will give pretty good function
131 // resolution. Much smaller and the buffer becomes
132 // much too large for very little gain.
133 // Note: a timer period of 100us is also a reasonable
134 // compromise. Any smaller and the overhead of
135 // handling the timter (profile) interrupt could
136 // swamp the system. A fast processor might get
137 // by with a smaller value, but a slow one could
138 // even be swamped by this value. If the value is
139 // too large, the usefulness of the profile is reduced.
141 // no more interrupts than 1/10ms.
142 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
143 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
144 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
150 static char reboot_stack
[2048];
152 static void zylinjtag_reboot(cyg_addrword_t data
)
155 diag_printf("Rebooting in 500 ticks..\n");
156 cyg_thread_delay(500);
157 diag_printf("Unmounting /config..\n");
159 diag_printf("Rebooting..\n");
160 HAL_PLATFORM_RESET();
162 static cyg_thread zylinjtag_thread_object
;
163 static cyg_handle_t zylinjtag_thread_handle
;
167 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
168 (void *) reboot_stack
, sizeof(reboot_stack
),
169 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
170 cyg_thread_resume(zylinjtag_thread_handle
);
173 static char zylinjtag_reboot_port_stack
[2048];
174 static cyg_thread zylinjtag_reboot_port_thread_object
;
175 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
177 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
179 int so_reuseaddr_option
= 1;
182 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
184 LOG_ERROR("error creating socket: %s", strerror(errno
));
188 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
191 struct sockaddr_in sin
;
192 unsigned int address_size
;
193 address_size
= sizeof(sin
);
194 memset(&sin
, 0, sizeof(sin
));
195 sin
.sin_family
= AF_INET
;
196 sin
.sin_addr
.s_addr
= INADDR_ANY
;
197 sin
.sin_port
= htons(1234);
199 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
201 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
205 if (listen(fd
, 1) == -1)
207 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
210 // socket_nonblock(fd);
213 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
215 diag_printf("Got reboot signal on port 1234");
221 void reboot_port(void)
223 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
224 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
225 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
226 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
229 int configuration_output_handler(struct command_context
*context
,
232 diag_printf("%s", line
);
237 int zy1000_configuration_output_handler_log(struct command_context
*context
,
240 LOG_USER_N("%s", line
);
245 #ifdef CYGPKG_PROFILE_GPROF
247 int eCosBoard_handle_eCosBoard_profile_command(struct command_context
*cmd_ctx
, char *cmd
, char **args
, int argc
)
249 command_print(cmd_ctx
, "Profiling started");
256 externC
void phi_init_all_network_interfaces(void);
258 struct command_context
*cmd_ctx
;
260 static bool webRunning
= false;
262 void keep_webserver(void)
264 // Target initialisation is only attempted at startup, so we sleep forever and
265 // let the http server bail us out(i.e. get config files set up).
266 diag_printf("OpenOCD has invoked exit().\n"
267 "Use web server to correct any configuration settings and reboot.\n");
271 // exit() will terminate the current thread and we we'll then sleep eternally or
272 // we'll have a reboot scheduled.
275 extern void printDccChar(char c
);
277 static char logBuffer
[128 * 1024];
278 static const int logSize
= sizeof(logBuffer
);
282 void _zylinjtag_diag_write_char(char c
, void **param
)
286 logBuffer
[writePtr
] = c
;
287 writePtr
= (writePtr
+ 1) % logSize
;
294 HAL_DIAG_WRITE_CHAR('\r');
296 HAL_DIAG_WRITE_CHAR(c
);
299 #ifdef CYGPKG_HAL_ZYLIN_PHI
304 void copyfile(char *name2
, char *name1
);
306 void copydir(char *name
, char *destdir
);
309 MTAB_ENTRY(romfs_mte1
,
313 (CYG_ADDRWORD
) &filedata
[0]);
316 void openocd_sleep_prelude(void)
318 cyg_mutex_unlock(&httpstate
.jim_lock
);
321 void openocd_sleep_postlude(void)
323 cyg_mutex_lock(&httpstate
.jim_lock
);
328 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
329 diag_printf("Formatting JFFS2...\n");
331 cyg_io_handle_t handle
;
334 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
337 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
342 cyg_io_flash_getconfig_devsize_t ds
;
344 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
347 diag_printf("Flash error cyg_io_get_config %d\n", err
);
351 cyg_io_flash_getconfig_erase_t e
;
357 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
358 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
361 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
365 diag_printf("Flash formatted successfully\n");
371 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
372 Jim_Obj
* const *argv
)
384 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
385 Jim_Obj
* const *argv
)
387 cyg_handle_t thread
= 0;
389 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
391 /* Loop over the threads, and generate a table row for
394 while (cyg_thread_get_next(&thread
, &id
))
396 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
398 cyg_thread_info info
;
401 cyg_thread_get_info(thread
, id
, &info
);
403 if (info
.name
== NULL
)
404 info
.name
= "<no name>";
406 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
407 info
.name
, strlen(info
.name
)));
409 /* Translate the state into a string.
412 state_string
= "RUN";
413 else if (info
.state
& 0x04)
414 state_string
= "SUSP";
416 switch (info
.state
& 0x1b)
419 state_string
= "SLEEP";
422 state_string
= "CNTSLEEP";
425 state_string
= "CREATE";
428 state_string
= "EXIT";
431 state_string
= "????";
435 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
436 state_string
, strlen(state_string
)));
438 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
439 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
441 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
444 Jim_ListAppendElement(interp
, threads
, threadObj
);
446 Jim_SetResult(interp
, threads
);
451 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
452 Jim_Obj
* const *argv
)
454 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
456 if (logCount
>= logSize
)
458 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
459 % logSize
, logSize
- logCount
% logSize
);
461 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
463 Jim_SetResult(interp
, tclOutput
);
467 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
468 Jim_Obj
* const *argv
)
474 static void zylinjtag_startNetwork(void)
476 // Bring TCP/IP up immediately before we're ready to accept commands.
478 // That is as soon as a PING responds, we're accepting telnet sessions.
479 #if defined(CYGPKG_NET_FREEBSD_STACK)
480 phi_init_all_network_interfaces();
486 diag_printf("Network not up and running\n");
490 /* very first thing we want is a reboot capability */
493 #if defined(CYGPKG_NET_FREEBSD_STACK)
495 tftpd_start(69, &fileops
);
498 cyg_httpd_init_tcl_interpreter();
500 interp
= httpstate
.jim_interp
;
502 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
504 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
505 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
506 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
507 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
508 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
509 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
515 diag_printf("Web server running\n");
519 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
522 strcpy(ifr
.ifr_name
, "eth0");
524 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
529 diag_printf("Can't obtain MAC address\n");
534 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
535 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
536 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
537 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
538 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
543 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
548 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
553 char *infoStr
= "unknown";
556 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
557 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
558 infoStr
= "undefined instruction";
560 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
561 infoStr
= "software interrupt";
563 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
564 infoStr
= "abort prefetch";
566 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
567 infoStr
= "abort data";
574 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
576 diag_printf("Dumping log\n---\n");
577 if (logCount
>= logSize
)
579 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
581 diag_write(logBuffer
, writePtr
);
583 diag_printf("---\nLogdump complete.\n");
584 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
585 diag_printf("\n---\nRebooting\n");
586 HAL_PLATFORM_RESET();
590 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
591 static void setHandler(cyg_code_t exception
)
593 cyg_exception_handler_t
*old_handler
;
594 cyg_addrword_t old_data
;
596 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
597 &old_handler
, &old_data
);
601 static cyg_thread zylinjtag_uart_thread_object
;
602 static cyg_handle_t zylinjtag_uart_thread_handle
;
603 static char uart_stack
[4096];
605 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
606 static char backwardBuffer
[1024];
608 void setNoDelay(int session
, int flag
)
611 // This decreases latency dramatically for e.g. GDB load which
612 // does not have a sliding window protocol
614 // Can cause *lots* of TCP/IP packets to be sent and it would have
615 // to be enabled/disabled on the fly to avoid the CPU being
617 setsockopt(session
, /* socket affected */
618 IPPROTO_TCP
, /* set option at TCP level */
619 TCP_NODELAY
, /* name of option */
620 (char *) &flag
, /* the cast is historical
622 sizeof(int)); /* length of option value */
626 #define TEST_TCPIP() 0
635 } tcpipSent
[512 * 1024];
639 static void zylinjtag_uart(cyg_addrword_t data
)
641 int so_reuseaddr_option
= 1;
644 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
646 LOG_ERROR("error creating socket: %s", strerror(errno
));
650 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
653 struct sockaddr_in sin
;
654 unsigned int address_size
;
655 address_size
= sizeof(sin
);
656 memset(&sin
, 0, sizeof(sin
));
657 sin
.sin_family
= AF_INET
;
658 sin
.sin_addr
.s_addr
= INADDR_ANY
;
659 sin
.sin_port
= htons(5555);
661 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
663 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
667 if (listen(fd
, 1) == -1)
669 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
672 // socket_nonblock(fd);
677 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
683 setNoDelay(session
, 1);
684 int oldopts
= fcntl(session
, F_GETFL
, 0);
685 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
687 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
694 #ifdef CYGPKG_PROFILE_GPROF
712 FD_SET(session
, &read_fds
);
714 FD_SET(serHandle
, &read_fds
);
715 if (serHandle
> fd_max
)
721 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
722 if ((actual
== 0) && (actual2
== 0))
724 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
733 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
735 t
= read(serHandle
, backwardBuffer
,
736 sizeof(backwardBuffer
));
752 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
760 if (FD_ISSET(session
, &read_fds
)
761 && (sizeof(forwardBuffer
) > actual
))
763 // NB! Here it is important that we empty the TCP/IP read buffer
764 // to make transmission tick right
765 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
768 // this will block if there is no data at all
769 t
= read_socket(session
, forwardBuffer
+ actual
,
770 sizeof(forwardBuffer
) - actual
);
781 /* Do not put things into the serial buffer if it has something to send
782 * as that can cause a single byte to be sent at the time.
786 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
793 // The serial buffer is full
806 tcpipSent
[cur
].req
= x
;
807 tcpipSent
[cur
].actual
= y
;
808 tcpipSent
[cur
].req2
= x2
;
809 tcpipSent
[cur
].actual2
= y2
;
814 closeSession
: close(session
);
819 for (i
= 0; i
< 1024; i
++)
821 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
822 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
833 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
834 (void *) uart_stack
, sizeof(uart_stack
),
835 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
836 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
837 cyg_thread_resume(zylinjtag_uart_thread_handle
);
840 int handle_uart_command(struct command_context
*cmd_ctx
, char *cmd
,
841 char **args
, int argc
)
843 static int current_baud
= 38400;
846 command_print(cmd_ctx
, "%d", current_baud
);
851 return ERROR_INVALID_ARGUMENTS
;
854 current_baud
= atol(args
[0]);
857 switch (current_baud
)
860 baud
= CYGNUM_SERIAL_BAUD_9600
;
863 baud
= CYGNUM_SERIAL_BAUD_19200
;
866 baud
= CYGNUM_SERIAL_BAUD_38400
;
869 baud
= CYGNUM_SERIAL_BAUD_57600
;
872 baud
= CYGNUM_SERIAL_BAUD_115200
;
875 baud
= CYGNUM_SERIAL_BAUD_230400
;
878 command_print(cmd_ctx
, "unsupported baudrate");
879 return ERROR_INVALID_ARGUMENTS
;
882 cyg_serial_info_t buf
;
884 //get existing serial configuration
885 len
= sizeof(cyg_serial_info_t
);
887 cyg_io_handle_t serial_handle
;
889 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
892 LOG_ERROR("/dev/ser0 not found\n");
896 err
= cyg_io_get_config(serial_handle
,
897 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
898 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
902 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
907 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
911 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
918 bool logAllToSerial
= false;
921 int boolParam(char *var
);
924 struct command_context
*setup_command_handler(void);
926 static const char *zylin_config_dir
="/config/settings";
928 static int add_default_dirs(void)
930 add_script_search_dir(zylin_config_dir
);
931 add_script_search_dir("/rom/lib/openocd");
932 add_script_search_dir("/rom");
936 int ioutil_init(struct command_context
*cmd_ctx
);
938 int main(int argc
, char *argv
[])
940 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
941 * need to allocate towards the end of the heap. */
943 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
944 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
945 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
946 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
951 atexit(keep_webserver
);
953 diag_init_putc(_zylinjtag_diag_write_char
);
954 // We want this in the log.
955 diag_printf("Zylin ZY1000.\n");
957 err
= mount("", "/ram", "ramfs");
960 diag_printf("unable to mount ramfs\n");
965 sprintf(address
, "%p", &filedata
[0]);
966 err
= mount(address
, "/rom", "romfs");
969 diag_printf("unable to mount /rom\n");
972 err
= mount("", "/log", "logfs");
975 diag_printf("unable to mount logfs\n");
978 err
= mount("", "/tftp", "tftpfs");
981 diag_printf("unable to mount logfs\n");
984 log
= fopen("/log/log", "w");
987 diag_printf("Could not open log file /ram/log\n");
992 copydir("/rom", "/ram/cgi");
994 err
= mount("/dev/flash1", "/config", "jffs2");
997 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
998 err
= mount("", "/config", "ramfs");
1001 diag_printf("unable to mount /config as ramdisk.\n");
1007 /* are we using a ram disk instead of a flash disk? This is used
1008 * for ZY1000 live demo...
1010 * copy over flash disk to ram block device
1012 if (boolParam("ramdisk"))
1014 diag_printf("Unmounting /config from flash and using ram instead\n");
1015 err
= umount("/config");
1018 diag_printf("unable to unmount jffs\n");
1022 err
= mount("/dev/flash1", "/config2", "jffs2");
1025 diag_printf("unable to mount jffs\n");
1029 err
= mount("", "/config", "ramfs");
1032 diag_printf("unable to mount ram block device\n");
1036 // copydir("/config2", "/config");
1037 copyfile("/config2/ip", "/config/ip");
1038 copydir("/config2/settings", "/config/settings");
1044 mkdir(zylin_config_dir
, 0777);
1045 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1046 mkdir(dirname
, 0777);
1048 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1049 mkdir(dirname
, 0777);
1051 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1052 mkdir(dirname
, 0777);
1055 logAllToSerial
= boolParam("logserial");
1057 // We need the network & web server in case there is something wrong with
1058 // the config files that invoke exit()
1059 zylinjtag_startNetwork();
1061 /* we're going to access the jim interpreter from here on... */
1062 openocd_sleep_postlude();
1067 /* initialize commandline interface */
1068 struct command_context
* cmd_ctx
;
1069 cmd_ctx
= setup_command_handler();
1070 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1071 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1074 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1076 return EXIT_FAILURE
;
1081 #ifdef CYGPKG_PROFILE_GPROF
1082 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1086 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1087 "uart <baud> - forward uart on port 5555");
1090 errVal
= log_init(cmd_ctx
);
1091 if (errVal
!= ERROR_OK
)
1093 diag_printf("log_init() failed %d\n", errVal
);
1097 set_log_output(cmd_ctx
, log
);
1099 LOG_DEBUG("log init complete");
1101 // diag_printf("Executing config files\n");
1106 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1107 command_run_line(cmd_ctx
, "debug_level 3");
1110 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1112 /* we MUST always run the init command as it will launch telnet sessions */
1113 command_run_line(cmd_ctx
, "init");
1116 // diag_printf() is really invoked from many more places than we trust it
1117 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1119 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1120 // fingers that it doesn't cause any crashes.
1121 diag_printf("Init complete, GDB & telnet servers launched.\n");
1122 command_set_output_handler(cmd_ctx
,
1123 zy1000_configuration_output_handler_log
, NULL
);
1124 if (!logAllToSerial
)
1129 /* handle network connections */
1130 server_loop(cmd_ctx
);
1131 openocd_sleep_prelude();
1133 /* shut server down */
1136 /* free commandline interface */
1137 command_done(cmd_ctx
);
1145 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1146 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1148 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1152 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1154 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1155 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1157 #include <pkgconf/system.h>
1158 #include <pkgconf/hal.h>
1159 #include <pkgconf/kernel.h>
1160 #include <pkgconf/io_fileio.h>
1161 #include <pkgconf/fs_rom.h>
1163 #include <cyg/kernel/ktypes.h> // base kernel types
1164 #include <cyg/infra/cyg_trac.h> // tracing macros
1165 #include <cyg/infra/cyg_ass.h> // assertion macros
1166 #include <cyg/fileio/fileio.h>
1167 #include <cyg/kernel/kapi.h>
1168 #include <cyg/infra/diag.h>
1170 //==========================================================================
1171 // Eventually we want to eXecute In Place from the ROM in a protected
1172 // environment, so we'll need executables to be aligned to a boundary
1173 // suitable for MMU protection. A suitable boundary would be the 4k
1174 // boundary in all the CPU architectures I am currently aware of.
1176 // Forward definitions
1178 // Filesystem operations
1179 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1180 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1181 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1182 int mode
, cyg_file
*fte
);
1183 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1184 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1187 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1188 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1189 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1191 //==========================================================================
1192 // Filesystem table entries
1194 // -------------------------------------------------------------------------
1196 // This defines the entry in the filesystem table.
1197 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1198 // we should never block in any filesystem operations.
1200 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1205 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1206 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1207 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1208 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1209 (cyg_fsop_link
*)cyg_fileio_erofs
,
1210 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1211 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1212 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1213 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1214 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1217 // -------------------------------------------------------------------------
1219 // This defines a single ROMFS loaded into ROM at the configured address
1221 // MTAB_ENTRY(rom_mte, // structure name
1222 // "/rom", // mount point
1223 // "romfs", // FIlesystem type
1224 // "", // hardware device
1225 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1229 // -------------------------------------------------------------------------
1231 // This set of file operations are used for normal open files.
1233 static cyg_fileops tftpfs_fileops
=
1234 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1235 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1236 tftpfs_fo_fsync
, tftpfs_fo_close
,
1237 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1238 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1239 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1241 // -------------------------------------------------------------------------
1243 // Process a mount request. This mainly finds root for the
1246 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1251 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1266 static void freeTftp(struct Tftp
*t
)
1279 static const int tftpMaxSize
= 8192 * 1024;
1280 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1281 int mode
, cyg_file
*file
)
1284 tftp
= malloc(sizeof(struct Tftp
));
1287 memset(tftp
, 0, sizeof(struct Tftp
));
1289 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1290 file
->f_type
= CYG_FILE_TYPE_FILE
;
1291 file
->f_ops
= &tftpfs_fileops
;
1296 tftp
->mem
= malloc(tftpMaxSize
);
1297 if (tftp
->mem
== NULL
)
1303 char *server
= strchr(name
, '/');
1310 tftp
->server
= malloc(server
- name
+ 1);
1311 if (tftp
->server
== NULL
)
1316 strncpy(tftp
->server
, name
, server
- name
);
1317 tftp
->server
[server
- name
] = 0;
1319 tftp
->file
= strdup(server
+ 1);
1320 if (tftp
->file
== NULL
)
1326 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1331 static int fetchTftp(struct Tftp
*tftp
)
1333 if (!tftp
->readFile
)
1336 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1337 tftpMaxSize
, TFTP_OCTET
, &err
);
1339 if (tftp
->actual
< 0)
1348 // -------------------------------------------------------------------------
1349 // tftpfs_fo_write()
1350 // Read data from file.
1352 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1354 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1356 if (fetchTftp(tftp
) != ENOERR
)
1360 off_t pos
= fp
->f_offset
;
1362 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1364 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1365 char *buf
= (char *) iov
->iov_base
;
1366 off_t len
= iov
->iov_len
;
1368 if (len
+ pos
> tftp
->actual
)
1370 len
= tftp
->actual
- pos
;
1372 resid
+= iov
->iov_len
- len
;
1374 memcpy(buf
, tftp
->mem
+ pos
, len
);
1378 uio
->uio_resid
= resid
;
1384 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1386 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1389 off_t pos
= fp
->f_offset
;
1391 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1393 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1394 char *buf
= (char *) iov
->iov_base
;
1395 off_t len
= iov
->iov_len
;
1397 if (len
+ pos
> tftpMaxSize
)
1399 len
= tftpMaxSize
- pos
;
1401 resid
+= iov
->iov_len
- len
;
1403 memcpy(tftp
->mem
+ pos
, buf
, len
);
1407 uio
->uio_resid
= resid
;
1415 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1421 // -------------------------------------------------------------------------
1423 // Close a file. We just clear out the data pointer.
1425 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1427 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1432 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1433 TFTP_OCTET
, &error
);
1441 // -------------------------------------------------------------------------
1443 // Seek to a new file position.
1445 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1447 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1450 if (fetchTftp(tftp
) != ENOERR
)
1456 // Pos is already where we want to be.
1460 // Add pos to current offset.
1461 pos
+= fp
->f_offset
;
1465 // Add pos to file size.
1466 pos
+= tftp
->actual
;
1473 // Check that pos is still within current file size, or at the
1475 if (pos
< 0 || pos
> tftp
->actual
)
1478 // All OK, set fp offset and return new position.
1479 *apos
= fp
->f_offset
= pos
;
1487 cyg_thread_delay(us
/ 10000 + 1);
1493 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1495 cyg_httpd_start_chunked("text");
1496 if (logCount
>= logSize
)
1498 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1499 - logCount
% logSize
);
1501 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1502 cyg_httpd_end_chunked();
1506 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1508 // Filesystem operations
1509 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1510 static int logfs_umount(cyg_mtab_entry
*mte
);
1511 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1512 int mode
, cyg_file
*fte
);
1513 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1516 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1517 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1519 #include <cyg/io/devtab.h>
1521 //==========================================================================
1522 // Filesystem table entries
1524 // -------------------------------------------------------------------------
1526 // This defines the entry in the filesystem table.
1527 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1528 // we should never block in any filesystem operations.
1529 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1530 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1534 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1535 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1536 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1537 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1538 (cyg_fsop_link
*)cyg_fileio_erofs
,
1539 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1540 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1541 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1542 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1543 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1545 // -------------------------------------------------------------------------
1547 // This set of file operations are used for normal open files.
1549 static cyg_fileops logfs_fileops
=
1550 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1551 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1552 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1553 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1554 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1555 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1557 // -------------------------------------------------------------------------
1559 // Process a mount request. This mainly finds root for the
1562 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1567 static int logfs_umount(cyg_mtab_entry
*mte
)
1572 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1573 int mode
, cyg_file
*file
)
1575 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1576 file
->f_type
= CYG_FILE_TYPE_FILE
;
1577 file
->f_ops
= &logfs_fileops
;
1584 // -------------------------------------------------------------------------
1586 // Write data to file.
1588 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1591 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1593 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1594 char *buf
= (char *) iov
->iov_base
;
1595 off_t len
= iov
->iov_len
;
1597 diag_write(buf
, len
);
1603 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1608 // -------------------------------------------------------------------------
1610 // Close a file. We just clear out the data pointer.
1612 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1617 int loadFile(const char *fileName
, void **data
, int *len
);
1619 /* boolean parameter stored on config */
1620 int boolParam(char *var
)
1622 bool result
= false;
1623 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1629 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1633 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)