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 ***************************************************************************/
24 #include <helper/types.h>
25 #include <jtag/jtag.h>
26 #include <helper/ioutil.h>
27 #include <helper/configuration.h>
29 #include <server/server.h>
30 #include <server/telnet_server.h>
31 #include <server/gdb_server.h>
34 #include <helper/time_support.h>
43 #include <cyg/io/flash.h>
44 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
49 #include <cyg/fileio/fileio.h>
51 #include <cyg/athttpd/http.h>
52 #include <cyg/athttpd/socket.h>
53 #include <cyg/athttpd/handler.h>
54 #include <cyg/athttpd/cgi.h>
55 #include <cyg/athttpd/forms.h>
56 #include <cyg/discover/discover.h>
57 #include <cyg/io/io.h>
58 #include <cyg/io/serialio.h>
59 #include <netinet/tcp.h>
60 #include <cyg/hal/hal_diag.h>
64 #ifdef CYGPKG_HAL_NIOS2
65 #define ZY1000_SER_DEV "/dev/uart_0"
67 #define ZY1000_SER_DEV "/dev/ser0"
73 #if defined(CYGPKG_NET_FREEBSD_STACK)
74 #include <tftp_support.h>
75 /* posix compatibility broken*/
76 struct tftpd_fileops fileops
=
78 (int (*)(const char *, int))open
,
80 (int (*)(int, const void *, int))write
,
81 (int (*)(int, void *, int))read
87 void diag_write(char *buf
, int len
)
90 for (j
= 0; j
< len
; j
++)
92 diag_printf("%c", buf
[j
]);
96 static bool serialLog
= true;
97 static bool writeLog
= true;
102 extern struct flash_driver
*flash_drivers
[];
103 extern struct target_type
*target_types
[];
105 #ifdef CYGPKG_PROFILE_GPROF
106 #include <cyg/profile/profile.h>
108 extern char _stext
, _etext
; // Defined by the linker
110 static char *start_of_code
=&_stext
;
111 static char *end_of_code
=&_etext
;
113 void start_profile(void)
115 // This starts up the system-wide profiling, gathering
116 // profile information on all of the code, with a 16 byte
117 // "bucket" size, at a rate of 100us/profile hit.
118 // Note: a bucket size of 16 will give pretty good function
119 // resolution. Much smaller and the buffer becomes
120 // much too large for very little gain.
121 // Note: a timer period of 100us is also a reasonable
122 // compromise. Any smaller and the overhead of
123 // handling the timter (profile) interrupt could
124 // swamp the system. A fast processor might get
125 // by with a smaller value, but a slow one could
126 // even be swamped by this value. If the value is
127 // too large, the usefulness of the profile is reduced.
129 // no more interrupts than 1/10ms.
130 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
131 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
132 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
138 static char reboot_stack
[2048];
140 static void zylinjtag_reboot(cyg_addrword_t data
)
143 diag_printf("Rebooting in 500 ticks..\n");
144 cyg_thread_delay(500);
145 diag_printf("Unmounting /config..\n");
147 diag_printf("Rebooting..\n");
148 HAL_PLATFORM_RESET();
150 static cyg_thread zylinjtag_thread_object
;
151 static cyg_handle_t zylinjtag_thread_handle
;
155 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
156 (void *) reboot_stack
, sizeof(reboot_stack
),
157 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
158 cyg_thread_resume(zylinjtag_thread_handle
);
161 static char zylinjtag_reboot_port_stack
[2048];
162 static cyg_thread zylinjtag_reboot_port_thread_object
;
163 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
165 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
167 int so_reuseaddr_option
= 1;
170 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
172 LOG_ERROR("error creating socket: %s", strerror(errno
));
176 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
179 struct sockaddr_in sin
;
180 unsigned int address_size
;
181 address_size
= sizeof(sin
);
182 memset(&sin
, 0, sizeof(sin
));
183 sin
.sin_family
= AF_INET
;
184 sin
.sin_addr
.s_addr
= INADDR_ANY
;
185 sin
.sin_port
= htons(1234);
187 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
189 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
193 if (listen(fd
, 1) == -1)
195 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
198 // socket_nonblock(fd);
201 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
203 diag_printf("Got reboot signal on port 1234");
209 void reboot_port(void)
211 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
212 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
213 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
214 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
217 int configuration_output_handler(struct command_context
*context
,
220 diag_printf("%s", line
);
225 int zy1000_configuration_output_handler_log(struct command_context
*context
,
228 LOG_USER_N("%s", line
);
233 #ifdef CYGPKG_PROFILE_GPROF
234 //extern int64_t totaltime;
236 static int zylinjtag_Jim_Command_profile(Jim_Interp
*interp
, int argc
,
237 Jim_Obj
* const *argv
)
239 if ((argc
== 2) && (strcmp(Jim_GetString(argv
[1], NULL
), "stats")==0))
242 //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
245 LOG_USER("Profiling started");
254 externC
void phi_init_all_network_interfaces(void);
256 struct command_context
*cmd_ctx
;
258 static bool webRunning
= false;
260 void keep_webserver(void)
262 // Target initialisation is only attempted at startup, so we sleep forever and
263 // let the http server bail us out(i.e. get config files set up).
264 diag_printf("OpenOCD has invoked exit().\n"
265 "Use web server to correct any configuration settings and reboot.\n");
269 // exit() will terminate the current thread and we we'll then sleep eternally or
270 // we'll have a reboot scheduled.
273 extern void printDccChar(char c
);
275 static char logBuffer
[128 * 1024];
276 static const int logSize
= sizeof(logBuffer
);
280 void _zylinjtag_diag_write_char(char c
, void **param
)
284 logBuffer
[writePtr
] = c
;
285 writePtr
= (writePtr
+ 1) % logSize
;
292 HAL_DIAG_WRITE_CHAR('\r');
294 HAL_DIAG_WRITE_CHAR(c
);
297 #ifdef CYGPKG_HAL_ZYLIN_PHI
302 void copyfile(char *name2
, char *name1
);
304 void copydir(char *name
, char *destdir
);
307 MTAB_ENTRY(romfs_mte1
,
311 (CYG_ADDRWORD
) &filedata
[0]);
314 void openocd_sleep_prelude(void)
316 cyg_mutex_unlock(&httpstate
.jim_lock
);
319 void openocd_sleep_postlude(void)
321 cyg_mutex_lock(&httpstate
.jim_lock
);
326 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
327 diag_printf("Formatting JFFS2...\n");
329 cyg_io_handle_t handle
;
332 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
335 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
340 cyg_io_flash_getconfig_devsize_t ds
;
342 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
345 diag_printf("Flash error cyg_io_get_config %d\n", err
);
349 cyg_io_flash_getconfig_erase_t e
;
355 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
356 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
359 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
363 diag_printf("Flash formatted successfully\n");
369 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
370 Jim_Obj
* const *argv
)
382 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
383 Jim_Obj
* const *argv
)
385 cyg_handle_t thread
= 0;
387 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
389 /* Loop over the threads, and generate a table row for
392 while (cyg_thread_get_next(&thread
, &id
))
394 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
396 cyg_thread_info info
;
399 cyg_thread_get_info(thread
, id
, &info
);
401 if (info
.name
== NULL
)
402 info
.name
= "<no name>";
404 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
405 info
.name
, strlen(info
.name
)));
407 /* Translate the state into a string.
410 state_string
= "RUN";
411 else if (info
.state
& 0x04)
412 state_string
= "SUSP";
414 switch (info
.state
& 0x1b)
417 state_string
= "SLEEP";
420 state_string
= "CNTSLEEP";
423 state_string
= "CREATE";
426 state_string
= "EXIT";
429 state_string
= "????";
433 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
434 state_string
, strlen(state_string
)));
436 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
437 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
439 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
442 Jim_ListAppendElement(interp
, threads
, threadObj
);
444 Jim_SetResult(interp
, threads
);
449 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
450 Jim_Obj
* const *argv
)
452 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
454 if (logCount
>= logSize
)
456 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
457 % logSize
, logSize
- logCount
% logSize
);
459 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
461 Jim_SetResult(interp
, tclOutput
);
465 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
466 Jim_Obj
* const *argv
)
472 static void zylinjtag_startNetwork(void)
474 // Bring TCP/IP up immediately before we're ready to accept commands.
476 // That is as soon as a PING responds, we're accepting telnet sessions.
477 #if defined(CYGPKG_NET_FREEBSD_STACK)
478 phi_init_all_network_interfaces();
484 diag_printf("Network not up and running\n");
488 /* very first thing we want is a reboot capability */
491 #if defined(CYGPKG_NET_FREEBSD_STACK)
493 tftpd_start(69, &fileops
);
496 cyg_httpd_init_tcl_interpreter();
498 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
500 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
501 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
502 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
503 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
504 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
505 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
511 diag_printf("Web server running\n");
515 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
518 strcpy(ifr
.ifr_name
, "eth0");
520 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
525 diag_printf("Can't obtain MAC address\n");
530 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
531 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
532 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
533 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
534 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
535 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
536 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
539 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
544 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
549 char *infoStr
= "unknown";
552 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
553 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
554 infoStr
= "undefined instruction";
556 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
557 infoStr
= "software interrupt";
559 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
560 infoStr
= "abort prefetch";
562 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
563 infoStr
= "abort data";
570 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
572 diag_printf("Dumping log\n---\n");
573 if (logCount
>= logSize
)
575 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
577 diag_write(logBuffer
, writePtr
);
579 diag_printf("---\nLogdump complete.\n");
580 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
581 diag_printf("\n---\nRebooting\n");
582 HAL_PLATFORM_RESET();
586 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
587 static void setHandler(cyg_code_t exception
)
589 cyg_exception_handler_t
*old_handler
;
590 cyg_addrword_t old_data
;
592 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
593 &old_handler
, &old_data
);
597 static cyg_thread zylinjtag_uart_thread_object
;
598 static cyg_handle_t zylinjtag_uart_thread_handle
;
599 static char uart_stack
[4096];
601 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
602 static char backwardBuffer
[1024];
604 void setNoDelay(int session
, int flag
)
607 // This decreases latency dramatically for e.g. GDB load which
608 // does not have a sliding window protocol
610 // Can cause *lots* of TCP/IP packets to be sent and it would have
611 // to be enabled/disabled on the fly to avoid the CPU being
613 setsockopt(session
, /* socket affected */
614 IPPROTO_TCP
, /* set option at TCP level */
615 TCP_NODELAY
, /* name of option */
616 (char *) &flag
, /* the cast is historical
618 sizeof(int)); /* length of option value */
622 #define TEST_TCPIP() 0
631 } tcpipSent
[512 * 1024];
635 static void zylinjtag_uart(cyg_addrword_t data
)
637 int so_reuseaddr_option
= 1;
640 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
642 LOG_ERROR("error creating socket: %s", strerror(errno
));
646 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
649 struct sockaddr_in sin
;
650 unsigned int address_size
;
651 address_size
= sizeof(sin
);
652 memset(&sin
, 0, sizeof(sin
));
653 sin
.sin_family
= AF_INET
;
654 sin
.sin_addr
.s_addr
= INADDR_ANY
;
655 sin
.sin_port
= htons(5555);
657 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
659 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
663 if (listen(fd
, 1) == -1)
665 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
668 // socket_nonblock(fd);
673 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
679 setNoDelay(session
, 1);
680 int oldopts
= fcntl(session
, F_GETFL
, 0);
681 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
683 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
690 #ifdef CYGPKG_PROFILE_GPROF
708 FD_SET(session
, &read_fds
);
710 FD_SET(serHandle
, &read_fds
);
711 if (serHandle
> fd_max
)
717 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
718 if ((actual
== 0) && (actual2
== 0))
720 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
729 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
731 t
= read(serHandle
, backwardBuffer
,
732 sizeof(backwardBuffer
));
748 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
756 if (FD_ISSET(session
, &read_fds
)
757 && (sizeof(forwardBuffer
) > actual
))
759 // NB! Here it is important that we empty the TCP/IP read buffer
760 // to make transmission tick right
761 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
764 // this will block if there is no data at all
765 t
= read_socket(session
, forwardBuffer
+ actual
,
766 sizeof(forwardBuffer
) - actual
);
777 /* Do not put things into the serial buffer if it has something to send
778 * as that can cause a single byte to be sent at the time.
782 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
789 // The serial buffer is full
802 tcpipSent
[cur
].req
= x
;
803 tcpipSent
[cur
].actual
= y
;
804 tcpipSent
[cur
].req2
= x2
;
805 tcpipSent
[cur
].actual2
= y2
;
810 closeSession
: close(session
);
815 for (i
= 0; i
< 1024; i
++)
817 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
818 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
829 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
830 (void *) uart_stack
, sizeof(uart_stack
),
831 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
832 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
833 cyg_thread_resume(zylinjtag_uart_thread_handle
);
836 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
837 Jim_Obj
* const *argv
)
839 static int current_baud
= 38400;
842 command_print(cmd_ctx
, "%d", current_baud
);
851 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
854 current_baud
= new_baudrate
;
857 switch (current_baud
)
860 baud
= CYGNUM_SERIAL_BAUD_9600
;
863 baud
= CYGNUM_SERIAL_BAUD_19200
;
866 baud
= CYGNUM_SERIAL_BAUD_38400
;
869 baud
= CYGNUM_SERIAL_BAUD_57600
;
872 baud
= CYGNUM_SERIAL_BAUD_115200
;
875 baud
= CYGNUM_SERIAL_BAUD_230400
;
878 command_print(cmd_ctx
, "unsupported baudrate");
879 return ERROR_INVALID_ARGUMENTS
;
882 cyg_serial_info_t buf
;
884 //get existing serial configuration
885 len
= sizeof(cyg_serial_info_t
);
887 cyg_io_handle_t serial_handle
;
889 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
892 LOG_ERROR("Could not open serial port\n");
896 err
= cyg_io_get_config(serial_handle
,
897 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
898 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
902 LOG_ERROR("Failed to get serial port settings %d", err
);
907 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
911 LOG_ERROR("Failed to set serial port settings %d", err
);
918 bool logAllToSerial
= false;
921 int boolParam(char *var
);
924 static const char *zylin_config_dir
="/config/settings";
926 static int add_default_dirs(void)
928 add_script_search_dir(zylin_config_dir
);
929 add_script_search_dir("/rom/lib/openocd");
930 add_script_search_dir("/rom");
934 int main(int argc
, char *argv
[])
936 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
937 * need to allocate towards the end of the heap. */
939 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
940 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
941 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
942 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
947 atexit(keep_webserver
);
949 diag_init_putc(_zylinjtag_diag_write_char
);
950 // We want this in the log.
951 diag_printf("Zylin ZY1000.\n");
953 err
= mount("", "/ram", "ramfs");
956 diag_printf("unable to mount ramfs\n");
961 sprintf(address
, "%p", &filedata
[0]);
962 err
= mount(address
, "/rom", "romfs");
965 diag_printf("unable to mount /rom\n");
968 err
= mount("", "/log", "logfs");
971 diag_printf("unable to mount logfs\n");
974 err
= mount("", "/tftp", "tftpfs");
977 diag_printf("unable to mount logfs\n");
980 log
= fopen("/log/log", "w");
983 diag_printf("Could not open log file /ram/log\n");
988 copydir("/rom", "/ram/cgi");
990 err
= mount("/dev/flash1", "/config", "jffs2");
993 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
994 err
= mount("", "/config", "ramfs");
997 diag_printf("unable to mount /config as ramdisk.\n");
1003 /* are we using a ram disk instead of a flash disk? This is used
1004 * for ZY1000 live demo...
1006 * copy over flash disk to ram block device
1008 if (boolParam("ramdisk"))
1010 diag_printf("Unmounting /config from flash and using ram instead\n");
1011 err
= umount("/config");
1014 diag_printf("unable to unmount jffs\n");
1018 err
= mount("/dev/flash1", "/config2", "jffs2");
1021 diag_printf("unable to mount jffs\n");
1025 err
= mount("", "/config", "ramfs");
1028 diag_printf("unable to mount ram block device\n");
1032 // copydir("/config2", "/config");
1033 copyfile("/config2/ip", "/config/ip");
1034 copydir("/config2/settings", "/config/settings");
1040 mkdir(zylin_config_dir
, 0777);
1041 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1042 mkdir(dirname
, 0777);
1044 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1045 mkdir(dirname
, 0777);
1047 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1048 mkdir(dirname
, 0777);
1051 logAllToSerial
= boolParam("logserial");
1053 // We need the network & web server in case there is something wrong with
1054 // the config files that invoke exit()
1055 zylinjtag_startNetwork();
1057 /* we're going to access the jim interpreter from here on... */
1058 openocd_sleep_postlude();
1063 /* initialize commandline interface */
1064 struct command_context
* cmd_ctx
;
1065 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1066 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1067 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1068 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1070 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1071 return EXIT_FAILURE
;
1073 #ifdef CYGPKG_PROFILE_GPROF
1074 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_profile", zylinjtag_Jim_Command_profile
,
1078 Jim_CreateCommand(httpstate
.jim_interp
, "uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1083 set_log_output(cmd_ctx
, log
);
1085 LOG_DEBUG("log init complete");
1087 // diag_printf("Executing config files\n");
1092 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1093 command_run_line(cmd_ctx
, "debug_level 3");
1096 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1099 ret
= server_init(cmd_ctx
);
1100 if (ERROR_OK
!= ret
)
1101 return EXIT_FAILURE
;
1103 /* we MUST always run the init command as it will launch telnet sessions */
1104 command_run_line(cmd_ctx
, "init");
1107 // diag_printf() is really invoked from many more places than we trust it
1108 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1110 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1111 // fingers that it doesn't cause any crashes.
1112 diag_printf("Init complete, GDB & telnet servers launched.\n");
1113 command_set_output_handler(cmd_ctx
,
1114 zy1000_configuration_output_handler_log
, NULL
);
1115 if (!logAllToSerial
)
1120 /* handle network connections */
1121 server_loop(cmd_ctx
);
1122 openocd_sleep_prelude();
1124 /* shut server down */
1127 /* free commandline interface */
1128 command_done(cmd_ctx
);
1136 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1137 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1139 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1143 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1145 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1146 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1148 #include <pkgconf/system.h>
1149 #include <pkgconf/hal.h>
1150 #include <pkgconf/kernel.h>
1151 #include <pkgconf/io_fileio.h>
1152 #include <pkgconf/fs_rom.h>
1154 #include <cyg/kernel/ktypes.h> // base kernel types
1155 #include <cyg/infra/cyg_trac.h> // tracing macros
1156 #include <cyg/infra/cyg_ass.h> // assertion macros
1157 #include <cyg/fileio/fileio.h>
1158 #include <cyg/kernel/kapi.h>
1159 #include <cyg/infra/diag.h>
1161 //==========================================================================
1162 // Eventually we want to eXecute In Place from the ROM in a protected
1163 // environment, so we'll need executables to be aligned to a boundary
1164 // suitable for MMU protection. A suitable boundary would be the 4k
1165 // boundary in all the CPU architectures I am currently aware of.
1167 // Forward definitions
1169 // Filesystem operations
1170 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1171 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1172 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1173 int mode
, cyg_file
*fte
);
1174 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1175 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1178 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1179 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1180 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1182 //==========================================================================
1183 // Filesystem table entries
1185 // -------------------------------------------------------------------------
1187 // This defines the entry in the filesystem table.
1188 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1189 // we should never block in any filesystem operations.
1191 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1196 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1197 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1198 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1199 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1200 (cyg_fsop_link
*)cyg_fileio_erofs
,
1201 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1202 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1203 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1204 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1205 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1208 // -------------------------------------------------------------------------
1210 // This defines a single ROMFS loaded into ROM at the configured address
1212 // MTAB_ENTRY(rom_mte, // structure name
1213 // "/rom", // mount point
1214 // "romfs", // FIlesystem type
1215 // "", // hardware device
1216 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1220 // -------------------------------------------------------------------------
1222 // This set of file operations are used for normal open files.
1224 static cyg_fileops tftpfs_fileops
=
1225 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1226 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1227 tftpfs_fo_fsync
, tftpfs_fo_close
,
1228 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1229 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1230 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1232 // -------------------------------------------------------------------------
1234 // Process a mount request. This mainly finds root for the
1237 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1242 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1257 static void freeTftp(struct Tftp
*t
)
1270 static const int tftpMaxSize
= 8192 * 1024;
1271 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1272 int mode
, cyg_file
*file
)
1275 tftp
= malloc(sizeof(struct Tftp
));
1278 memset(tftp
, 0, sizeof(struct Tftp
));
1280 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1281 file
->f_type
= CYG_FILE_TYPE_FILE
;
1282 file
->f_ops
= &tftpfs_fileops
;
1287 tftp
->mem
= malloc(tftpMaxSize
);
1288 if (tftp
->mem
== NULL
)
1294 char *server
= strchr(name
, '/');
1301 tftp
->server
= malloc(server
- name
+ 1);
1302 if (tftp
->server
== NULL
)
1307 strncpy(tftp
->server
, name
, server
- name
);
1308 tftp
->server
[server
- name
] = 0;
1310 tftp
->file
= strdup(server
+ 1);
1311 if (tftp
->file
== NULL
)
1317 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1322 static int fetchTftp(struct Tftp
*tftp
)
1324 if (!tftp
->readFile
)
1327 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1328 tftpMaxSize
, TFTP_OCTET
, &err
);
1330 if (tftp
->actual
< 0)
1339 // -------------------------------------------------------------------------
1340 // tftpfs_fo_write()
1341 // Read data from file.
1343 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1345 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1347 if (fetchTftp(tftp
) != ENOERR
)
1351 off_t pos
= fp
->f_offset
;
1353 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1355 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1356 char *buf
= (char *) iov
->iov_base
;
1357 off_t len
= iov
->iov_len
;
1359 if (len
+ pos
> tftp
->actual
)
1361 len
= tftp
->actual
- pos
;
1363 resid
+= iov
->iov_len
- len
;
1365 memcpy(buf
, tftp
->mem
+ pos
, len
);
1369 uio
->uio_resid
= resid
;
1375 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1377 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1380 off_t pos
= fp
->f_offset
;
1382 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1384 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1385 char *buf
= (char *) iov
->iov_base
;
1386 off_t len
= iov
->iov_len
;
1388 if (len
+ pos
> tftpMaxSize
)
1390 len
= tftpMaxSize
- pos
;
1392 resid
+= iov
->iov_len
- len
;
1394 memcpy(tftp
->mem
+ pos
, buf
, len
);
1398 uio
->uio_resid
= resid
;
1406 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1412 // -------------------------------------------------------------------------
1414 // Close a file. We just clear out the data pointer.
1416 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1418 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1423 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1424 TFTP_OCTET
, &error
);
1432 // -------------------------------------------------------------------------
1434 // Seek to a new file position.
1436 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1438 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1441 if (fetchTftp(tftp
) != ENOERR
)
1447 // Pos is already where we want to be.
1451 // Add pos to current offset.
1452 pos
+= fp
->f_offset
;
1456 // Add pos to file size.
1457 pos
+= tftp
->actual
;
1464 // Check that pos is still within current file size, or at the
1466 if (pos
< 0 || pos
> tftp
->actual
)
1469 // All OK, set fp offset and return new position.
1470 *apos
= fp
->f_offset
= pos
;
1478 cyg_thread_delay(us
/ 10000 + 1);
1484 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1486 cyg_httpd_start_chunked("text");
1487 if (logCount
>= logSize
)
1489 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1490 - logCount
% logSize
);
1492 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1493 cyg_httpd_end_chunked();
1497 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1499 // Filesystem operations
1500 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1501 static int logfs_umount(cyg_mtab_entry
*mte
);
1502 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1503 int mode
, cyg_file
*fte
);
1504 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1507 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1508 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1510 #include <cyg/io/devtab.h>
1512 //==========================================================================
1513 // Filesystem table entries
1515 // -------------------------------------------------------------------------
1517 // This defines the entry in the filesystem table.
1518 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1519 // we should never block in any filesystem operations.
1520 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1521 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1525 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1526 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1527 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1528 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1529 (cyg_fsop_link
*)cyg_fileio_erofs
,
1530 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1531 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1532 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1533 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1534 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1536 // -------------------------------------------------------------------------
1538 // This set of file operations are used for normal open files.
1540 static cyg_fileops logfs_fileops
=
1541 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1542 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1543 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1544 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1545 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1546 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1548 // -------------------------------------------------------------------------
1550 // Process a mount request. This mainly finds root for the
1553 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1558 static int logfs_umount(cyg_mtab_entry
*mte
)
1563 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1564 int mode
, cyg_file
*file
)
1566 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1567 file
->f_type
= CYG_FILE_TYPE_FILE
;
1568 file
->f_ops
= &logfs_fileops
;
1575 // -------------------------------------------------------------------------
1577 // Write data to file.
1579 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1582 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1584 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1585 char *buf
= (char *) iov
->iov_base
;
1586 off_t len
= iov
->iov_len
;
1588 diag_write(buf
, len
);
1594 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1599 // -------------------------------------------------------------------------
1601 // Close a file. We just clear out the data pointer.
1603 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1608 int loadFile(const char *fileName
, void **data
, int *len
);
1610 /* boolean parameter stored on config */
1611 int boolParam(char *var
)
1613 bool result
= false;
1614 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1620 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1624 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)