1 /***************************************************************************
2 * Copyright (C) 2007-2008 by Øyvind Harboe *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
27 #include "configuration.h"
37 #include "telnet_server.h"
38 #include "gdb_server.h"
40 #include <time_support.h>
48 #include <cyg/io/flash.h>
49 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
54 #include <cyg/fileio/fileio.h>
56 #include <cyg/athttpd/http.h>
57 #include <cyg/athttpd/socket.h>
58 #include <cyg/athttpd/handler.h>
59 #include <cyg/athttpd/cgi.h>
60 #include <cyg/athttpd/forms.h>
61 #include <cyg/discover/discover.h>
62 #include <cyg/hal/hal_diag.h>
63 #include <cyg/kernel/kapi.h>
64 #include <cyg/io/serialio.h>
65 #include <cyg/io/io.h>
66 #include <netinet/tcp.h>
68 #include <sys/ioctl.h>
69 #include <sys/socket.h>
70 #include <netinet/in.h>
72 #include <arpa/inet.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
76 #include <netinet/in.h>
78 #include <arpa/inet.h>
88 #if defined(CYGPKG_NET_FREEBSD_STACK)
89 #include <tftp_support.h>
90 /* posix compatibility broken*/
91 struct tftpd_fileops fileops
=
93 (int (*)(const char *, int))open
,
95 (int (*)(int, const void *, int))write
,
96 ( int (*)(int, void *, int))read
102 void diag_write(char *buf
, int len
)
105 for (j
= 0; j
< len
; j
++)
107 diag_printf("%c", buf
[j
]);
111 static bool serialLog
= true;
112 static bool writeLog
= true;
117 extern flash_driver_t
*flash_drivers
[];
118 extern target_type_t
*target_types
[];
120 #ifdef CYGPKG_PROFILE_GPROF
121 #include <cyg/profile/profile.h>
123 extern char _stext
, _etext
; // Defined by the linker
125 static char *start_of_code
=&_stext
;
126 static char *end_of_code
=&_etext
;
128 void start_profile(void)
130 // This starts up the system-wide profiling, gathering
131 // profile information on all of the code, with a 16 byte
132 // "bucket" size, at a rate of 100us/profile hit.
133 // Note: a bucket size of 16 will give pretty good function
134 // resolution. Much smaller and the buffer becomes
135 // much too large for very little gain.
136 // Note: a timer period of 100us is also a reasonable
137 // compromise. Any smaller and the overhead of
138 // handling the timter (profile) interrupt could
139 // swamp the system. A fast processor might get
140 // by with a smaller value, but a slow one could
141 // even be swamped by this value. If the value is
142 // too large, the usefulness of the profile is reduced.
144 // no more interrupts than 1/10ms.
145 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
146 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
147 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
154 static char reboot_stack
[2048];
156 static void zylinjtag_reboot(cyg_addrword_t data
)
159 diag_printf("Rebooting in 100 ticks..\n");
160 cyg_thread_delay(100);
161 diag_printf("Unmounting /config..\n");
163 diag_printf("Rebooting..\n");
164 HAL_PLATFORM_RESET();
166 static cyg_thread zylinjtag_thread_object
;
167 static cyg_handle_t zylinjtag_thread_handle
;
171 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
172 (void *) reboot_stack
, sizeof(reboot_stack
),
173 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
174 cyg_thread_resume(zylinjtag_thread_handle
);
177 int configuration_output_handler(struct command_context_s
*context
,
180 diag_printf("%s", line
);
185 int zy1000_configuration_output_handler_log(struct command_context_s
*context
,
188 LOG_USER_N("%s", line
);
193 #ifdef CYGPKG_PROFILE_GPROF
194 extern void start_profile(void);
196 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
198 command_print(cmd_ctx
, "Profiling started");
205 externC
void phi_init_all_network_interfaces(void);
207 command_context_t
*cmd_ctx
;
209 static bool webRunning
= false;
211 void keep_webserver(void)
213 // Target initialisation is only attempted at startup, so we sleep forever and
214 // let the http server bail us out(i.e. get config files set up).
215 diag_printf("OpenOCD has invoked exit().\n"
216 "Use web server to correct any configuration settings and reboot.\n");
220 // exit() will terminate the current thread and we we'll then sleep eternally or
221 // we'll have a reboot scheduled.
224 extern void printDccChar(char c
);
226 static char logBuffer
[128 * 1024];
227 static const int logSize
= sizeof(logBuffer
);
231 void _zylinjtag_diag_write_char(char c
, void **param
)
235 logBuffer
[writePtr
] = c
;
236 writePtr
= (writePtr
+ 1) % logSize
;
243 HAL_DIAG_WRITE_CHAR('\r');
245 HAL_DIAG_WRITE_CHAR(c
);
248 #ifdef CYGPKG_HAL_ZYLIN_PHI
253 void copyfile(char *name2
, char *name1
);
255 void copydir(char *name
, char *destdir
);
258 MTAB_ENTRY( romfs_mte1
,
262 (CYG_ADDRWORD
) &filedata
[0] );
265 void openocd_sleep_prelude(void)
267 cyg_mutex_unlock(&httpstate
.jim_lock
);
270 void openocd_sleep_postlude(void)
272 cyg_mutex_lock(&httpstate
.jim_lock
);
277 diag_printf("Formatting JFFS2...\n");
279 cyg_io_handle_t handle
;
282 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
285 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
290 cyg_io_flash_getconfig_devsize_t ds
;
292 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
295 diag_printf("Flash error cyg_io_get_config %d\n", err
);
299 cyg_io_flash_getconfig_erase_t e
;
305 e
.err_address
= &err_addr
;
307 diag_printf("Formatting 0x%08x bytes\n", ds
.dev_size
);
308 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
311 diag_printf("Flash erase error %d offset 0x%p\n", err
, err_addr
);
315 diag_printf("Flash formatted successfully\n");
320 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
321 Jim_Obj
* const *argv
)
333 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
334 Jim_Obj
* const *argv
)
336 cyg_handle_t thread
= 0;
338 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
340 /* Loop over the threads, and generate a table row for
343 while (cyg_thread_get_next(&thread
, &id
))
345 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
347 cyg_thread_info info
;
350 cyg_thread_get_info(thread
, id
, &info
);
352 if (info
.name
== NULL
)
353 info
.name
= "<no name>";
355 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
356 info
.name
, strlen(info
.name
)));
358 /* Translate the state into a string.
361 state_string
= "RUN";
362 else if (info
.state
& 0x04)
363 state_string
= "SUSP";
365 switch (info
.state
& 0x1b)
368 state_string
= "SLEEP";
371 state_string
= "CNTSLEEP";
374 state_string
= "CREATE";
377 state_string
= "EXIT";
380 state_string
= "????";
384 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
385 state_string
, strlen(state_string
)));
387 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
388 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
390 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
393 Jim_ListAppendElement(interp
, threads
, threadObj
);
395 Jim_SetResult(interp
, threads
);
400 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
401 Jim_Obj
* const *argv
)
403 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
405 if (logCount
>= logSize
)
407 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
408 % logSize
, logSize
- logCount
% logSize
);
410 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
412 Jim_SetResult(interp
, tclOutput
);
416 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
417 Jim_Obj
* const *argv
)
424 extern Jim_Interp
*interp
;
426 static void zylinjtag_startNetwork(void)
428 // Bring TCP/IP up immediately before we're ready to accept commands.
430 // That is as soon as a PING responds, we're accepting telnet sessions.
431 #if defined(CYGPKG_NET_FREEBSD_STACK)
432 phi_init_all_network_interfaces();
438 diag_printf("Network not up and running\n");
441 #if defined(CYGPKG_NET_FREEBSD_STACK)
443 tftpd_start(69, &fileops
);
446 cyg_httpd_init_tcl_interpreter();
448 interp
= httpstate
.jim_interp
;
450 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
452 Jim_CreateCommand(httpstate
.jim_interp
, "reboot",
453 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
454 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
455 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
456 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
457 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
463 diag_printf("Web server running\n");
467 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
470 strcpy(ifr
.ifr_name
, "eth0");
472 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
477 diag_printf("Can't obtain MAC address\n");
482 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
483 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
484 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
485 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
486 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
487 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
488 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
491 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
496 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
501 char *infoStr
= "unknown";
504 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
505 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
506 infoStr
= "undefined instruction";
508 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
509 infoStr
= "software interrupt";
511 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
512 infoStr
= "abort prefetch";
514 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
515 infoStr
= "abort data";
522 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
524 diag_printf("Dumping log\n---\n");
525 if (logCount
>= logSize
)
527 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
529 diag_write(logBuffer
, writePtr
);
531 diag_printf("---\nLogdump complete.\n");
532 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
533 diag_printf("\n---\nRebooting\n");
534 HAL_PLATFORM_RESET();
538 static void setHandler(cyg_code_t exception
)
540 cyg_exception_handler_t
*old_handler
;
541 cyg_addrword_t old_data
;
543 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
544 &old_handler
, &old_data
);
547 static cyg_thread zylinjtag_uart_thread_object
;
548 static cyg_handle_t zylinjtag_uart_thread_handle
;
549 static char uart_stack
[4096];
551 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
552 static char backwardBuffer
[1024];
554 void setNoDelay(int session
, int flag
)
557 // This decreases latency dramatically for e.g. GDB load which
558 // does not have a sliding window protocol
560 // Can cause *lots* of TCP/IP packets to be sent and it would have
561 // to be enabled/disabled on the fly to avoid the CPU being
563 setsockopt(session
, /* socket affected */
564 IPPROTO_TCP
, /* set option at TCP level */
565 TCP_NODELAY
, /* name of option */
566 (char *) &flag
, /* the cast is historical
568 sizeof(int)); /* length of option value */
578 } tcpipSent
[512 * 1024];
581 static void zylinjtag_uart(cyg_addrword_t data
)
583 int so_reuseaddr_option
= 1;
586 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
588 LOG_ERROR("error creating socket: %s", strerror(errno
));
592 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
595 struct sockaddr_in sin
;
596 unsigned int address_size
;
597 address_size
= sizeof(sin
);
598 memset(&sin
, 0, sizeof(sin
));
599 sin
.sin_family
= AF_INET
;
600 sin
.sin_addr
.s_addr
= INADDR_ANY
;
601 sin
.sin_port
= htons(5555);
603 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
605 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
609 if (listen(fd
, 1) == -1)
611 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
614 // socket_nonblock(fd);
619 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
625 setNoDelay(session
, 1);
626 int oldopts
= fcntl(session
, F_GETFL
, 0);
627 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
629 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
636 #ifdef CYGPKG_PROFILE_GPROF
652 FD_SET(session
, &read_fds
);
654 FD_SET(serHandle
, &read_fds
);
655 if (serHandle
> fd_max
)
661 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
662 if ((actual
== 0) && (actual2
== 0))
664 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
673 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
674 actual2
= read(serHandle
, backwardBuffer
,
675 sizeof(backwardBuffer
));
691 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
699 if (FD_ISSET(session
, &read_fds
)
700 && (sizeof(forwardBuffer
) > actual
))
702 // NB! Here it is important that we empty the TCP/IP read buffer
703 // to make transmission tick right
704 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
707 // this will block if there is no data at all
708 t
= read_socket(session
, forwardBuffer
+ actual
,
709 sizeof(forwardBuffer
) - actual
);
721 /* Do not put things into the serial buffer if it has something to send
722 * as that can cause a single byte to be sent at the time.
726 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
733 // The serial buffer is full
745 tcpipSent
[cur
].req
= x
;
746 tcpipSent
[cur
].actual
= y
;
747 tcpipSent
[cur
].req2
= x2
;
748 tcpipSent
[cur
].actual2
= y2
;
753 closeSession
: close(session
);
757 for (i
= 0; i
< 1024; i
++)
759 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
760 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
770 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
771 (void *) uart_stack
, sizeof(uart_stack
),
772 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
773 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
774 cyg_thread_resume(zylinjtag_uart_thread_handle
);
777 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
778 char **args
, int argc
)
780 static int current_baud
= 38400;
783 command_print(cmd_ctx
, "%d", current_baud
);
788 return ERROR_INVALID_ARGUMENTS
;
791 current_baud
= atol(args
[0]);
794 switch (current_baud
)
797 baud
= CYGNUM_SERIAL_BAUD_9600
;
800 baud
= CYGNUM_SERIAL_BAUD_19200
;
803 baud
= CYGNUM_SERIAL_BAUD_38400
;
806 baud
= CYGNUM_SERIAL_BAUD_57600
;
809 baud
= CYGNUM_SERIAL_BAUD_115200
;
812 baud
= CYGNUM_SERIAL_BAUD_230400
;
815 command_print(cmd_ctx
, "unsupported baudrate");
816 return ERROR_INVALID_ARGUMENTS
;
819 cyg_serial_info_t buf
;
821 //get existing serial configuration
822 len
= sizeof(cyg_serial_info_t
);
824 cyg_io_handle_t serial_handle
;
826 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
829 LOG_ERROR("/dev/ser0 not found\n");
833 err
= cyg_io_get_config(serial_handle
,
834 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
835 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
839 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
844 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
848 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
855 bool logAllToSerial
= false;
858 int boolParam(char *var
);
861 command_context_t
*setup_command_handler(void);
863 extern const char *zylin_config_dir
;
865 int add_default_dirs(void)
867 add_script_search_dir(zylin_config_dir
);
868 add_script_search_dir("/rom/lib/openocd");
869 add_script_search_dir("/rom");
873 int ioutil_init(struct command_context_s
*cmd_ctx
);
875 int main(int argc
, char *argv
[])
877 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
878 * need to allocate towards the end of the heap. */
880 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
881 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
882 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
883 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
888 atexit(keep_webserver
);
890 diag_init_putc(_zylinjtag_diag_write_char
);
891 // We want this in the log.
892 diag_printf("Zylin ZY1000.\n");
894 err
= mount("", "/ram", "ramfs");
897 diag_printf("unable to mount ramfs\n");
902 sprintf(address
, "%p", &filedata
[0]);
903 err
= mount(address
, "/rom", "romfs");
906 diag_printf("unable to mount /rom\n");
909 err
= mount("", "/log", "logfs");
912 diag_printf("unable to mount logfs\n");
915 err
= mount("", "/tftp", "tftpfs");
918 diag_printf("unable to mount logfs\n");
921 log
= fopen("/log/log", "w");
924 diag_printf("Could not open log file /ram/log\n");
929 copydir("/rom", "/ram/cgi");
931 err
= mount("/dev/flash1", "/config", "jffs2");
934 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
935 err
= mount("", "/config", "ramfs");
938 diag_printf("unable to mount /config as ramdisk.\n");
944 /* are we using a ram disk instead of a flash disk? This is used
945 * for ZY1000 live demo...
947 * copy over flash disk to ram block device
949 if (boolParam("ramdisk"))
951 diag_printf("Unmounting /config from flash and using ram instead\n");
952 err
= umount("/config");
955 diag_printf("unable to unmount jffs\n");
959 err
= mount("/dev/flash1", "/config2", "jffs2");
962 diag_printf("unable to mount jffs\n");
966 err
= mount("", "/config", "ramfs");
969 diag_printf("unable to mount ram block device\n");
973 // copydir("/config2", "/config");
974 copyfile("/config2/ip", "/config/ip");
975 copydir("/config2/settings", "/config/settings");
981 mkdir(zylin_config_dir
, 0777);
982 char *dirname
=alloc_printf("%s/target", zylin_config_dir
);
983 mkdir(dirname
, 0777);
985 dirname
=alloc_printf("%s/board", zylin_config_dir
);
986 mkdir(dirname
, 0777);
988 dirname
=alloc_printf("%s/event", zylin_config_dir
);
989 mkdir(dirname
, 0777);
992 logAllToSerial
= boolParam("logserial");
994 // We need the network & web server in case there is something wrong with
995 // the config files that invoke exit()
996 zylinjtag_startNetwork();
998 /* we're going to access the jim interpreter from here on... */
999 openocd_sleep_postlude();
1004 /* initialize commandline interface */
1005 command_context_t
* cmd_ctx
;
1006 cmd_ctx
= setup_command_handler();
1007 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1008 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1011 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1013 return EXIT_FAILURE
;
1018 #ifdef CYGPKG_PROFILE_GPROF
1019 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1023 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1024 "uart <baud> - forward uart on port 5555");
1027 errVal
= log_init(cmd_ctx
);
1028 if (errVal
!= ERROR_OK
)
1030 diag_printf("log_init() failed %d\n", errVal
);
1034 set_log_output(cmd_ctx
, log
);
1036 LOG_DEBUG("log init complete");
1038 // diag_printf("Executing config files\n");
1043 "%s/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1044 command_run_line(cmd_ctx
, "debug_level 3");
1047 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1049 /* we MUST always run the init command as it will launch telnet sessions */
1050 command_run_line(cmd_ctx
, "init");
1053 // diag_printf() is really invoked from many more places than we trust it
1054 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1056 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1057 // fingers that it doesn't cause any crashes.
1058 diag_printf("Init complete, GDB & telnet servers launched.\n");
1059 command_set_output_handler(cmd_ctx
,
1060 zy1000_configuration_output_handler_log
, NULL
);
1061 if (!logAllToSerial
)
1066 /* handle network connections */
1067 server_loop(cmd_ctx
);
1068 openocd_sleep_prelude();
1070 /* shut server down */
1073 /* free commandline interface */
1074 command_done(cmd_ctx
);
1082 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1083 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1085 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1089 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1091 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1092 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1094 #include <pkgconf/system.h>
1095 #include <pkgconf/hal.h>
1096 #include <pkgconf/kernel.h>
1097 #include <pkgconf/io_fileio.h>
1098 #include <pkgconf/fs_rom.h>
1100 #include <cyg/kernel/ktypes.h> // base kernel types
1101 #include <cyg/infra/cyg_trac.h> // tracing macros
1102 #include <cyg/infra/cyg_ass.h> // assertion macros
1103 #include <cyg/fileio/fileio.h>
1104 #include <cyg/kernel/kapi.h>
1105 #include <cyg/infra/diag.h>
1107 //==========================================================================
1108 // Eventually we want to eXecute In Place from the ROM in a protected
1109 // environment, so we'll need executables to be aligned to a boundary
1110 // suitable for MMU protection. A suitable boundary would be the 4k
1111 // boundary in all the CPU architectures I am currently aware of.
1113 // Forward definitions
1115 // Filesystem operations
1116 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1117 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1118 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1119 int mode
, cyg_file
*fte
);
1120 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1121 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1124 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1125 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1126 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1128 //==========================================================================
1129 // Filesystem table entries
1131 // -------------------------------------------------------------------------
1133 // This defines the entry in the filesystem table.
1134 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1135 // we should never block in any filesystem operations.
1137 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
1142 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1143 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1144 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1145 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1146 (cyg_fsop_link
*)cyg_fileio_erofs
,
1147 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1148 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1149 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1150 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1151 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1154 // -------------------------------------------------------------------------
1156 // This defines a single ROMFS loaded into ROM at the configured address
1158 // MTAB_ENTRY( rom_mte, // structure name
1159 // "/rom", // mount point
1160 // "romfs", // FIlesystem type
1161 // "", // hardware device
1162 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1166 // -------------------------------------------------------------------------
1168 // This set of file operations are used for normal open files.
1170 static cyg_fileops tftpfs_fileops
=
1171 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1172 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1173 tftpfs_fo_fsync
, tftpfs_fo_close
,
1174 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1175 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1176 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1178 // -------------------------------------------------------------------------
1180 // Process a mount request. This mainly finds root for the
1183 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1188 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1203 static void freeTftp(struct Tftp
*t
)
1216 static const int tftpMaxSize
= 8192 * 1024;
1217 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1218 int mode
, cyg_file
*file
)
1221 tftp
= malloc(sizeof(struct Tftp
));
1224 memset(tftp
, 0, sizeof(struct Tftp
));
1226 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1227 file
->f_type
= CYG_FILE_TYPE_FILE
;
1228 file
->f_ops
= &tftpfs_fileops
;
1233 tftp
->mem
= malloc(tftpMaxSize
);
1234 if (tftp
->mem
== NULL
)
1240 char *server
= strchr(name
, '/');
1247 tftp
->server
= malloc(server
- name
+ 1);
1248 if (tftp
->server
== NULL
)
1253 strncpy(tftp
->server
, name
, server
- name
);
1254 tftp
->server
[server
- name
] = 0;
1256 tftp
->file
= strdup(server
+ 1);
1257 if (tftp
->file
== NULL
)
1263 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1268 static int fetchTftp(struct Tftp
*tftp
)
1270 if (!tftp
->readFile
)
1273 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1274 tftpMaxSize
, TFTP_OCTET
, &err
);
1276 if (tftp
->actual
< 0)
1285 // -------------------------------------------------------------------------
1286 // tftpfs_fo_write()
1287 // Read data from file.
1289 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1291 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1293 if (fetchTftp(tftp
) != ENOERR
)
1297 off_t pos
= fp
->f_offset
;
1299 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1301 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1302 char *buf
= (char *) iov
->iov_base
;
1303 off_t len
= iov
->iov_len
;
1305 if (len
+ pos
> tftp
->actual
)
1307 len
= tftp
->actual
- pos
;
1309 resid
+= iov
->iov_len
- len
;
1311 memcpy(buf
, tftp
->mem
+ pos
, len
);
1315 uio
->uio_resid
= resid
;
1321 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1323 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1326 off_t pos
= fp
->f_offset
;
1328 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1330 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1331 char *buf
= (char *) iov
->iov_base
;
1332 off_t len
= iov
->iov_len
;
1334 if (len
+ pos
> tftpMaxSize
)
1336 len
= tftpMaxSize
- pos
;
1338 resid
+= iov
->iov_len
- len
;
1340 memcpy(tftp
->mem
+ pos
, buf
, len
);
1344 uio
->uio_resid
= resid
;
1352 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1358 // -------------------------------------------------------------------------
1360 // Close a file. We just clear out the data pointer.
1362 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1364 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1369 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1370 TFTP_OCTET
, &error
);
1378 // -------------------------------------------------------------------------
1380 // Seek to a new file position.
1382 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1384 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1387 if (fetchTftp(tftp
) != ENOERR
)
1393 // Pos is already where we want to be.
1397 // Add pos to current offset.
1398 pos
+= fp
->f_offset
;
1402 // Add pos to file size.
1403 pos
+= tftp
->actual
;
1410 // Check that pos is still within current file size, or at the
1412 if (pos
< 0 || pos
> tftp
->actual
)
1415 // All OK, set fp offset and return new position.
1416 *apos
= fp
->f_offset
= pos
;
1424 cyg_thread_delay(us
/ 10000 + 1);
1430 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1432 cyg_httpd_start_chunked("text");
1433 if (logCount
>= logSize
)
1435 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1436 - logCount
% logSize
);
1438 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1439 cyg_httpd_end_chunked();
1443 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1445 // Filesystem operations
1446 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1447 static int logfs_umount(cyg_mtab_entry
*mte
);
1448 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1449 int mode
, cyg_file
*fte
);
1450 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1453 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1454 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1456 #include <cyg/io/devtab.h>
1458 //==========================================================================
1459 // Filesystem table entries
1461 // -------------------------------------------------------------------------
1463 // This defines the entry in the filesystem table.
1464 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1465 // we should never block in any filesystem operations.
1466 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
1467 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
1471 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1472 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1473 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1474 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1475 (cyg_fsop_link
*)cyg_fileio_erofs
,
1476 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1477 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1478 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1479 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1480 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1482 // -------------------------------------------------------------------------
1484 // This set of file operations are used for normal open files.
1486 static cyg_fileops logfs_fileops
=
1487 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1488 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1489 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1490 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1491 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1492 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1494 // -------------------------------------------------------------------------
1496 // Process a mount request. This mainly finds root for the
1499 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1504 static int logfs_umount(cyg_mtab_entry
*mte
)
1509 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1510 int mode
, cyg_file
*file
)
1512 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1513 file
->f_type
= CYG_FILE_TYPE_FILE
;
1514 file
->f_ops
= &logfs_fileops
;
1521 // -------------------------------------------------------------------------
1523 // Write data to file.
1525 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1528 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1530 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1531 char *buf
= (char *) iov
->iov_base
;
1532 off_t len
= iov
->iov_len
;
1534 diag_write(buf
, len
);
1540 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1545 // -------------------------------------------------------------------------
1547 // Close a file. We just clear out the data pointer.
1549 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)