1 /***************************************************************************
2 * Copyright (C) 2007-2009 by Øyvind Harboe *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
26 #include "configuration.h"
33 #include "telnet_server.h"
34 #include "gdb_server.h"
37 #include <time_support.h>
45 #include <cyg/io/flash.h>
46 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
51 #include <cyg/fileio/fileio.h>
53 #include <cyg/athttpd/http.h>
54 #include <cyg/athttpd/socket.h>
55 #include <cyg/athttpd/handler.h>
56 #include <cyg/athttpd/cgi.h>
57 #include <cyg/athttpd/forms.h>
58 #include <cyg/discover/discover.h>
59 #include <cyg/hal/hal_diag.h>
60 #include <cyg/kernel/kapi.h>
61 #include <cyg/io/serialio.h>
62 #include <cyg/io/io.h>
63 #include <netinet/tcp.h>
65 #include <sys/ioctl.h>
66 #include <sys/socket.h>
67 #include <netinet/in.h>
69 #include <arpa/inet.h>
70 #include <sys/types.h>
71 #include <sys/socket.h>
73 #include <netinet/in.h>
75 #include <arpa/inet.h>
84 #ifdef CYGPKG_HAL_NIOS2
85 #define ZY1000_SER_DEV "/dev/uart_0"
87 #define ZY1000_SER_DEV "/dev/ser0"
93 #if defined(CYGPKG_NET_FREEBSD_STACK)
94 #include <tftp_support.h>
95 /* posix compatibility broken*/
96 struct tftpd_fileops fileops
=
98 (int (*)(const char *, int))open
,
100 (int (*)(int, const void *, int))write
,
101 (int (*)(int, void *, int))read
107 void diag_write(char *buf
, int len
)
110 for (j
= 0; j
< len
; j
++)
112 diag_printf("%c", buf
[j
]);
116 static bool serialLog
= true;
117 static bool writeLog
= true;
122 extern struct flash_driver
*flash_drivers
[];
123 extern struct target_type
*target_types
[];
125 #ifdef CYGPKG_PROFILE_GPROF
126 #include <cyg/profile/profile.h>
128 extern char _stext
, _etext
; // Defined by the linker
130 static char *start_of_code
=&_stext
;
131 static char *end_of_code
=&_etext
;
133 void start_profile(void)
135 // This starts up the system-wide profiling, gathering
136 // profile information on all of the code, with a 16 byte
137 // "bucket" size, at a rate of 100us/profile hit.
138 // Note: a bucket size of 16 will give pretty good function
139 // resolution. Much smaller and the buffer becomes
140 // much too large for very little gain.
141 // Note: a timer period of 100us is also a reasonable
142 // compromise. Any smaller and the overhead of
143 // handling the timter (profile) interrupt could
144 // swamp the system. A fast processor might get
145 // by with a smaller value, but a slow one could
146 // even be swamped by this value. If the value is
147 // too large, the usefulness of the profile is reduced.
149 // no more interrupts than 1/10ms.
150 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
151 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
152 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
158 static char reboot_stack
[2048];
160 static void zylinjtag_reboot(cyg_addrword_t data
)
163 diag_printf("Rebooting in 500 ticks..\n");
164 cyg_thread_delay(500);
165 diag_printf("Unmounting /config..\n");
167 diag_printf("Rebooting..\n");
168 HAL_PLATFORM_RESET();
170 static cyg_thread zylinjtag_thread_object
;
171 static cyg_handle_t zylinjtag_thread_handle
;
175 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
176 (void *) reboot_stack
, sizeof(reboot_stack
),
177 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
178 cyg_thread_resume(zylinjtag_thread_handle
);
181 static char zylinjtag_reboot_port_stack
[2048];
182 static cyg_thread zylinjtag_reboot_port_thread_object
;
183 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
185 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
187 int so_reuseaddr_option
= 1;
190 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
192 LOG_ERROR("error creating socket: %s", strerror(errno
));
196 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
199 struct sockaddr_in sin
;
200 unsigned int address_size
;
201 address_size
= sizeof(sin
);
202 memset(&sin
, 0, sizeof(sin
));
203 sin
.sin_family
= AF_INET
;
204 sin
.sin_addr
.s_addr
= INADDR_ANY
;
205 sin
.sin_port
= htons(1234);
207 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
209 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
213 if (listen(fd
, 1) == -1)
215 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
218 // socket_nonblock(fd);
221 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
223 diag_printf("Got reboot signal on port 1234");
229 void reboot_port(void)
231 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
232 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
233 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
234 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
237 int configuration_output_handler(struct command_context
*context
,
240 diag_printf("%s", line
);
245 int zy1000_configuration_output_handler_log(struct command_context
*context
,
248 LOG_USER_N("%s", line
);
253 #ifdef CYGPKG_PROFILE_GPROF
255 int eCosBoard_handle_eCosBoard_profile_command(struct command_context
*cmd_ctx
, char *cmd
, char **args
, int argc
)
257 command_print(cmd_ctx
, "Profiling started");
264 externC
void phi_init_all_network_interfaces(void);
266 struct command_context
*cmd_ctx
;
268 static bool webRunning
= false;
270 void keep_webserver(void)
272 // Target initialisation is only attempted at startup, so we sleep forever and
273 // let the http server bail us out(i.e. get config files set up).
274 diag_printf("OpenOCD has invoked exit().\n"
275 "Use web server to correct any configuration settings and reboot.\n");
279 // exit() will terminate the current thread and we we'll then sleep eternally or
280 // we'll have a reboot scheduled.
283 extern void printDccChar(char c
);
285 static char logBuffer
[128 * 1024];
286 static const int logSize
= sizeof(logBuffer
);
290 void _zylinjtag_diag_write_char(char c
, void **param
)
294 logBuffer
[writePtr
] = c
;
295 writePtr
= (writePtr
+ 1) % logSize
;
302 HAL_DIAG_WRITE_CHAR('\r');
304 HAL_DIAG_WRITE_CHAR(c
);
307 #ifdef CYGPKG_HAL_ZYLIN_PHI
312 void copyfile(char *name2
, char *name1
);
314 void copydir(char *name
, char *destdir
);
317 MTAB_ENTRY(romfs_mte1
,
321 (CYG_ADDRWORD
) &filedata
[0]);
324 void openocd_sleep_prelude(void)
326 cyg_mutex_unlock(&httpstate
.jim_lock
);
329 void openocd_sleep_postlude(void)
331 cyg_mutex_lock(&httpstate
.jim_lock
);
336 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
337 diag_printf("Formatting JFFS2...\n");
339 cyg_io_handle_t handle
;
342 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
345 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
350 cyg_io_flash_getconfig_devsize_t ds
;
352 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
355 diag_printf("Flash error cyg_io_get_config %d\n", err
);
359 cyg_io_flash_getconfig_erase_t e
;
365 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
366 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
369 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
373 diag_printf("Flash formatted successfully\n");
379 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
380 Jim_Obj
* const *argv
)
392 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
393 Jim_Obj
* const *argv
)
395 cyg_handle_t thread
= 0;
397 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
399 /* Loop over the threads, and generate a table row for
402 while (cyg_thread_get_next(&thread
, &id
))
404 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
406 cyg_thread_info info
;
409 cyg_thread_get_info(thread
, id
, &info
);
411 if (info
.name
== NULL
)
412 info
.name
= "<no name>";
414 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
415 info
.name
, strlen(info
.name
)));
417 /* Translate the state into a string.
420 state_string
= "RUN";
421 else if (info
.state
& 0x04)
422 state_string
= "SUSP";
424 switch (info
.state
& 0x1b)
427 state_string
= "SLEEP";
430 state_string
= "CNTSLEEP";
433 state_string
= "CREATE";
436 state_string
= "EXIT";
439 state_string
= "????";
443 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
444 state_string
, strlen(state_string
)));
446 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
447 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
449 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
452 Jim_ListAppendElement(interp
, threads
, threadObj
);
454 Jim_SetResult(interp
, threads
);
459 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
460 Jim_Obj
* const *argv
)
462 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
464 if (logCount
>= logSize
)
466 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
467 % logSize
, logSize
- logCount
% logSize
);
469 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
471 Jim_SetResult(interp
, tclOutput
);
475 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
476 Jim_Obj
* const *argv
)
482 static void zylinjtag_startNetwork(void)
484 // Bring TCP/IP up immediately before we're ready to accept commands.
486 // That is as soon as a PING responds, we're accepting telnet sessions.
487 #if defined(CYGPKG_NET_FREEBSD_STACK)
488 phi_init_all_network_interfaces();
494 diag_printf("Network not up and running\n");
498 /* very first thing we want is a reboot capability */
501 #if defined(CYGPKG_NET_FREEBSD_STACK)
503 tftpd_start(69, &fileops
);
506 cyg_httpd_init_tcl_interpreter();
508 interp
= httpstate
.jim_interp
;
510 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
512 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
513 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
514 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
515 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
516 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
517 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
523 diag_printf("Web server running\n");
527 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
530 strcpy(ifr
.ifr_name
, "eth0");
532 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
537 diag_printf("Can't obtain MAC address\n");
542 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
544 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
545 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
546 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
547 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
548 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
551 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
556 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
561 char *infoStr
= "unknown";
564 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
565 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
566 infoStr
= "undefined instruction";
568 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
569 infoStr
= "software interrupt";
571 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
572 infoStr
= "abort prefetch";
574 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
575 infoStr
= "abort data";
582 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
584 diag_printf("Dumping log\n---\n");
585 if (logCount
>= logSize
)
587 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
589 diag_write(logBuffer
, writePtr
);
591 diag_printf("---\nLogdump complete.\n");
592 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
593 diag_printf("\n---\nRebooting\n");
594 HAL_PLATFORM_RESET();
598 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
599 static void setHandler(cyg_code_t exception
)
601 cyg_exception_handler_t
*old_handler
;
602 cyg_addrword_t old_data
;
604 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
605 &old_handler
, &old_data
);
609 static cyg_thread zylinjtag_uart_thread_object
;
610 static cyg_handle_t zylinjtag_uart_thread_handle
;
611 static char uart_stack
[4096];
613 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
614 static char backwardBuffer
[1024];
616 void setNoDelay(int session
, int flag
)
619 // This decreases latency dramatically for e.g. GDB load which
620 // does not have a sliding window protocol
622 // Can cause *lots* of TCP/IP packets to be sent and it would have
623 // to be enabled/disabled on the fly to avoid the CPU being
625 setsockopt(session
, /* socket affected */
626 IPPROTO_TCP
, /* set option at TCP level */
627 TCP_NODELAY
, /* name of option */
628 (char *) &flag
, /* the cast is historical
630 sizeof(int)); /* length of option value */
634 #define TEST_TCPIP() 0
643 } tcpipSent
[512 * 1024];
647 static void zylinjtag_uart(cyg_addrword_t data
)
649 int so_reuseaddr_option
= 1;
652 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
654 LOG_ERROR("error creating socket: %s", strerror(errno
));
658 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
661 struct sockaddr_in sin
;
662 unsigned int address_size
;
663 address_size
= sizeof(sin
);
664 memset(&sin
, 0, sizeof(sin
));
665 sin
.sin_family
= AF_INET
;
666 sin
.sin_addr
.s_addr
= INADDR_ANY
;
667 sin
.sin_port
= htons(5555);
669 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
671 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
675 if (listen(fd
, 1) == -1)
677 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
680 // socket_nonblock(fd);
685 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
691 setNoDelay(session
, 1);
692 int oldopts
= fcntl(session
, F_GETFL
, 0);
693 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
695 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
702 #ifdef CYGPKG_PROFILE_GPROF
720 FD_SET(session
, &read_fds
);
722 FD_SET(serHandle
, &read_fds
);
723 if (serHandle
> fd_max
)
729 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
730 if ((actual
== 0) && (actual2
== 0))
732 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
741 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
743 t
= read(serHandle
, backwardBuffer
,
744 sizeof(backwardBuffer
));
760 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
768 if (FD_ISSET(session
, &read_fds
)
769 && (sizeof(forwardBuffer
) > actual
))
771 // NB! Here it is important that we empty the TCP/IP read buffer
772 // to make transmission tick right
773 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
776 // this will block if there is no data at all
777 t
= read_socket(session
, forwardBuffer
+ actual
,
778 sizeof(forwardBuffer
) - actual
);
789 /* Do not put things into the serial buffer if it has something to send
790 * as that can cause a single byte to be sent at the time.
794 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
801 // The serial buffer is full
814 tcpipSent
[cur
].req
= x
;
815 tcpipSent
[cur
].actual
= y
;
816 tcpipSent
[cur
].req2
= x2
;
817 tcpipSent
[cur
].actual2
= y2
;
822 closeSession
: close(session
);
827 for (i
= 0; i
< 1024; i
++)
829 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
830 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
841 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
842 (void *) uart_stack
, sizeof(uart_stack
),
843 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
844 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
845 cyg_thread_resume(zylinjtag_uart_thread_handle
);
848 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
849 Jim_Obj
* const *argv
)
851 static int current_baud
= 38400;
854 command_print(cmd_ctx
, "%d", current_baud
);
863 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
866 current_baud
= new_baudrate
;
869 switch (current_baud
)
872 baud
= CYGNUM_SERIAL_BAUD_9600
;
875 baud
= CYGNUM_SERIAL_BAUD_19200
;
878 baud
= CYGNUM_SERIAL_BAUD_38400
;
881 baud
= CYGNUM_SERIAL_BAUD_57600
;
884 baud
= CYGNUM_SERIAL_BAUD_115200
;
887 baud
= CYGNUM_SERIAL_BAUD_230400
;
890 command_print(cmd_ctx
, "unsupported baudrate");
891 return ERROR_INVALID_ARGUMENTS
;
894 cyg_serial_info_t buf
;
896 //get existing serial configuration
897 len
= sizeof(cyg_serial_info_t
);
899 cyg_io_handle_t serial_handle
;
901 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
904 LOG_ERROR("Could not open serial port\n");
908 err
= cyg_io_get_config(serial_handle
,
909 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
910 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
914 LOG_ERROR("Failed to get serial port settings %d", err
);
919 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
923 LOG_ERROR("Failed to set serial port settings %d", err
);
930 bool logAllToSerial
= false;
933 int boolParam(char *var
);
936 struct command_context
*setup_command_handler(void);
938 static const char *zylin_config_dir
="/config/settings";
940 static int add_default_dirs(void)
942 add_script_search_dir(zylin_config_dir
);
943 add_script_search_dir("/rom/lib/openocd");
944 add_script_search_dir("/rom");
948 int ioutil_init(struct command_context
*cmd_ctx
);
950 int main(int argc
, char *argv
[])
952 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
953 * need to allocate towards the end of the heap. */
955 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
956 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
957 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
958 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
963 atexit(keep_webserver
);
965 diag_init_putc(_zylinjtag_diag_write_char
);
966 // We want this in the log.
967 diag_printf("Zylin ZY1000.\n");
969 err
= mount("", "/ram", "ramfs");
972 diag_printf("unable to mount ramfs\n");
977 sprintf(address
, "%p", &filedata
[0]);
978 err
= mount(address
, "/rom", "romfs");
981 diag_printf("unable to mount /rom\n");
984 err
= mount("", "/log", "logfs");
987 diag_printf("unable to mount logfs\n");
990 err
= mount("", "/tftp", "tftpfs");
993 diag_printf("unable to mount logfs\n");
996 log
= fopen("/log/log", "w");
999 diag_printf("Could not open log file /ram/log\n");
1004 copydir("/rom", "/ram/cgi");
1006 err
= mount("/dev/flash1", "/config", "jffs2");
1009 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1010 err
= mount("", "/config", "ramfs");
1013 diag_printf("unable to mount /config as ramdisk.\n");
1019 /* are we using a ram disk instead of a flash disk? This is used
1020 * for ZY1000 live demo...
1022 * copy over flash disk to ram block device
1024 if (boolParam("ramdisk"))
1026 diag_printf("Unmounting /config from flash and using ram instead\n");
1027 err
= umount("/config");
1030 diag_printf("unable to unmount jffs\n");
1034 err
= mount("/dev/flash1", "/config2", "jffs2");
1037 diag_printf("unable to mount jffs\n");
1041 err
= mount("", "/config", "ramfs");
1044 diag_printf("unable to mount ram block device\n");
1048 // copydir("/config2", "/config");
1049 copyfile("/config2/ip", "/config/ip");
1050 copydir("/config2/settings", "/config/settings");
1056 mkdir(zylin_config_dir
, 0777);
1057 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1058 mkdir(dirname
, 0777);
1060 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1061 mkdir(dirname
, 0777);
1063 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1064 mkdir(dirname
, 0777);
1067 logAllToSerial
= boolParam("logserial");
1069 // We need the network & web server in case there is something wrong with
1070 // the config files that invoke exit()
1071 zylinjtag_startNetwork();
1073 /* we're going to access the jim interpreter from here on... */
1074 openocd_sleep_postlude();
1079 /* initialize commandline interface */
1080 struct command_context
* cmd_ctx
;
1081 cmd_ctx
= setup_command_handler();
1082 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1083 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1086 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1088 return EXIT_FAILURE
;
1093 #ifdef CYGPKG_PROFILE_GPROF
1094 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1098 Jim_CreateCommand(interp
, "uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1102 errVal
= log_init(cmd_ctx
);
1103 if (errVal
!= ERROR_OK
)
1105 diag_printf("log_init() failed %d\n", errVal
);
1109 set_log_output(cmd_ctx
, log
);
1111 LOG_DEBUG("log init complete");
1113 // diag_printf("Executing config files\n");
1118 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1119 command_run_line(cmd_ctx
, "debug_level 3");
1122 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1124 /* we MUST always run the init command as it will launch telnet sessions */
1125 command_run_line(cmd_ctx
, "init");
1128 // diag_printf() is really invoked from many more places than we trust it
1129 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1131 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1132 // fingers that it doesn't cause any crashes.
1133 diag_printf("Init complete, GDB & telnet servers launched.\n");
1134 command_set_output_handler(cmd_ctx
,
1135 zy1000_configuration_output_handler_log
, NULL
);
1136 if (!logAllToSerial
)
1141 /* handle network connections */
1142 server_loop(cmd_ctx
);
1143 openocd_sleep_prelude();
1145 /* shut server down */
1148 /* free commandline interface */
1149 command_done(cmd_ctx
);
1157 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1158 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1160 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1164 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1166 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1167 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1169 #include <pkgconf/system.h>
1170 #include <pkgconf/hal.h>
1171 #include <pkgconf/kernel.h>
1172 #include <pkgconf/io_fileio.h>
1173 #include <pkgconf/fs_rom.h>
1175 #include <cyg/kernel/ktypes.h> // base kernel types
1176 #include <cyg/infra/cyg_trac.h> // tracing macros
1177 #include <cyg/infra/cyg_ass.h> // assertion macros
1178 #include <cyg/fileio/fileio.h>
1179 #include <cyg/kernel/kapi.h>
1180 #include <cyg/infra/diag.h>
1182 //==========================================================================
1183 // Eventually we want to eXecute In Place from the ROM in a protected
1184 // environment, so we'll need executables to be aligned to a boundary
1185 // suitable for MMU protection. A suitable boundary would be the 4k
1186 // boundary in all the CPU architectures I am currently aware of.
1188 // Forward definitions
1190 // Filesystem operations
1191 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1192 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1193 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1194 int mode
, cyg_file
*fte
);
1195 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1196 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1199 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1200 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1201 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1203 //==========================================================================
1204 // Filesystem table entries
1206 // -------------------------------------------------------------------------
1208 // This defines the entry in the filesystem table.
1209 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1210 // we should never block in any filesystem operations.
1212 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1217 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1218 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1219 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1220 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1221 (cyg_fsop_link
*)cyg_fileio_erofs
,
1222 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1223 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1224 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1225 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1226 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1229 // -------------------------------------------------------------------------
1231 // This defines a single ROMFS loaded into ROM at the configured address
1233 // MTAB_ENTRY(rom_mte, // structure name
1234 // "/rom", // mount point
1235 // "romfs", // FIlesystem type
1236 // "", // hardware device
1237 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1241 // -------------------------------------------------------------------------
1243 // This set of file operations are used for normal open files.
1245 static cyg_fileops tftpfs_fileops
=
1246 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1247 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1248 tftpfs_fo_fsync
, tftpfs_fo_close
,
1249 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1250 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1251 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1253 // -------------------------------------------------------------------------
1255 // Process a mount request. This mainly finds root for the
1258 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1263 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1278 static void freeTftp(struct Tftp
*t
)
1291 static const int tftpMaxSize
= 8192 * 1024;
1292 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1293 int mode
, cyg_file
*file
)
1296 tftp
= malloc(sizeof(struct Tftp
));
1299 memset(tftp
, 0, sizeof(struct Tftp
));
1301 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1302 file
->f_type
= CYG_FILE_TYPE_FILE
;
1303 file
->f_ops
= &tftpfs_fileops
;
1308 tftp
->mem
= malloc(tftpMaxSize
);
1309 if (tftp
->mem
== NULL
)
1315 char *server
= strchr(name
, '/');
1322 tftp
->server
= malloc(server
- name
+ 1);
1323 if (tftp
->server
== NULL
)
1328 strncpy(tftp
->server
, name
, server
- name
);
1329 tftp
->server
[server
- name
] = 0;
1331 tftp
->file
= strdup(server
+ 1);
1332 if (tftp
->file
== NULL
)
1338 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1343 static int fetchTftp(struct Tftp
*tftp
)
1345 if (!tftp
->readFile
)
1348 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1349 tftpMaxSize
, TFTP_OCTET
, &err
);
1351 if (tftp
->actual
< 0)
1360 // -------------------------------------------------------------------------
1361 // tftpfs_fo_write()
1362 // Read data from file.
1364 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1366 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1368 if (fetchTftp(tftp
) != ENOERR
)
1372 off_t pos
= fp
->f_offset
;
1374 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1376 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1377 char *buf
= (char *) iov
->iov_base
;
1378 off_t len
= iov
->iov_len
;
1380 if (len
+ pos
> tftp
->actual
)
1382 len
= tftp
->actual
- pos
;
1384 resid
+= iov
->iov_len
- len
;
1386 memcpy(buf
, tftp
->mem
+ pos
, len
);
1390 uio
->uio_resid
= resid
;
1396 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1398 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1401 off_t pos
= fp
->f_offset
;
1403 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1405 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1406 char *buf
= (char *) iov
->iov_base
;
1407 off_t len
= iov
->iov_len
;
1409 if (len
+ pos
> tftpMaxSize
)
1411 len
= tftpMaxSize
- pos
;
1413 resid
+= iov
->iov_len
- len
;
1415 memcpy(tftp
->mem
+ pos
, buf
, len
);
1419 uio
->uio_resid
= resid
;
1427 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1433 // -------------------------------------------------------------------------
1435 // Close a file. We just clear out the data pointer.
1437 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1439 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1444 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1445 TFTP_OCTET
, &error
);
1453 // -------------------------------------------------------------------------
1455 // Seek to a new file position.
1457 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1459 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1462 if (fetchTftp(tftp
) != ENOERR
)
1468 // Pos is already where we want to be.
1472 // Add pos to current offset.
1473 pos
+= fp
->f_offset
;
1477 // Add pos to file size.
1478 pos
+= tftp
->actual
;
1485 // Check that pos is still within current file size, or at the
1487 if (pos
< 0 || pos
> tftp
->actual
)
1490 // All OK, set fp offset and return new position.
1491 *apos
= fp
->f_offset
= pos
;
1499 cyg_thread_delay(us
/ 10000 + 1);
1505 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1507 cyg_httpd_start_chunked("text");
1508 if (logCount
>= logSize
)
1510 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1511 - logCount
% logSize
);
1513 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1514 cyg_httpd_end_chunked();
1518 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1520 // Filesystem operations
1521 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1522 static int logfs_umount(cyg_mtab_entry
*mte
);
1523 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1524 int mode
, cyg_file
*fte
);
1525 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1528 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1529 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1531 #include <cyg/io/devtab.h>
1533 //==========================================================================
1534 // Filesystem table entries
1536 // -------------------------------------------------------------------------
1538 // This defines the entry in the filesystem table.
1539 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1540 // we should never block in any filesystem operations.
1541 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1542 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1546 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1547 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1548 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1549 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1550 (cyg_fsop_link
*)cyg_fileio_erofs
,
1551 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1552 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1553 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1554 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1555 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1557 // -------------------------------------------------------------------------
1559 // This set of file operations are used for normal open files.
1561 static cyg_fileops logfs_fileops
=
1562 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1563 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1564 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1565 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1566 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1567 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1569 // -------------------------------------------------------------------------
1571 // Process a mount request. This mainly finds root for the
1574 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1579 static int logfs_umount(cyg_mtab_entry
*mte
)
1584 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1585 int mode
, cyg_file
*file
)
1587 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1588 file
->f_type
= CYG_FILE_TYPE_FILE
;
1589 file
->f_ops
= &logfs_fileops
;
1596 // -------------------------------------------------------------------------
1598 // Write data to file.
1600 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1603 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1605 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1606 char *buf
= (char *) iov
->iov_base
;
1607 off_t len
= iov
->iov_len
;
1609 diag_write(buf
, len
);
1615 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1620 // -------------------------------------------------------------------------
1622 // Close a file. We just clear out the data pointer.
1624 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1629 int loadFile(const char *fileName
, void **data
, int *len
);
1631 /* boolean parameter stored on config */
1632 int boolParam(char *var
)
1634 bool result
= false;
1635 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1641 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1645 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)