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 #include <cyg/hal/io.h>
66 #define ZY1000_SER_DEV "/dev/uart_0"
68 #define ZY1000_SER_DEV "/dev/ser0"
74 #if defined(CYGPKG_NET_FREEBSD_STACK)
75 #include <tftp_support.h>
76 /* posix compatibility broken*/
77 struct tftpd_fileops fileops
=
79 (int (*)(const char *, int))open
,
81 (int (*)(int, const void *, int))write
,
82 (int (*)(int, void *, int))read
88 void diag_write(char *buf
, int len
)
91 for (j
= 0; j
< len
; j
++)
93 diag_printf("%c", buf
[j
]);
97 static bool serialLog
= true;
98 static bool writeLog
= true;
103 extern struct flash_driver
*flash_drivers
[];
104 extern struct target_type
*target_types
[];
106 #ifdef CYGPKG_PROFILE_GPROF
107 #include <cyg/profile/profile.h>
109 extern char _stext
, _etext
; // Defined by the linker
111 static char *start_of_code
=&_stext
;
112 static char *end_of_code
=&_etext
;
114 void start_profile(void)
116 // This starts up the system-wide profiling, gathering
117 // profile information on all of the code, with a 16 byte
118 // "bucket" size, at a rate of 100us/profile hit.
119 // Note: a bucket size of 16 will give pretty good function
120 // resolution. Much smaller and the buffer becomes
121 // much too large for very little gain.
122 // Note: a timer period of 100us is also a reasonable
123 // compromise. Any smaller and the overhead of
124 // handling the timter (profile) interrupt could
125 // swamp the system. A fast processor might get
126 // by with a smaller value, but a slow one could
127 // even be swamped by this value. If the value is
128 // too large, the usefulness of the profile is reduced.
130 // no more interrupts than 1/10ms.
131 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
132 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
133 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
139 static char reboot_stack
[2048];
141 static void zylinjtag_reboot(cyg_addrword_t data
)
144 diag_printf("Rebooting in 500 ticks..\n");
145 cyg_thread_delay(500);
146 diag_printf("Unmounting /config..\n");
148 diag_printf("Rebooting..\n");
149 #ifdef CYGPKG_HAL_NIOS2
150 /* This will reboot & reconfigure the FPGA from the bootloader
153 IOWR(REMOTE_UPDATE_BASE
, 0x20, 0x1);
155 HAL_PLATFORM_RESET();
158 static cyg_thread zylinjtag_thread_object
;
159 static cyg_handle_t zylinjtag_thread_handle
;
163 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
164 (void *) reboot_stack
, sizeof(reboot_stack
),
165 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
166 cyg_thread_resume(zylinjtag_thread_handle
);
169 static char zylinjtag_reboot_port_stack
[2048];
170 static cyg_thread zylinjtag_reboot_port_thread_object
;
171 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
173 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
175 int so_reuseaddr_option
= 1;
178 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
180 LOG_ERROR("error creating socket: %s", strerror(errno
));
184 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
187 struct sockaddr_in sin
;
188 unsigned int address_size
;
189 address_size
= sizeof(sin
);
190 memset(&sin
, 0, sizeof(sin
));
191 sin
.sin_family
= AF_INET
;
192 sin
.sin_addr
.s_addr
= INADDR_ANY
;
193 sin
.sin_port
= htons(1234);
195 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
197 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
201 if (listen(fd
, 1) == -1)
203 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
206 // socket_nonblock(fd);
209 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
211 diag_printf("Got reboot signal on port 1234");
217 void reboot_port(void)
219 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
220 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
221 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
222 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
225 int configuration_output_handler(struct command_context
*context
,
228 diag_printf("%s", line
);
233 int zy1000_configuration_output_handler_log(struct command_context
*context
,
236 LOG_USER_N("%s", line
);
241 #ifdef CYGPKG_PROFILE_GPROF
242 //extern int64_t totaltime;
244 static int zylinjtag_Jim_Command_profile(Jim_Interp
*interp
, int argc
,
245 Jim_Obj
* const *argv
)
247 if ((argc
== 2) && (strcmp(Jim_GetString(argv
[1], NULL
), "stats")==0))
250 //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
253 LOG_USER("Profiling started");
262 externC
void phi_init_all_network_interfaces(void);
264 struct command_context
*cmd_ctx
;
266 static bool webRunning
= false;
268 void keep_webserver(void)
270 // Target initialisation is only attempted at startup, so we sleep forever and
271 // let the http server bail us out(i.e. get config files set up).
272 diag_printf("OpenOCD has invoked exit().\n"
273 "Use web server to correct any configuration settings and reboot.\n");
277 // exit() will terminate the current thread and we we'll then sleep eternally or
278 // we'll have a reboot scheduled.
281 extern void printDccChar(char c
);
283 static char logBuffer
[128 * 1024];
284 static const int logSize
= sizeof(logBuffer
);
288 void _zylinjtag_diag_write_char(char c
, void **param
)
292 logBuffer
[writePtr
] = c
;
293 writePtr
= (writePtr
+ 1) % logSize
;
300 HAL_DIAG_WRITE_CHAR('\r');
302 HAL_DIAG_WRITE_CHAR(c
);
305 #ifdef CYGPKG_HAL_ZYLIN_PHI
310 void copyfile(char *name2
, char *name1
);
312 void copydir(char *name
, char *destdir
);
315 MTAB_ENTRY(romfs_mte1
,
319 (CYG_ADDRWORD
) &filedata
[0]);
322 void openocd_sleep_prelude(void)
324 cyg_mutex_unlock(&httpstate
.jim_lock
);
327 void openocd_sleep_postlude(void)
329 cyg_mutex_lock(&httpstate
.jim_lock
);
334 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
335 diag_printf("Formatting JFFS2...\n");
337 cyg_io_handle_t handle
;
340 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
343 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
348 cyg_io_flash_getconfig_devsize_t ds
;
350 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
353 diag_printf("Flash error cyg_io_get_config %d\n", err
);
357 cyg_io_flash_getconfig_erase_t e
;
363 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
364 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
367 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
371 diag_printf("Flash formatted successfully\n");
377 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
378 Jim_Obj
* const *argv
)
390 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
391 Jim_Obj
* const *argv
)
393 cyg_handle_t thread
= 0;
395 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
397 /* Loop over the threads, and generate a table row for
400 while (cyg_thread_get_next(&thread
, &id
))
402 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
404 cyg_thread_info info
;
407 cyg_thread_get_info(thread
, id
, &info
);
409 if (info
.name
== NULL
)
410 info
.name
= "<no name>";
412 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
413 info
.name
, strlen(info
.name
)));
415 /* Translate the state into a string.
418 state_string
= "RUN";
419 else if (info
.state
& 0x04)
420 state_string
= "SUSP";
422 switch (info
.state
& 0x1b)
425 state_string
= "SLEEP";
428 state_string
= "CNTSLEEP";
431 state_string
= "CREATE";
434 state_string
= "EXIT";
437 state_string
= "????";
441 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
442 state_string
, strlen(state_string
)));
444 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
445 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
447 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
450 Jim_ListAppendElement(interp
, threads
, threadObj
);
452 Jim_SetResult(interp
, threads
);
457 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
458 Jim_Obj
* const *argv
)
460 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
462 if (logCount
>= logSize
)
464 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
465 % logSize
, logSize
- logCount
% logSize
);
467 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
469 Jim_SetResult(interp
, tclOutput
);
473 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
474 Jim_Obj
* const *argv
)
480 static void zylinjtag_startNetwork(void)
482 // Bring TCP/IP up immediately before we're ready to accept commands.
484 // That is as soon as a PING responds, we're accepting telnet sessions.
485 #if defined(CYGPKG_NET_FREEBSD_STACK)
486 phi_init_all_network_interfaces();
492 diag_printf("Network not up and running\n");
496 /* very first thing we want is a reboot capability */
499 #if defined(CYGPKG_NET_FREEBSD_STACK)
501 tftpd_start(69, &fileops
);
504 cyg_httpd_init_tcl_interpreter();
506 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
508 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
509 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
510 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
511 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
512 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
513 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
519 diag_printf("Web server running\n");
523 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
526 strcpy(ifr
.ifr_name
, "eth0");
528 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
533 diag_printf("Can't obtain MAC address\n");
538 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
544 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
547 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
552 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
557 char *infoStr
= "unknown";
560 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
561 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
562 infoStr
= "undefined instruction";
564 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
565 infoStr
= "software interrupt";
567 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
568 infoStr
= "abort prefetch";
570 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
571 infoStr
= "abort data";
578 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
580 diag_printf("Dumping log\n---\n");
581 if (logCount
>= logSize
)
583 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
585 diag_write(logBuffer
, writePtr
);
587 diag_printf("---\nLogdump complete.\n");
588 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
589 diag_printf("\n---\nRebooting\n");
590 HAL_PLATFORM_RESET();
594 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
595 static void setHandler(cyg_code_t exception
)
597 cyg_exception_handler_t
*old_handler
;
598 cyg_addrword_t old_data
;
600 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
601 &old_handler
, &old_data
);
605 static cyg_thread zylinjtag_uart_thread_object
;
606 static cyg_handle_t zylinjtag_uart_thread_handle
;
607 static char uart_stack
[4096];
609 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
610 static char backwardBuffer
[1024];
612 void setNoDelay(int session
, int flag
)
615 // This decreases latency dramatically for e.g. GDB load which
616 // does not have a sliding window protocol
618 // Can cause *lots* of TCP/IP packets to be sent and it would have
619 // to be enabled/disabled on the fly to avoid the CPU being
621 setsockopt(session
, /* socket affected */
622 IPPROTO_TCP
, /* set option at TCP level */
623 TCP_NODELAY
, /* name of option */
624 (char *) &flag
, /* the cast is historical
626 sizeof(int)); /* length of option value */
630 #define TEST_TCPIP() 0
639 } tcpipSent
[512 * 1024];
643 static void zylinjtag_uart(cyg_addrword_t data
)
645 int so_reuseaddr_option
= 1;
648 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
650 LOG_ERROR("error creating socket: %s", strerror(errno
));
654 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
657 struct sockaddr_in sin
;
658 unsigned int address_size
;
659 address_size
= sizeof(sin
);
660 memset(&sin
, 0, sizeof(sin
));
661 sin
.sin_family
= AF_INET
;
662 sin
.sin_addr
.s_addr
= INADDR_ANY
;
663 sin
.sin_port
= htons(5555);
665 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
667 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
671 if (listen(fd
, 1) == -1)
673 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
676 // socket_nonblock(fd);
681 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
687 setNoDelay(session
, 1);
688 int oldopts
= fcntl(session
, F_GETFL
, 0);
689 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
691 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
698 #ifdef CYGPKG_PROFILE_GPROF
716 FD_SET(session
, &read_fds
);
718 FD_SET(serHandle
, &read_fds
);
719 if (serHandle
> fd_max
)
725 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
726 if ((actual
== 0) && (actual2
== 0))
728 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
737 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
739 t
= read(serHandle
, backwardBuffer
,
740 sizeof(backwardBuffer
));
756 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
764 if (FD_ISSET(session
, &read_fds
)
765 && (sizeof(forwardBuffer
) > actual
))
767 // NB! Here it is important that we empty the TCP/IP read buffer
768 // to make transmission tick right
769 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
772 // this will block if there is no data at all
773 t
= read_socket(session
, forwardBuffer
+ actual
,
774 sizeof(forwardBuffer
) - actual
);
785 /* Do not put things into the serial buffer if it has something to send
786 * as that can cause a single byte to be sent at the time.
790 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
797 // The serial buffer is full
810 tcpipSent
[cur
].req
= x
;
811 tcpipSent
[cur
].actual
= y
;
812 tcpipSent
[cur
].req2
= x2
;
813 tcpipSent
[cur
].actual2
= y2
;
818 closeSession
: close(session
);
823 for (i
= 0; i
< 1024; i
++)
825 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
826 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
837 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
838 (void *) uart_stack
, sizeof(uart_stack
),
839 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
840 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
841 cyg_thread_resume(zylinjtag_uart_thread_handle
);
844 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
845 Jim_Obj
* const *argv
)
847 static int current_baud
= 38400;
850 Jim_SetResult(interp
, Jim_NewIntObj(interp
, current_baud
));
859 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
862 current_baud
= new_baudrate
;
865 switch (current_baud
)
868 baud
= CYGNUM_SERIAL_BAUD_9600
;
871 baud
= CYGNUM_SERIAL_BAUD_19200
;
874 baud
= CYGNUM_SERIAL_BAUD_38400
;
877 baud
= CYGNUM_SERIAL_BAUD_57600
;
880 baud
= CYGNUM_SERIAL_BAUD_115200
;
883 baud
= CYGNUM_SERIAL_BAUD_230400
;
886 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "unsupported baudrate", -1));
890 cyg_serial_info_t buf
;
892 //get existing serial configuration
893 len
= sizeof(cyg_serial_info_t
);
895 cyg_io_handle_t serial_handle
;
897 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
900 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Could not open serial port", -1));
904 err
= cyg_io_get_config(serial_handle
,
905 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
906 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
910 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to get serial port settings", -1));
915 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
919 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to set serial port settings", -1));
926 bool logAllToSerial
= false;
929 int boolParam(char *var
);
932 static const char *zylin_config_dir
="/config/settings";
934 static int add_default_dirs(void)
936 add_script_search_dir(zylin_config_dir
);
937 add_script_search_dir("/rom/lib/openocd");
938 add_script_search_dir("/rom");
942 int main(int argc
, char *argv
[])
944 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
945 * need to allocate towards the end of the heap. */
947 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
948 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
949 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
950 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
955 atexit(keep_webserver
);
957 diag_init_putc(_zylinjtag_diag_write_char
);
958 // We want this in the log.
959 #ifdef CYGPKG_HAL_NIOS2
960 diag_printf("Zylin ZY1000 PCB revc.\n");
962 diag_printf("Zylin ZY1000 PCB revb.\n");
965 err
= mount("", "/ram", "ramfs");
968 diag_printf("unable to mount ramfs\n");
973 sprintf(address
, "%p", &filedata
[0]);
974 err
= mount(address
, "/rom", "romfs");
977 diag_printf("unable to mount /rom\n");
980 err
= mount("", "/log", "logfs");
983 diag_printf("unable to mount logfs\n");
986 err
= mount("", "/tftp", "tftpfs");
989 diag_printf("unable to mount logfs\n");
992 log
= fopen("/log/log", "w");
995 diag_printf("Could not open log file /ram/log\n");
1000 copydir("/rom", "/ram/cgi");
1002 #ifdef CYGPKG_HAL_NIOS2
1003 cyg_flashaddr_t err_address
;
1004 #define UNCACHED_EXT_FLASH_BASE (0x80000000 + EXT_FLASH_BASE)
1005 /* The revc flash is locked upon reset, unlock it */
1006 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
1007 if ((err
= flash_unlock((void *) UNCACHED_EXT_FLASH_BASE
, EXT_FLASH_SPAN
,
1008 (void **) &err_address
)) != 0)
1010 diag_printf("Error: could not unlock flash\n");
1016 err
= mount("/dev/flash1", "/config", "jffs2");
1019 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1020 err
= mount("", "/config", "ramfs");
1023 diag_printf("unable to mount /config as ramdisk.\n");
1029 /* are we using a ram disk instead of a flash disk? This is used
1030 * for ZY1000 live demo...
1032 * copy over flash disk to ram block device
1034 if (boolParam("ramdisk"))
1036 diag_printf("Unmounting /config from flash and using ram instead\n");
1037 err
= umount("/config");
1040 diag_printf("unable to unmount jffs\n");
1044 err
= mount("/dev/flash1", "/config2", "jffs2");
1047 diag_printf("unable to mount jffs\n");
1051 err
= mount("", "/config", "ramfs");
1054 diag_printf("unable to mount ram block device\n");
1058 // copydir("/config2", "/config");
1059 copyfile("/config2/ip", "/config/ip");
1060 copydir("/config2/settings", "/config/settings");
1066 mkdir(zylin_config_dir
, 0777);
1067 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1068 mkdir(dirname
, 0777);
1070 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1071 mkdir(dirname
, 0777);
1073 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1074 mkdir(dirname
, 0777);
1077 logAllToSerial
= boolParam("logserial");
1079 // We need the network & web server in case there is something wrong with
1080 // the config files that invoke exit()
1081 zylinjtag_startNetwork();
1083 /* we're going to access the jim interpreter from here on... */
1084 openocd_sleep_postlude();
1089 /* initialize commandline interface */
1090 struct command_context
* cmd_ctx
;
1091 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1092 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1093 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1094 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1096 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1097 return EXIT_FAILURE
;
1099 #ifdef CYGPKG_PROFILE_GPROF
1100 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_profile", zylinjtag_Jim_Command_profile
,
1104 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
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");
1125 ret
= server_init(cmd_ctx
);
1126 if (ERROR_OK
!= ret
)
1127 return EXIT_FAILURE
;
1129 /* we MUST always run the init command as it will launch telnet sessions */
1130 command_run_line(cmd_ctx
, "init");
1133 // diag_printf() is really invoked from many more places than we trust it
1134 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1136 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1137 // fingers that it doesn't cause any crashes.
1138 diag_printf("Init complete, GDB & telnet servers launched.\n");
1139 command_set_output_handler(cmd_ctx
,
1140 zy1000_configuration_output_handler_log
, NULL
);
1141 if (!logAllToSerial
)
1146 /* handle network connections */
1147 server_loop(cmd_ctx
);
1148 openocd_sleep_prelude();
1150 /* shut server down */
1153 /* free commandline interface */
1154 command_done(cmd_ctx
);
1162 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1163 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1165 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1169 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1171 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1172 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1174 #include <pkgconf/system.h>
1175 #include <pkgconf/hal.h>
1176 #include <pkgconf/kernel.h>
1177 #include <pkgconf/io_fileio.h>
1178 #include <pkgconf/fs_rom.h>
1180 #include <cyg/kernel/ktypes.h> // base kernel types
1181 #include <cyg/infra/cyg_trac.h> // tracing macros
1182 #include <cyg/infra/cyg_ass.h> // assertion macros
1183 #include <cyg/fileio/fileio.h>
1184 #include <cyg/kernel/kapi.h>
1185 #include <cyg/infra/diag.h>
1187 //==========================================================================
1188 // Eventually we want to eXecute In Place from the ROM in a protected
1189 // environment, so we'll need executables to be aligned to a boundary
1190 // suitable for MMU protection. A suitable boundary would be the 4k
1191 // boundary in all the CPU architectures I am currently aware of.
1193 // Forward definitions
1195 // Filesystem operations
1196 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1197 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1198 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1199 int mode
, cyg_file
*fte
);
1200 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1201 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1204 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1205 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1206 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1208 //==========================================================================
1209 // Filesystem table entries
1211 // -------------------------------------------------------------------------
1213 // This defines the entry in the filesystem table.
1214 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1215 // we should never block in any filesystem operations.
1217 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1222 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1223 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1224 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1225 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1226 (cyg_fsop_link
*)cyg_fileio_erofs
,
1227 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1228 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1229 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1230 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1231 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1234 // -------------------------------------------------------------------------
1236 // This defines a single ROMFS loaded into ROM at the configured address
1238 // MTAB_ENTRY(rom_mte, // structure name
1239 // "/rom", // mount point
1240 // "romfs", // FIlesystem type
1241 // "", // hardware device
1242 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1246 // -------------------------------------------------------------------------
1248 // This set of file operations are used for normal open files.
1250 static cyg_fileops tftpfs_fileops
=
1251 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1252 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1253 tftpfs_fo_fsync
, tftpfs_fo_close
,
1254 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1255 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1256 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1258 // -------------------------------------------------------------------------
1260 // Process a mount request. This mainly finds root for the
1263 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1268 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1283 static void freeTftp(struct Tftp
*t
)
1296 static const int tftpMaxSize
= 8192 * 1024;
1297 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1298 int mode
, cyg_file
*file
)
1301 tftp
= malloc(sizeof(struct Tftp
));
1304 memset(tftp
, 0, sizeof(struct Tftp
));
1306 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1307 file
->f_type
= CYG_FILE_TYPE_FILE
;
1308 file
->f_ops
= &tftpfs_fileops
;
1313 tftp
->mem
= malloc(tftpMaxSize
);
1314 if (tftp
->mem
== NULL
)
1320 char *server
= strchr(name
, '/');
1327 tftp
->server
= malloc(server
- name
+ 1);
1328 if (tftp
->server
== NULL
)
1333 strncpy(tftp
->server
, name
, server
- name
);
1334 tftp
->server
[server
- name
] = 0;
1336 tftp
->file
= strdup(server
+ 1);
1337 if (tftp
->file
== NULL
)
1343 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1348 static int fetchTftp(struct Tftp
*tftp
)
1350 if (!tftp
->readFile
)
1353 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1354 tftpMaxSize
, TFTP_OCTET
, &err
);
1356 if (tftp
->actual
< 0)
1365 // -------------------------------------------------------------------------
1366 // tftpfs_fo_write()
1367 // Read data from file.
1369 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1371 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1373 if (fetchTftp(tftp
) != ENOERR
)
1377 off_t pos
= fp
->f_offset
;
1379 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1381 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1382 char *buf
= (char *) iov
->iov_base
;
1383 off_t len
= iov
->iov_len
;
1385 if (len
+ pos
> tftp
->actual
)
1387 len
= tftp
->actual
- pos
;
1389 resid
+= iov
->iov_len
- len
;
1391 memcpy(buf
, tftp
->mem
+ pos
, len
);
1395 uio
->uio_resid
= resid
;
1401 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1403 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1406 off_t pos
= fp
->f_offset
;
1408 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1410 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1411 char *buf
= (char *) iov
->iov_base
;
1412 off_t len
= iov
->iov_len
;
1414 if (len
+ pos
> tftpMaxSize
)
1416 len
= tftpMaxSize
- pos
;
1418 resid
+= iov
->iov_len
- len
;
1420 memcpy(tftp
->mem
+ pos
, buf
, len
);
1424 uio
->uio_resid
= resid
;
1432 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1438 // -------------------------------------------------------------------------
1440 // Close a file. We just clear out the data pointer.
1442 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1444 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1449 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1450 TFTP_OCTET
, &error
);
1458 // -------------------------------------------------------------------------
1460 // Seek to a new file position.
1462 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1464 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1467 if (fetchTftp(tftp
) != ENOERR
)
1473 // Pos is already where we want to be.
1477 // Add pos to current offset.
1478 pos
+= fp
->f_offset
;
1482 // Add pos to file size.
1483 pos
+= tftp
->actual
;
1490 // Check that pos is still within current file size, or at the
1492 if (pos
< 0 || pos
> tftp
->actual
)
1495 // All OK, set fp offset and return new position.
1496 *apos
= fp
->f_offset
= pos
;
1504 cyg_thread_delay(us
/ 10000 + 1);
1510 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1512 cyg_httpd_start_chunked("text");
1513 if (logCount
>= logSize
)
1515 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1516 - logCount
% logSize
);
1518 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1519 cyg_httpd_end_chunked();
1523 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1525 // Filesystem operations
1526 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1527 static int logfs_umount(cyg_mtab_entry
*mte
);
1528 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1529 int mode
, cyg_file
*fte
);
1530 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1533 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1534 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1536 #include <cyg/io/devtab.h>
1538 //==========================================================================
1539 // Filesystem table entries
1541 // -------------------------------------------------------------------------
1543 // This defines the entry in the filesystem table.
1544 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1545 // we should never block in any filesystem operations.
1546 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1547 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1551 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1552 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1553 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1554 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1555 (cyg_fsop_link
*)cyg_fileio_erofs
,
1556 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1557 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1558 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1559 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1560 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1562 // -------------------------------------------------------------------------
1564 // This set of file operations are used for normal open files.
1566 static cyg_fileops logfs_fileops
=
1567 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1568 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1569 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1570 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1571 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1572 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1574 // -------------------------------------------------------------------------
1576 // Process a mount request. This mainly finds root for the
1579 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1584 static int logfs_umount(cyg_mtab_entry
*mte
)
1589 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1590 int mode
, cyg_file
*file
)
1592 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1593 file
->f_type
= CYG_FILE_TYPE_FILE
;
1594 file
->f_ops
= &logfs_fileops
;
1601 // -------------------------------------------------------------------------
1603 // Write data to file.
1605 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1608 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1610 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1611 char *buf
= (char *) iov
->iov_base
;
1612 off_t len
= iov
->iov_len
;
1614 diag_write(buf
, len
);
1620 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1625 // -------------------------------------------------------------------------
1627 // Close a file. We just clear out the data pointer.
1629 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1634 int loadFile(const char *fileName
, void **data
, int *len
);
1636 /* boolean parameter stored on config */
1637 int boolParam(char *var
)
1639 bool result
= false;
1640 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1646 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1650 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)