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 ***************************************************************************/
27 #include "configuration.h"
36 #include "telnet_server.h"
37 #include "gdb_server.h"
39 #include <time_support.h>
41 #include <sys/types.h>
49 #include <cyg/io/flash.h>
50 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
55 #include <cyg/fileio/fileio.h>
57 #include <cyg/athttpd/http.h>
58 #include <cyg/athttpd/socket.h>
59 #include <cyg/athttpd/handler.h>
60 #include <cyg/athttpd/cgi.h>
61 #include <cyg/athttpd/forms.h>
62 #include <cyg/discover/discover.h>
63 #include <cyg/hal/hal_diag.h>
64 #include <cyg/kernel/kapi.h>
65 #include <cyg/io/serialio.h>
66 #include <cyg/io/io.h>
67 #include <netinet/tcp.h>
69 #include <sys/ioctl.h>
70 #include <sys/socket.h>
71 #include <netinet/in.h>
73 #include <arpa/inet.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
77 #include <netinet/in.h>
79 #include <arpa/inet.h>
88 #if defined(CYGPKG_NET_FREEBSD_STACK)
89 #include <tftp_support.h>
90 /* posix compatibility broken*/
91 struct tftpd_fileops fileops =
93 (int (*)(const char *, int))open,
95 (int (*)(int, const void *, int))write,
96 ( int (*)(int, void *, int))read
101 #define ZYLIN_VERSION "1.48"
102 #define ZYLIN_DATE __DATE__
103 #define ZYLIN_TIME __TIME__
104 /* hmmm.... we can't pick up the right # during build if we've checked this out
105 * in Eclipse... arrggghh...*/
106 #define ZYLIN_OPENOCD "$Revision$"
107 #define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME
108 #define ZYLIN_CONFIG_DIR "/config/settings"
110 void diag_write(char *buf, int len)
113 for (j = 0; j < len; j++)
115 diag_printf("%c", buf[j]);
119 static bool serialLog = true;
120 static bool writeLog = true;
125 /* Give TELNET a way to find out what version this is */
126 int handle_zy1000_version_command(struct command_context_s *cmd_ctx, char *cmd,
127 char **args, int argc)
131 return ERROR_COMMAND_SYNTAX_ERROR;
135 command_print(cmd_ctx, ZYLIN_OPENOCD_VERSION);
136 } else if (strcmp("openocd", args[0])==0)
139 revision=atol(ZYLIN_OPENOCD+strlen("XRevision: "));
140 command_print(cmd_ctx, "%d", revision);
141 } else if (strcmp("zy1000", args[0])==0)
143 command_print(cmd_ctx, "%s", ZYLIN_VERSION);
144 } else if (strcmp("date", args[0])==0)
146 command_print(cmd_ctx, "%s", ZYLIN_DATE);
149 return ERROR_COMMAND_SYNTAX_ERROR;
158 extern flash_driver_t *flash_drivers[];
159 extern target_type_t *target_types[];
161 #ifdef CYGPKG_PROFILE_GPROF
162 #include <cyg/profile/profile.h>
164 extern char _stext, _etext; // Defined by the linker
166 static char *start_of_code=&_stext;
167 static char *end_of_code=&_etext;
169 void start_profile(void)
171 // This starts up the system-wide profiling, gathering
172 // profile information on all of the code, with a 16 byte
173 // "bucket" size, at a rate of 100us/profile hit.
174 // Note: a bucket size of 16 will give pretty good function
175 // resolution. Much smaller and the buffer becomes
176 // much too large for very little gain.
177 // Note: a timer period of 100us is also a reasonable
178 // compromise. Any smaller and the overhead of
179 // handling the timter (profile) interrupt could
180 // swamp the system. A fast processor might get
181 // by with a smaller value, but a slow one could
182 // even be swamped by this value. If the value is
183 // too large, the usefulness of the profile is reduced.
185 // no more interrupts than 1/10ms.
186 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
187 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
188 profile_on(start_of_code, end_of_code, 16, 10000); // Nios DRAM
192 // launch GDB server if a config file exists
193 bool zylinjtag_parse_config_file(struct command_context_s *cmd_ctx, const char *config_file_name)
195 bool foundFile = false;
196 FILE *config_file = NULL;
197 command_print(cmd_ctx, "executing config file %s", config_file_name);
198 config_file = fopen(config_file_name, "r");
203 retval = command_run_linef(cmd_ctx, "script %s", config_file_name);
204 if (retval == ERROR_OK)
210 command_print(cmd_ctx, "Failed executing %s %d", config_file_name, retval);
215 command_print(cmd_ctx, "No %s found", config_file_name);
224 static char reboot_stack[2048];
228 zylinjtag_reboot(cyg_addrword_t data)
231 diag_printf("Rebooting in 100 ticks..\n");
232 cyg_thread_delay(100);
233 diag_printf("Unmounting /config..\n");
235 diag_printf("Rebooting..\n");
236 HAL_PLATFORM_RESET();
238 static cyg_thread zylinjtag_thread_object;
239 static cyg_handle_t zylinjtag_thread_handle;
247 (void *)reboot_stack,
248 sizeof(reboot_stack),
249 &zylinjtag_thread_handle,
250 &zylinjtag_thread_object);
251 cyg_thread_resume(zylinjtag_thread_handle);
254 int configuration_output_handler(struct command_context_s *context, const char* line)
256 diag_printf("%s", line);
261 int zy1000_configuration_output_handler_log(struct command_context_s *context, const char* line)
263 LOG_USER_N("%s", line);
268 int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
269 char **args, int argc)
273 command_print(cmd_ctx, "rm <filename>");
274 return ERROR_INVALID_ARGUMENTS;
277 if (unlink(args[0]) != 0)
279 command_print(cmd_ctx, "failed: %d", errno);
285 int loadFile(const char *fileName, void **data, int *len);
287 int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
288 char **args, int argc)
292 command_print(cmd_ctx, "cat <filename>");
293 return ERROR_INVALID_ARGUMENTS;
296 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
300 int retval = loadFile(args[0], &data, &len);
301 if (retval == ERROR_OK)
303 command_print(cmd_ctx, "%s", data);
308 command_print(cmd_ctx, "%s not found %d", args[0], retval);
313 int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
314 char **args, int argc)
318 command_print(cmd_ctx, "trunc <filename>");
319 return ERROR_INVALID_ARGUMENTS;
322 FILE *config_file = NULL;
323 config_file = fopen(args[0], "w");
324 if (config_file != NULL)
331 int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
334 struct mallinfo info;
338 command_print(cmd_ctx, "meminfo");
339 return ERROR_INVALID_ARGUMENTS;
346 command_print(cmd_ctx, "Diff: %d", prev - info.fordblks);
348 prev = info.fordblks;
350 command_print(cmd_ctx, "Available ram: %d", info.fordblks );
355 static bool savePower;
357 static void setPower(bool power)
362 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x14, 0x8);
365 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x8);
369 int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
373 return ERROR_INVALID_ARGUMENTS;
378 if (strcmp(args[0], "on") == 0)
382 else if (strcmp(args[0], "off") == 0)
387 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
388 return ERROR_INVALID_ARGUMENTS;
392 command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
397 int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
398 char **args, int argc)
402 command_print(cmd_ctx,
403 "append <filename> [<string1>, [<string2>, ...]]");
404 return ERROR_INVALID_ARGUMENTS;
407 FILE *config_file = NULL;
408 config_file = fopen(args[0], "a");
409 if (config_file != NULL)
412 fseek(config_file, 0, SEEK_END);
414 for (i = 1; i < argc; i++)
416 fwrite(args[i], strlen(args[i]), 1, config_file);
419 fwrite(" ", 1, 1, config_file);
422 fwrite("\n", 1, 1, config_file);
429 extern int telnet_socket;
431 int readMore(int fd, void *data, int length)
433 /* used in select() */
436 /* monitor sockets for acitvity */
439 /* listen for new connections */
440 FD_SET(fd, &read_fds);
442 // Maximum 5 seconds.
447 int retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
450 diag_printf("Timed out waiting for binary payload\n");
456 return read_socket(fd, data, length);
459 int readAll(int fd, void *data, int length)
464 int actual = readMore(fd, ((char *) data) + pos, length - pos);
465 // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
475 int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
480 return ERROR_INVALID_ARGUMENTS;
482 HAL_READ_UINT32(strtoul(args[0], NULL, 0), value);
483 command_print(cmd_ctx, "0x%x : 0x%x", strtoul(args[0], NULL, 0), value);
487 int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
491 return ERROR_INVALID_ARGUMENTS;
493 HAL_WRITE_UINT32(strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0));
497 int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
501 return ERROR_INVALID_ARGUMENTS;
504 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
508 int retval = loadFile(args[0], &data, &len);
509 if (retval != ERROR_OK)
512 FILE *f = fopen(args[1], "wb");
514 retval = ERROR_INVALID_ARGUMENTS;
519 int chunk = len - pos;
520 static const int maxChunk = 512 * 1024; // ~1/sec
521 if (chunk > maxChunk)
526 if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
527 retval = ERROR_INVALID_ARGUMENTS;
529 if (retval != ERROR_OK)
534 command_print(cmd_ctx, "%d", len - pos);
542 if (retval == ERROR_OK)
544 command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
547 command_print(cmd_ctx, "Failed: %d", retval);
555 if (retval != ERROR_OK)
561 #ifdef CYGPKG_PROFILE_GPROF
562 extern void start_profile();
564 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
566 command_print(cmd_ctx, "Profiling started");
573 externC void phi_init_all_network_interfaces();
575 command_context_t *cmd_ctx;
577 static bool webRunning = false;
579 void keep_webserver()
581 // Target initialisation is only attempted at startup, so we sleep forever and
582 // let the http server bail us out(i.e. get config files set up).
583 diag_printf("OpenOCD has invoked exit().\n"
584 "Use web server to correct any configuration settings and reboot.\n");
588 // exit() will terminate the current thread and we we'll then sleep eternally or
589 // we'll have a reboot scheduled.
592 extern void printDccChar(char c);
594 static char logBuffer[128 * 1024];
595 static const int logSize = sizeof(logBuffer);
599 void _zylinjtag_diag_write_char(char c, void **param)
603 logBuffer[writePtr] = c;
604 writePtr = (writePtr + 1) % logSize;
611 HAL_DIAG_WRITE_CHAR('\r');
613 HAL_DIAG_WRITE_CHAR(c);
616 #ifdef CYGPKG_HAL_ZYLIN_PHI
621 #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
624 static void copyfile(char *name2, char *name1)
632 fd1 = open(name1, O_WRONLY | O_CREAT);
634 SHOW_RESULT( open, fd1 );
636 fd2 = open(name2, O_RDONLY);
638 SHOW_RESULT( open, fd2 );
642 done = read(fd2, buf, IOSIZE );
645 SHOW_RESULT( read, done );
649 if( done == 0 ) break;
651 wrote = write(fd1, buf, done);
652 if( wrote != done ) SHOW_RESULT( write, wrote );
654 if( wrote != done ) break;
658 if( err < 0 ) SHOW_RESULT( close, err );
661 if( err < 0 ) SHOW_RESULT( close, err );
664 static void copydir(char *name, char *destdir)
669 dirp = opendir(destdir);
672 mkdir(destdir, 0777);
675 err = closedir(dirp);
678 dirp = opendir(name);
679 if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
683 struct dirent *entry = readdir(dirp);
688 if (strcmp(entry->d_name, ".") == 0)
690 if (strcmp(entry->d_name, "..") == 0)
695 char fullPath[PATH_MAX];
696 strncpy(fullPath, name, PATH_MAX);
697 strcat(fullPath, "/");
698 strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
700 if (stat(fullPath, &buf) == -1)
702 diag_printf("unable to read status from %s", fullPath);
705 isDir = S_ISDIR(buf.st_mode) != 0;
710 // diag_printf("<INFO>: entry %14s",entry->d_name);
711 char fullname[PATH_MAX];
712 char fullname2[PATH_MAX];
714 strcpy(fullname, name);
715 strcat(fullname, "/");
716 strcat(fullname, entry->d_name);
718 strcpy(fullname2, destdir);
719 strcat(fullname2, "/");
720 strcat(fullname2, entry->d_name);
721 // diag_printf("from %s to %s\n", fullname, fullname2);
722 copyfile(fullname, fullname2);
724 // diag_printf("\n");
727 err = closedir(dirp);
728 if( err < 0 ) SHOW_RESULT( stat, err );
732 MTAB_ENTRY( romfs_mte1,
736 (CYG_ADDRWORD) &filedata[0] );
739 void openocd_sleep_prelude()
741 cyg_mutex_unlock(&httpstate.jim_lock);
744 void openocd_sleep_postlude()
746 cyg_mutex_lock(&httpstate.jim_lock);
752 diag_printf("Formatting JFFS2...\n");
754 cyg_io_handle_t handle;
757 err = cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, &handle);
760 diag_printf("Flash Error cyg_io_lookup: %d\n", err);
766 cyg_io_flash_getconfig_devsize_t ds;
768 err = cyg_io_get_config(handle,
769 CYG_IO_GET_CONFIG_FLASH_DEVSIZE, &ds, &len);
772 diag_printf("Flash error cyg_io_get_config %d\n", err);
776 cyg_io_flash_getconfig_erase_t e;
782 e.err_address = &err_addr;
784 diag_printf("Formatting 0x%08x bytes\n", ds.dev_size);
785 err = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_FLASH_ERASE,
789 diag_printf("Flash erase error %d offset 0x%p\n", err, err_addr);
793 diag_printf("Flash formatted successfully\n");
801 zylinjtag_Jim_Command_format_jffs2(Jim_Interp *interp,
803 Jim_Obj * const *argv)
816 zylinjtag_Jim_Command_rm(Jim_Interp *interp,
818 Jim_Obj * const *argv)
823 Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
828 if (unlink(Jim_GetString(argv[1], NULL)) == 0)
830 if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
833 return del ? JIM_OK : JIM_ERR;
836 static int zylinjtag_Jim_Command_threads(Jim_Interp *interp, int argc,
837 Jim_Obj * const *argv)
839 cyg_handle_t thread = 0;
841 Jim_Obj *threads = Jim_NewListObj(interp, NULL, 0);
843 /* Loop over the threads, and generate a table row for
846 while (cyg_thread_get_next(&thread, &id))
848 Jim_Obj *threadObj = Jim_NewListObj(interp, NULL, 0);
850 cyg_thread_info info;
853 cyg_thread_get_info(thread, id, &info);
855 if (info.name == NULL)
856 info.name = "<no name>";
858 Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
859 info.name, strlen(info.name)));
861 /* Translate the state into a string.
864 state_string = "RUN";
865 else if (info.state & 0x04)
866 state_string = "SUSP";
868 switch (info.state & 0x1b)
871 state_string = "SLEEP";
874 state_string = "CNTSLEEP";
877 state_string = "CREATE";
880 state_string = "EXIT";
883 state_string = "????";
887 Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
888 state_string, strlen(state_string)));
890 Jim_ListAppendElement (interp, threadObj, Jim_NewIntObj(interp, id));
891 Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, info.set_pri));
892 Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, info.cur_pri));
894 Jim_ListAppendElement(interp, threads, threadObj);
896 Jim_SetResult( interp, threads);
903 zylinjtag_Jim_Command_ls(Jim_Interp *interp,
905 Jim_Obj * const *argv)
909 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
913 char *name = (char*) Jim_GetString(argv[1], NULL);
916 dirp = opendir(name);
921 Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
925 struct dirent *entry = NULL;
926 entry = readdir(dirp);
930 if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
933 Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
937 Jim_SetResult(interp, objPtr);
944 zylinjtag_Jim_Command_getmem(Jim_Interp *interp,
946 Jim_Obj * const *argv)
950 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
956 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
958 if (Jim_GetLong(interp, argv[2], &length) != JIM_OK)
961 if (length < 0 && length > (4096 * 1024))
963 Jim_WrongNumArgs(interp, 1, argv, "getmem ?dir?");
967 void *mem = malloc(length);
971 target_t *target = get_current_target(cmd_ctx);
976 if ((address % 4 == 0) && (count % 4 == 0))
982 if ((retval = target->type->read_memory(target, address, size, count, mem)) != ERROR_OK)
988 Jim_Obj *objPtr = Jim_NewStringObj(interp, mem, length);
989 Jim_SetResult(interp, objPtr);
997 zylinjtag_Jim_Command_peek(Jim_Interp *interp,
999 Jim_Obj * const *argv)
1003 Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
1008 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1011 int value = *((volatile int *) address);
1013 Jim_SetResult(interp, Jim_NewIntObj(interp, value));
1019 zylinjtag_Jim_Command_poke(Jim_Interp *interp,
1021 Jim_Obj * const *argv)
1025 Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
1030 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1033 if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
1036 *((volatile int *) address) = value;
1044 zylinjtag_Jim_Command_flash(Jim_Interp *interp,
1046 Jim_Obj * const *argv)
1050 flash_bank_t *t = get_flash_bank_by_num_noprobe(0);
1060 if (retval == JIM_OK)
1062 Jim_SetResult(interp, Jim_NewIntObj(interp, base));
1073 zylinjtag_Jim_Command_log(Jim_Interp *interp,
1075 Jim_Obj * const *argv)
1077 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1079 if (logCount >= logSize)
1081 Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer+logCount%logSize, logSize-logCount%logSize);
1083 Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);
1085 Jim_SetResult(interp, tclOutput);
1090 zylinjtag_Jim_Command_reboot(Jim_Interp *interp,
1092 Jim_Obj * const *argv)
1099 zylinjtag_Jim_Command_mac(Jim_Interp *interp,
1101 Jim_Obj * const *argv)
1104 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1106 Jim_AppendString(httpstate.jim_interp, tclOutput, hwaddr, strlen(hwaddr));
1108 Jim_SetResult(interp, tclOutput);
1114 zylinjtag_Jim_Command_ip(Jim_Interp *interp,
1116 Jim_Obj * const *argv)
1118 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1120 struct ifaddrs *ifa = NULL, *ifp = NULL;
1122 if (getifaddrs(&ifp) < 0)
1127 for (ifa = ifp; ifa; ifa = ifa->ifa_next)
1132 if (ifa->ifa_addr->sa_family == AF_INET)
1133 salen = sizeof(struct sockaddr_in);
1134 else if (ifa->ifa_addr->sa_family == AF_INET6)
1135 salen = sizeof(struct sockaddr_in6);
1139 if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
1140 NI_NUMERICHOST) < 0)
1145 Jim_AppendString(httpstate.jim_interp, tclOutput, ip, strlen(ip));
1152 Jim_SetResult(interp, tclOutput);
1157 extern Jim_Interp *interp;
1160 static void zylinjtag_startNetwork()
1162 // Bring TCP/IP up immediately before we're ready to accept commands.
1164 // That is as soon as a PING responds, we're accepting telnet sessions.
1165 #if defined(CYGPKG_NET_FREEBSD_STACK)
1166 phi_init_all_network_interfaces();
1172 diag_printf("Network not up and running\n");
1175 #if defined(CYGPKG_NET_FREEBSD_STACK)
1177 tftpd_start(69, &fileops);
1180 cyg_httpd_init_tcl_interpreter();
1182 interp = httpstate.jim_interp;
1184 Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log, NULL, NULL);
1185 Jim_CreateCommand(httpstate.jim_interp, "reboot", zylinjtag_Jim_Command_reboot, NULL, NULL);
1186 Jim_CreateCommand(httpstate.jim_interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);
1187 Jim_CreateCommand(httpstate.jim_interp, "zy1000_flash", zylinjtag_Jim_Command_flash, NULL, NULL);
1188 Jim_CreateCommand(httpstate.jim_interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);
1189 Jim_CreateCommand(httpstate.jim_interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);
1190 Jim_CreateCommand(httpstate.jim_interp, "threads", zylinjtag_Jim_Command_threads, NULL, NULL);
1191 Jim_CreateCommand(httpstate.jim_interp, "getmem", zylinjtag_Jim_Command_getmem, NULL, NULL);
1192 Jim_CreateCommand(httpstate.jim_interp, "mac", zylinjtag_Jim_Command_mac, NULL, NULL);
1193 Jim_CreateCommand(httpstate.jim_interp, "ip", zylinjtag_Jim_Command_ip, NULL, NULL);
1194 Jim_CreateCommand(httpstate.jim_interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
1195 Jim_CreateCommand(httpstate.jim_interp, "format_jffs2", zylinjtag_Jim_Command_format_jffs2, NULL, NULL);
1201 diag_printf("Web server running\n");
1205 s = socket(AF_INET, SOCK_DGRAM, 0);
1208 strcpy(ifr.ifr_name, "eth0");
1210 res = ioctl(s, SIOCGIFHWADDR, &ifr);
1215 diag_printf("Can't obtain MAC address\n");
1220 sprintf(hwaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
1221 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[0],
1222 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[1],
1223 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[2],
1224 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[3],
1225 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[4],
1226 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[5]);
1229 discover_message=alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr);
1239 print_exception_handler(cyg_addrword_t data, cyg_code_t exception, cyg_addrword_t info)
1243 char *infoStr = "unknown";
1246 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1247 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:
1248 infoStr = "undefined instruction";
1250 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:
1251 infoStr = "software interrupt";
1253 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:
1254 infoStr = "abort prefetch";
1256 case CYGNUM_HAL_VECTOR_ABORT_DATA:
1257 infoStr = "abort data";
1264 diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
1266 diag_printf("Dumping log\n---\n");
1267 if (logCount >= logSize)
1269 diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);
1271 diag_write(logBuffer, writePtr);
1273 diag_printf("---\nLogdump complete.\n");
1274 diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
1275 diag_printf("\n---\nRebooting\n");
1276 HAL_PLATFORM_RESET();
1280 static void setHandler(cyg_code_t exception)
1282 cyg_exception_handler_t *old_handler;
1283 cyg_addrword_t old_data;
1285 cyg_exception_set_handler(exception,
1286 print_exception_handler,
1292 static cyg_thread zylinjtag_uart_thread_object;
1293 static cyg_handle_t zylinjtag_uart_thread_handle;
1294 static char uart_stack[4096];
1296 static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
1297 static char backwardBuffer[1024];
1300 void setNoDelay(int session, int flag)
1303 // This decreases latency dramatically for e.g. GDB load which
1304 // does not have a sliding window protocol
1306 // Can cause *lots* of TCP/IP packets to be sent and it would have
1307 // to be enabled/disabled on the fly to avoid the CPU being
1309 setsockopt(session, /* socket affected */
1310 IPPROTO_TCP, /* set option at TCP level */
1311 TCP_NODELAY, /* name of option */
1312 (char *) &flag, /* the cast is historical
1314 sizeof(int)); /* length of option value */
1324 } tcpipSent[512 * 1024];
1328 zylinjtag_uart(cyg_addrword_t data)
1330 int so_reuseaddr_option = 1;
1333 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1335 LOG_ERROR("error creating socket: %s", strerror(errno));
1339 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
1341 struct sockaddr_in sin;
1342 unsigned int address_size;
1343 address_size = sizeof(sin);
1344 memset(&sin, 0, sizeof(sin));
1345 sin.sin_family = AF_INET;
1346 sin.sin_addr.s_addr = INADDR_ANY;
1347 sin.sin_port = htons(5555);
1349 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
1351 LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
1355 if (listen(fd, 1) == -1)
1357 LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
1360 // socket_nonblock(fd);
1365 int session = accept(fd, (struct sockaddr *) &sin, &address_size);
1371 setNoDelay(session, 1);
1372 int oldopts = fcntl(session, F_GETFL, 0);
1373 fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
1375 int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);
1382 #ifdef CYGPKG_PROFILE_GPROF
1395 FD_ZERO(&write_fds);
1398 FD_SET(session, &read_fds);
1400 FD_SET(serHandle, &read_fds);
1401 if (serHandle > fd_max)
1407 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
1408 if ((actual == 0) && (actual2 == 0))
1410 int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);
1419 memset(backwardBuffer, 's', sizeof(backwardBuffer));
1420 actual2=read(serHandle, backwardBuffer, sizeof(backwardBuffer));
1423 if (errno != EAGAIN)
1436 int written = write(session, backwardBuffer + pos2, actual2);
1444 if (FD_ISSET(session, &read_fds)&&(sizeof(forwardBuffer)>actual))
1446 // NB! Here it is important that we empty the TCP/IP read buffer
1447 // to make transmission tick right
1448 memmove(forwardBuffer, forwardBuffer + pos, actual);
1451 // this will block if there is no data at all
1452 t=read_socket(session, forwardBuffer+actual, sizeof(forwardBuffer)-actual);
1464 /* Do not put things into the serial buffer if it has something to send
1465 * as that can cause a single byte to be sent at the time.
1469 int written = write(serHandle, forwardBuffer + pos, actual);
1472 if (errno != EAGAIN)
1476 // The serial buffer is full
1487 tcpipSent[cur].req = x;
1488 tcpipSent[cur].actual = y;
1489 tcpipSent[cur].req2 = x2;
1490 tcpipSent[cur].actual2 = y2;
1500 for (i = 0; i < 1024; i++)
1502 diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual, tcpipSent[i].req2, tcpipSent[i].actual2);
1510 void startUart(void)
1512 cyg_thread_create(1,
1518 &zylinjtag_uart_thread_handle,
1519 &zylinjtag_uart_thread_object);
1520 cyg_thread_set_priority(zylinjtag_uart_thread_handle, 1); // low priority as it sits in a busy loop
1521 cyg_thread_resume(zylinjtag_uart_thread_handle);
1526 int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1528 static int current_baud = 38400;
1531 command_print(cmd_ctx, "%d", current_baud);
1533 } else if (argc != 1)
1535 return ERROR_INVALID_ARGUMENTS;
1538 current_baud = atol(args[0]);
1541 switch (current_baud)
1544 baud = CYGNUM_SERIAL_BAUD_9600;
1547 baud = CYGNUM_SERIAL_BAUD_19200;
1550 baud = CYGNUM_SERIAL_BAUD_38400;
1553 baud = CYGNUM_SERIAL_BAUD_57600;
1556 baud = CYGNUM_SERIAL_BAUD_115200;
1559 baud = CYGNUM_SERIAL_BAUD_230400;
1562 command_print(cmd_ctx, "unsupported baudrate");
1563 return ERROR_INVALID_ARGUMENTS;
1566 cyg_serial_info_t buf;
1568 //get existing serial configuration
1569 len = sizeof(cyg_serial_info_t);
1571 cyg_io_handle_t serial_handle;
1573 err = cyg_io_lookup("/dev/ser0", &serial_handle);
1576 LOG_ERROR("/dev/ser0 not found\n");
1581 err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buf, &len);
1582 err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &buf, &len);
1585 command_print(cmd_ctx, "Failed to get serial port settings %d", err);
1590 err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf, &len);
1593 command_print(cmd_ctx, "Failed to set serial port settings %d", err);
1600 bool logAllToSerial = false;
1602 /* boolean parameter stored on config */
1603 bool boolParam(char *var)
1605 bool result = false;
1606 char *name = alloc_printf(ZYLIN_CONFIG_DIR "/%s", var);
1612 if (loadFile(name, &data, &len) == ERROR_OK)
1616 result = strncmp((char *) data, "1", len) == 0;
1623 command_context_t *setup_command_handler();
1625 int add_default_dirs(void)
1627 add_script_search_dir(ZYLIN_CONFIG_DIR);
1628 add_script_search_dir("/rom/lib/openocd");
1629 add_script_search_dir("/rom");
1633 static cyg_uint8 *ramblockdevice;
1634 static const int ramblockdevice_size=4096*1024;
1635 int main(int argc, char *argv[])
1637 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
1638 * need to allocate towards the end of the heap. */
1640 ramblockdevice=(cyg_uint8 *)malloc(ramblockdevice_size);
1641 memset(ramblockdevice, 0xff, ramblockdevice_size);
1645 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1646 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION);
1647 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH);
1648 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA);
1653 setPower(true); // on by default
1655 atexit(keep_webserver);
1657 err = mount("", "/ram", "ramfs");
1660 diag_printf("unable to mount ramfs\n");
1665 sprintf(address, "%p", &filedata[0]);
1666 err = mount(address, "/rom", "romfs");
1669 diag_printf("unable to mount /rom\n");
1672 err = mount("", "/log", "logfs");
1675 diag_printf("unable to mount logfs\n");
1678 err = mount("", "/tftp", "tftpfs");
1681 diag_printf("unable to mount logfs\n");
1684 log = fopen("/log/log", "w");
1687 diag_printf("Could not open log file /ram/log\n");
1691 diag_init_putc(_zylinjtag_diag_write_char);
1693 // We want this in the log.
1694 diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
1695 diag_printf("%s\n", ZYLIN_OPENOCD_VERSION);
1697 copydir("/rom", "/ram/cgi");
1699 err = mount("/dev/flash1", "/config", "jffs2");
1702 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1703 err = mount("", "/config", "ramfs");
1706 diag_printf("unable to mount /config as ramdisk.\n");
1711 /* are we using a ram disk instead of a flash disk? This is used
1712 * for ZY1000 live demo...
1714 * copy over flash disk to ram block device
1716 if (boolParam("ramdisk"))
1718 diag_printf("Unmounting /config from flash and using ram instead\n");
1719 err=umount("/config");
1722 diag_printf("unable to unmount jffs\n");
1726 err = mount("/dev/flash1", "/config2", "jffs2");
1729 diag_printf("unable to mount jffs\n");
1733 err = mount("", "/config", "ramfs");
1736 diag_printf("unable to mount ram block device\n");
1740 // copydir("/config2", "/config");
1741 copyfile("/config2/ip", "/config/ip");
1742 copydir("/config2/settings", "/config/settings");
1747 /* we're not going to use a ram block disk */
1748 free(ramblockdevice);
1753 mkdir(ZYLIN_CONFIG_DIR, 0777);
1754 mkdir(ZYLIN_CONFIG_DIR "/target", 0777);
1755 mkdir(ZYLIN_CONFIG_DIR "/event", 0777);
1757 logAllToSerial = boolParam("logserial");
1759 // We need the network & web server in case there is something wrong with
1760 // the config files that invoke exit()
1761 zylinjtag_startNetwork();
1763 /* we're going to access the jim interpreter from here on... */
1764 openocd_sleep_postlude();
1769 /* initialize commandline interface */
1770 command_context_t *cmd_ctx;
1771 cmd_ctx = setup_command_handler();
1772 command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
1773 command_context_mode(cmd_ctx, COMMAND_CONFIG);
1776 register_command(cmd_ctx, NULL, "zy1000_version", handle_zy1000_version_command,
1777 COMMAND_EXEC, "show zy1000 version numbers");
1779 register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
1782 register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
1783 "display file content");
1785 register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
1786 "truncate a file to 0 size");
1788 register_command(cmd_ctx, NULL, "append_file", handle_append_command,
1789 COMMAND_ANY, "append a variable number of strings to a file");
1791 register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
1792 "power <on/off> - turn power switch to target on/off. No arguments - print status.");
1794 register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
1795 COMMAND_ANY, "display available ram memory");
1797 register_command(cmd_ctx, NULL, "cp", handle_cp_command,
1798 COMMAND_ANY, "copy a file <from> <to>");
1800 #ifdef CYGPKG_PROFILE_GPROF
1801 register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,
1804 register_command(cmd_ctx, NULL, "uart", handle_uart_command,
1805 COMMAND_ANY, "uart <baud> - forward uart on port 5555");
1809 errVal = log_init(cmd_ctx);
1810 if (errVal != ERROR_OK)
1812 diag_printf("log_init() failed %d\n", errVal);
1816 set_log_output(cmd_ctx, log);
1818 LOG_DEBUG("log init complete");
1820 // diag_printf("Executing config files\n");
1824 diag_printf(ZYLIN_CONFIG_DIR "/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
1825 command_run_line(cmd_ctx, "debug_level 3");
1828 zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
1831 // diag_printf() is really invoked from many more places than we trust it
1832 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1834 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1835 // fingers that it doesn't cause any crashes.
1836 diag_printf("Init complete, GDB & telnet servers launched.\n");
1837 command_set_output_handler(cmd_ctx, zy1000_configuration_output_handler_log, NULL);
1838 if (!logAllToSerial)
1843 /* handle network connections */
1844 server_loop(cmd_ctx);
1845 openocd_sleep_prelude();
1847 /* shut server down */
1850 /* free commandline interface */
1851 command_done(cmd_ctx);
1861 cyg_httpd_exec_cgi_tcl(char *file_name);
1862 cyg_int32 homeForm(CYG_HTTPD_STATE *p)
1864 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1868 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);
1870 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label, "text", "text/plain");
1871 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream");
1873 #include <pkgconf/system.h>
1874 #include <pkgconf/hal.h>
1875 #include <pkgconf/kernel.h>
1876 #include <pkgconf/io_fileio.h>
1877 #include <pkgconf/fs_rom.h>
1879 #include <cyg/kernel/ktypes.h> // base kernel types
1880 #include <cyg/infra/cyg_trac.h> // tracing macros
1881 #include <cyg/infra/cyg_ass.h> // assertion macros
1883 #include <sys/types.h>
1885 #include <sys/stat.h>
1894 #include <cyg/fileio/fileio.h>
1896 #include <cyg/kernel/kapi.h>
1897 #include <cyg/infra/diag.h>
1899 //==========================================================================
1900 // Eventually we want to eXecute In Place from the ROM in a protected
1901 // environment, so we'll need executables to be aligned to a boundary
1902 // suitable for MMU protection. A suitable boundary would be the 4k
1903 // boundary in all the CPU architectures I am currently aware of.
1905 // Forward definitions
1907 // Filesystem operations
1908 static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
1909 static int tftpfs_umount(cyg_mtab_entry *mte);
1910 static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
1911 int mode, cyg_file *fte);
1912 static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
1913 static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
1916 static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
1917 static int tftpfs_fo_close(struct CYG_FILE_TAG *fp);
1918 static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence);
1920 //==========================================================================
1921 // Filesystem table entries
1923 // -------------------------------------------------------------------------
1925 // This defines the entry in the filesystem table.
1926 // For simplicity we use _FILESYSTEM synchronization for all accesses since
1927 // we should never block in any filesystem operations.
1929 FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0,
1934 (cyg_fsop_unlink *)cyg_fileio_erofs,
1935 (cyg_fsop_mkdir *)cyg_fileio_erofs,
1936 (cyg_fsop_rmdir *)cyg_fileio_erofs,
1937 (cyg_fsop_rename *)cyg_fileio_erofs,
1938 (cyg_fsop_link *)cyg_fileio_erofs,
1939 (cyg_fsop_opendir *)cyg_fileio_erofs,
1940 (cyg_fsop_chdir *)cyg_fileio_erofs,
1941 (cyg_fsop_stat *)cyg_fileio_erofs,
1942 (cyg_fsop_getinfo *)cyg_fileio_erofs,
1943 (cyg_fsop_setinfo *)cyg_fileio_erofs);
1946 // -------------------------------------------------------------------------
1948 // This defines a single ROMFS loaded into ROM at the configured address
1950 // MTAB_ENTRY( rom_mte, // structure name
1951 // "/rom", // mount point
1952 // "romfs", // FIlesystem type
1953 // "", // hardware device
1954 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
1958 // -------------------------------------------------------------------------
1960 // This set of file operations are used for normal open files.
1962 static cyg_fileops tftpfs_fileops =
1967 (cyg_fileop_ioctl *)cyg_fileio_erofs,
1971 (cyg_fileop_fstat *) cyg_fileio_erofs,
1972 (cyg_fileop_getinfo *) cyg_fileio_erofs,
1973 (cyg_fileop_setinfo *)cyg_fileio_erofs,
1976 // -------------------------------------------------------------------------
1978 // Process a mount request. This mainly finds root for the
1981 static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
1986 static int tftpfs_umount(cyg_mtab_entry *mte)
2001 static void freeTftp(struct Tftp *t)
2014 static const int tftpMaxSize = 8192 * 1024;
2015 static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2016 int mode, cyg_file *file)
2019 tftp = malloc(sizeof(struct Tftp));
2022 memset(tftp, 0, sizeof(struct Tftp));
2024 file->f_flag |= mode & CYG_FILE_MODE_MASK;
2025 file->f_type = CYG_FILE_TYPE_FILE;
2026 file->f_ops = &tftpfs_fileops;
2031 tftp->mem = malloc(tftpMaxSize);
2032 if (tftp->mem == NULL)
2038 char *server = strchr(name, '/');
2045 tftp->server = malloc(server - name + 1);
2046 if (tftp->server == NULL)
2051 strncpy(tftp->server, name, server - name);
2052 tftp->server[server - name] = 0;
2054 tftp->file = strdup(server + 1);
2055 if (tftp->file == NULL)
2061 file->f_data = (CYG_ADDRWORD) tftp;
2066 static int fetchTftp(struct Tftp *tftp)
2068 if (!tftp->readFile)
2071 tftp->actual = tftp_client_get( tftp->file, tftp->server, 0, tftp->mem, tftpMaxSize, TFTP_OCTET, &err);
2073 if (tftp->actual < 0)
2082 // -------------------------------------------------------------------------
2083 // tftpfs_fo_write()
2084 // Read data from file.
2087 tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2089 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2091 if (fetchTftp(tftp) != ENOERR)
2095 off_t pos = fp->f_offset;
2097 for (i = 0; i < uio->uio_iovcnt; i++)
2099 cyg_iovec *iov = &uio->uio_iov[i];
2100 char *buf = (char *) iov->iov_base;
2101 off_t len = iov->iov_len;
2103 if (len + pos > tftp->actual)
2105 len = tftp->actual - pos;
2107 resid += iov->iov_len - len;
2109 memcpy(buf, tftp->mem + pos, len);
2113 uio->uio_resid = resid;
2121 tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2123 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2126 off_t pos = fp->f_offset;
2128 for (i = 0; i < uio->uio_iovcnt; i++)
2130 cyg_iovec *iov = &uio->uio_iov[i];
2131 char *buf = (char *) iov->iov_base;
2132 off_t len = iov->iov_len;
2134 if (len + pos > tftpMaxSize)
2136 len = tftpMaxSize - pos;
2138 resid += iov->iov_len - len;
2140 memcpy(tftp->mem + pos, buf, len);
2144 uio->uio_resid = resid;
2153 tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
2159 // -------------------------------------------------------------------------
2161 // Close a file. We just clear out the data pointer.
2163 static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)
2165 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2170 tftp_client_put( tftp->file, tftp->server, 0, tftp->mem, fp->f_offset, TFTP_OCTET, &error);
2178 // -------------------------------------------------------------------------
2180 // Seek to a new file position.
2182 static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)
2184 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2187 if (fetchTftp(tftp) != ENOERR)
2193 // Pos is already where we want to be.
2197 // Add pos to current offset.
2198 pos += fp->f_offset;
2202 // Add pos to file size.
2203 pos += tftp->actual;
2210 // Check that pos is still within current file size, or at the
2212 if (pos < 0 || pos > tftp->actual)
2215 // All OK, set fp offset and return new position.
2216 *apos = fp->f_offset = pos;
2224 cyg_thread_delay(us / 10000 + 1);
2231 show_log_entry(CYG_HTTPD_STATE *phttpstate)
2233 cyg_httpd_start_chunked("text");
2234 if (logCount >= logSize)
2236 cyg_httpd_write_chunked(logBuffer+logCount%logSize, logSize-logCount%logSize);
2238 cyg_httpd_write_chunked(logBuffer, writePtr);
2239 cyg_httpd_end_chunked();
2243 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);
2245 // Filesystem operations
2246 static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
2247 static int logfs_umount(cyg_mtab_entry *mte);
2248 static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2249 int mode, cyg_file *fte);
2251 logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
2254 static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
2255 static int logfs_fo_close(struct CYG_FILE_TAG *fp);
2257 #include <cyg/io/devtab.h>
2259 //==========================================================================
2260 // Filesystem table entries
2262 // -------------------------------------------------------------------------
2264 // This defines the entry in the filesystem table.
2265 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2266 // we should never block in any filesystem operations.
2267 FSTAB_ENTRY( logfs_fste, "logfs", 0,
2268 CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,
2272 (cyg_fsop_unlink *)cyg_fileio_erofs,
2273 (cyg_fsop_mkdir *)cyg_fileio_erofs,
2274 (cyg_fsop_rmdir *)cyg_fileio_erofs,
2275 (cyg_fsop_rename *)cyg_fileio_erofs,
2276 (cyg_fsop_link *)cyg_fileio_erofs,
2277 (cyg_fsop_opendir *)cyg_fileio_erofs,
2278 (cyg_fsop_chdir *)cyg_fileio_erofs,
2279 (cyg_fsop_stat *)cyg_fileio_erofs,
2280 (cyg_fsop_getinfo *)cyg_fileio_erofs,
2281 (cyg_fsop_setinfo *)cyg_fileio_erofs);
2283 // -------------------------------------------------------------------------
2285 // This set of file operations are used for normal open files.
2287 static cyg_fileops logfs_fileops =
2289 (cyg_fileop_read *)cyg_fileio_erofs,
2290 (cyg_fileop_write *)logfs_fo_write,
2291 (cyg_fileop_lseek *) cyg_fileio_erofs,
2292 (cyg_fileop_ioctl *)cyg_fileio_erofs,
2296 (cyg_fileop_fstat *)cyg_fileio_erofs,
2297 (cyg_fileop_getinfo *) cyg_fileio_erofs,
2298 (cyg_fileop_setinfo *)cyg_fileio_erofs,
2301 // -------------------------------------------------------------------------
2303 // Process a mount request. This mainly finds root for the
2306 static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
2311 static int logfs_umount(cyg_mtab_entry *mte)
2316 static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2317 int mode, cyg_file *file)
2319 file->f_flag |= mode & CYG_FILE_MODE_MASK;
2320 file->f_type = CYG_FILE_TYPE_FILE;
2321 file->f_ops = &logfs_fileops;
2328 // -------------------------------------------------------------------------
2330 // Write data to file.
2333 logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2336 for (i = 0; i < uio->uio_iovcnt; i++)
2338 cyg_iovec *iov = &uio->uio_iov[i];
2339 char *buf = (char *) iov->iov_base;
2340 off_t len = iov->iov_len;
2342 diag_write(buf, len);
2349 logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
2354 // -------------------------------------------------------------------------
2356 // Close a file. We just clear out the data pointer.
2358 static int logfs_fo_close(struct CYG_FILE_TAG *fp)