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
[];
105 #ifdef CYGPKG_PROFILE_GPROF
106 #include <cyg/profile/profile.h>
108 extern char _stext
, _etext
; // Defined by the linker
110 static char *start_of_code
=&_stext
;
111 static char *end_of_code
=&_etext
;
113 void start_profile(void)
115 // This starts up the system-wide profiling, gathering
116 // profile information on all of the code, with a 16 byte
117 // "bucket" size, at a rate of 100us/profile hit.
118 // Note: a bucket size of 16 will give pretty good function
119 // resolution. Much smaller and the buffer becomes
120 // much too large for very little gain.
121 // Note: a timer period of 100us is also a reasonable
122 // compromise. Any smaller and the overhead of
123 // handling the timter (profile) interrupt could
124 // swamp the system. A fast processor might get
125 // by with a smaller value, but a slow one could
126 // even be swamped by this value. If the value is
127 // too large, the usefulness of the profile is reduced.
129 // no more interrupts than 1/10ms.
130 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
131 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
132 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
138 static char reboot_stack
[2048];
140 static void zylinjtag_reboot(cyg_addrword_t data
)
143 diag_printf("Rebooting in 500 ticks..\n");
144 cyg_thread_delay(500);
145 diag_printf("Unmounting /config..\n");
147 diag_printf("Rebooting..\n");
148 #ifdef CYGPKG_HAL_NIOS2
149 /* This will reboot & reconfigure the FPGA from the bootloader
152 IOWR(REMOTE_UPDATE_BASE
, 0x20, 0x1);
154 HAL_PLATFORM_RESET();
157 static cyg_thread zylinjtag_thread_object
;
158 static cyg_handle_t zylinjtag_thread_handle
;
162 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
163 (void *) reboot_stack
, sizeof(reboot_stack
),
164 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
165 cyg_thread_resume(zylinjtag_thread_handle
);
168 static char zylinjtag_reboot_port_stack
[2048];
169 static cyg_thread zylinjtag_reboot_port_thread_object
;
170 static cyg_handle_t zylinjtag_reboot_port_thread_handle
;
172 static void zylinjtag_reboot_port_task(cyg_addrword_t data
)
174 int so_reuseaddr_option
= 1;
177 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
179 LOG_ERROR("error creating socket: %s", strerror(errno
));
183 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
186 struct sockaddr_in sin
;
187 unsigned int address_size
;
188 address_size
= sizeof(sin
);
189 memset(&sin
, 0, sizeof(sin
));
190 sin
.sin_family
= AF_INET
;
191 sin
.sin_addr
.s_addr
= INADDR_ANY
;
192 sin
.sin_port
= htons(1234);
194 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
196 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
200 if (listen(fd
, 1) == -1)
202 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
205 // socket_nonblock(fd);
208 accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
210 diag_printf("Got reboot signal on port 1234");
216 void reboot_port(void)
218 cyg_thread_create(1, zylinjtag_reboot_port_task
, (cyg_addrword_t
) 0, "wait for reboot signal on port 1234",
219 (void *) zylinjtag_reboot_port_stack
, sizeof(zylinjtag_reboot_port_stack
),
220 &zylinjtag_reboot_port_thread_handle
, &zylinjtag_reboot_port_thread_object
);
221 cyg_thread_resume(zylinjtag_reboot_port_thread_handle
);
224 int configuration_output_handler(struct command_context
*context
,
227 diag_printf("%s", line
);
232 int zy1000_configuration_output_handler_log(struct command_context
*context
,
235 LOG_USER_N("%s", line
);
240 #ifdef CYGPKG_PROFILE_GPROF
241 //extern int64_t totaltime;
243 static int zylinjtag_Jim_Command_profile(Jim_Interp
*interp
, int argc
,
244 Jim_Obj
* const *argv
)
246 if ((argc
== 2) && (strcmp(Jim_GetString(argv
[1], NULL
), "stats")==0))
249 //LOG_USER("Stats %dms sleeping in select()", (int)totaltime);
252 LOG_USER("Profiling started");
261 externC
void phi_init_all_network_interfaces(void);
263 struct command_context
*cmd_ctx
;
265 static bool webRunning
= false;
267 void keep_webserver(void)
269 // Target initialisation is only attempted at startup, so we sleep forever and
270 // let the http server bail us out(i.e. get config files set up).
271 diag_printf("OpenOCD has invoked exit().\n"
272 "Use web server to correct any configuration settings and reboot.\n");
276 // exit() will terminate the current thread and we we'll then sleep eternally or
277 // we'll have a reboot scheduled.
280 extern void printDccChar(char c
);
282 static char logBuffer
[128 * 1024];
283 static const int logSize
= sizeof(logBuffer
);
287 void _zylinjtag_diag_write_char(char c
, void **param
)
291 logBuffer
[writePtr
] = c
;
292 writePtr
= (writePtr
+ 1) % logSize
;
299 HAL_DIAG_WRITE_CHAR('\r');
301 HAL_DIAG_WRITE_CHAR(c
);
304 #ifdef CYGPKG_HAL_ZYLIN_PHI
309 void copyfile(char *name2
, char *name1
);
311 void copydir(char *name
, char *destdir
);
314 MTAB_ENTRY(romfs_mte1
,
318 (CYG_ADDRWORD
) &filedata
[0]);
321 void openocd_sleep_prelude(void)
323 cyg_mutex_unlock(&httpstate
.jim_lock
);
326 void openocd_sleep_postlude(void)
328 cyg_mutex_lock(&httpstate
.jim_lock
);
333 #ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
334 diag_printf("Formatting JFFS2...\n");
336 cyg_io_handle_t handle
;
339 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
342 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
347 cyg_io_flash_getconfig_devsize_t ds
;
349 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
352 diag_printf("Flash error cyg_io_get_config %d\n", err
);
356 cyg_io_flash_getconfig_erase_t e
;
362 diag_printf("Formatting 0x%08x bytes\n", (int)ds
.dev_size
);
363 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
366 diag_printf("Flash erase error %d offset 0x%08x\n", err
, e
.err_address
);
370 diag_printf("Flash formatted successfully\n");
376 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
377 Jim_Obj
* const *argv
)
389 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
390 Jim_Obj
* const *argv
)
392 cyg_handle_t thread
= 0;
394 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
396 /* Loop over the threads, and generate a table row for
399 while (cyg_thread_get_next(&thread
, &id
))
401 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
403 cyg_thread_info info
;
406 cyg_thread_get_info(thread
, id
, &info
);
408 if (info
.name
== NULL
)
409 info
.name
= "<no name>";
411 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
412 info
.name
, strlen(info
.name
)));
414 /* Translate the state into a string.
417 state_string
= "RUN";
418 else if (info
.state
& 0x04)
419 state_string
= "SUSP";
421 switch (info
.state
& 0x1b)
424 state_string
= "SLEEP";
427 state_string
= "CNTSLEEP";
430 state_string
= "CREATE";
433 state_string
= "EXIT";
436 state_string
= "????";
440 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
441 state_string
, strlen(state_string
)));
443 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
444 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
446 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
449 Jim_ListAppendElement(interp
, threads
, threadObj
);
451 Jim_SetResult(interp
, threads
);
456 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
457 Jim_Obj
* const *argv
)
459 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
461 if (logCount
>= logSize
)
463 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
464 % logSize
, logSize
- logCount
% logSize
);
466 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
468 Jim_SetResult(interp
, tclOutput
);
472 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
473 Jim_Obj
* const *argv
)
479 static void zylinjtag_startNetwork(void)
481 // Bring TCP/IP up immediately before we're ready to accept commands.
483 // That is as soon as a PING responds, we're accepting telnet sessions.
484 #if defined(CYGPKG_NET_FREEBSD_STACK)
485 phi_init_all_network_interfaces();
491 diag_printf("Network not up and running\n");
495 /* very first thing we want is a reboot capability */
498 #if defined(CYGPKG_NET_FREEBSD_STACK)
500 tftpd_start(69, &fileops
);
503 cyg_httpd_init_tcl_interpreter();
505 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
507 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_reboot",
508 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
509 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
510 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
511 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
512 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
518 diag_printf("Web server running\n");
522 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
525 strcpy(ifr
.ifr_name
, "eth0");
527 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
532 diag_printf("Can't obtain MAC address\n");
537 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
538 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
539 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
540 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
541 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
542 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
543 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
546 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
551 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
556 char *infoStr
= "unknown";
559 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
560 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
561 infoStr
= "undefined instruction";
563 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
564 infoStr
= "software interrupt";
566 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
567 infoStr
= "abort prefetch";
569 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
570 infoStr
= "abort data";
577 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
579 diag_printf("Dumping log\n---\n");
580 if (logCount
>= logSize
)
582 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
584 diag_write(logBuffer
, writePtr
);
586 diag_printf("---\nLogdump complete.\n");
587 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
588 diag_printf("\n---\nRebooting\n");
589 HAL_PLATFORM_RESET();
593 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
594 static void setHandler(cyg_code_t exception
)
596 cyg_exception_handler_t
*old_handler
;
597 cyg_addrword_t old_data
;
599 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
600 &old_handler
, &old_data
);
604 static cyg_thread zylinjtag_uart_thread_object
;
605 static cyg_handle_t zylinjtag_uart_thread_handle
;
606 static char uart_stack
[4096];
608 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
609 static char backwardBuffer
[1024];
611 void setNoDelay(int session
, int flag
)
614 // This decreases latency dramatically for e.g. GDB load which
615 // does not have a sliding window protocol
617 // Can cause *lots* of TCP/IP packets to be sent and it would have
618 // to be enabled/disabled on the fly to avoid the CPU being
620 setsockopt(session
, /* socket affected */
621 IPPROTO_TCP
, /* set option at TCP level */
622 TCP_NODELAY
, /* name of option */
623 (char *) &flag
, /* the cast is historical
625 sizeof(int)); /* length of option value */
629 #define TEST_TCPIP() 0
638 } tcpipSent
[512 * 1024];
642 static void zylinjtag_uart(cyg_addrword_t data
)
644 int so_reuseaddr_option
= 1;
647 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
649 LOG_ERROR("error creating socket: %s", strerror(errno
));
653 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
656 struct sockaddr_in sin
;
657 unsigned int address_size
;
658 address_size
= sizeof(sin
);
659 memset(&sin
, 0, sizeof(sin
));
660 sin
.sin_family
= AF_INET
;
661 sin
.sin_addr
.s_addr
= INADDR_ANY
;
662 sin
.sin_port
= htons(5555);
664 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
666 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
670 if (listen(fd
, 1) == -1)
672 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
675 // socket_nonblock(fd);
680 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
686 setNoDelay(session
, 1);
687 int oldopts
= fcntl(session
, F_GETFL
, 0);
688 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
690 int serHandle
= open(ZY1000_SER_DEV
, O_RDWR
| O_NONBLOCK
);
697 #ifdef CYGPKG_PROFILE_GPROF
715 FD_SET(session
, &read_fds
);
717 FD_SET(serHandle
, &read_fds
);
718 if (serHandle
> fd_max
)
724 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
725 if ((actual
== 0) && (actual2
== 0))
727 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
736 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
738 t
= read(serHandle
, backwardBuffer
,
739 sizeof(backwardBuffer
));
755 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
763 if (FD_ISSET(session
, &read_fds
)
764 && (sizeof(forwardBuffer
) > actual
))
766 // NB! Here it is important that we empty the TCP/IP read buffer
767 // to make transmission tick right
768 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
771 // this will block if there is no data at all
772 t
= read_socket(session
, forwardBuffer
+ actual
,
773 sizeof(forwardBuffer
) - actual
);
784 /* Do not put things into the serial buffer if it has something to send
785 * as that can cause a single byte to be sent at the time.
789 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
796 // The serial buffer is full
809 tcpipSent
[cur
].req
= x
;
810 tcpipSent
[cur
].actual
= y
;
811 tcpipSent
[cur
].req2
= x2
;
812 tcpipSent
[cur
].actual2
= y2
;
817 closeSession
: close(session
);
822 for (i
= 0; i
< 1024; i
++)
824 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
825 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
836 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
837 (void *) uart_stack
, sizeof(uart_stack
),
838 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
839 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
840 cyg_thread_resume(zylinjtag_uart_thread_handle
);
843 static int zylinjtag_Jim_Command_uart(Jim_Interp
*interp
, int argc
,
844 Jim_Obj
* const *argv
)
846 static int current_baud
= 38400;
849 Jim_SetResult(interp
, Jim_NewIntObj(interp
, current_baud
));
858 if (Jim_GetLong(interp
, argv
[1], &new_baudrate
) != JIM_OK
)
861 current_baud
= new_baudrate
;
864 switch (current_baud
)
867 baud
= CYGNUM_SERIAL_BAUD_9600
;
870 baud
= CYGNUM_SERIAL_BAUD_19200
;
873 baud
= CYGNUM_SERIAL_BAUD_38400
;
876 baud
= CYGNUM_SERIAL_BAUD_57600
;
879 baud
= CYGNUM_SERIAL_BAUD_115200
;
882 baud
= CYGNUM_SERIAL_BAUD_230400
;
885 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "unsupported baudrate", -1));
889 cyg_serial_info_t buf
;
891 //get existing serial configuration
892 len
= sizeof(cyg_serial_info_t
);
894 cyg_io_handle_t serial_handle
;
896 err
= cyg_io_lookup(ZY1000_SER_DEV
, &serial_handle
);
899 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Could not open serial port", -1));
903 err
= cyg_io_get_config(serial_handle
,
904 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
905 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
909 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to get serial port settings", -1));
914 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
918 Jim_SetResult(interp
, Jim_NewStringObj(interp
, "Failed to set serial port settings", -1));
925 bool logAllToSerial
= false;
928 int boolParam(char *var
);
931 static const char *zylin_config_dir
="/config/settings";
933 static int add_default_dirs(void)
935 add_script_search_dir(zylin_config_dir
);
936 add_script_search_dir("/rom/lib/openocd");
937 add_script_search_dir("/rom");
941 int main(int argc
, char *argv
[])
943 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
944 * need to allocate towards the end of the heap. */
946 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
947 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
948 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
949 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
954 atexit(keep_webserver
);
956 diag_init_putc(_zylinjtag_diag_write_char
);
957 // We want this in the log.
958 #ifdef CYGPKG_HAL_NIOS2
959 diag_printf("Zylin ZY1000 PCB revc.\n");
961 diag_printf("Zylin ZY1000 PCB revb.\n");
964 err
= mount("", "/ram", "ramfs");
967 diag_printf("unable to mount ramfs\n");
972 sprintf(address
, "%p", &filedata
[0]);
973 err
= mount(address
, "/rom", "romfs");
976 diag_printf("unable to mount /rom\n");
979 err
= mount("", "/log", "logfs");
982 diag_printf("unable to mount logfs\n");
985 err
= mount("", "/tftp", "tftpfs");
988 diag_printf("unable to mount logfs\n");
991 log
= fopen("/log/log", "w");
994 diag_printf("Could not open log file /ram/log\n");
999 copydir("/rom", "/ram/cgi");
1001 #ifdef CYGPKG_HAL_NIOS2
1002 cyg_flashaddr_t err_address
;
1003 #define UNCACHED_EXT_FLASH_BASE (0x80000000 + EXT_FLASH_BASE)
1004 /* The revc flash is locked upon reset, unlock it */
1005 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
1006 if ((err
= flash_unlock((void *) UNCACHED_EXT_FLASH_BASE
, EXT_FLASH_SPAN
,
1007 (void **) &err_address
)) != 0)
1009 diag_printf("Error: could not unlock flash\n");
1015 err
= mount("/dev/flash1", "/config", "jffs2");
1018 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1019 err
= mount("", "/config", "ramfs");
1022 diag_printf("unable to mount /config as ramdisk.\n");
1028 /* are we using a ram disk instead of a flash disk? This is used
1029 * for ZY1000 live demo...
1031 * copy over flash disk to ram block device
1033 if (boolParam("ramdisk"))
1035 diag_printf("Unmounting /config from flash and using ram instead\n");
1036 err
= umount("/config");
1039 diag_printf("unable to unmount jffs\n");
1043 err
= mount("/dev/flash1", "/config2", "jffs2");
1046 diag_printf("unable to mount jffs\n");
1050 err
= mount("", "/config", "ramfs");
1053 diag_printf("unable to mount ram block device\n");
1057 // copydir("/config2", "/config");
1058 copyfile("/config2/ip", "/config/ip");
1059 copydir("/config2/settings", "/config/settings");
1065 mkdir(zylin_config_dir
, 0777);
1066 char *dirname
= alloc_printf("%s/target", zylin_config_dir
);
1067 mkdir(dirname
, 0777);
1069 dirname
= alloc_printf("%s/board", zylin_config_dir
);
1070 mkdir(dirname
, 0777);
1072 dirname
= alloc_printf("%s/event", zylin_config_dir
);
1073 mkdir(dirname
, 0777);
1076 logAllToSerial
= boolParam("logserial");
1078 // We need the network & web server in case there is something wrong with
1079 // the config files that invoke exit()
1080 zylinjtag_startNetwork();
1082 /* we're going to access the jim interpreter from here on... */
1083 openocd_sleep_postlude();
1088 /* initialize commandline interface */
1089 struct command_context
* cmd_ctx
;
1090 struct command_context
*setup_command_handler(Jim_Interp
*interp
);
1091 cmd_ctx
= setup_command_handler(httpstate
.jim_interp
);
1092 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1093 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1095 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1096 return EXIT_FAILURE
;
1098 #ifdef CYGPKG_PROFILE_GPROF
1099 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_profile", zylinjtag_Jim_Command_profile
,
1103 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_uart", zylinjtag_Jim_Command_uart
, NULL
, NULL
);
1108 set_log_output(cmd_ctx
, log
);
1110 LOG_DEBUG("log init complete");
1112 // diag_printf("Executing config files\n");
1117 "%s/logserial = 1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1118 command_run_line(cmd_ctx
, "debug_level 3");
1121 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1124 ret
= server_init(cmd_ctx
);
1125 if (ERROR_OK
!= ret
)
1126 return EXIT_FAILURE
;
1128 /* we MUST always run the init command as it will launch telnet sessions */
1129 command_run_line(cmd_ctx
, "init");
1132 // diag_printf() is really invoked from many more places than we trust it
1133 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1135 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1136 // fingers that it doesn't cause any crashes.
1137 diag_printf("Init complete, GDB & telnet servers launched.\n");
1138 command_set_output_handler(cmd_ctx
,
1139 zy1000_configuration_output_handler_log
, NULL
);
1140 if (!logAllToSerial
)
1145 /* handle network connections */
1146 server_loop(cmd_ctx
);
1147 openocd_sleep_prelude();
1149 /* shut server down */
1152 /* free commandline interface */
1153 command_done(cmd_ctx
);
1161 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1162 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1164 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1168 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1170 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1171 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1173 #include <pkgconf/system.h>
1174 #include <pkgconf/hal.h>
1175 #include <pkgconf/kernel.h>
1176 #include <pkgconf/io_fileio.h>
1177 #include <pkgconf/fs_rom.h>
1179 #include <cyg/kernel/ktypes.h> // base kernel types
1180 #include <cyg/infra/cyg_trac.h> // tracing macros
1181 #include <cyg/infra/cyg_ass.h> // assertion macros
1182 #include <cyg/fileio/fileio.h>
1183 #include <cyg/kernel/kapi.h>
1184 #include <cyg/infra/diag.h>
1186 //==========================================================================
1187 // Eventually we want to eXecute In Place from the ROM in a protected
1188 // environment, so we'll need executables to be aligned to a boundary
1189 // suitable for MMU protection. A suitable boundary would be the 4k
1190 // boundary in all the CPU architectures I am currently aware of.
1192 // Forward definitions
1194 // Filesystem operations
1195 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1196 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1197 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1198 int mode
, cyg_file
*fte
);
1199 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1200 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1203 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1204 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1205 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1207 //==========================================================================
1208 // Filesystem table entries
1210 // -------------------------------------------------------------------------
1212 // This defines the entry in the filesystem table.
1213 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1214 // we should never block in any filesystem operations.
1216 FSTAB_ENTRY(tftpfs_fste
, "tftpfs", 0,
1221 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1222 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1223 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1224 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1225 (cyg_fsop_link
*)cyg_fileio_erofs
,
1226 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1227 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1228 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1229 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1230 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1233 // -------------------------------------------------------------------------
1235 // This defines a single ROMFS loaded into ROM at the configured address
1237 // MTAB_ENTRY(rom_mte, // structure name
1238 // "/rom", // mount point
1239 // "romfs", // FIlesystem type
1240 // "", // hardware device
1241 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1245 // -------------------------------------------------------------------------
1247 // This set of file operations are used for normal open files.
1249 static cyg_fileops tftpfs_fileops
=
1250 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1251 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1252 tftpfs_fo_fsync
, tftpfs_fo_close
,
1253 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1254 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1255 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1257 // -------------------------------------------------------------------------
1259 // Process a mount request. This mainly finds root for the
1262 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1267 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1282 static void freeTftp(struct Tftp
*t
)
1295 static const int tftpMaxSize
= 8192 * 1024;
1296 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1297 int mode
, cyg_file
*file
)
1300 tftp
= malloc(sizeof(struct Tftp
));
1303 memset(tftp
, 0, sizeof(struct Tftp
));
1305 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1306 file
->f_type
= CYG_FILE_TYPE_FILE
;
1307 file
->f_ops
= &tftpfs_fileops
;
1312 tftp
->mem
= malloc(tftpMaxSize
);
1313 if (tftp
->mem
== NULL
)
1319 char *server
= strchr(name
, '/');
1326 tftp
->server
= malloc(server
- name
+ 1);
1327 if (tftp
->server
== NULL
)
1332 strncpy(tftp
->server
, name
, server
- name
);
1333 tftp
->server
[server
- name
] = 0;
1335 tftp
->file
= strdup(server
+ 1);
1336 if (tftp
->file
== NULL
)
1342 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1347 static int fetchTftp(struct Tftp
*tftp
)
1349 if (!tftp
->readFile
)
1352 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1353 tftpMaxSize
, TFTP_OCTET
, &err
);
1355 if (tftp
->actual
< 0)
1364 // -------------------------------------------------------------------------
1365 // tftpfs_fo_write()
1366 // Read data from file.
1368 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1370 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1372 if (fetchTftp(tftp
) != ENOERR
)
1376 off_t pos
= fp
->f_offset
;
1378 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1380 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1381 char *buf
= (char *) iov
->iov_base
;
1382 off_t len
= iov
->iov_len
;
1384 if (len
+ pos
> tftp
->actual
)
1386 len
= tftp
->actual
- pos
;
1388 resid
+= iov
->iov_len
- len
;
1390 memcpy(buf
, tftp
->mem
+ pos
, len
);
1394 uio
->uio_resid
= resid
;
1400 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1402 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1405 off_t pos
= fp
->f_offset
;
1407 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1409 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1410 char *buf
= (char *) iov
->iov_base
;
1411 off_t len
= iov
->iov_len
;
1413 if (len
+ pos
> tftpMaxSize
)
1415 len
= tftpMaxSize
- pos
;
1417 resid
+= iov
->iov_len
- len
;
1419 memcpy(tftp
->mem
+ pos
, buf
, len
);
1423 uio
->uio_resid
= resid
;
1431 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1437 // -------------------------------------------------------------------------
1439 // Close a file. We just clear out the data pointer.
1441 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1443 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1448 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1449 TFTP_OCTET
, &error
);
1457 // -------------------------------------------------------------------------
1459 // Seek to a new file position.
1461 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1463 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1466 if (fetchTftp(tftp
) != ENOERR
)
1472 // Pos is already where we want to be.
1476 // Add pos to current offset.
1477 pos
+= fp
->f_offset
;
1481 // Add pos to file size.
1482 pos
+= tftp
->actual
;
1489 // Check that pos is still within current file size, or at the
1491 if (pos
< 0 || pos
> tftp
->actual
)
1494 // All OK, set fp offset and return new position.
1495 *apos
= fp
->f_offset
= pos
;
1503 cyg_thread_delay(us
/ 10000 + 1);
1509 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1511 cyg_httpd_start_chunked("text");
1512 if (logCount
>= logSize
)
1514 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1515 - logCount
% logSize
);
1517 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1518 cyg_httpd_end_chunked();
1522 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1524 // Filesystem operations
1525 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1526 static int logfs_umount(cyg_mtab_entry
*mte
);
1527 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1528 int mode
, cyg_file
*fte
);
1529 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1532 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1533 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1535 #include <cyg/io/devtab.h>
1537 //==========================================================================
1538 // Filesystem table entries
1540 // -------------------------------------------------------------------------
1542 // This defines the entry in the filesystem table.
1543 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1544 // we should never block in any filesystem operations.
1545 FSTAB_ENTRY(logfs_fste
, "logfs", 0,
1546 CYG_SYNCMODE_FILE_FILESYSTEM
| CYG_SYNCMODE_IO_FILESYSTEM
,
1550 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1551 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1552 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1553 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1554 (cyg_fsop_link
*)cyg_fileio_erofs
,
1555 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1556 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1557 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1558 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1559 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1561 // -------------------------------------------------------------------------
1563 // This set of file operations are used for normal open files.
1565 static cyg_fileops logfs_fileops
=
1566 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1567 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1568 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1569 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1570 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1571 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1573 // -------------------------------------------------------------------------
1575 // Process a mount request. This mainly finds root for the
1578 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1583 static int logfs_umount(cyg_mtab_entry
*mte
)
1588 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1589 int mode
, cyg_file
*file
)
1591 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1592 file
->f_type
= CYG_FILE_TYPE_FILE
;
1593 file
->f_ops
= &logfs_fileops
;
1600 // -------------------------------------------------------------------------
1602 // Write data to file.
1604 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1607 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1609 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1610 char *buf
= (char *) iov
->iov_base
;
1611 off_t len
= iov
->iov_len
;
1613 diag_write(buf
, len
);
1619 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1624 // -------------------------------------------------------------------------
1626 // Close a file. We just clear out the data pointer.
1628 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
1633 int loadFile(const char *fileName
, void **data
, int *len
);
1635 /* boolean parameter stored on config */
1636 int boolParam(char *var
)
1638 bool result
= false;
1639 char *name
= alloc_printf("%s/%s", zylin_config_dir
, var
);
1645 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1649 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)