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"
34 #include "telnet_server.h"
35 #include "gdb_server.h"
38 #include <time_support.h>
46 #include <cyg/io/flash.h>
47 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
52 #include <cyg/fileio/fileio.h>
54 #include <cyg/athttpd/http.h>
55 #include <cyg/athttpd/socket.h>
56 #include <cyg/athttpd/handler.h>
57 #include <cyg/athttpd/cgi.h>
58 #include <cyg/athttpd/forms.h>
59 #include <cyg/discover/discover.h>
60 #include <cyg/hal/hal_diag.h>
61 #include <cyg/kernel/kapi.h>
62 #include <cyg/io/serialio.h>
63 #include <cyg/io/io.h>
64 #include <netinet/tcp.h>
66 #include <sys/ioctl.h>
67 #include <sys/socket.h>
68 #include <netinet/in.h>
70 #include <arpa/inet.h>
71 #include <sys/types.h>
72 #include <sys/socket.h>
74 #include <netinet/in.h>
76 #include <arpa/inet.h>
86 #if defined(CYGPKG_NET_FREEBSD_STACK)
87 #include <tftp_support.h>
88 /* posix compatibility broken*/
89 struct tftpd_fileops fileops
=
91 (int (*)(const char *, int))open
,
93 (int (*)(int, const void *, int))write
,
94 (int (*)(int, void *, int))read
100 void diag_write(char *buf
, int len
)
103 for (j
= 0; j
< len
; j
++)
105 diag_printf("%c", buf
[j
]);
109 static bool serialLog
= true;
110 static bool writeLog
= true;
115 extern struct flash_driver
*flash_drivers
[];
116 extern struct target_type
*target_types
[];
118 #ifdef CYGPKG_PROFILE_GPROF
119 #include <cyg/profile/profile.h>
121 extern char _stext
, _etext
; // Defined by the linker
123 static char *start_of_code
=&_stext
;
124 static char *end_of_code
=&_etext
;
126 void start_profile(void)
128 // This starts up the system-wide profiling, gathering
129 // profile information on all of the code, with a 16 byte
130 // "bucket" size, at a rate of 100us/profile hit.
131 // Note: a bucket size of 16 will give pretty good function
132 // resolution. Much smaller and the buffer becomes
133 // much too large for very little gain.
134 // Note: a timer period of 100us is also a reasonable
135 // compromise. Any smaller and the overhead of
136 // handling the timter (profile) interrupt could
137 // swamp the system. A fast processor might get
138 // by with a smaller value, but a slow one could
139 // even be swamped by this value. If the value is
140 // too large, the usefulness of the profile is reduced.
142 // no more interrupts than 1/10ms.
143 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
144 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
145 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
151 static char reboot_stack
[2048];
153 static void zylinjtag_reboot(cyg_addrword_t data
)
156 diag_printf("Rebooting in 500 ticks..\n");
157 cyg_thread_delay(500);
158 diag_printf("Unmounting /config..\n");
160 diag_printf("Rebooting..\n");
161 HAL_PLATFORM_RESET();
163 static cyg_thread zylinjtag_thread_object
;
164 static cyg_handle_t zylinjtag_thread_handle
;
168 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
169 (void *) reboot_stack
, sizeof(reboot_stack
),
170 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
171 cyg_thread_resume(zylinjtag_thread_handle
);
174 static char zylinjtag_reboot_port_stack
[2048];
175 static cyg_thread zylinjtag_reboot_port_thread_object
;
176 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
178 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
180 int so_reuseaddr_option
= 1;
183 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
185 LOG_ERROR("error creating socket: %s", strerror(errno
));
189 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
192 struct sockaddr_in sin
;
193 unsigned int address_size
;
194 address_size
= sizeof(sin
);
195 memset(&sin
, 0, sizeof(sin
));
196 sin
.sin_family
= AF_INET
;
197 sin
.sin_addr
.s_addr
= INADDR_ANY
;
198 sin
.sin_port
= htons(1234);
200 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
202 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
206 if (listen(fd
, 1) == -1)
208 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
211 // socket_nonblock(fd);
214 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
216 diag_printf("Got reboot signal on port 1234");
222 void reboot_port(void)
224 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
225 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
226 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
227 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
230 int configuration_output_handler(struct command_context
*context
,
233 diag_printf("%s", line
);
238 int zy1000_configuration_output_handler_log(struct command_context
*context
,
241 LOG_USER_N("%s", line
);
246 #ifdef CYGPKG_PROFILE_GPROF
248 int eCosBoard_handle_eCosBoard_profile_command(struct command_context
*cmd_ctx
, char *cmd
, char **args
, int argc
)
250 command_print(cmd_ctx
, "Profiling started");
257 externC
void phi_init_all_network_interfaces(void);
259 struct command_context
*cmd_ctx
;
261 static bool webRunning
= false;
263 void keep_webserver(void)
265 // Target initialisation is only attempted at startup, so we sleep forever and
266 // let the http server bail us out(i.e. get config files set up).
267 diag_printf("OpenOCD has invoked exit().\n"
268 "Use web server to correct any configuration settings and reboot.\n");
272 // exit() will terminate the current thread and we we'll then sleep eternally or
273 // we'll have a reboot scheduled.
276 extern void printDccChar(char c
);
278 static char logBuffer
[128 * 1024];
279 static const int logSize
= sizeof(logBuffer
);
283 void _zylinjtag_diag_write_char(char c
, void **param
)
287 logBuffer
[writePtr
] = c
;
288 writePtr
= (writePtr
+ 1) % logSize
;
295 HAL_DIAG_WRITE_CHAR('\r');
297 HAL_DIAG_WRITE_CHAR(c
);
300 #ifdef CYGPKG_HAL_ZYLIN_PHI
305 void copyfile(char *name2
, char *name1
);
307 void copydir(char *name
, char *destdir
);
310 MTAB_ENTRY(romfs_mte1
,
314 (CYG_ADDRWORD
) &filedata
[0]);
317 void openocd_sleep_prelude(void)
319 cyg_mutex_unlock(&httpstate
.jim_lock
);
322 void openocd_sleep_postlude(void)
324 cyg_mutex_lock(&httpstate
.jim_lock
);
329 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
330 diag_printf("Formatting JFFS2...\n");
332 cyg_io_handle_t handle
;
335 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
338 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
343 cyg_io_flash_getconfig_devsize_t ds
;
345 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
348 diag_printf("Flash error cyg_io_get_config %d\n", err
);
352 cyg_io_flash_getconfig_erase_t e
;
358 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
359 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
362 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
366 diag_printf("Flash formatted successfully\n");
372 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
373 Jim_Obj
* const *argv
)
385 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
386 Jim_Obj
* const *argv
)
388 cyg_handle_t thread
= 0;
390 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
392 /* Loop over the threads, and generate a table row for
395 while (cyg_thread_get_next(&thread
, &id
))
397 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
399 cyg_thread_info info
;
402 cyg_thread_get_info(thread
, id
, &info
);
404 if (info
.name
== NULL
)
405 info
.name
= "<no name>";
407 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
408 info
.name
, strlen(info
.name
)));
410 /* Translate the state into a string.
413 state_string
= "RUN";
414 else if (info
.state
& 0x04)
415 state_string
= "SUSP";
417 switch (info
.state
& 0x1b)
420 state_string
= "SLEEP";
423 state_string
= "CNTSLEEP";
426 state_string
= "CREATE";
429 state_string
= "EXIT";
432 state_string
= "????";
436 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
437 state_string
, strlen(state_string
)));
439 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
440 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
442 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
445 Jim_ListAppendElement(interp
, threads
, threadObj
);
447 Jim_SetResult(interp
, threads
);
452 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
453 Jim_Obj
* const *argv
)
455 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
457 if (logCount
>= logSize
)
459 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
460 % logSize
, logSize
- logCount
% logSize
);
462 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
464 Jim_SetResult(interp
, tclOutput
);
468 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
469 Jim_Obj
* const *argv
)
475 static void zylinjtag_startNetwork(void)
477 // Bring TCP/IP up immediately before we're ready to accept commands.
479 // That is as soon as a PING responds, we're accepting telnet sessions.
480 #if defined(CYGPKG_NET_FREEBSD_STACK)
481 phi_init_all_network_interfaces();
487 diag_printf("Network not up and running\n");
491 /* very first thing we want is a reboot capability */
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
, "zy1000_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
, "format_jffs2",
510 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
516 diag_printf("Web server running\n");
520 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
523 strcpy(ifr
.ifr_name
, "eth0");
525 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
530 diag_printf("Can't obtain MAC address\n");
535 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
536 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
537 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
538 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
544 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
549 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
554 char *infoStr
= "unknown";
557 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
558 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
559 infoStr
= "undefined instruction";
561 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
562 infoStr
= "software interrupt";
564 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
565 infoStr
= "abort prefetch";
567 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
568 infoStr
= "abort data";
575 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
577 diag_printf("Dumping log\n---\n");
578 if (logCount
>= logSize
)
580 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
582 diag_write(logBuffer
, writePtr
);
584 diag_printf("---\nLogdump complete.\n");
585 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
586 diag_printf("\n---\nRebooting\n");
587 HAL_PLATFORM_RESET();
591 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
592 static void setHandler(cyg_code_t exception
)
594 cyg_exception_handler_t
*old_handler
;
595 cyg_addrword_t old_data
;
597 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
598 &old_handler
, &old_data
);
602 static cyg_thread zylinjtag_uart_thread_object
;
603 static cyg_handle_t zylinjtag_uart_thread_handle
;
604 static char uart_stack
[4096];
606 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
607 static char backwardBuffer
[1024];
609 void setNoDelay(int session
, int flag
)
612 // This decreases latency dramatically for e.g. GDB load which
613 // does not have a sliding window protocol
615 // Can cause *lots* of TCP/IP packets to be sent and it would have
616 // to be enabled/disabled on the fly to avoid the CPU being
618 setsockopt(session
, /* socket affected */
619 IPPROTO_TCP
, /* set option at TCP level */
620 TCP_NODELAY
, /* name of option */
621 (char *) &flag
, /* the cast is historical
623 sizeof(int)); /* length of option value */
627 #define TEST_TCPIP() 0
636 } tcpipSent
[512 * 1024];
640 static void zylinjtag_uart(cyg_addrword_t data
)
642 int so_reuseaddr_option
= 1;
645 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
647 LOG_ERROR("error creating socket: %s", strerror(errno
));
651 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
654 struct sockaddr_in sin
;
655 unsigned int address_size
;
656 address_size
= sizeof(sin
);
657 memset(&sin
, 0, sizeof(sin
));
658 sin
.sin_family
= AF_INET
;
659 sin
.sin_addr
.s_addr
= INADDR_ANY
;
660 sin
.sin_port
= htons(5555);
662 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
664 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
668 if (listen(fd
, 1) == -1)
670 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
673 // socket_nonblock(fd);
678 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
684 setNoDelay(session
, 1);
685 int oldopts
= fcntl(session
, F_GETFL
, 0);
686 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
688 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
695 #ifdef CYGPKG_PROFILE_GPROF
713 FD_SET(session
, &read_fds
);
715 FD_SET(serHandle
, &read_fds
);
716 if (serHandle
> fd_max
)
722 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
723 if ((actual
== 0) && (actual2
== 0))
725 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
734 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
736 t
= read(serHandle
, backwardBuffer
,
737 sizeof(backwardBuffer
));
753 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
761 if (FD_ISSET(session
, &read_fds
)
762 && (sizeof(forwardBuffer
) > actual
))
764 // NB! Here it is important that we empty the TCP/IP read buffer
765 // to make transmission tick right
766 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
769 // this will block if there is no data at all
770 t
= read_socket(session
, forwardBuffer
+ actual
,
771 sizeof(forwardBuffer
) - actual
);
782 /* Do not put things into the serial buffer if it has something to send
783 * as that can cause a single byte to be sent at the time.
787 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
794 // The serial buffer is full
807 tcpipSent
[cur
].req
= x
;
808 tcpipSent
[cur
].actual
= y
;
809 tcpipSent
[cur
].req2
= x2
;
810 tcpipSent
[cur
].actual2
= y2
;
815 closeSession
: close(session
);
820 for (i
= 0; i
< 1024; i
++)
822 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
823 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
834 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
835 (void *) uart_stack
, sizeof(uart_stack
),
836 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
837 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
838 cyg_thread_resume(zylinjtag_uart_thread_handle
);
841 int handle_uart_command(struct command_context
*cmd_ctx
, char *cmd
,
842 char **args
, int argc
)
844 static int current_baud
= 38400;
847 command_print(cmd_ctx
, "%d", current_baud
);
852 return ERROR_INVALID_ARGUMENTS
;
855 current_baud
= atol(args
[0]);
858 switch (current_baud
)
861 baud
= CYGNUM_SERIAL_BAUD_9600
;
864 baud
= CYGNUM_SERIAL_BAUD_19200
;
867 baud
= CYGNUM_SERIAL_BAUD_38400
;
870 baud
= CYGNUM_SERIAL_BAUD_57600
;
873 baud
= CYGNUM_SERIAL_BAUD_115200
;
876 baud
= CYGNUM_SERIAL_BAUD_230400
;
879 command_print(cmd_ctx
, "unsupported baudrate");
880 return ERROR_INVALID_ARGUMENTS
;
883 cyg_serial_info_t buf
;
885 //get existing serial configuration
886 len
= sizeof(cyg_serial_info_t
);
888 cyg_io_handle_t serial_handle
;
890 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
893 LOG_ERROR("/dev/ser0 not found\n");
897 err
= cyg_io_get_config(serial_handle
,
898 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
899 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
903 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
908 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
912 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
919 bool logAllToSerial
= false;
922 int boolParam(char *var
);
925 struct command_context
*setup_command_handler(void);
927 static const char *zylin_config_dir
="/config/settings";
929 static int add_default_dirs(void)
931 add_script_search_dir(zylin_config_dir
);
932 add_script_search_dir("/rom/lib/openocd");
933 add_script_search_dir("/rom");
937 int ioutil_init(struct command_context
*cmd_ctx
);
939 int main(int argc
, char *argv
[])
941 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
942 * need to allocate towards the end of the heap. */
944 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
945 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
946 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
947 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
952 atexit(keep_webserver
);
954 diag_init_putc(_zylinjtag_diag_write_char
);
955 // We want this in the log.
956 diag_printf("Zylin ZY1000.\n");
958 err
= mount("", "/ram", "ramfs");
961 diag_printf("unable to mount ramfs\n");
966 sprintf(address
, "%p", &filedata
[0]);
967 err
= mount(address
, "/rom", "romfs");
970 diag_printf("unable to mount /rom\n");
973 err
= mount("", "/log", "logfs");
976 diag_printf("unable to mount logfs\n");
979 err
= mount("", "/tftp", "tftpfs");
982 diag_printf("unable to mount logfs\n");
985 log
= fopen("/log/log", "w");
988 diag_printf("Could not open log file /ram/log\n");
993 copydir("/rom", "/ram/cgi");
995 err
= mount("/dev/flash1", "/config", "jffs2");
998 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
999 err
= mount("", "/config", "ramfs");
1002 diag_printf("unable to mount /config as ramdisk.\n");
1008 /* are we using a ram disk instead of a flash disk? This is used
1009 * for ZY1000 live demo...
1011 * copy over flash disk to ram block device
1013 if (boolParam("ramdisk"))
1015 diag_printf("Unmounting /config from flash and using ram instead\n");
1016 err
= umount("/config");
1019 diag_printf("unable to unmount jffs\n");
1023 err
= mount("/dev/flash1", "/config2", "jffs2");
1026 diag_printf("unable to mount jffs\n");
1030 err
= mount("", "/config", "ramfs");
1033 diag_printf("unable to mount ram block device\n");
1037 // copydir("/config2", "/config");
1038 copyfile("/config2/ip", "/config/ip");
1039 copydir("/config2/settings", "/config/settings");
1045 mkdir(zylin_config_dir
, 0777);
1046 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1047 mkdir(dirname
, 0777);
1049 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1050 mkdir(dirname
, 0777);
1052 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1053 mkdir(dirname
, 0777);
1056 logAllToSerial
= boolParam("logserial");
1058 // We need the network & web server in case there is something wrong with
1059 // the config files that invoke exit()
1060 zylinjtag_startNetwork();
1062 /* we're going to access the jim interpreter from here on... */
1063 openocd_sleep_postlude();
1068 /* initialize commandline interface */
1069 struct command_context
* cmd_ctx
;
1070 cmd_ctx
= setup_command_handler();
1071 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1072 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1075 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1077 return EXIT_FAILURE
;
1082 #ifdef CYGPKG_PROFILE_GPROF
1083 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1087 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1088 "uart <baud> - forward uart on port 5555");
1091 errVal
= log_init(cmd_ctx
);
1092 if (errVal
!= ERROR_OK
)
1094 diag_printf("log_init() failed %d\n", errVal
);
1098 set_log_output(cmd_ctx
, log
);
1100 LOG_DEBUG("log init complete");
1102 // diag_printf("Executing config files\n");
1107 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1108 command_run_line(cmd_ctx
, "debug_level 3");
1111 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1113 /* we MUST always run the init command as it will launch telnet sessions */
1114 command_run_line(cmd_ctx
, "init");
1117 // diag_printf() is really invoked from many more places than we trust it
1118 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1120 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1121 // fingers that it doesn't cause any crashes.
1122 diag_printf("Init complete, GDB & telnet servers launched.\n");
1123 command_set_output_handler(cmd_ctx
,
1124 zy1000_configuration_output_handler_log
, NULL
);
1125 if (!logAllToSerial
)
1130 /* handle network connections */
1131 server_loop(cmd_ctx
);
1132 openocd_sleep_prelude();
1134 /* shut server down */
1137 /* free commandline interface */
1138 command_done(cmd_ctx
);
1146 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1147 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1149 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1153 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1155 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1156 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1158 #include <pkgconf/system.h>
1159 #include <pkgconf/hal.h>
1160 #include <pkgconf/kernel.h>
1161 #include <pkgconf/io_fileio.h>
1162 #include <pkgconf/fs_rom.h>
1164 #include <cyg/kernel/ktypes.h> // base kernel types
1165 #include <cyg/infra/cyg_trac.h> // tracing macros
1166 #include <cyg/infra/cyg_ass.h> // assertion macros
1167 #include <cyg/fileio/fileio.h>
1168 #include <cyg/kernel/kapi.h>
1169 #include <cyg/infra/diag.h>
1171 //==========================================================================
1172 // Eventually we want to eXecute In Place from the ROM in a protected
1173 // environment, so we'll need executables to be aligned to a boundary
1174 // suitable for MMU protection. A suitable boundary would be the 4k
1175 // boundary in all the CPU architectures I am currently aware of.
1177 // Forward definitions
1179 // Filesystem operations
1180 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1181 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1182 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1183 int mode
, cyg_file
*fte
);
1184 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1185 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1188 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1189 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1190 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1192 //==========================================================================
1193 // Filesystem table entries
1195 // -------------------------------------------------------------------------
1197 // This defines the entry in the filesystem table.
1198 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1199 // we should never block in any filesystem operations.
1201 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1206 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1207 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1208 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1209 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1210 (cyg_fsop_link
*)cyg_fileio_erofs
,
1211 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1212 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1213 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1214 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1215 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1218 // -------------------------------------------------------------------------
1220 // This defines a single ROMFS loaded into ROM at the configured address
1222 // MTAB_ENTRY(rom_mte, // structure name
1223 // "/rom", // mount point
1224 // "romfs", // FIlesystem type
1225 // "", // hardware device
1226 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1230 // -------------------------------------------------------------------------
1232 // This set of file operations are used for normal open files.
1234 static cyg_fileops tftpfs_fileops
=
1235 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1236 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1237 tftpfs_fo_fsync
, tftpfs_fo_close
,
1238 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1239 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1240 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1242 // -------------------------------------------------------------------------
1244 // Process a mount request. This mainly finds root for the
1247 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1252 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1267 static void freeTftp(struct Tftp
*t
)
1280 static const int tftpMaxSize
= 8192 * 1024;
1281 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1282 int mode
, cyg_file
*file
)
1285 tftp
= malloc(sizeof(struct Tftp
));
1288 memset(tftp
, 0, sizeof(struct Tftp
));
1290 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1291 file
->f_type
= CYG_FILE_TYPE_FILE
;
1292 file
->f_ops
= &tftpfs_fileops
;
1297 tftp
->mem
= malloc(tftpMaxSize
);
1298 if (tftp
->mem
== NULL
)
1304 char *server
= strchr(name
, '/');
1311 tftp
->server
= malloc(server
- name
+ 1);
1312 if (tftp
->server
== NULL
)
1317 strncpy(tftp
->server
, name
, server
- name
);
1318 tftp
->server
[server
- name
] = 0;
1320 tftp
->file
= strdup(server
+ 1);
1321 if (tftp
->file
== NULL
)
1327 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1332 static int fetchTftp(struct Tftp
*tftp
)
1334 if (!tftp
->readFile
)
1337 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1338 tftpMaxSize
, TFTP_OCTET
, &err
);
1340 if (tftp
->actual
< 0)
1349 // -------------------------------------------------------------------------
1350 // tftpfs_fo_write()
1351 // Read data from file.
1353 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1355 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1357 if (fetchTftp(tftp
) != ENOERR
)
1361 off_t pos
= fp
->f_offset
;
1363 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1365 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1366 char *buf
= (char *) iov
->iov_base
;
1367 off_t len
= iov
->iov_len
;
1369 if (len
+ pos
> tftp
->actual
)
1371 len
= tftp
->actual
- pos
;
1373 resid
+= iov
->iov_len
- len
;
1375 memcpy(buf
, tftp
->mem
+ pos
, len
);
1379 uio
->uio_resid
= resid
;
1385 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1387 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1390 off_t pos
= fp
->f_offset
;
1392 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1394 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1395 char *buf
= (char *) iov
->iov_base
;
1396 off_t len
= iov
->iov_len
;
1398 if (len
+ pos
> tftpMaxSize
)
1400 len
= tftpMaxSize
- pos
;
1402 resid
+= iov
->iov_len
- len
;
1404 memcpy(tftp
->mem
+ pos
, buf
, len
);
1408 uio
->uio_resid
= resid
;
1416 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1422 // -------------------------------------------------------------------------
1424 // Close a file. We just clear out the data pointer.
1426 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1428 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1433 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1434 TFTP_OCTET
, &error
);
1442 // -------------------------------------------------------------------------
1444 // Seek to a new file position.
1446 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1448 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1451 if (fetchTftp(tftp
) != ENOERR
)
1457 // Pos is already where we want to be.
1461 // Add pos to current offset.
1462 pos
+= fp
->f_offset
;
1466 // Add pos to file size.
1467 pos
+= tftp
->actual
;
1474 // Check that pos is still within current file size, or at the
1476 if (pos
< 0 || pos
> tftp
->actual
)
1479 // All OK, set fp offset and return new position.
1480 *apos
= fp
->f_offset
= pos
;
1488 cyg_thread_delay(us
/ 10000 + 1);
1494 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1496 cyg_httpd_start_chunked("text");
1497 if (logCount
>= logSize
)
1499 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1500 - logCount
% logSize
);
1502 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1503 cyg_httpd_end_chunked();
1507 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1509 // Filesystem operations
1510 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1511 static int logfs_umount(cyg_mtab_entry
*mte
);
1512 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1513 int mode
, cyg_file
*fte
);
1514 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1517 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1518 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1520 #include <cyg/io/devtab.h>
1522 //==========================================================================
1523 // Filesystem table entries
1525 // -------------------------------------------------------------------------
1527 // This defines the entry in the filesystem table.
1528 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1529 // we should never block in any filesystem operations.
1530 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1531 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1535 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1536 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1537 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1538 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1539 (cyg_fsop_link
*)cyg_fileio_erofs
,
1540 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1541 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1542 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1543 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1544 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1546 // -------------------------------------------------------------------------
1548 // This set of file operations are used for normal open files.
1550 static cyg_fileops logfs_fileops
=
1551 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1552 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1553 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1554 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1555 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1556 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1558 // -------------------------------------------------------------------------
1560 // Process a mount request. This mainly finds root for the
1563 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1568 static int logfs_umount(cyg_mtab_entry
*mte
)
1573 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1574 int mode
, cyg_file
*file
)
1576 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1577 file
->f_type
= CYG_FILE_TYPE_FILE
;
1578 file
->f_ops
= &logfs_fileops
;
1585 // -------------------------------------------------------------------------
1587 // Write data to file.
1589 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1592 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1594 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1595 char *buf
= (char *) iov
->iov_base
;
1596 off_t len
= iov
->iov_len
;
1598 diag_write(buf
, len
);
1604 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1609 // -------------------------------------------------------------------------
1611 // Close a file. We just clear out the data pointer.
1613 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1618 int loadFile(const char *fileName
, void **data
, int *len
);
1620 /* boolean parameter stored on config */
1621 int boolParam(char *var
)
1623 bool result
= false;
1624 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1630 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1634 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)