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;
102 #ifdef CYGPKG_PROFILE_GPROF
103 #include <cyg/profile/profile.h>
105 extern char _stext
, _etext
; // Defined by the linker
107 static char *start_of_code
=&_stext
;
108 static char *end_of_code
=&_etext
;
110 void start_profile(void)
112 // This starts up the system-wide profiling, gathering
113 // profile information on all of the code, with a 16 byte
114 // "bucket" size, at a rate of 100us/profile hit.
115 // Note: a bucket size of 16 will give pretty good function
116 // resolution. Much smaller and the buffer becomes
117 // much too large for very little gain.
118 // Note: a timer period of 100us is also a reasonable
119 // compromise. Any smaller and the overhead of
120 // handling the timter (profile) interrupt could
121 // swamp the system. A fast processor might get
122 // by with a smaller value, but a slow one could
123 // even be swamped by this value. If the value is
124 // too large, the usefulness of the profile is reduced.
126 // no more interrupts than 1/10ms.
127 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
128 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
129 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
135 static char reboot_stack
[2048];
137 static void zylinjtag_reboot(cyg_addrword_t data
)
140 diag_printf("Rebooting in 500 ticks..\n");
141 cyg_thread_delay(500);
142 diag_printf("Unmounting /config..\n");
144 diag_printf("Rebooting..\n");
145 #ifdef CYGPKG_HAL_NIOS2
146 /* This will reboot & reconfigure the FPGA from the bootloader
149 IOWR(REMOTE_UPDATE_BASE
, 0x20, 0x1);
151 HAL_PLATFORM_RESET();
154 static cyg_thread zylinjtag_thread_object
;
155 static cyg_handle_t zylinjtag_thread_handle
;
159 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
160 (void *) reboot_stack
, sizeof(reboot_stack
),
161 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
162 cyg_thread_resume(zylinjtag_thread_handle
);
165 static char zylinjtag_reboot_port_stack
[2048];
166 static cyg_thread zylinjtag_reboot_port_thread_object
;
167 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
169 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
171 int so_reuseaddr_option
= 1;
174 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
176 LOG_ERROR("error creating socket: %s", strerror(errno
));
180 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
183 struct sockaddr_in sin
;
184 unsigned int address_size
;
185 address_size
= sizeof(sin
);
186 memset(&sin
, 0, sizeof(sin
));
187 sin
.sin_family
= AF_INET
;
188 sin
.sin_addr
.s_addr
= INADDR_ANY
;
189 sin
.sin_port
= htons(1234);
191 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
193 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
197 if (listen(fd
, 1) == -1)
199 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
202 // socket_nonblock(fd);
205 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
207 diag_printf("Got reboot signal on port 1234");
213 void reboot_port(void)
215 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
216 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
217 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
218 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
221 int configuration_output_handler(struct command_context
*context
,
224 diag_printf("%s", line
);
229 int zy1000_configuration_output_handler_log(struct command_context
*context
,
232 LOG_USER_N("%s", line
);
237 #ifdef CYGPKG_PROFILE_GPROF
238 //extern int64_t totaltime;
240 static int zylinjtag_Jim_Command_profile(Jim_Interp
*interp
, int argc
,
241 Jim_Obj
* const *argv
)
243 if ((argc
== 2) && (strcmp(Jim_GetString(argv
[1], NULL
), "stats")==0))
246 //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
249 LOG_USER("Profiling started");
258 externC
void phi_init_all_network_interfaces(void);
260 struct command_context
*cmd_ctx
;
262 static bool webRunning
= false;
264 void keep_webserver(void)
266 // Target initialisation is only attempted at startup, so we sleep forever and
267 // let the http server bail us out(i.e. get config files set up).
268 diag_printf("OpenOCD has invoked exit().\n"
269 "Use web server to correct any configuration settings and reboot.\n");
273 // exit() will terminate the current thread and we we'll then sleep eternally or
274 // we'll have a reboot scheduled.
277 extern void printDccChar(char c
);
279 static char logBuffer
[128 * 1024];
280 static const int logSize
= sizeof(logBuffer
);
284 void _zylinjtag_diag_write_char(char c
, void **param
)
288 logBuffer
[writePtr
] = c
;
289 writePtr
= (writePtr
+ 1) % logSize
;
296 HAL_DIAG_WRITE_CHAR('\r');
298 HAL_DIAG_WRITE_CHAR(c
);
301 #ifdef CYGPKG_HAL_ZYLIN_PHI
306 void copyfile(char *name2
, char *name1
);
308 void copydir(char *name
, char *destdir
);
311 MTAB_ENTRY(romfs_mte1
,
315 (CYG_ADDRWORD
) &filedata
[0]);
318 void openocd_sleep_prelude(void)
320 cyg_mutex_unlock(&httpstate
.jim_lock
);
323 void openocd_sleep_postlude(void)
325 cyg_mutex_lock(&httpstate
.jim_lock
);
330 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
331 diag_printf("Formatting JFFS2...\n");
333 cyg_io_handle_t handle
;
336 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
339 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
344 cyg_io_flash_getconfig_devsize_t ds
;
346 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
349 diag_printf("Flash error cyg_io_get_config %d\n", err
);
353 cyg_io_flash_getconfig_erase_t e
;
359 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
360 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
363 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
367 diag_printf("Flash formatted successfully\n");
373 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
374 Jim_Obj
* const *argv
)
386 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
387 Jim_Obj
* const *argv
)
389 cyg_handle_t thread
= 0;
391 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
393 /* Loop over the threads, and generate a table row for
396 while (cyg_thread_get_next(&thread
, &id
))
398 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
400 cyg_thread_info info
;
403 cyg_thread_get_info(thread
, id
, &info
);
405 if (info
.name
== NULL
)
406 info
.name
= "<no name>";
408 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
409 info
.name
, strlen(info
.name
)));
411 /* Translate the state into a string.
414 state_string
= "RUN";
415 else if (info
.state
& 0x04)
416 state_string
= "SUSP";
418 switch (info
.state
& 0x1b)
421 state_string
= "SLEEP";
424 state_string
= "CNTSLEEP";
427 state_string
= "CREATE";
430 state_string
= "EXIT";
433 state_string
= "????";
437 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
438 state_string
, strlen(state_string
)));
440 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
441 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
443 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
446 Jim_ListAppendElement(interp
, threads
, threadObj
);
448 Jim_SetResult(interp
, threads
);
453 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
454 Jim_Obj
* const *argv
)
456 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
458 if (logCount
>= logSize
)
460 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
461 % logSize
, logSize
- logCount
% logSize
);
463 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
465 Jim_SetResult(interp
, tclOutput
);
469 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
470 Jim_Obj
* const *argv
)
476 static void zylinjtag_startNetwork(void)
478 // Bring TCP/IP up immediately before we're ready to accept commands.
480 // That is as soon as a PING responds, we're accepting telnet sessions.
481 #if defined(CYGPKG_NET_FREEBSD_STACK)
482 phi_init_all_network_interfaces();
488 diag_printf("Network not up and running\n");
492 /* very first thing we want is a reboot capability */
495 #if defined(CYGPKG_NET_FREEBSD_STACK)
497 tftpd_start(69, &fileops
);
500 cyg_httpd_init_tcl_interpreter();
502 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
504 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
505 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
506 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
507 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
508 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
509 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
515 diag_printf("Web server running\n");
519 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
522 strcpy(ifr
.ifr_name
, "eth0");
524 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
529 diag_printf("Can't obtain MAC address\n");
534 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
535 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
536 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
537 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
538 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
543 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
548 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
553 char *infoStr
= "unknown";
556 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
557 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
558 infoStr
= "undefined instruction";
560 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
561 infoStr
= "software interrupt";
563 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
564 infoStr
= "abort prefetch";
566 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
567 infoStr
= "abort data";
574 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
576 diag_printf("Dumping log\n---\n");
577 if (logCount
>= logSize
)
579 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
581 diag_write(logBuffer
, writePtr
);
583 diag_printf("---\nLogdump complete.\n");
584 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
585 diag_printf("\n---\nRebooting\n");
586 HAL_PLATFORM_RESET();
590 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
591 static void setHandler(cyg_code_t exception
)
593 cyg_exception_handler_t
*old_handler
;
594 cyg_addrword_t old_data
;
596 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
597 &old_handler
, &old_data
);
601 static cyg_thread zylinjtag_uart_thread_object
;
602 static cyg_handle_t zylinjtag_uart_thread_handle
;
603 static char uart_stack
[4096];
605 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
606 static char backwardBuffer
[1024];
608 void setNoDelay(int session
, int flag
)
611 // This decreases latency dramatically for e.g. GDB load which
612 // does not have a sliding window protocol
614 // Can cause *lots* of TCP/IP packets to be sent and it would have
615 // to be enabled/disabled on the fly to avoid the CPU being
617 setsockopt(session
, /* socket affected */
618 IPPROTO_TCP
, /* set option at TCP level */
619 TCP_NODELAY
, /* name of option */
620 (char *) &flag
, /* the cast is historical
622 sizeof(int)); /* length of option value */
626 #define TEST_TCPIP() 0
635 } tcpipSent
[512 * 1024];
639 static void zylinjtag_uart(cyg_addrword_t data
)
641 int so_reuseaddr_option
= 1;
644 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
646 LOG_ERROR("error creating socket: %s", strerror(errno
));
650 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
653 struct sockaddr_in sin
;
654 unsigned int address_size
;
655 address_size
= sizeof(sin
);
656 memset(&sin
, 0, sizeof(sin
));
657 sin
.sin_family
= AF_INET
;
658 sin
.sin_addr
.s_addr
= INADDR_ANY
;
659 sin
.sin_port
= htons(5555);
661 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
663 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
667 if (listen(fd
, 1) == -1)
669 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
672 // socket_nonblock(fd);
677 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
683 setNoDelay(session
, 1);
684 int oldopts
= fcntl(session
, F_GETFL
, 0);
685 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
687 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
694 #ifdef CYGPKG_PROFILE_GPROF
712 FD_SET(session
, &read_fds
);
714 FD_SET(serHandle
, &read_fds
);
715 if (serHandle
> fd_max
)
721 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
722 if ((actual
== 0) && (actual2
== 0))
724 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
733 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
735 t
= read(serHandle
, backwardBuffer
,
736 sizeof(backwardBuffer
));
752 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
760 if (FD_ISSET(session
, &read_fds
)
761 && (sizeof(forwardBuffer
) > actual
))
763 // NB! Here it is important that we empty the TCP/IP read buffer
764 // to make transmission tick right
765 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
768 // this will block if there is no data at all
769 t
= read_socket(session
, forwardBuffer
+ actual
,
770 sizeof(forwardBuffer
) - actual
);
781 /* Do not put things into the serial buffer if it has something to send
782 * as that can cause a single byte to be sent at the time.
786 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
793 // The serial buffer is full
806 tcpipSent
[cur
].req
= x
;
807 tcpipSent
[cur
].actual
= y
;
808 tcpipSent
[cur
].req2
= x2
;
809 tcpipSent
[cur
].actual2
= y2
;
814 closeSession
: close(session
);
819 for (i
= 0; i
< 1024; i
++)
821 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
822 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
833 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
834 (void *) uart_stack
, sizeof(uart_stack
),
835 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
836 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
837 cyg_thread_resume(zylinjtag_uart_thread_handle
);
840 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
841 Jim_Obj
* const *argv
)
843 static int current_baud
= 38400;
846 Jim_SetResult(interp
, Jim_NewIntObj(interp
, current_baud
));
855 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
858 current_baud
= new_baudrate
;
861 switch (current_baud
)
864 baud
= CYGNUM_SERIAL_BAUD_9600
;
867 baud
= CYGNUM_SERIAL_BAUD_19200
;
870 baud
= CYGNUM_SERIAL_BAUD_38400
;
873 baud
= CYGNUM_SERIAL_BAUD_57600
;
876 baud
= CYGNUM_SERIAL_BAUD_115200
;
879 baud
= CYGNUM_SERIAL_BAUD_230400
;
882 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "unsupported baudrate", -1));
886 cyg_serial_info_t buf
;
888 //get existing serial configuration
889 len
= sizeof(cyg_serial_info_t
);
891 cyg_io_handle_t serial_handle
;
893 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
896 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Could not open serial port", -1));
900 err
= cyg_io_get_config(serial_handle
,
901 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
902 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
906 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to get serial port settings", -1));
911 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
915 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to set serial port settings", -1));
922 bool logAllToSerial
= false;
925 int boolParam(char *var
);
928 static const char *zylin_config_dir
="/config/settings";
930 static int add_default_dirs(void)
932 add_script_search_dir(zylin_config_dir
);
933 add_script_search_dir("/rom/lib/openocd");
934 add_script_search_dir("/rom");
938 int main(int argc
, char *argv
[])
940 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
941 * need to allocate towards the end of the heap. */
943 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
944 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
945 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
946 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
951 atexit(keep_webserver
);
953 diag_init_putc(_zylinjtag_diag_write_char
);
954 // We want this in the log.
955 #ifdef CYGPKG_HAL_NIOS2
956 diag_printf("Zylin ZY1000 PCB revc.\n");
958 diag_printf("Zylin ZY1000 PCB revb.\n");
961 err
= mount("", "/ram", "ramfs");
964 diag_printf("unable to mount ramfs\n");
969 sprintf(address
, "%p", &filedata
[0]);
970 err
= mount(address
, "/rom", "romfs");
973 diag_printf("unable to mount /rom\n");
976 err
= mount("", "/log", "logfs");
979 diag_printf("unable to mount logfs\n");
982 err
= mount("", "/tftp", "tftpfs");
985 diag_printf("unable to mount logfs\n");
988 log
= fopen("/log/log", "w");
991 diag_printf("Could not open log file /ram/log\n");
996 copydir("/rom", "/ram/cgi");
998 #ifdef CYGPKG_HAL_NIOS2
999 cyg_flashaddr_t err_address
;
1000 #define UNCACHED_EXT_FLASH_BASE (0x80000000 + EXT_FLASH_BASE)
1001 /* The revc flash is locked upon reset, unlock it */
1002 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
1003 if ((err
= flash_unlock((void *) UNCACHED_EXT_FLASH_BASE
, EXT_FLASH_SPAN
,
1004 (void **) &err_address
)) != 0)
1006 diag_printf("Error: could not unlock flash\n");
1012 err
= mount("/dev/flash1", "/config", "jffs2");
1015 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1016 err
= mount("", "/config", "ramfs");
1019 diag_printf("unable to mount /config as ramdisk.\n");
1025 /* are we using a ram disk instead of a flash disk? This is used
1026 * for ZY1000 live demo...
1028 * copy over flash disk to ram block device
1030 if (boolParam("ramdisk"))
1032 diag_printf("Unmounting /config from flash and using ram instead\n");
1033 err
= umount("/config");
1036 diag_printf("unable to unmount jffs\n");
1040 err
= mount("/dev/flash1", "/config2", "jffs2");
1043 diag_printf("unable to mount jffs\n");
1047 err
= mount("", "/config", "ramfs");
1050 diag_printf("unable to mount ram block device\n");
1054 // copydir("/config2", "/config");
1055 copyfile("/config2/ip", "/config/ip");
1056 copydir("/config2/settings", "/config/settings");
1062 mkdir(zylin_config_dir
, 0777);
1063 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1064 mkdir(dirname
, 0777);
1066 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1067 mkdir(dirname
, 0777);
1069 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1070 mkdir(dirname
, 0777);
1073 logAllToSerial
= boolParam("logserial");
1075 // We need the network & web server in case there is something wrong with
1076 // the config files that invoke exit()
1077 zylinjtag_startNetwork();
1079 /* we're going to access the jim interpreter from here on... */
1080 openocd_sleep_postlude();
1085 /* initialize commandline interface */
1086 struct command_context
* cmd_ctx
;
1087 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1088 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1089 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1090 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1092 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1093 return EXIT_FAILURE
;
1095 #ifdef CYGPKG_PROFILE_GPROF
1096 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_profile", zylinjtag_Jim_Command_profile
,
1100 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1105 set_log_output(cmd_ctx
, log
);
1107 LOG_DEBUG("log init complete");
1109 // diag_printf("Executing config files\n");
1114 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1115 command_run_line(cmd_ctx
, "debug_level 3");
1118 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1121 ret
= server_init(cmd_ctx
);
1122 if (ERROR_OK
!= ret
)
1123 return EXIT_FAILURE
;
1125 /* we MUST always run the init command as it will launch telnet sessions */
1126 command_run_line(cmd_ctx
, "init");
1129 // diag_printf() is really invoked from many more places than we trust it
1130 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1132 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1133 // fingers that it doesn't cause any crashes.
1134 diag_printf("Init complete, GDB & telnet servers launched.\n");
1135 command_set_output_handler(cmd_ctx
,
1136 zy1000_configuration_output_handler_log
, NULL
);
1137 if (!logAllToSerial
)
1142 /* handle network connections */
1143 server_loop(cmd_ctx
);
1144 openocd_sleep_prelude();
1146 /* shut server down */
1149 /* free commandline interface */
1150 command_done(cmd_ctx
);
1158 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1159 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1161 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1165 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1167 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1168 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1170 #include <pkgconf/system.h>
1171 #include <pkgconf/hal.h>
1172 #include <pkgconf/kernel.h>
1173 #include <pkgconf/io_fileio.h>
1174 #include <pkgconf/fs_rom.h>
1176 #include <cyg/kernel/ktypes.h> // base kernel types
1177 #include <cyg/infra/cyg_trac.h> // tracing macros
1178 #include <cyg/infra/cyg_ass.h> // assertion macros
1179 #include <cyg/fileio/fileio.h>
1180 #include <cyg/kernel/kapi.h>
1181 #include <cyg/infra/diag.h>
1183 //==========================================================================
1184 // Eventually we want to eXecute In Place from the ROM in a protected
1185 // environment, so we'll need executables to be aligned to a boundary
1186 // suitable for MMU protection. A suitable boundary would be the 4k
1187 // boundary in all the CPU architectures I am currently aware of.
1189 // Forward definitions
1191 // Filesystem operations
1192 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1193 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1194 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1195 int mode
, cyg_file
*fte
);
1196 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1197 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1200 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1201 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1202 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1204 //==========================================================================
1205 // Filesystem table entries
1207 // -------------------------------------------------------------------------
1209 // This defines the entry in the filesystem table.
1210 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1211 // we should never block in any filesystem operations.
1213 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1218 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1219 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1220 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1221 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1222 (cyg_fsop_link
*)cyg_fileio_erofs
,
1223 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1224 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1225 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1226 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1227 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1230 // -------------------------------------------------------------------------
1232 // This defines a single ROMFS loaded into ROM at the configured address
1234 // MTAB_ENTRY(rom_mte, // structure name
1235 // "/rom", // mount point
1236 // "romfs", // FIlesystem type
1237 // "", // hardware device
1238 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1242 // -------------------------------------------------------------------------
1244 // This set of file operations are used for normal open files.
1246 static cyg_fileops tftpfs_fileops
=
1247 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1248 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1249 tftpfs_fo_fsync
, tftpfs_fo_close
,
1250 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1251 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1252 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1254 // -------------------------------------------------------------------------
1256 // Process a mount request. This mainly finds root for the
1259 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1264 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1279 static void freeTftp(struct Tftp
*t
)
1292 static const int tftpMaxSize
= 8192 * 1024;
1293 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1294 int mode
, cyg_file
*file
)
1297 tftp
= malloc(sizeof(struct Tftp
));
1300 memset(tftp
, 0, sizeof(struct Tftp
));
1302 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1303 file
->f_type
= CYG_FILE_TYPE_FILE
;
1304 file
->f_ops
= &tftpfs_fileops
;
1309 tftp
->mem
= malloc(tftpMaxSize
);
1310 if (tftp
->mem
== NULL
)
1316 char *server
= strchr(name
, '/');
1323 tftp
->server
= malloc(server
- name
+ 1);
1324 if (tftp
->server
== NULL
)
1329 strncpy(tftp
->server
, name
, server
- name
);
1330 tftp
->server
[server
- name
] = 0;
1332 tftp
->file
= strdup(server
+ 1);
1333 if (tftp
->file
== NULL
)
1339 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1344 static int fetchTftp(struct Tftp
*tftp
)
1346 if (!tftp
->readFile
)
1349 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1350 tftpMaxSize
, TFTP_OCTET
, &err
);
1352 if (tftp
->actual
< 0)
1361 // -------------------------------------------------------------------------
1362 // tftpfs_fo_write()
1363 // Read data from file.
1365 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1367 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1369 if (fetchTftp(tftp
) != ENOERR
)
1373 off_t pos
= fp
->f_offset
;
1375 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1377 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1378 char *buf
= (char *) iov
->iov_base
;
1379 off_t len
= iov
->iov_len
;
1381 if (len
+ pos
> tftp
->actual
)
1383 len
= tftp
->actual
- pos
;
1385 resid
+= iov
->iov_len
- len
;
1387 memcpy(buf
, tftp
->mem
+ pos
, len
);
1391 uio
->uio_resid
= resid
;
1397 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1399 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1402 off_t pos
= fp
->f_offset
;
1404 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1406 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1407 char *buf
= (char *) iov
->iov_base
;
1408 off_t len
= iov
->iov_len
;
1410 if (len
+ pos
> tftpMaxSize
)
1412 len
= tftpMaxSize
- pos
;
1414 resid
+= iov
->iov_len
- len
;
1416 memcpy(tftp
->mem
+ pos
, buf
, len
);
1420 uio
->uio_resid
= resid
;
1428 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1434 // -------------------------------------------------------------------------
1436 // Close a file. We just clear out the data pointer.
1438 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1440 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1445 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1446 TFTP_OCTET
, &error
);
1454 // -------------------------------------------------------------------------
1456 // Seek to a new file position.
1458 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1460 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1463 if (fetchTftp(tftp
) != ENOERR
)
1469 // Pos is already where we want to be.
1473 // Add pos to current offset.
1474 pos
+= fp
->f_offset
;
1478 // Add pos to file size.
1479 pos
+= tftp
->actual
;
1486 // Check that pos is still within current file size, or at the
1488 if (pos
< 0 || pos
> tftp
->actual
)
1491 // All OK, set fp offset and return new position.
1492 *apos
= fp
->f_offset
= pos
;
1500 cyg_thread_delay(us
/ 10000 + 1);
1506 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1508 cyg_httpd_start_chunked("text");
1509 if (logCount
>= logSize
)
1511 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1512 - logCount
% logSize
);
1514 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1515 cyg_httpd_end_chunked();
1519 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1521 // Filesystem operations
1522 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1523 static int logfs_umount(cyg_mtab_entry
*mte
);
1524 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1525 int mode
, cyg_file
*fte
);
1526 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1529 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1530 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1532 #include <cyg/io/devtab.h>
1534 //==========================================================================
1535 // Filesystem table entries
1537 // -------------------------------------------------------------------------
1539 // This defines the entry in the filesystem table.
1540 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1541 // we should never block in any filesystem operations.
1542 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1543 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1547 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1548 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1549 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1550 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1551 (cyg_fsop_link
*)cyg_fileio_erofs
,
1552 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1553 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1554 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1555 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1556 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1558 // -------------------------------------------------------------------------
1560 // This set of file operations are used for normal open files.
1562 static cyg_fileops logfs_fileops
=
1563 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1564 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1565 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1566 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1567 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1568 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1570 // -------------------------------------------------------------------------
1572 // Process a mount request. This mainly finds root for the
1575 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1580 static int logfs_umount(cyg_mtab_entry
*mte
)
1585 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1586 int mode
, cyg_file
*file
)
1588 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1589 file
->f_type
= CYG_FILE_TYPE_FILE
;
1590 file
->f_ops
= &logfs_fileops
;
1597 // -------------------------------------------------------------------------
1599 // Write data to file.
1601 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1604 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1606 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1607 char *buf
= (char *) iov
->iov_base
;
1608 off_t len
= iov
->iov_len
;
1610 diag_write(buf
, len
);
1616 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1621 // -------------------------------------------------------------------------
1623 // Close a file. We just clear out the data pointer.
1625 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1630 int loadFile(const char *fileName
, void **data
, int *len
);
1632 /* boolean parameter stored on config */
1633 int boolParam(char *var
)
1635 bool result
= false;
1636 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1642 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1646 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)