1 /***************************************************************************
2 * Copyright (C) 2007-2010 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/util.h>
28 #include <helper/configuration.h>
30 #include <server/server.h>
31 #include <server/telnet_server.h>
32 #include <server/gdb_server.h>
35 #include <helper/time_support.h>
44 #include <cyg/io/flash.h>
45 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
50 #include <cyg/fileio/fileio.h>
52 #include <cyg/athttpd/http.h>
53 #include <cyg/athttpd/socket.h>
54 #include <cyg/athttpd/handler.h>
55 #include <cyg/athttpd/cgi.h>
56 #include <cyg/athttpd/forms.h>
57 #include <cyg/discover/discover.h>
58 #include <cyg/io/io.h>
59 #include <cyg/io/serialio.h>
60 #include <netinet/tcp.h>
61 #include <cyg/hal/hal_diag.h>
65 #ifdef CYGPKG_HAL_NIOS2
66 #include <cyg/hal/io.h>
67 #define ZY1000_SER_DEV "/dev/uart_0"
69 #define ZY1000_SER_DEV "/dev/ser0"
75 #if defined(CYGPKG_NET_FREEBSD_STACK)
76 #include <tftp_support.h>
77 /* posix compatibility broken*/
78 struct tftpd_fileops fileops
=
80 (int (*)(const char *, int))open
,
82 (int (*)(int, const void *, int))write
,
83 (int (*)(int, void *, int))read
89 void diag_write(char *buf
, int len
)
92 for (j
= 0; j
< len
; j
++)
94 diag_printf("%c", buf
[j
]);
98 static bool serialLog
= true;
99 static bool writeLog
= true;
103 #ifdef CYGPKG_PROFILE_GPROF
104 #include <cyg/profile/profile.h>
106 extern char _stext
, _etext
; // Defined by the linker
108 static char *start_of_code
=&_stext
;
109 static char *end_of_code
=&_etext
;
111 void start_profile(void)
113 // This starts up the system-wide profiling, gathering
114 // profile information on all of the code, with a 16 byte
115 // "bucket" size, at a rate of 100us/profile hit.
116 // Note: a bucket size of 16 will give pretty good function
117 // resolution. Much smaller and the buffer becomes
118 // much too large for very little gain.
119 // Note: a timer period of 100us is also a reasonable
120 // compromise. Any smaller and the overhead of
121 // handling the timter (profile) interrupt could
122 // swamp the system. A fast processor might get
123 // by with a smaller value, but a slow one could
124 // even be swamped by this value. If the value is
125 // too large, the usefulness of the profile is reduced.
127 // no more interrupts than 1/10ms.
128 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
129 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
130 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
136 static char reboot_stack
[2048];
138 static void zylinjtag_reboot(cyg_addrword_t data
)
141 diag_printf("Rebooting in 500 ticks..\n");
142 cyg_thread_delay(500);
143 diag_printf("Unmounting /config..\n");
145 diag_printf("Rebooting..\n");
146 #ifdef CYGPKG_HAL_NIOS2
147 /* This will reboot & reconfigure the FPGA from the bootloader
150 IOWR(REMOTE_UPDATE_BASE
, 0x20, 0x1);
152 HAL_PLATFORM_RESET();
155 static cyg_thread zylinjtag_thread_object
;
156 static cyg_handle_t zylinjtag_thread_handle
;
160 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
161 (void *) reboot_stack
, sizeof(reboot_stack
),
162 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
163 cyg_thread_resume(zylinjtag_thread_handle
);
166 static char zylinjtag_reboot_port_stack
[2048];
167 static cyg_thread zylinjtag_reboot_port_thread_object
;
168 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
170 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
172 int so_reuseaddr_option
= 1;
175 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
177 LOG_ERROR("error creating socket: %s", strerror(errno
));
181 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
184 struct sockaddr_in sin
;
185 unsigned int address_size
;
186 address_size
= sizeof(sin
);
187 memset(&sin
, 0, sizeof(sin
));
188 sin
.sin_family
= AF_INET
;
189 sin
.sin_addr
.s_addr
= INADDR_ANY
;
190 sin
.sin_port
= htons(1234);
192 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
194 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
198 if (listen(fd
, 1) == -1)
200 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
203 // socket_nonblock(fd);
206 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
208 diag_printf("Got reboot signal on port 1234");
214 void reboot_port(void)
216 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
217 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
218 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
219 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
222 int configuration_output_handler(struct command_context
*context
,
225 diag_printf("%s", line
);
230 int zy1000_configuration_output_handler_log(struct command_context
*context
,
233 LOG_USER_N("%s", line
);
238 #ifdef CYGPKG_PROFILE_GPROF
239 //extern int64_t totaltime;
241 static int zylinjtag_Jim_Command_profile(Jim_Interp
*interp
, int argc
,
242 Jim_Obj
* const *argv
)
244 if ((argc
== 2) && (strcmp(Jim_GetString(argv
[1], NULL
), "stats")==0))
247 //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
250 LOG_USER("Profiling started");
259 externC
void phi_init_all_network_interfaces(void);
261 struct command_context
*cmd_ctx
;
263 static bool webRunning
= false;
265 void keep_webserver(void)
267 // Target initialisation is only attempted at startup, so we sleep forever and
268 // let the http server bail us out(i.e. get config files set up).
269 diag_printf("OpenOCD has invoked exit().\n"
270 "Use web server to correct any configuration settings and reboot.\n");
274 // exit() will terminate the current thread and we we'll then sleep eternally or
275 // we'll have a reboot scheduled.
278 extern void printDccChar(char c
);
280 static char logBuffer
[128 * 1024];
281 static const int logSize
= sizeof(logBuffer
);
285 void _zylinjtag_diag_write_char(char c
, void **param
)
289 logBuffer
[writePtr
] = c
;
290 writePtr
= (writePtr
+ 1) % logSize
;
297 HAL_DIAG_WRITE_CHAR('\r');
299 HAL_DIAG_WRITE_CHAR(c
);
302 #ifdef CYGPKG_HAL_ZYLIN_PHI
307 void copyfile(char *name2
, char *name1
);
309 void copydir(char *name
, char *destdir
);
312 MTAB_ENTRY(romfs_mte1
,
316 (CYG_ADDRWORD
) &filedata
[0]);
319 void openocd_sleep_prelude(void)
321 cyg_mutex_unlock(&httpstate
.jim_lock
);
324 void openocd_sleep_postlude(void)
326 cyg_mutex_lock(&httpstate
.jim_lock
);
331 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
332 diag_printf("Formatting JFFS2...\n");
334 cyg_io_handle_t handle
;
337 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
340 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
345 cyg_io_flash_getconfig_devsize_t ds
;
347 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
350 diag_printf("Flash error cyg_io_get_config %d\n", err
);
354 cyg_io_flash_getconfig_erase_t e
;
360 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
361 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
364 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
368 diag_printf("Flash formatted successfully\n");
374 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
375 Jim_Obj
* const *argv
)
387 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
388 Jim_Obj
* const *argv
)
390 cyg_handle_t thread
= 0;
392 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
394 /* Loop over the threads, and generate a table row for
397 while (cyg_thread_get_next(&thread
, &id
))
399 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
401 cyg_thread_info info
;
404 cyg_thread_get_info(thread
, id
, &info
);
406 if (info
.name
== NULL
)
407 info
.name
= "<no name>";
409 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
410 info
.name
, strlen(info
.name
)));
412 /* Translate the state into a string.
415 state_string
= "RUN";
416 else if (info
.state
& 0x04)
417 state_string
= "SUSP";
419 switch (info
.state
& 0x1b)
422 state_string
= "SLEEP";
425 state_string
= "CNTSLEEP";
428 state_string
= "CREATE";
431 state_string
= "EXIT";
434 state_string
= "????";
438 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
439 state_string
, strlen(state_string
)));
441 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
442 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
444 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
447 Jim_ListAppendElement(interp
, threads
, threadObj
);
449 Jim_SetResult(interp
, threads
);
454 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
455 Jim_Obj
* const *argv
)
457 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
459 if (logCount
>= logSize
)
461 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
462 % logSize
, logSize
- logCount
% logSize
);
464 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
466 Jim_SetResult(interp
, tclOutput
);
470 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
471 Jim_Obj
* const *argv
)
477 static void zylinjtag_startNetwork(void)
479 // Bring TCP/IP up immediately before we're ready to accept commands.
481 // That is as soon as a PING responds, we're accepting telnet sessions.
482 #if defined(CYGPKG_NET_FREEBSD_STACK)
483 phi_init_all_network_interfaces();
489 diag_printf("Network not up and running\n");
493 /* very first thing we want is a reboot capability */
496 #if defined(CYGPKG_NET_FREEBSD_STACK)
498 tftpd_start(69, &fileops
);
501 cyg_httpd_init_tcl_interpreter();
503 // Kludge! Why can't I do this from httpd.c??? I get linker errors...
504 // some of that --start/end-group stuff?
505 Jim_InitStaticExtensions(httpstate
.jim_interp
);
507 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
509 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
510 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
511 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
512 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
513 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
514 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
520 diag_printf("Web server running\n");
524 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
527 strcpy(ifr
.ifr_name
, "eth0");
529 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
534 diag_printf("Can't obtain MAC address\n");
539 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
544 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
545 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
548 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
553 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
558 char *infoStr
= "unknown";
561 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
562 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
563 infoStr
= "undefined instruction";
565 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
566 infoStr
= "software interrupt";
568 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
569 infoStr
= "abort prefetch";
571 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
572 infoStr
= "abort data";
579 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
581 diag_printf("Dumping log\n---\n");
582 if (logCount
>= logSize
)
584 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
586 diag_write(logBuffer
, writePtr
);
588 diag_printf("---\nLogdump complete.\n");
589 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
590 diag_printf("\n---\nRebooting\n");
591 HAL_PLATFORM_RESET();
595 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
596 static void setHandler(cyg_code_t exception
)
598 cyg_exception_handler_t
*old_handler
;
599 cyg_addrword_t old_data
;
601 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
602 &old_handler
, &old_data
);
606 static cyg_thread zylinjtag_uart_thread_object
;
607 static cyg_handle_t zylinjtag_uart_thread_handle
;
608 static char uart_stack
[4096];
610 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
611 static char backwardBuffer
[1024];
613 void setNoDelay(int session
, int flag
)
616 // This decreases latency dramatically for e.g. GDB load which
617 // does not have a sliding window protocol
619 // Can cause *lots* of TCP/IP packets to be sent and it would have
620 // to be enabled/disabled on the fly to avoid the CPU being
622 setsockopt(session
, /* socket affected */
623 IPPROTO_TCP
, /* set option at TCP level */
624 TCP_NODELAY
, /* name of option */
625 (char *) &flag
, /* the cast is historical
627 sizeof(int)); /* length of option value */
631 #define TEST_TCPIP() 0
640 } tcpipSent
[512 * 1024];
644 static void zylinjtag_uart(cyg_addrword_t data
)
646 int so_reuseaddr_option
= 1;
649 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
651 LOG_ERROR("error creating socket: %s", strerror(errno
));
655 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
658 struct sockaddr_in sin
;
659 unsigned int address_size
;
660 address_size
= sizeof(sin
);
661 memset(&sin
, 0, sizeof(sin
));
662 sin
.sin_family
= AF_INET
;
663 sin
.sin_addr
.s_addr
= INADDR_ANY
;
664 sin
.sin_port
= htons(5555);
666 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
668 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
672 if (listen(fd
, 1) == -1)
674 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
677 // socket_nonblock(fd);
682 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
688 setNoDelay(session
, 1);
689 int oldopts
= fcntl(session
, F_GETFL
, 0);
690 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
692 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
699 #ifdef CYGPKG_PROFILE_GPROF
717 FD_SET(session
, &read_fds
);
719 FD_SET(serHandle
, &read_fds
);
720 if (serHandle
> fd_max
)
726 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
727 if ((actual
== 0) && (actual2
== 0))
729 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
738 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
740 t
= read(serHandle
, backwardBuffer
,
741 sizeof(backwardBuffer
));
757 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
765 if (FD_ISSET(session
, &read_fds
)
766 && (sizeof(forwardBuffer
) > actual
))
768 // NB! Here it is important that we empty the TCP/IP read buffer
769 // to make transmission tick right
770 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
773 // this will block if there is no data at all
774 t
= read_socket(session
, forwardBuffer
+ actual
,
775 sizeof(forwardBuffer
) - actual
);
786 /* Do not put things into the serial buffer if it has something to send
787 * as that can cause a single byte to be sent at the time.
791 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
798 // The serial buffer is full
811 tcpipSent
[cur
].req
= x
;
812 tcpipSent
[cur
].actual
= y
;
813 tcpipSent
[cur
].req2
= x2
;
814 tcpipSent
[cur
].actual2
= y2
;
819 closeSession
: close(session
);
824 for (i
= 0; i
< 1024; i
++)
826 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
827 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
838 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
839 (void *) uart_stack
, sizeof(uart_stack
),
840 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
841 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
842 cyg_thread_resume(zylinjtag_uart_thread_handle
);
845 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
846 Jim_Obj
* const *argv
)
848 static int current_baud
= 38400;
851 Jim_SetResult(interp
, Jim_NewIntObj(interp
, current_baud
));
860 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
863 current_baud
= new_baudrate
;
866 switch (current_baud
)
869 baud
= CYGNUM_SERIAL_BAUD_9600
;
872 baud
= CYGNUM_SERIAL_BAUD_19200
;
875 baud
= CYGNUM_SERIAL_BAUD_38400
;
878 baud
= CYGNUM_SERIAL_BAUD_57600
;
881 baud
= CYGNUM_SERIAL_BAUD_115200
;
884 baud
= CYGNUM_SERIAL_BAUD_230400
;
887 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "unsupported baudrate", -1));
891 cyg_serial_info_t buf
;
893 //get existing serial configuration
894 len
= sizeof(cyg_serial_info_t
);
896 cyg_io_handle_t serial_handle
;
898 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
901 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Could not open serial port", -1));
905 err
= cyg_io_get_config(serial_handle
,
906 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
907 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
911 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to get serial port settings", -1));
916 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
920 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to set serial port settings", -1));
927 bool logAllToSerial
= false;
930 int boolParam(char *var
);
933 static const char *zylin_config_dir
="/config/settings";
935 static int add_default_dirs(void)
937 add_script_search_dir(zylin_config_dir
);
938 add_script_search_dir("/rom/lib/openocd");
939 add_script_search_dir("/rom");
943 int main(int argc
, char *argv
[])
945 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
946 * need to allocate towards the end of the heap. */
948 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
949 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
950 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
951 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
956 atexit(keep_webserver
);
958 diag_init_putc(_zylinjtag_diag_write_char
);
959 // We want this in the log.
960 #ifdef CYGPKG_HAL_NIOS2
961 diag_printf("Zylin ZY1000 PCB revc.\n");
963 diag_printf("Zylin ZY1000 PCB revb.\n");
966 err
= mount("", "/ram", "ramfs");
969 diag_printf("unable to mount ramfs\n");
974 sprintf(address
, "%p", &filedata
[0]);
975 err
= mount(address
, "/rom", "romfs");
978 diag_printf("unable to mount /rom\n");
981 err
= mount("", "/log", "logfs");
984 diag_printf("unable to mount logfs\n");
987 err
= mount("", "/tftp", "tftpfs");
990 diag_printf("unable to mount logfs\n");
993 log
= fopen("/log/log", "w");
996 diag_printf("Could not open log file /ram/log\n");
1001 copydir("/rom", "/ram/cgi");
1003 #ifdef CYGPKG_HAL_NIOS2
1004 cyg_flashaddr_t err_address
;
1005 #define UNCACHED_EXT_FLASH_BASE (0x80000000 + EXT_FLASH_BASE)
1006 /* The revc flash is locked upon reset, unlock it */
1007 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
1008 if ((err
= flash_unlock((void *) UNCACHED_EXT_FLASH_BASE
, EXT_FLASH_SPAN
,
1009 (void **) &err_address
)) != 0)
1011 diag_printf("Error: could not unlock flash\n");
1017 err
= mount("/dev/flash1", "/config", "jffs2");
1020 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1021 err
= mount("", "/config", "ramfs");
1024 diag_printf("unable to mount /config as ramdisk.\n");
1030 /* are we using a ram disk instead of a flash disk? This is used
1031 * for ZY1000 live demo...
1033 * copy over flash disk to ram block device
1035 if (boolParam("ramdisk"))
1037 diag_printf("Unmounting /config from flash and using ram instead\n");
1038 err
= umount("/config");
1041 diag_printf("unable to unmount jffs\n");
1045 err
= mount("/dev/flash1", "/config2", "jffs2");
1048 diag_printf("unable to mount jffs\n");
1052 err
= mount("", "/config", "ramfs");
1055 diag_printf("unable to mount ram block device\n");
1059 // copydir("/config2", "/config");
1060 copyfile("/config2/ip", "/config/ip");
1061 copydir("/config2/settings", "/config/settings");
1067 mkdir(zylin_config_dir
, 0777);
1068 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1069 mkdir(dirname
, 0777);
1071 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1072 mkdir(dirname
, 0777);
1074 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1075 mkdir(dirname
, 0777);
1078 logAllToSerial
= boolParam("logserial");
1080 // We need the network & web server in case there is something wrong with
1081 // the config files that invoke exit()
1082 zylinjtag_startNetwork();
1084 /* we're going to access the jim interpreter from here on... */
1085 openocd_sleep_postlude();
1090 /* initialize commandline interface */
1091 struct command_context
* cmd_ctx
;
1092 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1093 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1094 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1095 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1097 if (util_init(cmd_ctx
) != ERROR_OK
)
1098 return EXIT_FAILURE
;
1100 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1101 return EXIT_FAILURE
;
1103 #ifdef CYGPKG_PROFILE_GPROF
1104 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_profile", zylinjtag_Jim_Command_profile
,
1108 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1113 set_log_output(cmd_ctx
, log
);
1115 LOG_DEBUG("log init complete");
1117 // diag_printf("Executing config files\n");
1122 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1123 command_run_line(cmd_ctx
, "debug_level 3");
1126 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1129 ret
= server_init(cmd_ctx
);
1130 if (ERROR_OK
!= ret
)
1131 return EXIT_FAILURE
;
1133 /* we MUST always run the init command as it will launch telnet sessions */
1134 command_run_line(cmd_ctx
, "init");
1137 // diag_printf() is really invoked from many more places than we trust it
1138 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1140 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1141 // fingers that it doesn't cause any crashes.
1142 diag_printf("Init complete, GDB & telnet servers launched.\n");
1143 command_set_output_handler(cmd_ctx
,
1144 zy1000_configuration_output_handler_log
, NULL
);
1145 if (!logAllToSerial
)
1150 /* handle network connections */
1151 server_loop(cmd_ctx
);
1152 openocd_sleep_prelude();
1154 /* shut server down */
1157 /* free commandline interface */
1158 command_done(cmd_ctx
);
1166 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1167 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1169 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1173 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1175 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1176 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1178 #include <pkgconf/system.h>
1179 #include <pkgconf/hal.h>
1180 #include <pkgconf/kernel.h>
1181 #include <pkgconf/io_fileio.h>
1182 #include <pkgconf/fs_rom.h>
1184 #include <cyg/kernel/ktypes.h> // base kernel types
1185 #include <cyg/infra/cyg_trac.h> // tracing macros
1186 #include <cyg/infra/cyg_ass.h> // assertion macros
1187 #include <cyg/fileio/fileio.h>
1188 #include <cyg/kernel/kapi.h>
1189 #include <cyg/infra/diag.h>
1191 //==========================================================================
1192 // Eventually we want to eXecute In Place from the ROM in a protected
1193 // environment, so we'll need executables to be aligned to a boundary
1194 // suitable for MMU protection. A suitable boundary would be the 4k
1195 // boundary in all the CPU architectures I am currently aware of.
1197 // Forward definitions
1199 // Filesystem operations
1200 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1201 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1202 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1203 int mode
, cyg_file
*fte
);
1204 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1205 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1208 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1209 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1210 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1212 //==========================================================================
1213 // Filesystem table entries
1215 // -------------------------------------------------------------------------
1217 // This defines the entry in the filesystem table.
1218 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1219 // we should never block in any filesystem operations.
1221 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1226 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1227 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1228 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1229 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1230 (cyg_fsop_link
*)cyg_fileio_erofs
,
1231 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1232 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1233 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1234 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1235 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1238 // -------------------------------------------------------------------------
1240 // This defines a single ROMFS loaded into ROM at the configured address
1242 // MTAB_ENTRY(rom_mte, // structure name
1243 // "/rom", // mount point
1244 // "romfs", // FIlesystem type
1245 // "", // hardware device
1246 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1250 // -------------------------------------------------------------------------
1252 // This set of file operations are used for normal open files.
1254 static cyg_fileops tftpfs_fileops
=
1255 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1256 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1257 tftpfs_fo_fsync
, tftpfs_fo_close
,
1258 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1259 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1260 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1262 // -------------------------------------------------------------------------
1264 // Process a mount request. This mainly finds root for the
1267 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1272 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1288 static void freeTftp(struct Tftp
*t
)
1301 static const int tftpMaxSize
= 8192 * 1024;
1302 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1303 int mode
, cyg_file
*file
)
1306 tftp
= malloc(sizeof(struct Tftp
));
1309 memset(tftp
, 0, sizeof(struct Tftp
));
1311 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1312 file
->f_type
= CYG_FILE_TYPE_FILE
;
1313 file
->f_ops
= &tftpfs_fileops
;
1318 tftp
->mem
= malloc(tftpMaxSize
);
1319 if (tftp
->mem
== NULL
)
1325 char *server
= strchr(name
, '/');
1332 tftp
->server
= malloc(server
- name
+ 1);
1333 if (tftp
->server
== NULL
)
1338 strncpy(tftp
->server
, name
, server
- name
);
1339 tftp
->server
[server
- name
] = 0;
1341 tftp
->port
= 0; /* default port 69 */
1343 port
= strchr(tftp
->server
, ':');
1346 tftp
->port
= atoi(port
+ 1);
1350 tftp
->file
= strdup(server
+ 1);
1351 if (tftp
->file
== NULL
)
1357 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1362 static int fetchTftp(struct Tftp
*tftp
)
1364 if (!tftp
->readFile
)
1367 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, tftp
->port
, tftp
->mem
,
1368 tftpMaxSize
, TFTP_OCTET
, &err
);
1370 if (tftp
->actual
< 0)
1379 // -------------------------------------------------------------------------
1380 // tftpfs_fo_write()
1381 // Read data from file.
1383 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1385 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1387 if (fetchTftp(tftp
) != ENOERR
)
1391 off_t pos
= fp
->f_offset
;
1393 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1395 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1396 char *buf
= (char *) iov
->iov_base
;
1397 off_t len
= iov
->iov_len
;
1399 if (len
+ pos
> tftp
->actual
)
1401 len
= tftp
->actual
- pos
;
1403 resid
+= iov
->iov_len
- len
;
1405 memcpy(buf
, tftp
->mem
+ pos
, len
);
1409 uio
->uio_resid
= resid
;
1415 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1417 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1420 off_t pos
= fp
->f_offset
;
1422 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1424 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1425 char *buf
= (char *) iov
->iov_base
;
1426 off_t len
= iov
->iov_len
;
1428 if (len
+ pos
> tftpMaxSize
)
1430 len
= tftpMaxSize
- pos
;
1432 resid
+= iov
->iov_len
- len
;
1434 memcpy(tftp
->mem
+ pos
, buf
, len
);
1438 uio
->uio_resid
= resid
;
1446 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1452 // -------------------------------------------------------------------------
1454 // Close a file. We just clear out the data pointer.
1456 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1458 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1463 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1464 TFTP_OCTET
, &error
);
1472 // -------------------------------------------------------------------------
1474 // Seek to a new file position.
1476 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1478 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1481 if (fetchTftp(tftp
) != ENOERR
)
1487 // Pos is already where we want to be.
1491 // Add pos to current offset.
1492 pos
+= fp
->f_offset
;
1496 // Add pos to file size.
1497 pos
+= tftp
->actual
;
1504 // Check that pos is still within current file size, or at the
1506 if (pos
< 0 || pos
> tftp
->actual
)
1509 // All OK, set fp offset and return new position.
1510 *apos
= fp
->f_offset
= pos
;
1518 cyg_thread_delay(us
/ 10000 + 1);
1524 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1526 cyg_httpd_start_chunked("text");
1527 if (logCount
>= logSize
)
1529 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1530 - logCount
% logSize
);
1532 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1533 cyg_httpd_end_chunked();
1537 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1539 // Filesystem operations
1540 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1541 static int logfs_umount(cyg_mtab_entry
*mte
);
1542 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1543 int mode
, cyg_file
*fte
);
1544 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1547 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1548 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1550 #include <cyg/io/devtab.h>
1552 //==========================================================================
1553 // Filesystem table entries
1555 // -------------------------------------------------------------------------
1557 // This defines the entry in the filesystem table.
1558 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1559 // we should never block in any filesystem operations.
1560 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1561 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1565 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1566 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1567 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1568 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1569 (cyg_fsop_link
*)cyg_fileio_erofs
,
1570 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1571 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1572 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1573 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1574 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1576 // -------------------------------------------------------------------------
1578 // This set of file operations are used for normal open files.
1580 static cyg_fileops logfs_fileops
=
1581 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1582 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1583 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1584 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1585 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1586 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1588 // -------------------------------------------------------------------------
1590 // Process a mount request. This mainly finds root for the
1593 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1598 static int logfs_umount(cyg_mtab_entry
*mte
)
1603 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1604 int mode
, cyg_file
*file
)
1606 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1607 file
->f_type
= CYG_FILE_TYPE_FILE
;
1608 file
->f_ops
= &logfs_fileops
;
1615 // -------------------------------------------------------------------------
1617 // Write data to file.
1619 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1622 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1624 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1625 char *buf
= (char *) iov
->iov_base
;
1626 off_t len
= iov
->iov_len
;
1628 diag_write(buf
, len
);
1634 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1639 // -------------------------------------------------------------------------
1641 // Close a file. We just clear out the data pointer.
1643 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1648 int loadFile(const char *fileName
, void **data
, int *len
);
1650 /* boolean parameter stored on config */
1651 int boolParam(char *var
)
1653 bool result
= false;
1654 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1660 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1664 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)