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>
49 #include <cyg/io/flash.h>
50 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
55 #include <cyg/fileio/fileio.h>
57 #include <cyg/athttpd/http.h>
58 #include <cyg/athttpd/socket.h>
59 #include <cyg/athttpd/handler.h>
60 #include <cyg/athttpd/cgi.h>
61 #include <cyg/athttpd/forms.h>
62 #include <cyg/discover/discover.h>
63 #include <cyg/hal/hal_diag.h>
64 #include <cyg/kernel/kapi.h>
65 #include <cyg/io/serialio.h>
66 #include <cyg/io/io.h>
67 #include <netinet/tcp.h>
69 #include <sys/ioctl.h>
70 #include <sys/socket.h>
71 #include <netinet/in.h>
73 #include <arpa/inet.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
77 #include <netinet/in.h>
79 #include <arpa/inet.h>
89 #if defined(CYGPKG_NET_FREEBSD_STACK)
90 #include <tftp_support.h>
91 /* posix compatibility broken*/
92 struct tftpd_fileops fileops
=
94 (int (*)(const char *, int))open
,
96 (int (*)(int, const void *, int))write
,
97 ( int (*)(int, void *, int))read
103 void diag_write(char *buf
, int len
)
106 for (j
= 0; j
< len
; j
++)
108 diag_printf("%c", buf
[j
]);
112 static bool serialLog
= true;
113 static bool writeLog
= true;
118 extern flash_driver_t
*flash_drivers
[];
119 extern target_type_t
*target_types
[];
121 #ifdef CYGPKG_PROFILE_GPROF
122 #include <cyg/profile/profile.h>
124 extern char _stext
, _etext
; // Defined by the linker
126 static char *start_of_code
=&_stext
;
127 static char *end_of_code
=&_etext
;
129 void start_profile(void)
131 // This starts up the system-wide profiling, gathering
132 // profile information on all of the code, with a 16 byte
133 // "bucket" size, at a rate of 100us/profile hit.
134 // Note: a bucket size of 16 will give pretty good function
135 // resolution. Much smaller and the buffer becomes
136 // much too large for very little gain.
137 // Note: a timer period of 100us is also a reasonable
138 // compromise. Any smaller and the overhead of
139 // handling the timter (profile) interrupt could
140 // swamp the system. A fast processor might get
141 // by with a smaller value, but a slow one could
142 // even be swamped by this value. If the value is
143 // too large, the usefulness of the profile is reduced.
145 // no more interrupts than 1/10ms.
146 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
147 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
148 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
155 static char reboot_stack
[2048];
157 static void zylinjtag_reboot(cyg_addrword_t data
)
160 diag_printf("Rebooting in 100 ticks..\n");
161 cyg_thread_delay(100);
162 diag_printf("Unmounting /config..\n");
164 diag_printf("Rebooting..\n");
165 HAL_PLATFORM_RESET();
167 static cyg_thread zylinjtag_thread_object
;
168 static cyg_handle_t zylinjtag_thread_handle
;
172 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
173 (void *) reboot_stack
, sizeof(reboot_stack
),
174 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
175 cyg_thread_resume(zylinjtag_thread_handle
);
178 int configuration_output_handler(struct command_context_s
*context
,
181 diag_printf("%s", line
);
186 int zy1000_configuration_output_handler_log(struct command_context_s
*context
,
189 LOG_USER_N("%s", line
);
194 #ifdef CYGPKG_PROFILE_GPROF
195 extern void start_profile(void);
197 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
199 command_print(cmd_ctx
, "Profiling started");
206 externC
void phi_init_all_network_interfaces(void);
208 command_context_t
*cmd_ctx
;
210 static bool webRunning
= false;
212 void keep_webserver(void)
214 // Target initialisation is only attempted at startup, so we sleep forever and
215 // let the http server bail us out(i.e. get config files set up).
216 diag_printf("OpenOCD has invoked exit().\n"
217 "Use web server to correct any configuration settings and reboot.\n");
221 // exit() will terminate the current thread and we we'll then sleep eternally or
222 // we'll have a reboot scheduled.
225 extern void printDccChar(char c
);
227 static char logBuffer
[128 * 1024];
228 static const int logSize
= sizeof(logBuffer
);
232 void _zylinjtag_diag_write_char(char c
, void **param
)
236 logBuffer
[writePtr
] = c
;
237 writePtr
= (writePtr
+ 1) % logSize
;
244 HAL_DIAG_WRITE_CHAR('\r');
246 HAL_DIAG_WRITE_CHAR(c
);
249 #ifdef CYGPKG_HAL_ZYLIN_PHI
254 void copyfile(char *name2
, char *name1
);
256 void copydir(char *name
, char *destdir
);
259 MTAB_ENTRY( romfs_mte1
,
263 (CYG_ADDRWORD
) &filedata
[0] );
266 void openocd_sleep_prelude(void)
268 cyg_mutex_unlock(&httpstate
.jim_lock
);
271 void openocd_sleep_postlude(void)
273 cyg_mutex_lock(&httpstate
.jim_lock
);
278 diag_printf("Formatting JFFS2...\n");
280 cyg_io_handle_t handle
;
283 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
286 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
291 cyg_io_flash_getconfig_devsize_t ds
;
293 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
296 diag_printf("Flash error cyg_io_get_config %d\n", err
);
300 cyg_io_flash_getconfig_erase_t e
;
306 e
.err_address
= &err_addr
;
308 diag_printf("Formatting 0x%08x bytes\n", ds
.dev_size
);
309 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
312 diag_printf("Flash erase error %d offset 0x%p\n", err
, err_addr
);
316 diag_printf("Flash formatted successfully\n");
321 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
322 Jim_Obj
* const *argv
)
334 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
335 Jim_Obj
* const *argv
)
337 cyg_handle_t thread
= 0;
339 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
341 /* Loop over the threads, and generate a table row for
344 while (cyg_thread_get_next(&thread
, &id
))
346 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
348 cyg_thread_info info
;
351 cyg_thread_get_info(thread
, id
, &info
);
353 if (info
.name
== NULL
)
354 info
.name
= "<no name>";
356 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
357 info
.name
, strlen(info
.name
)));
359 /* Translate the state into a string.
362 state_string
= "RUN";
363 else if (info
.state
& 0x04)
364 state_string
= "SUSP";
366 switch (info
.state
& 0x1b)
369 state_string
= "SLEEP";
372 state_string
= "CNTSLEEP";
375 state_string
= "CREATE";
378 state_string
= "EXIT";
381 state_string
= "????";
385 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
386 state_string
, strlen(state_string
)));
388 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
389 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
391 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
394 Jim_ListAppendElement(interp
, threads
, threadObj
);
396 Jim_SetResult(interp
, threads
);
401 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
402 Jim_Obj
* const *argv
)
404 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
406 if (logCount
>= logSize
)
408 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
409 % logSize
, logSize
- logCount
% logSize
);
411 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
413 Jim_SetResult(interp
, tclOutput
);
417 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
418 Jim_Obj
* const *argv
)
425 extern Jim_Interp
*interp
;
427 static void zylinjtag_startNetwork(void)
429 // Bring TCP/IP up immediately before we're ready to accept commands.
431 // That is as soon as a PING responds, we're accepting telnet sessions.
432 #if defined(CYGPKG_NET_FREEBSD_STACK)
433 phi_init_all_network_interfaces();
439 diag_printf("Network not up and running\n");
442 #if defined(CYGPKG_NET_FREEBSD_STACK)
444 tftpd_start(69, &fileops
);
447 cyg_httpd_init_tcl_interpreter();
449 interp
= httpstate
.jim_interp
;
451 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
453 Jim_CreateCommand(httpstate
.jim_interp
, "reboot",
454 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
455 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
456 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
457 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
458 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
464 diag_printf("Web server running\n");
468 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
471 strcpy(ifr
.ifr_name
, "eth0");
473 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
478 diag_printf("Can't obtain MAC address\n");
483 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
484 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
485 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
486 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
487 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
488 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
489 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
492 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
497 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
502 char *infoStr
= "unknown";
505 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
506 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
507 infoStr
= "undefined instruction";
509 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
510 infoStr
= "software interrupt";
512 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
513 infoStr
= "abort prefetch";
515 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
516 infoStr
= "abort data";
523 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
525 diag_printf("Dumping log\n---\n");
526 if (logCount
>= logSize
)
528 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
530 diag_write(logBuffer
, writePtr
);
532 diag_printf("---\nLogdump complete.\n");
533 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
534 diag_printf("\n---\nRebooting\n");
535 HAL_PLATFORM_RESET();
539 static void setHandler(cyg_code_t exception
)
541 cyg_exception_handler_t
*old_handler
;
542 cyg_addrword_t old_data
;
544 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
545 &old_handler
, &old_data
);
548 static cyg_thread zylinjtag_uart_thread_object
;
549 static cyg_handle_t zylinjtag_uart_thread_handle
;
550 static char uart_stack
[4096];
552 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
553 static char backwardBuffer
[1024];
555 void setNoDelay(int session
, int flag
)
558 // This decreases latency dramatically for e.g. GDB load which
559 // does not have a sliding window protocol
561 // Can cause *lots* of TCP/IP packets to be sent and it would have
562 // to be enabled/disabled on the fly to avoid the CPU being
564 setsockopt(session
, /* socket affected */
565 IPPROTO_TCP
, /* set option at TCP level */
566 TCP_NODELAY
, /* name of option */
567 (char *) &flag
, /* the cast is historical
569 sizeof(int)); /* length of option value */
579 } tcpipSent
[512 * 1024];
582 static void zylinjtag_uart(cyg_addrword_t data
)
584 int so_reuseaddr_option
= 1;
587 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
589 LOG_ERROR("error creating socket: %s", strerror(errno
));
593 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
596 struct sockaddr_in sin
;
597 unsigned int address_size
;
598 address_size
= sizeof(sin
);
599 memset(&sin
, 0, sizeof(sin
));
600 sin
.sin_family
= AF_INET
;
601 sin
.sin_addr
.s_addr
= INADDR_ANY
;
602 sin
.sin_port
= htons(5555);
604 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
606 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
610 if (listen(fd
, 1) == -1)
612 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
615 // socket_nonblock(fd);
620 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
626 setNoDelay(session
, 1);
627 int oldopts
= fcntl(session
, F_GETFL
, 0);
628 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
630 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
637 #ifdef CYGPKG_PROFILE_GPROF
653 FD_SET(session
, &read_fds
);
655 FD_SET(serHandle
, &read_fds
);
656 if (serHandle
> fd_max
)
662 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
663 if ((actual
== 0) && (actual2
== 0))
665 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
674 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
675 actual2
= read(serHandle
, backwardBuffer
,
676 sizeof(backwardBuffer
));
692 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
700 if (FD_ISSET(session
, &read_fds
)
701 && (sizeof(forwardBuffer
) > actual
))
703 // NB! Here it is important that we empty the TCP/IP read buffer
704 // to make transmission tick right
705 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
708 // this will block if there is no data at all
709 t
= read_socket(session
, forwardBuffer
+ actual
,
710 sizeof(forwardBuffer
) - actual
);
722 /* Do not put things into the serial buffer if it has something to send
723 * as that can cause a single byte to be sent at the time.
727 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
734 // The serial buffer is full
746 tcpipSent
[cur
].req
= x
;
747 tcpipSent
[cur
].actual
= y
;
748 tcpipSent
[cur
].req2
= x2
;
749 tcpipSent
[cur
].actual2
= y2
;
754 closeSession
: close(session
);
758 for (i
= 0; i
< 1024; i
++)
760 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
761 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
771 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
772 (void *) uart_stack
, sizeof(uart_stack
),
773 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
774 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
775 cyg_thread_resume(zylinjtag_uart_thread_handle
);
778 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
779 char **args
, int argc
)
781 static int current_baud
= 38400;
784 command_print(cmd_ctx
, "%d", current_baud
);
789 return ERROR_INVALID_ARGUMENTS
;
792 current_baud
= atol(args
[0]);
795 switch (current_baud
)
798 baud
= CYGNUM_SERIAL_BAUD_9600
;
801 baud
= CYGNUM_SERIAL_BAUD_19200
;
804 baud
= CYGNUM_SERIAL_BAUD_38400
;
807 baud
= CYGNUM_SERIAL_BAUD_57600
;
810 baud
= CYGNUM_SERIAL_BAUD_115200
;
813 baud
= CYGNUM_SERIAL_BAUD_230400
;
816 command_print(cmd_ctx
, "unsupported baudrate");
817 return ERROR_INVALID_ARGUMENTS
;
820 cyg_serial_info_t buf
;
822 //get existing serial configuration
823 len
= sizeof(cyg_serial_info_t
);
825 cyg_io_handle_t serial_handle
;
827 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
830 LOG_ERROR("/dev/ser0 not found\n");
834 err
= cyg_io_get_config(serial_handle
,
835 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
836 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
840 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
845 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
849 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
856 bool logAllToSerial
= false;
859 int boolParam(char *var
);
862 command_context_t
*setup_command_handler(void);
864 extern const char *zylin_config_dir
;
866 int add_default_dirs(void)
868 add_script_search_dir(zylin_config_dir
);
869 add_script_search_dir("/rom/lib/openocd");
870 add_script_search_dir("/rom");
874 int ioutil_init(struct command_context_s
*cmd_ctx
);
876 int main(int argc
, char *argv
[])
878 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
879 * need to allocate towards the end of the heap. */
881 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
882 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
883 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
884 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
889 atexit(keep_webserver
);
891 diag_init_putc(_zylinjtag_diag_write_char
);
892 // We want this in the log.
893 diag_printf("Zylin ZY1000.\n");
895 err
= mount("", "/ram", "ramfs");
898 diag_printf("unable to mount ramfs\n");
903 sprintf(address
, "%p", &filedata
[0]);
904 err
= mount(address
, "/rom", "romfs");
907 diag_printf("unable to mount /rom\n");
910 err
= mount("", "/log", "logfs");
913 diag_printf("unable to mount logfs\n");
916 err
= mount("", "/tftp", "tftpfs");
919 diag_printf("unable to mount logfs\n");
922 log
= fopen("/log/log", "w");
925 diag_printf("Could not open log file /ram/log\n");
930 copydir("/rom", "/ram/cgi");
932 err
= mount("/dev/flash1", "/config", "jffs2");
935 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
936 err
= mount("", "/config", "ramfs");
939 diag_printf("unable to mount /config as ramdisk.\n");
945 /* are we using a ram disk instead of a flash disk? This is used
946 * for ZY1000 live demo...
948 * copy over flash disk to ram block device
950 if (boolParam("ramdisk"))
952 diag_printf("Unmounting /config from flash and using ram instead\n");
953 err
= umount("/config");
956 diag_printf("unable to unmount jffs\n");
960 err
= mount("/dev/flash1", "/config2", "jffs2");
963 diag_printf("unable to mount jffs\n");
967 err
= mount("", "/config", "ramfs");
970 diag_printf("unable to mount ram block device\n");
974 // copydir("/config2", "/config");
975 copyfile("/config2/ip", "/config/ip");
976 copydir("/config2/settings", "/config/settings");
982 mkdir(zylin_config_dir
, 0777);
983 char *dirname
=alloc_printf("%s/target", zylin_config_dir
);
984 mkdir(dirname
, 0777);
986 dirname
=alloc_printf("%s/board", zylin_config_dir
);
987 mkdir(dirname
, 0777);
989 dirname
=alloc_printf("%s/event", zylin_config_dir
);
990 mkdir(dirname
, 0777);
993 logAllToSerial
= boolParam("logserial");
995 // We need the network & web server in case there is something wrong with
996 // the config files that invoke exit()
997 zylinjtag_startNetwork();
999 /* we're going to access the jim interpreter from here on... */
1000 openocd_sleep_postlude();
1005 /* initialize commandline interface */
1006 command_context_t
* cmd_ctx
;
1007 cmd_ctx
= setup_command_handler();
1008 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1009 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1012 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1014 return EXIT_FAILURE
;
1019 #ifdef CYGPKG_PROFILE_GPROF
1020 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1024 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1025 "uart <baud> - forward uart on port 5555");
1028 errVal
= log_init(cmd_ctx
);
1029 if (errVal
!= ERROR_OK
)
1031 diag_printf("log_init() failed %d\n", errVal
);
1035 set_log_output(cmd_ctx
, log
);
1037 LOG_DEBUG("log init complete");
1039 // diag_printf("Executing config files\n");
1044 "%s/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1045 command_run_line(cmd_ctx
, "debug_level 3");
1048 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1051 // diag_printf() is really invoked from many more places than we trust it
1052 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1054 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1055 // fingers that it doesn't cause any crashes.
1056 diag_printf("Init complete, GDB & telnet servers launched.\n");
1057 command_set_output_handler(cmd_ctx
,
1058 zy1000_configuration_output_handler_log
, NULL
);
1059 if (!logAllToSerial
)
1064 /* handle network connections */
1065 server_loop(cmd_ctx
);
1066 openocd_sleep_prelude();
1068 /* shut server down */
1071 /* free commandline interface */
1072 command_done(cmd_ctx
);
1080 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1081 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1083 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1087 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1089 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1090 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1092 #include <pkgconf/system.h>
1093 #include <pkgconf/hal.h>
1094 #include <pkgconf/kernel.h>
1095 #include <pkgconf/io_fileio.h>
1096 #include <pkgconf/fs_rom.h>
1098 #include <cyg/kernel/ktypes.h> // base kernel types
1099 #include <cyg/infra/cyg_trac.h> // tracing macros
1100 #include <cyg/infra/cyg_ass.h> // assertion macros
1101 #include <cyg/fileio/fileio.h>
1102 #include <cyg/kernel/kapi.h>
1103 #include <cyg/infra/diag.h>
1105 //==========================================================================
1106 // Eventually we want to eXecute In Place from the ROM in a protected
1107 // environment, so we'll need executables to be aligned to a boundary
1108 // suitable for MMU protection. A suitable boundary would be the 4k
1109 // boundary in all the CPU architectures I am currently aware of.
1111 // Forward definitions
1113 // Filesystem operations
1114 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1115 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1116 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1117 int mode
, cyg_file
*fte
);
1118 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1119 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1122 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1123 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1124 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1126 //==========================================================================
1127 // Filesystem table entries
1129 // -------------------------------------------------------------------------
1131 // This defines the entry in the filesystem table.
1132 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1133 // we should never block in any filesystem operations.
1135 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
1140 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1141 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1142 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1143 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1144 (cyg_fsop_link
*)cyg_fileio_erofs
,
1145 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1146 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1147 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1148 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1149 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1152 // -------------------------------------------------------------------------
1154 // This defines a single ROMFS loaded into ROM at the configured address
1156 // MTAB_ENTRY( rom_mte, // structure name
1157 // "/rom", // mount point
1158 // "romfs", // FIlesystem type
1159 // "", // hardware device
1160 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1164 // -------------------------------------------------------------------------
1166 // This set of file operations are used for normal open files.
1168 static cyg_fileops tftpfs_fileops
=
1169 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1170 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1171 tftpfs_fo_fsync
, tftpfs_fo_close
,
1172 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1173 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1174 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1176 // -------------------------------------------------------------------------
1178 // Process a mount request. This mainly finds root for the
1181 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1186 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1201 static void freeTftp(struct Tftp
*t
)
1214 static const int tftpMaxSize
= 8192 * 1024;
1215 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1216 int mode
, cyg_file
*file
)
1219 tftp
= malloc(sizeof(struct Tftp
));
1222 memset(tftp
, 0, sizeof(struct Tftp
));
1224 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1225 file
->f_type
= CYG_FILE_TYPE_FILE
;
1226 file
->f_ops
= &tftpfs_fileops
;
1231 tftp
->mem
= malloc(tftpMaxSize
);
1232 if (tftp
->mem
== NULL
)
1238 char *server
= strchr(name
, '/');
1245 tftp
->server
= malloc(server
- name
+ 1);
1246 if (tftp
->server
== NULL
)
1251 strncpy(tftp
->server
, name
, server
- name
);
1252 tftp
->server
[server
- name
] = 0;
1254 tftp
->file
= strdup(server
+ 1);
1255 if (tftp
->file
== NULL
)
1261 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1266 static int fetchTftp(struct Tftp
*tftp
)
1268 if (!tftp
->readFile
)
1271 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1272 tftpMaxSize
, TFTP_OCTET
, &err
);
1274 if (tftp
->actual
< 0)
1283 // -------------------------------------------------------------------------
1284 // tftpfs_fo_write()
1285 // Read data from file.
1287 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1289 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1291 if (fetchTftp(tftp
) != ENOERR
)
1295 off_t pos
= fp
->f_offset
;
1297 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1299 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1300 char *buf
= (char *) iov
->iov_base
;
1301 off_t len
= iov
->iov_len
;
1303 if (len
+ pos
> tftp
->actual
)
1305 len
= tftp
->actual
- pos
;
1307 resid
+= iov
->iov_len
- len
;
1309 memcpy(buf
, tftp
->mem
+ pos
, len
);
1313 uio
->uio_resid
= resid
;
1319 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1321 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1324 off_t pos
= fp
->f_offset
;
1326 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1328 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1329 char *buf
= (char *) iov
->iov_base
;
1330 off_t len
= iov
->iov_len
;
1332 if (len
+ pos
> tftpMaxSize
)
1334 len
= tftpMaxSize
- pos
;
1336 resid
+= iov
->iov_len
- len
;
1338 memcpy(tftp
->mem
+ pos
, buf
, len
);
1342 uio
->uio_resid
= resid
;
1350 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1356 // -------------------------------------------------------------------------
1358 // Close a file. We just clear out the data pointer.
1360 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1362 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1367 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1368 TFTP_OCTET
, &error
);
1376 // -------------------------------------------------------------------------
1378 // Seek to a new file position.
1380 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1382 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1385 if (fetchTftp(tftp
) != ENOERR
)
1391 // Pos is already where we want to be.
1395 // Add pos to current offset.
1396 pos
+= fp
->f_offset
;
1400 // Add pos to file size.
1401 pos
+= tftp
->actual
;
1408 // Check that pos is still within current file size, or at the
1410 if (pos
< 0 || pos
> tftp
->actual
)
1413 // All OK, set fp offset and return new position.
1414 *apos
= fp
->f_offset
= pos
;
1422 cyg_thread_delay(us
/ 10000 + 1);
1428 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1430 cyg_httpd_start_chunked("text");
1431 if (logCount
>= logSize
)
1433 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1434 - logCount
% logSize
);
1436 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1437 cyg_httpd_end_chunked();
1441 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1443 // Filesystem operations
1444 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1445 static int logfs_umount(cyg_mtab_entry
*mte
);
1446 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1447 int mode
, cyg_file
*fte
);
1448 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1451 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1452 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1454 #include <cyg/io/devtab.h>
1456 //==========================================================================
1457 // Filesystem table entries
1459 // -------------------------------------------------------------------------
1461 // This defines the entry in the filesystem table.
1462 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1463 // we should never block in any filesystem operations.
1464 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
1465 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
1469 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1470 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1471 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1472 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1473 (cyg_fsop_link
*)cyg_fileio_erofs
,
1474 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1475 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1476 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1477 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1478 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1480 // -------------------------------------------------------------------------
1482 // This set of file operations are used for normal open files.
1484 static cyg_fileops logfs_fileops
=
1485 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1486 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1487 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1488 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1489 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1490 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1492 // -------------------------------------------------------------------------
1494 // Process a mount request. This mainly finds root for the
1497 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1502 static int logfs_umount(cyg_mtab_entry
*mte
)
1507 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1508 int mode
, cyg_file
*file
)
1510 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1511 file
->f_type
= CYG_FILE_TYPE_FILE
;
1512 file
->f_ops
= &logfs_fileops
;
1519 // -------------------------------------------------------------------------
1521 // Write data to file.
1523 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1526 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1528 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1529 char *buf
= (char *) iov
->iov_base
;
1530 off_t len
= iov
->iov_len
;
1532 diag_write(buf
, len
);
1538 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1543 // -------------------------------------------------------------------------
1545 // Close a file. We just clear out the data pointer.
1547 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)