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
195 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
197 command_print(cmd_ctx
, "Profiling started");
204 externC
void phi_init_all_network_interfaces(void);
206 command_context_t
*cmd_ctx
;
208 static bool webRunning
= false;
210 void keep_webserver(void)
212 // Target initialisation is only attempted at startup, so we sleep forever and
213 // let the http server bail us out(i.e. get config files set up).
214 diag_printf("OpenOCD has invoked exit().\n"
215 "Use web server to correct any configuration settings and reboot.\n");
219 // exit() will terminate the current thread and we we'll then sleep eternally or
220 // we'll have a reboot scheduled.
223 extern void printDccChar(char c
);
225 static char logBuffer
[128 * 1024];
226 static const int logSize
= sizeof(logBuffer
);
230 void _zylinjtag_diag_write_char(char c
, void **param
)
234 logBuffer
[writePtr
] = c
;
235 writePtr
= (writePtr
+ 1) % logSize
;
242 HAL_DIAG_WRITE_CHAR('\r');
244 HAL_DIAG_WRITE_CHAR(c
);
247 #ifdef CYGPKG_HAL_ZYLIN_PHI
252 void copyfile(char *name2
, char *name1
);
254 void copydir(char *name
, char *destdir
);
257 MTAB_ENTRY( romfs_mte1
,
261 (CYG_ADDRWORD
) &filedata
[0] );
264 void openocd_sleep_prelude(void)
266 cyg_mutex_unlock(&httpstate
.jim_lock
);
269 void openocd_sleep_postlude(void)
271 cyg_mutex_lock(&httpstate
.jim_lock
);
276 diag_printf("Formatting JFFS2...\n");
278 cyg_io_handle_t handle
;
281 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
284 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
289 cyg_io_flash_getconfig_devsize_t ds
;
291 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
294 diag_printf("Flash error cyg_io_get_config %d\n", err
);
298 cyg_io_flash_getconfig_erase_t e
;
304 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
305 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
308 diag_printf("Flash erase error %d offset 0x%p\n", err
, e
.err_address
);
312 diag_printf("Flash formatted successfully\n");
317 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
318 Jim_Obj
* const *argv
)
330 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
331 Jim_Obj
* const *argv
)
333 cyg_handle_t thread
= 0;
335 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
337 /* Loop over the threads, and generate a table row for
340 while (cyg_thread_get_next(&thread
, &id
))
342 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
344 cyg_thread_info info
;
347 cyg_thread_get_info(thread
, id
, &info
);
349 if (info
.name
== NULL
)
350 info
.name
= "<no name>";
352 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
353 info
.name
, strlen(info
.name
)));
355 /* Translate the state into a string.
358 state_string
= "RUN";
359 else if (info
.state
& 0x04)
360 state_string
= "SUSP";
362 switch (info
.state
& 0x1b)
365 state_string
= "SLEEP";
368 state_string
= "CNTSLEEP";
371 state_string
= "CREATE";
374 state_string
= "EXIT";
377 state_string
= "????";
381 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
382 state_string
, strlen(state_string
)));
384 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
385 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
387 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
390 Jim_ListAppendElement(interp
, threads
, threadObj
);
392 Jim_SetResult(interp
, threads
);
397 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
398 Jim_Obj
* const *argv
)
400 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
402 if (logCount
>= logSize
)
404 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
405 % logSize
, logSize
- logCount
% logSize
);
407 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
409 Jim_SetResult(interp
, tclOutput
);
413 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
414 Jim_Obj
* const *argv
)
421 static void zylinjtag_startNetwork(void)
423 // Bring TCP/IP up immediately before we're ready to accept commands.
425 // That is as soon as a PING responds, we're accepting telnet sessions.
426 #if defined(CYGPKG_NET_FREEBSD_STACK)
427 phi_init_all_network_interfaces();
433 diag_printf("Network not up and running\n");
436 #if defined(CYGPKG_NET_FREEBSD_STACK)
438 tftpd_start(69, &fileops
);
441 cyg_httpd_init_tcl_interpreter();
443 interp
= httpstate
.jim_interp
;
445 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
447 Jim_CreateCommand(httpstate
.jim_interp
, "reboot",
448 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
449 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
450 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
451 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
452 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
458 diag_printf("Web server running\n");
462 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
465 strcpy(ifr
.ifr_name
, "eth0");
467 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
472 diag_printf("Can't obtain MAC address\n");
477 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
478 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
479 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
480 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
481 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
482 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
483 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
486 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
491 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
496 char *infoStr
= "unknown";
499 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
500 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
501 infoStr
= "undefined instruction";
503 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
504 infoStr
= "software interrupt";
506 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
507 infoStr
= "abort prefetch";
509 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
510 infoStr
= "abort data";
517 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
519 diag_printf("Dumping log\n---\n");
520 if (logCount
>= logSize
)
522 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
524 diag_write(logBuffer
, writePtr
);
526 diag_printf("---\nLogdump complete.\n");
527 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
528 diag_printf("\n---\nRebooting\n");
529 HAL_PLATFORM_RESET();
533 static void setHandler(cyg_code_t exception
)
535 cyg_exception_handler_t
*old_handler
;
536 cyg_addrword_t old_data
;
538 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
539 &old_handler
, &old_data
);
542 static cyg_thread zylinjtag_uart_thread_object
;
543 static cyg_handle_t zylinjtag_uart_thread_handle
;
544 static char uart_stack
[4096];
546 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
547 static char backwardBuffer
[1024];
549 void setNoDelay(int session
, int flag
)
552 // This decreases latency dramatically for e.g. GDB load which
553 // does not have a sliding window protocol
555 // Can cause *lots* of TCP/IP packets to be sent and it would have
556 // to be enabled/disabled on the fly to avoid the CPU being
558 setsockopt(session
, /* socket affected */
559 IPPROTO_TCP
, /* set option at TCP level */
560 TCP_NODELAY
, /* name of option */
561 (char *) &flag
, /* the cast is historical
563 sizeof(int)); /* length of option value */
573 } tcpipSent
[512 * 1024];
576 static void zylinjtag_uart(cyg_addrword_t data
)
578 int so_reuseaddr_option
= 1;
581 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
583 LOG_ERROR("error creating socket: %s", strerror(errno
));
587 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
590 struct sockaddr_in sin
;
591 unsigned int address_size
;
592 address_size
= sizeof(sin
);
593 memset(&sin
, 0, sizeof(sin
));
594 sin
.sin_family
= AF_INET
;
595 sin
.sin_addr
.s_addr
= INADDR_ANY
;
596 sin
.sin_port
= htons(5555);
598 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
600 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
604 if (listen(fd
, 1) == -1)
606 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
609 // socket_nonblock(fd);
614 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
620 setNoDelay(session
, 1);
621 int oldopts
= fcntl(session
, F_GETFL
, 0);
622 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
624 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
631 #ifdef CYGPKG_PROFILE_GPROF
647 FD_SET(session
, &read_fds
);
649 FD_SET(serHandle
, &read_fds
);
650 if (serHandle
> fd_max
)
656 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
657 if ((actual
== 0) && (actual2
== 0))
659 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
668 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
670 t
= read(serHandle
, backwardBuffer
,
671 sizeof(backwardBuffer
));
688 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
696 if (FD_ISSET(session
, &read_fds
)
697 && (sizeof(forwardBuffer
) > actual
))
699 // NB! Here it is important that we empty the TCP/IP read buffer
700 // to make transmission tick right
701 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
704 // this will block if there is no data at all
705 t
= read_socket(session
, forwardBuffer
+ actual
,
706 sizeof(forwardBuffer
) - actual
);
718 /* Do not put things into the serial buffer if it has something to send
719 * as that can cause a single byte to be sent at the time.
723 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
730 // The serial buffer is full
742 tcpipSent
[cur
].req
= x
;
743 tcpipSent
[cur
].actual
= y
;
744 tcpipSent
[cur
].req2
= x2
;
745 tcpipSent
[cur
].actual2
= y2
;
750 closeSession
: close(session
);
754 for (i
= 0; i
< 1024; i
++)
756 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
757 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
767 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
768 (void *) uart_stack
, sizeof(uart_stack
),
769 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
770 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
771 cyg_thread_resume(zylinjtag_uart_thread_handle
);
774 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
775 char **args
, int argc
)
777 static int current_baud
= 38400;
780 command_print(cmd_ctx
, "%d", current_baud
);
785 return ERROR_INVALID_ARGUMENTS
;
788 current_baud
= atol(args
[0]);
791 switch (current_baud
)
794 baud
= CYGNUM_SERIAL_BAUD_9600
;
797 baud
= CYGNUM_SERIAL_BAUD_19200
;
800 baud
= CYGNUM_SERIAL_BAUD_38400
;
803 baud
= CYGNUM_SERIAL_BAUD_57600
;
806 baud
= CYGNUM_SERIAL_BAUD_115200
;
809 baud
= CYGNUM_SERIAL_BAUD_230400
;
812 command_print(cmd_ctx
, "unsupported baudrate");
813 return ERROR_INVALID_ARGUMENTS
;
816 cyg_serial_info_t buf
;
818 //get existing serial configuration
819 len
= sizeof(cyg_serial_info_t
);
821 cyg_io_handle_t serial_handle
;
823 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
826 LOG_ERROR("/dev/ser0 not found\n");
830 err
= cyg_io_get_config(serial_handle
,
831 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
832 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
836 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
841 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
845 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
852 bool logAllToSerial
= false;
855 int boolParam(char *var
);
858 command_context_t
*setup_command_handler(void);
860 static const char *zylin_config_dir
="/config/settings";
862 int add_default_dirs(void)
864 add_script_search_dir(zylin_config_dir
);
865 add_script_search_dir("/rom/lib/openocd");
866 add_script_search_dir("/rom");
870 int ioutil_init(struct command_context_s
*cmd_ctx
);
872 int main(int argc
, char *argv
[])
874 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
875 * need to allocate towards the end of the heap. */
877 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
878 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
879 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
880 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
885 atexit(keep_webserver
);
887 diag_init_putc(_zylinjtag_diag_write_char
);
888 // We want this in the log.
889 diag_printf("Zylin ZY1000.\n");
891 err
= mount("", "/ram", "ramfs");
894 diag_printf("unable to mount ramfs\n");
899 sprintf(address
, "%p", &filedata
[0]);
900 err
= mount(address
, "/rom", "romfs");
903 diag_printf("unable to mount /rom\n");
906 err
= mount("", "/log", "logfs");
909 diag_printf("unable to mount logfs\n");
912 err
= mount("", "/tftp", "tftpfs");
915 diag_printf("unable to mount logfs\n");
918 log
= fopen("/log/log", "w");
921 diag_printf("Could not open log file /ram/log\n");
926 copydir("/rom", "/ram/cgi");
928 err
= mount("/dev/flash1", "/config", "jffs2");
931 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
932 err
= mount("", "/config", "ramfs");
935 diag_printf("unable to mount /config as ramdisk.\n");
941 /* are we using a ram disk instead of a flash disk? This is used
942 * for ZY1000 live demo...
944 * copy over flash disk to ram block device
946 if (boolParam("ramdisk"))
948 diag_printf("Unmounting /config from flash and using ram instead\n");
949 err
= umount("/config");
952 diag_printf("unable to unmount jffs\n");
956 err
= mount("/dev/flash1", "/config2", "jffs2");
959 diag_printf("unable to mount jffs\n");
963 err
= mount("", "/config", "ramfs");
966 diag_printf("unable to mount ram block device\n");
970 // copydir("/config2", "/config");
971 copyfile("/config2/ip", "/config/ip");
972 copydir("/config2/settings", "/config/settings");
978 mkdir(zylin_config_dir
, 0777);
979 char *dirname
=alloc_printf("%s/target", zylin_config_dir
);
980 mkdir(dirname
, 0777);
982 dirname
=alloc_printf("%s/board", zylin_config_dir
);
983 mkdir(dirname
, 0777);
985 dirname
=alloc_printf("%s/event", zylin_config_dir
);
986 mkdir(dirname
, 0777);
989 logAllToSerial
= boolParam("logserial");
991 // We need the network & web server in case there is something wrong with
992 // the config files that invoke exit()
993 zylinjtag_startNetwork();
995 /* we're going to access the jim interpreter from here on... */
996 openocd_sleep_postlude();
1001 /* initialize commandline interface */
1002 command_context_t
* cmd_ctx
;
1003 cmd_ctx
= setup_command_handler();
1004 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1005 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1008 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1010 return EXIT_FAILURE
;
1015 #ifdef CYGPKG_PROFILE_GPROF
1016 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1020 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1021 "uart <baud> - forward uart on port 5555");
1024 errVal
= log_init(cmd_ctx
);
1025 if (errVal
!= ERROR_OK
)
1027 diag_printf("log_init() failed %d\n", errVal
);
1031 set_log_output(cmd_ctx
, log
);
1033 LOG_DEBUG("log init complete");
1035 // diag_printf("Executing config files\n");
1040 "%s/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1041 command_run_line(cmd_ctx
, "debug_level 3");
1044 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1046 /* we MUST always run the init command as it will launch telnet sessions */
1047 command_run_line(cmd_ctx
, "init");
1050 // diag_printf() is really invoked from many more places than we trust it
1051 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1053 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1054 // fingers that it doesn't cause any crashes.
1055 diag_printf("Init complete, GDB & telnet servers launched.\n");
1056 command_set_output_handler(cmd_ctx
,
1057 zy1000_configuration_output_handler_log
, NULL
);
1058 if (!logAllToSerial
)
1063 /* handle network connections */
1064 server_loop(cmd_ctx
);
1065 openocd_sleep_prelude();
1067 /* shut server down */
1070 /* free commandline interface */
1071 command_done(cmd_ctx
);
1079 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1080 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1082 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1086 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1088 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1089 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1091 #include <pkgconf/system.h>
1092 #include <pkgconf/hal.h>
1093 #include <pkgconf/kernel.h>
1094 #include <pkgconf/io_fileio.h>
1095 #include <pkgconf/fs_rom.h>
1097 #include <cyg/kernel/ktypes.h> // base kernel types
1098 #include <cyg/infra/cyg_trac.h> // tracing macros
1099 #include <cyg/infra/cyg_ass.h> // assertion macros
1100 #include <cyg/fileio/fileio.h>
1101 #include <cyg/kernel/kapi.h>
1102 #include <cyg/infra/diag.h>
1104 //==========================================================================
1105 // Eventually we want to eXecute In Place from the ROM in a protected
1106 // environment, so we'll need executables to be aligned to a boundary
1107 // suitable for MMU protection. A suitable boundary would be the 4k
1108 // boundary in all the CPU architectures I am currently aware of.
1110 // Forward definitions
1112 // Filesystem operations
1113 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1114 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1115 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1116 int mode
, cyg_file
*fte
);
1117 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1118 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1121 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1122 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1123 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1125 //==========================================================================
1126 // Filesystem table entries
1128 // -------------------------------------------------------------------------
1130 // This defines the entry in the filesystem table.
1131 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1132 // we should never block in any filesystem operations.
1134 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
1139 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1140 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1141 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1142 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1143 (cyg_fsop_link
*)cyg_fileio_erofs
,
1144 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1145 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1146 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1147 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1148 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1151 // -------------------------------------------------------------------------
1153 // This defines a single ROMFS loaded into ROM at the configured address
1155 // MTAB_ENTRY( rom_mte, // structure name
1156 // "/rom", // mount point
1157 // "romfs", // FIlesystem type
1158 // "", // hardware device
1159 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1163 // -------------------------------------------------------------------------
1165 // This set of file operations are used for normal open files.
1167 static cyg_fileops tftpfs_fileops
=
1168 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1169 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1170 tftpfs_fo_fsync
, tftpfs_fo_close
,
1171 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1172 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1173 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1175 // -------------------------------------------------------------------------
1177 // Process a mount request. This mainly finds root for the
1180 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1185 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1200 static void freeTftp(struct Tftp
*t
)
1213 static const int tftpMaxSize
= 8192 * 1024;
1214 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1215 int mode
, cyg_file
*file
)
1218 tftp
= malloc(sizeof(struct Tftp
));
1221 memset(tftp
, 0, sizeof(struct Tftp
));
1223 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1224 file
->f_type
= CYG_FILE_TYPE_FILE
;
1225 file
->f_ops
= &tftpfs_fileops
;
1230 tftp
->mem
= malloc(tftpMaxSize
);
1231 if (tftp
->mem
== NULL
)
1237 char *server
= strchr(name
, '/');
1244 tftp
->server
= malloc(server
- name
+ 1);
1245 if (tftp
->server
== NULL
)
1250 strncpy(tftp
->server
, name
, server
- name
);
1251 tftp
->server
[server
- name
] = 0;
1253 tftp
->file
= strdup(server
+ 1);
1254 if (tftp
->file
== NULL
)
1260 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1265 static int fetchTftp(struct Tftp
*tftp
)
1267 if (!tftp
->readFile
)
1270 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1271 tftpMaxSize
, TFTP_OCTET
, &err
);
1273 if (tftp
->actual
< 0)
1282 // -------------------------------------------------------------------------
1283 // tftpfs_fo_write()
1284 // Read data from file.
1286 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1288 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1290 if (fetchTftp(tftp
) != ENOERR
)
1294 off_t pos
= fp
->f_offset
;
1296 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1298 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1299 char *buf
= (char *) iov
->iov_base
;
1300 off_t len
= iov
->iov_len
;
1302 if (len
+ pos
> tftp
->actual
)
1304 len
= tftp
->actual
- pos
;
1306 resid
+= iov
->iov_len
- len
;
1308 memcpy(buf
, tftp
->mem
+ pos
, len
);
1312 uio
->uio_resid
= resid
;
1318 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1320 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1323 off_t pos
= fp
->f_offset
;
1325 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1327 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1328 char *buf
= (char *) iov
->iov_base
;
1329 off_t len
= iov
->iov_len
;
1331 if (len
+ pos
> tftpMaxSize
)
1333 len
= tftpMaxSize
- pos
;
1335 resid
+= iov
->iov_len
- len
;
1337 memcpy(tftp
->mem
+ pos
, buf
, len
);
1341 uio
->uio_resid
= resid
;
1349 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1355 // -------------------------------------------------------------------------
1357 // Close a file. We just clear out the data pointer.
1359 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1361 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1366 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1367 TFTP_OCTET
, &error
);
1375 // -------------------------------------------------------------------------
1377 // Seek to a new file position.
1379 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1381 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1384 if (fetchTftp(tftp
) != ENOERR
)
1390 // Pos is already where we want to be.
1394 // Add pos to current offset.
1395 pos
+= fp
->f_offset
;
1399 // Add pos to file size.
1400 pos
+= tftp
->actual
;
1407 // Check that pos is still within current file size, or at the
1409 if (pos
< 0 || pos
> tftp
->actual
)
1412 // All OK, set fp offset and return new position.
1413 *apos
= fp
->f_offset
= pos
;
1421 cyg_thread_delay(us
/ 10000 + 1);
1427 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1429 cyg_httpd_start_chunked("text");
1430 if (logCount
>= logSize
)
1432 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1433 - logCount
% logSize
);
1435 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1436 cyg_httpd_end_chunked();
1440 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1442 // Filesystem operations
1443 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1444 static int logfs_umount(cyg_mtab_entry
*mte
);
1445 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1446 int mode
, cyg_file
*fte
);
1447 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1450 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1451 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1453 #include <cyg/io/devtab.h>
1455 //==========================================================================
1456 // Filesystem table entries
1458 // -------------------------------------------------------------------------
1460 // This defines the entry in the filesystem table.
1461 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1462 // we should never block in any filesystem operations.
1463 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
1464 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
1468 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1469 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1470 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1471 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1472 (cyg_fsop_link
*)cyg_fileio_erofs
,
1473 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1474 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1475 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1476 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1477 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1479 // -------------------------------------------------------------------------
1481 // This set of file operations are used for normal open files.
1483 static cyg_fileops logfs_fileops
=
1484 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1485 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1486 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1487 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1488 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1489 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1491 // -------------------------------------------------------------------------
1493 // Process a mount request. This mainly finds root for the
1496 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1501 static int logfs_umount(cyg_mtab_entry
*mte
)
1506 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1507 int mode
, cyg_file
*file
)
1509 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1510 file
->f_type
= CYG_FILE_TYPE_FILE
;
1511 file
->f_ops
= &logfs_fileops
;
1518 // -------------------------------------------------------------------------
1520 // Write data to file.
1522 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1525 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1527 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1528 char *buf
= (char *) iov
->iov_base
;
1529 off_t len
= iov
->iov_len
;
1531 diag_write(buf
, len
);
1537 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1542 // -------------------------------------------------------------------------
1544 // Close a file. We just clear out the data pointer.
1546 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1551 int loadFile(const char *fileName
, void **data
, int *len
);
1553 /* boolean parameter stored on config */
1554 int boolParam(char *var
)
1556 bool result
= false;
1557 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1563 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1567 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)