1 /***************************************************************************
2 * Copyright (C) 2007-2008 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 "configuration.h"
25 #include "time_support.h"
37 #include "telnet_server.h"
38 #include "gdb_server.h"
40 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
43 #include <arpa/inet.h>
47 #include <netinet/tcp.h>
49 #include <sys/ioctl.h>
52 #include <cyg/athttpd/http.h>
53 #include <cyg/athttpd/socket.h>
54 #include <cyg/athttpd/handler.h>
55 #include <cyg/athttpd/cgi.h>
56 #include <cyg/athttpd/forms.h>
57 #include <cyg/discover/discover.h>
58 #include <cyg/fileio/fileio.h>
59 #include <cyg/hal/hal_diag.h>
60 #include <cyg/io/flash.h>
61 #include <cyg/io/serialio.h>
62 #include <cyg/io/io.h>
63 #include <cyg/kernel/kapi.h>
73 #if defined(CYGPKG_NET_FREEBSD_STACK)
74 #include <tftp_support.h>
75 /* posix compatibility broken*/
76 struct tftpd_fileops fileops
=
78 (int (*)(const char *, int))open
,
80 (int (*)(int, const void *, int))write
,
81 ( int (*)(int, void *, int))read
87 void diag_write(char *buf
, int len
)
90 for (j
= 0; j
< len
; j
++)
92 diag_printf("%c", buf
[j
]);
96 static bool serialLog
= true;
97 static bool writeLog
= true;
102 extern flash_driver_t
*flash_drivers
[];
103 extern target_type_t
*target_types
[];
105 #ifdef CYGPKG_PROFILE_GPROF
106 #include <cyg/profile/profile.h>
108 extern char _stext
, _etext
; // Defined by the linker
110 static char *start_of_code
=&_stext
;
111 static char *end_of_code
=&_etext
;
113 void start_profile(void)
115 // This starts up the system-wide profiling, gathering
116 // profile information on all of the code, with a 16 byte
117 // "bucket" size, at a rate of 100us/profile hit.
118 // Note: a bucket size of 16 will give pretty good function
119 // resolution. Much smaller and the buffer becomes
120 // much too large for very little gain.
121 // Note: a timer period of 100us is also a reasonable
122 // compromise. Any smaller and the overhead of
123 // handling the timter (profile) interrupt could
124 // swamp the system. A fast processor might get
125 // by with a smaller value, but a slow one could
126 // even be swamped by this value. If the value is
127 // too large, the usefulness of the profile is reduced.
129 // no more interrupts than 1/10ms.
130 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
131 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
132 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
139 static char reboot_stack
[2048];
141 static void zylinjtag_reboot(cyg_addrword_t data
)
144 diag_printf("Rebooting in 100 ticks..\n");
145 cyg_thread_delay(100);
146 diag_printf("Unmounting /config..\n");
148 diag_printf("Rebooting..\n");
149 HAL_PLATFORM_RESET();
151 static cyg_thread zylinjtag_thread_object
;
152 static cyg_handle_t zylinjtag_thread_handle
;
156 cyg_thread_create(1, zylinjtag_reboot
, (cyg_addrword_t
) 0, "reboot Thread",
157 (void *) reboot_stack
, sizeof(reboot_stack
),
158 &zylinjtag_thread_handle
, &zylinjtag_thread_object
);
159 cyg_thread_resume(zylinjtag_thread_handle
);
162 int configuration_output_handler(struct command_context_s
*context
,
165 diag_printf("%s", line
);
170 int zy1000_configuration_output_handler_log(struct command_context_s
*context
,
173 LOG_USER_N("%s", line
);
178 #ifdef CYGPKG_PROFILE_GPROF
179 extern void start_profile(void);
181 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
183 command_print(cmd_ctx
, "Profiling started");
190 externC
void phi_init_all_network_interfaces(void);
192 command_context_t
*cmd_ctx
;
194 static bool webRunning
= false;
196 void keep_webserver(void)
198 // Target initialisation is only attempted at startup, so we sleep forever and
199 // let the http server bail us out(i.e. get config files set up).
200 diag_printf("OpenOCD has invoked exit().\n"
201 "Use web server to correct any configuration settings and reboot.\n");
205 // exit() will terminate the current thread and we we'll then sleep eternally or
206 // we'll have a reboot scheduled.
209 extern void printDccChar(char c
);
211 static char logBuffer
[128 * 1024];
212 static const int logSize
= sizeof(logBuffer
);
216 void _zylinjtag_diag_write_char(char c
, void **param
)
220 logBuffer
[writePtr
] = c
;
221 writePtr
= (writePtr
+ 1) % logSize
;
228 HAL_DIAG_WRITE_CHAR('\r');
230 HAL_DIAG_WRITE_CHAR(c
);
233 #ifdef CYGPKG_HAL_ZYLIN_PHI
238 void copyfile(char *name2
, char *name1
);
240 void copydir(char *name
, char *destdir
);
243 MTAB_ENTRY( romfs_mte1
,
247 (CYG_ADDRWORD
) &filedata
[0] );
250 void openocd_sleep_prelude(void)
252 cyg_mutex_unlock(&httpstate
.jim_lock
);
255 void openocd_sleep_postlude(void)
257 cyg_mutex_lock(&httpstate
.jim_lock
);
262 diag_printf("Formatting JFFS2...\n");
264 cyg_io_handle_t handle
;
267 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
270 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
275 cyg_io_flash_getconfig_devsize_t ds
;
277 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
280 diag_printf("Flash error cyg_io_get_config %d\n", err
);
284 cyg_io_flash_getconfig_erase_t e
;
290 e
.err_address
= &err_addr
;
292 diag_printf("Formatting 0x%08x bytes\n", ds
.dev_size
);
293 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
, &e
, &len
);
296 diag_printf("Flash erase error %d offset 0x%p\n", err
, err_addr
);
300 diag_printf("Flash formatted successfully\n");
305 static int zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
, int argc
,
306 Jim_Obj
* const *argv
)
318 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
319 Jim_Obj
* const *argv
)
321 cyg_handle_t thread
= 0;
323 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
325 /* Loop over the threads, and generate a table row for
328 while (cyg_thread_get_next(&thread
, &id
))
330 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
332 cyg_thread_info info
;
335 cyg_thread_get_info(thread
, id
, &info
);
337 if (info
.name
== NULL
)
338 info
.name
= "<no name>";
340 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
341 info
.name
, strlen(info
.name
)));
343 /* Translate the state into a string.
346 state_string
= "RUN";
347 else if (info
.state
& 0x04)
348 state_string
= "SUSP";
350 switch (info
.state
& 0x1b)
353 state_string
= "SLEEP";
356 state_string
= "CNTSLEEP";
359 state_string
= "CREATE";
362 state_string
= "EXIT";
365 state_string
= "????";
369 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
370 state_string
, strlen(state_string
)));
372 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, id
));
373 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
375 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
,
378 Jim_ListAppendElement(interp
, threads
, threadObj
);
380 Jim_SetResult(interp
, threads
);
385 static int zylinjtag_Jim_Command_log(Jim_Interp
*interp
, int argc
,
386 Jim_Obj
* const *argv
)
388 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
390 if (logCount
>= logSize
)
392 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+ logCount
393 % logSize
, logSize
- logCount
% logSize
);
395 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
397 Jim_SetResult(interp
, tclOutput
);
401 static int zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
, int argc
,
402 Jim_Obj
* const *argv
)
409 extern Jim_Interp
*interp
;
411 static void zylinjtag_startNetwork(void)
413 // Bring TCP/IP up immediately before we're ready to accept commands.
415 // That is as soon as a PING responds, we're accepting telnet sessions.
416 #if defined(CYGPKG_NET_FREEBSD_STACK)
417 phi_init_all_network_interfaces();
423 diag_printf("Network not up and running\n");
426 #if defined(CYGPKG_NET_FREEBSD_STACK)
428 tftpd_start(69, &fileops
);
431 cyg_httpd_init_tcl_interpreter();
433 interp
= httpstate
.jim_interp
;
435 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
,
437 Jim_CreateCommand(httpstate
.jim_interp
, "reboot",
438 zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
439 Jim_CreateCommand(httpstate
.jim_interp
, "threads",
440 zylinjtag_Jim_Command_threads
, NULL
, NULL
);
441 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2",
442 zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
448 diag_printf("Web server running\n");
452 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
455 strcpy(ifr
.ifr_name
, "eth0");
457 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
462 diag_printf("Can't obtain MAC address\n");
467 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
468 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
469 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
470 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
471 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
472 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
473 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
476 = alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
481 static void print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
,
486 char *infoStr
= "unknown";
489 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
490 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
491 infoStr
= "undefined instruction";
493 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
494 infoStr
= "software interrupt";
496 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
497 infoStr
= "abort prefetch";
499 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
500 infoStr
= "abort data";
507 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
509 diag_printf("Dumping log\n---\n");
510 if (logCount
>= logSize
)
512 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
514 diag_write(logBuffer
, writePtr
);
516 diag_printf("---\nLogdump complete.\n");
517 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
518 diag_printf("\n---\nRebooting\n");
519 HAL_PLATFORM_RESET();
523 static void setHandler(cyg_code_t exception
)
525 cyg_exception_handler_t
*old_handler
;
526 cyg_addrword_t old_data
;
528 cyg_exception_set_handler(exception
, print_exception_handler
, 0,
529 &old_handler
, &old_data
);
532 static cyg_thread zylinjtag_uart_thread_object
;
533 static cyg_handle_t zylinjtag_uart_thread_handle
;
534 static char uart_stack
[4096];
536 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
537 static char backwardBuffer
[1024];
539 void setNoDelay(int session
, int flag
)
542 // This decreases latency dramatically for e.g. GDB load which
543 // does not have a sliding window protocol
545 // Can cause *lots* of TCP/IP packets to be sent and it would have
546 // to be enabled/disabled on the fly to avoid the CPU being
548 setsockopt(session
, /* socket affected */
549 IPPROTO_TCP
, /* set option at TCP level */
550 TCP_NODELAY
, /* name of option */
551 (char *) &flag
, /* the cast is historical
553 sizeof(int)); /* length of option value */
563 } tcpipSent
[512 * 1024];
566 static void zylinjtag_uart(cyg_addrword_t data
)
568 int so_reuseaddr_option
= 1;
571 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
573 LOG_ERROR("error creating socket: %s", strerror(errno
));
577 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*) &so_reuseaddr_option
,
580 struct sockaddr_in sin
;
581 unsigned int address_size
;
582 address_size
= sizeof(sin
);
583 memset(&sin
, 0, sizeof(sin
));
584 sin
.sin_family
= AF_INET
;
585 sin
.sin_addr
.s_addr
= INADDR_ANY
;
586 sin
.sin_port
= htons(5555);
588 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
590 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
594 if (listen(fd
, 1) == -1)
596 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
599 // socket_nonblock(fd);
604 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
610 setNoDelay(session
, 1);
611 int oldopts
= fcntl(session
, F_GETFL
, 0);
612 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
614 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
621 #ifdef CYGPKG_PROFILE_GPROF
637 FD_SET(session
, &read_fds
);
639 FD_SET(serHandle
, &read_fds
);
640 if (serHandle
> fd_max
)
646 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
647 if ((actual
== 0) && (actual2
== 0))
649 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
658 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
659 actual2
= read(serHandle
, backwardBuffer
,
660 sizeof(backwardBuffer
));
676 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
684 if (FD_ISSET(session
, &read_fds
)
685 && (sizeof(forwardBuffer
) > actual
))
687 // NB! Here it is important that we empty the TCP/IP read buffer
688 // to make transmission tick right
689 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
692 // this will block if there is no data at all
693 t
= read_socket(session
, forwardBuffer
+ actual
,
694 sizeof(forwardBuffer
) - actual
);
706 /* Do not put things into the serial buffer if it has something to send
707 * as that can cause a single byte to be sent at the time.
711 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
718 // The serial buffer is full
730 tcpipSent
[cur
].req
= x
;
731 tcpipSent
[cur
].actual
= y
;
732 tcpipSent
[cur
].req2
= x2
;
733 tcpipSent
[cur
].actual2
= y2
;
738 closeSession
: close(session
);
742 for (i
= 0; i
< 1024; i
++)
744 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
,
745 tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
755 cyg_thread_create(1, zylinjtag_uart
, (cyg_addrword_t
) 0, "uart thread",
756 (void *) uart_stack
, sizeof(uart_stack
),
757 &zylinjtag_uart_thread_handle
, &zylinjtag_uart_thread_object
);
758 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
759 cyg_thread_resume(zylinjtag_uart_thread_handle
);
762 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
,
763 char **args
, int argc
)
765 static int current_baud
= 38400;
768 command_print(cmd_ctx
, "%d", current_baud
);
773 return ERROR_INVALID_ARGUMENTS
;
776 current_baud
= atol(args
[0]);
779 switch (current_baud
)
782 baud
= CYGNUM_SERIAL_BAUD_9600
;
785 baud
= CYGNUM_SERIAL_BAUD_19200
;
788 baud
= CYGNUM_SERIAL_BAUD_38400
;
791 baud
= CYGNUM_SERIAL_BAUD_57600
;
794 baud
= CYGNUM_SERIAL_BAUD_115200
;
797 baud
= CYGNUM_SERIAL_BAUD_230400
;
800 command_print(cmd_ctx
, "unsupported baudrate");
801 return ERROR_INVALID_ARGUMENTS
;
804 cyg_serial_info_t buf
;
806 //get existing serial configuration
807 len
= sizeof(cyg_serial_info_t
);
809 cyg_io_handle_t serial_handle
;
811 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
814 LOG_ERROR("/dev/ser0 not found\n");
818 err
= cyg_io_get_config(serial_handle
,
819 CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
820 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
,
824 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
829 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
,
833 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
840 bool logAllToSerial
= false;
843 int boolParam(char *var
);
846 command_context_t
*setup_command_handler(void);
848 extern const char *zylin_config_dir
;
850 int add_default_dirs(void)
852 add_script_search_dir(zylin_config_dir
);
853 add_script_search_dir("/rom/lib/openocd");
854 add_script_search_dir("/rom");
858 int ioutil_init(struct command_context_s
*cmd_ctx
);
860 int main(int argc
, char *argv
[])
862 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
863 * need to allocate towards the end of the heap. */
865 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
866 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
867 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
868 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
873 atexit(keep_webserver
);
875 diag_init_putc(_zylinjtag_diag_write_char
);
876 // We want this in the log.
877 diag_printf("Zylin ZY1000.\n");
879 err
= mount("", "/ram", "ramfs");
882 diag_printf("unable to mount ramfs\n");
887 sprintf(address
, "%p", &filedata
[0]);
888 err
= mount(address
, "/rom", "romfs");
891 diag_printf("unable to mount /rom\n");
894 err
= mount("", "/log", "logfs");
897 diag_printf("unable to mount logfs\n");
900 err
= mount("", "/tftp", "tftpfs");
903 diag_printf("unable to mount logfs\n");
906 log
= fopen("/log/log", "w");
909 diag_printf("Could not open log file /ram/log\n");
914 copydir("/rom", "/ram/cgi");
916 err
= mount("/dev/flash1", "/config", "jffs2");
919 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
920 err
= mount("", "/config", "ramfs");
923 diag_printf("unable to mount /config as ramdisk.\n");
929 /* are we using a ram disk instead of a flash disk? This is used
930 * for ZY1000 live demo...
932 * copy over flash disk to ram block device
934 if (boolParam("ramdisk"))
936 diag_printf("Unmounting /config from flash and using ram instead\n");
937 err
= umount("/config");
940 diag_printf("unable to unmount jffs\n");
944 err
= mount("/dev/flash1", "/config2", "jffs2");
947 diag_printf("unable to mount jffs\n");
951 err
= mount("", "/config", "ramfs");
954 diag_printf("unable to mount ram block device\n");
958 // copydir("/config2", "/config");
959 copyfile("/config2/ip", "/config/ip");
960 copydir("/config2/settings", "/config/settings");
966 mkdir(zylin_config_dir
, 0777);
967 char *dirname
=alloc_printf("%s/target", zylin_config_dir
);
968 mkdir(dirname
, 0777);
970 dirname
=alloc_printf("%s/board", zylin_config_dir
);
971 mkdir(dirname
, 0777);
973 dirname
=alloc_printf("%s/event", zylin_config_dir
);
974 mkdir(dirname
, 0777);
977 logAllToSerial
= boolParam("logserial");
979 // We need the network & web server in case there is something wrong with
980 // the config files that invoke exit()
981 zylinjtag_startNetwork();
983 /* we're going to access the jim interpreter from here on... */
984 openocd_sleep_postlude();
989 /* initialize commandline interface */
990 command_context_t
* cmd_ctx
;
991 cmd_ctx
= setup_command_handler();
992 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
993 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
996 if (ioutil_init(cmd_ctx
) != ERROR_OK
)
1003 #ifdef CYGPKG_PROFILE_GPROF
1004 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1008 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
, COMMAND_ANY
,
1009 "uart <baud> - forward uart on port 5555");
1012 errVal
= log_init(cmd_ctx
);
1013 if (errVal
!= ERROR_OK
)
1015 diag_printf("log_init() failed %d\n", errVal
);
1019 set_log_output(cmd_ctx
, log
);
1021 LOG_DEBUG("log init complete");
1023 // diag_printf("Executing config files\n");
1028 "%s/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n", zylin_config_dir
);
1029 command_run_line(cmd_ctx
, "debug_level 3");
1032 command_run_linef(cmd_ctx
, "script /rom/openocd.cfg");
1035 // diag_printf() is really invoked from many more places than we trust it
1036 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1038 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1039 // fingers that it doesn't cause any crashes.
1040 diag_printf("Init complete, GDB & telnet servers launched.\n");
1041 command_set_output_handler(cmd_ctx
,
1042 zy1000_configuration_output_handler_log
, NULL
);
1043 if (!logAllToSerial
)
1048 /* handle network connections */
1049 server_loop(cmd_ctx
);
1050 openocd_sleep_prelude();
1052 /* shut server down */
1055 /* free commandline interface */
1056 command_done(cmd_ctx
);
1064 cyg_int32
cyg_httpd_exec_cgi_tcl(char *file_name
);
1065 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1067 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1071 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1073 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1074 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1076 #include <pkgconf/system.h>
1077 #include <pkgconf/hal.h>
1078 #include <pkgconf/kernel.h>
1079 #include <pkgconf/io_fileio.h>
1080 #include <pkgconf/fs_rom.h>
1082 #include <cyg/kernel/ktypes.h> // base kernel types
1083 #include <cyg/infra/cyg_trac.h> // tracing macros
1084 #include <cyg/infra/cyg_ass.h> // assertion macros
1085 #include <cyg/fileio/fileio.h>
1086 #include <cyg/kernel/kapi.h>
1087 #include <cyg/infra/diag.h>
1089 //==========================================================================
1090 // Eventually we want to eXecute In Place from the ROM in a protected
1091 // environment, so we'll need executables to be aligned to a boundary
1092 // suitable for MMU protection. A suitable boundary would be the 4k
1093 // boundary in all the CPU architectures I am currently aware of.
1095 // Forward definitions
1097 // Filesystem operations
1098 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1099 static int tftpfs_umount(cyg_mtab_entry
*mte
);
1100 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1101 int mode
, cyg_file
*fte
);
1102 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1103 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1106 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1107 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
1108 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
1110 //==========================================================================
1111 // Filesystem table entries
1113 // -------------------------------------------------------------------------
1115 // This defines the entry in the filesystem table.
1116 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1117 // we should never block in any filesystem operations.
1119 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
1124 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1125 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1126 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1127 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1128 (cyg_fsop_link
*)cyg_fileio_erofs
,
1129 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1130 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1131 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1132 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1133 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1136 // -------------------------------------------------------------------------
1138 // This defines a single ROMFS loaded into ROM at the configured address
1140 // MTAB_ENTRY( rom_mte, // structure name
1141 // "/rom", // mount point
1142 // "romfs", // FIlesystem type
1143 // "", // hardware device
1144 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1148 // -------------------------------------------------------------------------
1150 // This set of file operations are used for normal open files.
1152 static cyg_fileops tftpfs_fileops
=
1153 { tftpfs_fo_read
, tftpfs_fo_write
, tftpfs_fo_lseek
,
1154 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1155 tftpfs_fo_fsync
, tftpfs_fo_close
,
1156 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1157 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1158 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1160 // -------------------------------------------------------------------------
1162 // Process a mount request. This mainly finds root for the
1165 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1170 static int tftpfs_umount(cyg_mtab_entry
*mte
)
1185 static void freeTftp(struct Tftp
*t
)
1198 static const int tftpMaxSize
= 8192 * 1024;
1199 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1200 int mode
, cyg_file
*file
)
1203 tftp
= malloc(sizeof(struct Tftp
));
1206 memset(tftp
, 0, sizeof(struct Tftp
));
1208 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1209 file
->f_type
= CYG_FILE_TYPE_FILE
;
1210 file
->f_ops
= &tftpfs_fileops
;
1215 tftp
->mem
= malloc(tftpMaxSize
);
1216 if (tftp
->mem
== NULL
)
1222 char *server
= strchr(name
, '/');
1229 tftp
->server
= malloc(server
- name
+ 1);
1230 if (tftp
->server
== NULL
)
1235 strncpy(tftp
->server
, name
, server
- name
);
1236 tftp
->server
[server
- name
] = 0;
1238 tftp
->file
= strdup(server
+ 1);
1239 if (tftp
->file
== NULL
)
1245 file
->f_data
= (CYG_ADDRWORD
) tftp
;
1250 static int fetchTftp(struct Tftp
*tftp
)
1252 if (!tftp
->readFile
)
1255 tftp
->actual
= tftp_client_get(tftp
->file
, tftp
->server
, 0, tftp
->mem
,
1256 tftpMaxSize
, TFTP_OCTET
, &err
);
1258 if (tftp
->actual
< 0)
1267 // -------------------------------------------------------------------------
1268 // tftpfs_fo_write()
1269 // Read data from file.
1271 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1273 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1275 if (fetchTftp(tftp
) != ENOERR
)
1279 off_t pos
= fp
->f_offset
;
1281 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1283 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1284 char *buf
= (char *) iov
->iov_base
;
1285 off_t len
= iov
->iov_len
;
1287 if (len
+ pos
> tftp
->actual
)
1289 len
= tftp
->actual
- pos
;
1291 resid
+= iov
->iov_len
- len
;
1293 memcpy(buf
, tftp
->mem
+ pos
, len
);
1297 uio
->uio_resid
= resid
;
1303 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1305 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1308 off_t pos
= fp
->f_offset
;
1310 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1312 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1313 char *buf
= (char *) iov
->iov_base
;
1314 off_t len
= iov
->iov_len
;
1316 if (len
+ pos
> tftpMaxSize
)
1318 len
= tftpMaxSize
- pos
;
1320 resid
+= iov
->iov_len
- len
;
1322 memcpy(tftp
->mem
+ pos
, buf
, len
);
1326 uio
->uio_resid
= resid
;
1334 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1340 // -------------------------------------------------------------------------
1342 // Close a file. We just clear out the data pointer.
1344 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
1346 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1351 tftp_client_put(tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
,
1352 TFTP_OCTET
, &error
);
1360 // -------------------------------------------------------------------------
1362 // Seek to a new file position.
1364 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
1366 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
1369 if (fetchTftp(tftp
) != ENOERR
)
1375 // Pos is already where we want to be.
1379 // Add pos to current offset.
1380 pos
+= fp
->f_offset
;
1384 // Add pos to file size.
1385 pos
+= tftp
->actual
;
1392 // Check that pos is still within current file size, or at the
1394 if (pos
< 0 || pos
> tftp
->actual
)
1397 // All OK, set fp offset and return new position.
1398 *apos
= fp
->f_offset
= pos
;
1406 cyg_thread_delay(us
/ 10000 + 1);
1412 cyg_int32
show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
1414 cyg_httpd_start_chunked("text");
1415 if (logCount
>= logSize
)
1417 cyg_httpd_write_chunked(logBuffer
+ logCount
% logSize
, logSize
1418 - logCount
% logSize
);
1420 cyg_httpd_write_chunked(logBuffer
, writePtr
);
1421 cyg_httpd_end_chunked();
1425 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
1427 // Filesystem operations
1428 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
1429 static int logfs_umount(cyg_mtab_entry
*mte
);
1430 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1431 int mode
, cyg_file
*fte
);
1432 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
1435 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
1436 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
1438 #include <cyg/io/devtab.h>
1440 //==========================================================================
1441 // Filesystem table entries
1443 // -------------------------------------------------------------------------
1445 // This defines the entry in the filesystem table.
1446 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1447 // we should never block in any filesystem operations.
1448 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
1449 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
1453 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
1454 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
1455 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
1456 (cyg_fsop_rename
*)cyg_fileio_erofs
,
1457 (cyg_fsop_link
*)cyg_fileio_erofs
,
1458 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
1459 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
1460 (cyg_fsop_stat
*)cyg_fileio_erofs
,
1461 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
1462 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
1464 // -------------------------------------------------------------------------
1466 // This set of file operations are used for normal open files.
1468 static cyg_fileops logfs_fileops
=
1469 { (cyg_fileop_read
*) cyg_fileio_erofs
, (cyg_fileop_write
*) logfs_fo_write
,
1470 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
1471 (cyg_fileop_ioctl
*) cyg_fileio_erofs
, cyg_fileio_seltrue
,
1472 logfs_fo_fsync
, logfs_fo_close
, (cyg_fileop_fstat
*) cyg_fileio_erofs
,
1473 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
1474 (cyg_fileop_setinfo
*) cyg_fileio_erofs
, };
1476 // -------------------------------------------------------------------------
1478 // Process a mount request. This mainly finds root for the
1481 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
1486 static int logfs_umount(cyg_mtab_entry
*mte
)
1491 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
1492 int mode
, cyg_file
*file
)
1494 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
1495 file
->f_type
= CYG_FILE_TYPE_FILE
;
1496 file
->f_ops
= &logfs_fileops
;
1503 // -------------------------------------------------------------------------
1505 // Write data to file.
1507 static int logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
1510 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
1512 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
1513 char *buf
= (char *) iov
->iov_base
;
1514 off_t len
= iov
->iov_len
;
1516 diag_write(buf
, len
);
1522 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
1527 // -------------------------------------------------------------------------
1529 // Close a file. We just clear out the data pointer.
1531 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
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)