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.47"
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;
131 static int fastload_num
;
132 static struct FastLoad
*fastload
;
134 static void free_fastload()
139 for (i
=0; i
<fastload_num
; i
++)
141 if (fastload
[i
].data
)
142 free(fastload
[i
].data
);
150 int handle_fast_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
156 u32 max_address
=0xffffffff;
165 if ((argc
< 1)||(argc
> 5))
167 return ERROR_COMMAND_SYNTAX_ERROR
;
170 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
173 image
.base_address_set
= 1;
174 image
.base_address
= strtoul(args
[1], NULL
, 0);
178 image
.base_address_set
= 0;
182 image
.start_address_set
= 0;
186 min_address
=strtoul(args
[3], NULL
, 0);
190 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
193 if (min_address
>max_address
)
195 return ERROR_COMMAND_SYNTAX_ERROR
;
198 duration_start_measure(&duration
);
200 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
207 fastload_num
=image
.num_sections
;
208 fastload
=(struct FastLoad
*)malloc(sizeof(struct FastLoad
)*image
.num_sections
);
214 memset(fastload
, 0, sizeof(struct FastLoad
)*image
.num_sections
);
215 for (i
= 0; i
< image
.num_sections
; i
++)
217 buffer
= malloc(image
.sections
[i
].size
);
220 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
224 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
234 /* DANGER!!! beware of unsigned comparision here!!! */
236 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
237 (image
.sections
[i
].base_address
<max_address
))
239 if (image
.sections
[i
].base_address
<min_address
)
241 /* clip addresses below */
242 offset
+=min_address
-image
.sections
[i
].base_address
;
246 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
248 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
251 fastload
[i
].address
=image
.sections
[i
].base_address
+offset
;
252 fastload
[i
].data
=malloc(length
);
253 if (fastload
[i
].data
==NULL
)
258 memcpy(fastload
[i
].data
, buffer
+offset
, length
);
259 fastload
[i
].length
=length
;
261 image_size
+= length
;
262 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
268 duration_stop_measure(&duration
, &duration_text
);
269 if (retval
==ERROR_OK
)
271 command_print(cmd_ctx
, "Loaded %u bytes in %s", image_size
, duration_text
);
272 command_print(cmd_ctx
, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
278 if (retval
!=ERROR_OK
)
286 int handle_fast_load_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
289 return ERROR_COMMAND_SYNTAX_ERROR
;
292 LOG_ERROR("No image in memory");
298 for (i
=0; i
<fastload_num
;i
++)
301 target_t
*target
= get_current_target(cmd_ctx
);
302 if ((retval
= target_write_buffer(target
, fastload
[i
].address
, fastload
[i
].length
, fastload
[i
].data
)) != ERROR_OK
)
306 size
+=fastload
[i
].length
;
308 int after
=timeval_ms();
309 command_print(cmd_ctx
, "Loaded image %f kBytes/s", (float)(size
/1024.0)/((float)(after
-ms
)/1000.0));
314 /* Give TELNET a way to find out what version this is */
315 int handle_zy1000_version_command(struct command_context_s
*cmd_ctx
, char *cmd
,
316 char **args
, int argc
)
320 return ERROR_COMMAND_SYNTAX_ERROR
;
324 command_print(cmd_ctx
, ZYLIN_OPENOCD_VERSION
);
325 } else if (strcmp("openocd", args
[0])==0)
328 revision
=atol(ZYLIN_OPENOCD
+strlen("XRevision: "));
329 command_print(cmd_ctx
, "%d", revision
);
330 } else if (strcmp("zy1000", args
[0])==0)
332 command_print(cmd_ctx
, "%s", ZYLIN_VERSION
);
333 } else if (strcmp("date", args
[0])==0)
335 command_print(cmd_ctx
, "%s", ZYLIN_DATE
);
338 return ERROR_COMMAND_SYNTAX_ERROR
;
344 extern flash_driver_t
*flash_drivers
[];
345 extern target_type_t
*target_types
[];
347 #ifdef CYGPKG_PROFILE_GPROF
348 #include <cyg/profile/profile.h>
350 extern char _stext
, _etext
; // Defined by the linker
352 void start_profile(void)
354 // This starts up the system-wide profiling, gathering
355 // profile information on all of the code, with a 16 byte
356 // "bucket" size, at a rate of 100us/profile hit.
357 // Note: a bucket size of 16 will give pretty good function
358 // resolution. Much smaller and the buffer becomes
359 // much too large for very little gain.
360 // Note: a timer period of 100us is also a reasonable
361 // compromise. Any smaller and the overhead of
362 // handling the timter (profile) interrupt could
363 // swamp the system. A fast processor might get
364 // by with a smaller value, but a slow one could
365 // even be swamped by this value. If the value is
366 // too large, the usefulness of the profile is reduced.
368 // no more interrupts than 1/10ms.
369 // profile_on(&_stext, &_etext, 16, 10000); // DRAM
370 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
371 profile_on(0, &_etext
, 16, 10000); // SRAM & DRAM
375 // launch GDB server if a config file exists
376 bool zylinjtag_parse_config_file(struct command_context_s
*cmd_ctx
, const char *config_file_name
)
378 bool foundFile
= false;
379 FILE *config_file
= NULL
;
380 command_print(cmd_ctx
, "executing config file %s", config_file_name
);
381 config_file
= fopen(config_file_name
, "r");
386 retval
= command_run_linef(cmd_ctx
, "script %s", config_file_name
);
387 if (retval
== ERROR_OK
)
393 command_print(cmd_ctx
, "Failed executing %s %d", config_file_name
, retval
);
398 command_print(cmd_ctx
, "No %s found", config_file_name
);
407 static char reboot_stack
[2048];
411 zylinjtag_reboot(cyg_addrword_t data
)
414 diag_printf("Rebooting in 100 ticks..\n");
415 cyg_thread_delay(100);
416 diag_printf("Unmounting /config..\n");
418 diag_printf("Rebooting..\n");
419 HAL_PLATFORM_RESET();
421 static cyg_thread zylinjtag_thread_object
;
422 static cyg_handle_t zylinjtag_thread_handle
;
430 (void *)reboot_stack
,
431 sizeof(reboot_stack
),
432 &zylinjtag_thread_handle
,
433 &zylinjtag_thread_object
);
434 cyg_thread_resume(zylinjtag_thread_handle
);
437 int configuration_output_handler(struct command_context_s
*context
, const char* line
)
439 diag_printf("%s", line
);
444 int zy1000_configuration_output_handler_log(struct command_context_s
*context
, const char* line
)
446 LOG_USER_N("%s", line
);
451 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
452 char **args
, int argc
)
456 command_print(cmd_ctx
, "rm <filename>");
457 return ERROR_INVALID_ARGUMENTS
;
460 if (unlink(args
[0]) != 0)
462 command_print(cmd_ctx
, "failed: %d", errno
);
468 int loadFile(const char *fileName
, void **data
, int *len
);
470 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
471 char **args
, int argc
)
475 command_print(cmd_ctx
, "cat <filename>");
476 return ERROR_INVALID_ARGUMENTS
;
479 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
483 int retval
= loadFile(args
[0], &data
, &len
);
484 if (retval
== ERROR_OK
)
486 command_print(cmd_ctx
, "%s", data
);
491 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
496 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
497 char **args
, int argc
)
501 command_print(cmd_ctx
, "trunc <filename>");
502 return ERROR_INVALID_ARGUMENTS
;
505 FILE *config_file
= NULL
;
506 config_file
= fopen(args
[0], "w");
507 if (config_file
!= NULL
)
514 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
517 struct mallinfo info
;
521 command_print(cmd_ctx
, "meminfo");
522 return ERROR_INVALID_ARGUMENTS
;
529 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
531 prev
= info
.fordblks
;
533 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
538 static bool savePower
;
540 static void setPower(bool power
)
545 HAL_WRITE_UINT32(0x08000014, 0x8);
548 HAL_WRITE_UINT32(0x08000010, 0x8);
552 int handle_power_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
556 return ERROR_INVALID_ARGUMENTS
;
561 if (strcmp(args
[0], "on") == 0)
565 else if (strcmp(args
[0], "off") == 0)
570 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
571 return ERROR_INVALID_ARGUMENTS
;
575 command_print(cmd_ctx
, "Target power %s", savePower
? "on" : "off");
580 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
581 char **args
, int argc
)
585 command_print(cmd_ctx
,
586 "append <filename> [<string1>, [<string2>, ...]]");
587 return ERROR_INVALID_ARGUMENTS
;
590 FILE *config_file
= NULL
;
591 config_file
= fopen(args
[0], "a");
592 if (config_file
!= NULL
)
595 fseek(config_file
, 0, SEEK_END
);
597 for (i
= 1; i
< argc
; i
++)
599 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
602 fwrite(" ", 1, 1, config_file
);
605 fwrite("\n", 1, 1, config_file
);
612 extern int telnet_socket
;
614 int readMore(int fd
, void *data
, int length
)
616 /* used in select() */
619 /* monitor sockets for acitvity */
622 /* listen for new connections */
623 FD_SET(fd
, &read_fds
);
625 // Maximum 5 seconds.
630 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
633 diag_printf("Timed out waiting for binary payload\n");
639 return read_socket(fd
, data
, length
);
642 int readAll(int fd
, void *data
, int length
)
647 int actual
= readMore(fd
, ((char *) data
) + pos
, length
- pos
);
648 // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
658 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
663 return ERROR_INVALID_ARGUMENTS
;
665 HAL_READ_UINT32(strtoul(args
[0], NULL
, 0), value
);
666 command_print(cmd_ctx
, "0x%x : 0x%x", strtoul(args
[0], NULL
, 0), value
);
670 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
674 return ERROR_INVALID_ARGUMENTS
;
676 HAL_WRITE_UINT32(strtoul(args
[0], NULL
, 0), strtoul(args
[1], NULL
, 0));
680 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
684 return ERROR_INVALID_ARGUMENTS
;
687 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
691 int retval
= loadFile(args
[0], &data
, &len
);
692 if (retval
!= ERROR_OK
)
695 FILE *f
= fopen(args
[1], "wb");
697 retval
= ERROR_INVALID_ARGUMENTS
;
702 int chunk
= len
- pos
;
703 static const int maxChunk
= 512 * 1024; // ~1/sec
704 if (chunk
> maxChunk
)
709 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
710 retval
= ERROR_INVALID_ARGUMENTS
;
712 if (retval
!= ERROR_OK
)
717 command_print(cmd_ctx
, "%d", len
- pos
);
725 if (retval
== ERROR_OK
)
727 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
730 command_print(cmd_ctx
, "Failed: %d", retval
);
738 if (retval
!= ERROR_OK
)
744 #ifdef CYGPKG_PROFILE_GPROF
745 extern void start_profile();
747 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
749 command_print(cmd_ctx
, "Profiling started");
756 externC
void phi_init_all_network_interfaces();
758 command_context_t
*cmd_ctx
;
760 static bool webRunning
= false;
762 void keep_webserver()
764 // Target initialisation is only attempted at startup, so we sleep forever and
765 // let the http server bail us out(i.e. get config files set up).
766 diag_printf("OpenOCD has invoked exit().\n"
767 "Use web server to correct any configuration settings and reboot.\n");
771 // exit() will terminate the current thread and we we'll then sleep eternally or
772 // we'll have a reboot scheduled.
775 extern void printDccChar(char c
);
777 static char logBuffer
[128 * 1024];
778 static const int logSize
= sizeof(logBuffer
);
782 void _zylinjtag_diag_write_char(char c
, void **param
)
786 logBuffer
[writePtr
] = c
;
787 writePtr
= (writePtr
+ 1) % logSize
;
794 HAL_DIAG_WRITE_CHAR('\r');
796 HAL_DIAG_WRITE_CHAR(c
);
802 #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
805 static void copyfile(char *name2
, char *name1
)
813 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
815 SHOW_RESULT( open
, fd1
);
817 fd2
= open(name2
, O_RDONLY
);
819 SHOW_RESULT( open
, fd2
);
823 done
= read(fd2
, buf
, IOSIZE
);
826 SHOW_RESULT( read
, done
);
830 if( done
== 0 ) break;
832 wrote
= write(fd1
, buf
, done
);
833 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
835 if( wrote
!= done
) break;
839 if( err
< 0 ) SHOW_RESULT( close
, err
);
842 if( err
< 0 ) SHOW_RESULT( close
, err
);
845 static void copydir(char *name
, char *destdir
)
850 dirp
= opendir(destdir
);
853 mkdir(destdir
, 0777);
856 err
= closedir(dirp
);
859 dirp
= opendir(name
);
860 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
864 struct dirent
*entry
= readdir(dirp
);
869 if (strcmp(entry
->d_name
, ".") == 0)
871 if (strcmp(entry
->d_name
, "..") == 0)
876 char fullPath
[PATH_MAX
];
877 strncpy(fullPath
, name
, PATH_MAX
);
878 strcat(fullPath
, "/");
879 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
881 if (stat(fullPath
, &buf
) == -1)
883 diag_printf("unable to read status from %s", fullPath
);
886 isDir
= S_ISDIR(buf
.st_mode
) != 0;
891 // diag_printf("<INFO>: entry %14s",entry->d_name);
892 char fullname
[PATH_MAX
];
893 char fullname2
[PATH_MAX
];
895 strcpy(fullname
, name
);
896 strcat(fullname
, "/");
897 strcat(fullname
, entry
->d_name
);
899 strcpy(fullname2
, destdir
);
900 strcat(fullname2
, "/");
901 strcat(fullname2
, entry
->d_name
);
902 // diag_printf("from %s to %s\n", fullname, fullname2);
903 copyfile(fullname
, fullname2
);
905 // diag_printf("\n");
908 err
= closedir(dirp
);
909 if( err
< 0 ) SHOW_RESULT( stat
, err
);
913 MTAB_ENTRY( romfs_mte1
,
917 (CYG_ADDRWORD
) &filedata
[0] );
920 void openocd_sleep_prelude()
922 cyg_mutex_unlock(&httpstate
.jim_lock
);
925 void openocd_sleep_postlude()
927 cyg_mutex_lock(&httpstate
.jim_lock
);
931 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
933 Jim_Obj
* const *argv
)
938 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
943 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
945 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
948 return del
? JIM_OK
: JIM_ERR
;
951 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
952 Jim_Obj
* const *argv
)
954 cyg_handle_t thread
= 0;
956 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
958 /* Loop over the threads, and generate a table row for
961 while (cyg_thread_get_next(&thread
, &id
))
963 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
965 cyg_thread_info info
;
968 cyg_thread_get_info(thread
, id
, &info
);
970 if (info
.name
== NULL
)
971 info
.name
= "<no name>";
973 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
974 info
.name
, strlen(info
.name
)));
976 /* Translate the state into a string.
979 state_string
= "RUN";
980 else if (info
.state
& 0x04)
981 state_string
= "SUSP";
983 switch (info
.state
& 0x1b)
986 state_string
= "SLEEP";
989 state_string
= "CNTSLEEP";
992 state_string
= "CREATE";
995 state_string
= "EXIT";
998 state_string
= "????";
1002 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
1003 state_string
, strlen(state_string
)));
1005 Jim_ListAppendElement (interp
, threadObj
, Jim_NewIntObj(interp
, id
));
1006 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, info
.set_pri
));
1007 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, info
.cur_pri
));
1009 Jim_ListAppendElement(interp
, threads
, threadObj
);
1011 Jim_SetResult( interp
, threads
);
1018 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
1020 Jim_Obj
* const *argv
)
1024 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
1028 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
1031 dirp
= opendir(name
);
1036 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
1040 struct dirent
*entry
= NULL
;
1041 entry
= readdir(dirp
);
1045 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
1048 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
1052 Jim_SetResult(interp
, objPtr
);
1059 zylinjtag_Jim_Command_getmem(Jim_Interp
*interp
,
1061 Jim_Obj
* const *argv
)
1065 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
1071 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1073 if (Jim_GetLong(interp
, argv
[2], &length
) != JIM_OK
)
1076 if (length
< 0 && length
> (4096 * 1024))
1078 Jim_WrongNumArgs(interp
, 1, argv
, "getmem ?dir?");
1082 void *mem
= malloc(length
);
1086 target_t
*target
= get_current_target(cmd_ctx
);
1091 if ((address
% 4 == 0) && (count
% 4 == 0))
1097 if ((retval
= target
->type
->read_memory(target
, address
, size
, count
, mem
)) != ERROR_OK
)
1103 Jim_Obj
*objPtr
= Jim_NewStringObj(interp
, mem
, length
);
1104 Jim_SetResult(interp
, objPtr
);
1112 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
1114 Jim_Obj
* const *argv
)
1118 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
1123 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1126 int value
= *((volatile int *) address
);
1128 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
1134 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
1136 Jim_Obj
* const *argv
)
1140 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
1145 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1148 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
1151 *((volatile int *) address
) = value
;
1159 zylinjtag_Jim_Command_flash(Jim_Interp
*interp
,
1161 Jim_Obj
* const *argv
)
1165 flash_bank_t
*t
= get_flash_bank_by_num_noprobe(0);
1175 if (retval
== JIM_OK
)
1177 Jim_SetResult(interp
, Jim_NewIntObj(interp
, base
));
1188 zylinjtag_Jim_Command_log(Jim_Interp
*interp
,
1190 Jim_Obj
* const *argv
)
1192 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1194 if (logCount
>= logSize
)
1196 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+logCount
%logSize
, logSize
-logCount
%logSize
);
1198 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
1200 Jim_SetResult(interp
, tclOutput
);
1205 zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
,
1207 Jim_Obj
* const *argv
)
1214 zylinjtag_Jim_Command_mac(Jim_Interp
*interp
,
1216 Jim_Obj
* const *argv
)
1220 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
1223 strcpy(ifr
.ifr_name
, "eth0");
1225 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
1234 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1237 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
1238 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
1239 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
1240 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
1241 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
1242 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
1243 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
1245 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, hwaddr
, strlen(hwaddr
));
1247 Jim_SetResult(interp
, tclOutput
);
1253 zylinjtag_Jim_Command_ip(Jim_Interp
*interp
,
1255 Jim_Obj
* const *argv
)
1257 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1259 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
1261 if (getifaddrs(&ifp
) < 0)
1266 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
1271 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1272 salen
= sizeof(struct sockaddr_in
);
1273 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1274 salen
= sizeof(struct sockaddr_in6
);
1278 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
1279 NI_NUMERICHOST
) < 0)
1284 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, ip
, strlen(ip
));
1291 Jim_SetResult(interp
, tclOutput
);
1296 extern Jim_Interp
*interp
;
1298 static void zylinjtag_startNetwork()
1300 // Bring TCP/IP up immediately before we're ready to accept commands.
1302 // That is as soon as a PING responds, we're accepting telnet sessions.
1303 #if defined(CYGPKG_NET_FREEBSD_STACK)
1304 phi_init_all_network_interfaces();
1310 diag_printf("Network not up and running\n");
1313 #if defined(CYGPKG_NET_FREEBSD_STACK)
1315 tftpd_start(69, &fileops
);
1318 cyg_httpd_init_tcl_interpreter();
1320 interp
= httpstate
.jim_interp
;
1322 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
, NULL
, NULL
);
1323 Jim_CreateCommand(httpstate
.jim_interp
, "reboot", zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
1324 Jim_CreateCommand(httpstate
.jim_interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
1325 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_flash", zylinjtag_Jim_Command_flash
, NULL
, NULL
);
1326 Jim_CreateCommand(httpstate
.jim_interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
1327 Jim_CreateCommand(httpstate
.jim_interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
1328 Jim_CreateCommand(httpstate
.jim_interp
, "threads", zylinjtag_Jim_Command_threads
, NULL
, NULL
);
1329 Jim_CreateCommand(httpstate
.jim_interp
, "getmem", zylinjtag_Jim_Command_getmem
, NULL
, NULL
);
1330 Jim_CreateCommand(httpstate
.jim_interp
, "mac", zylinjtag_Jim_Command_mac
, NULL
, NULL
);
1331 Jim_CreateCommand(httpstate
.jim_interp
, "ip", zylinjtag_Jim_Command_ip
, NULL
, NULL
);
1332 Jim_CreateCommand(httpstate
.jim_interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
1338 diag_printf("Web server running\n");
1348 print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
, cyg_addrword_t info
)
1352 char *infoStr
= "unknown";
1355 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
1356 infoStr
= "undefined instruction";
1358 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
1359 infoStr
= "software interrupt";
1361 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
1362 infoStr
= "abort prefetch";
1364 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
1365 infoStr
= "abort data";
1371 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
1373 diag_printf("Dumping log\n---\n");
1374 if (logCount
>= logSize
)
1376 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
1378 diag_write(logBuffer
, writePtr
);
1380 diag_printf("---\nLogdump complete.\n");
1381 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
1382 diag_printf("\n---\nRebooting\n");
1383 HAL_PLATFORM_RESET();
1387 static void setHandler(cyg_code_t exception
)
1389 cyg_exception_handler_t
*old_handler
;
1390 cyg_addrword_t old_data
;
1392 cyg_exception_set_handler(exception
,
1393 print_exception_handler
,
1399 static cyg_thread zylinjtag_uart_thread_object
;
1400 static cyg_handle_t zylinjtag_uart_thread_handle
;
1401 static char uart_stack
[4096];
1403 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
1404 static char backwardBuffer
[1024];
1406 static cyg_io_handle_t serial_handle
;
1408 void setNoDelay(int session
, int flag
)
1411 // This decreases latency dramatically for e.g. GDB load which
1412 // does not have a sliding window protocol
1414 // Can cause *lots* of TCP/IP packets to be sent and it would have
1415 // to be enabled/disabled on the fly to avoid the CPU being
1417 setsockopt(session
, /* socket affected */
1418 IPPROTO_TCP
, /* set option at TCP level */
1419 TCP_NODELAY
, /* name of option */
1420 (char *) &flag
, /* the cast is historical
1422 sizeof(int)); /* length of option value */
1432 } tcpipSent
[512 * 1024];
1436 zylinjtag_uart(cyg_addrword_t data
)
1438 int so_reuseaddr_option
= 1;
1441 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
1443 LOG_ERROR("error creating socket: %s", strerror(errno
));
1447 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
1449 struct sockaddr_in sin
;
1450 unsigned int address_size
;
1451 address_size
= sizeof(sin
);
1452 memset(&sin
, 0, sizeof(sin
));
1453 sin
.sin_family
= AF_INET
;
1454 sin
.sin_addr
.s_addr
= INADDR_ANY
;
1455 sin
.sin_port
= htons(5555);
1457 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
1459 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
1463 if (listen(fd
, 1) == -1)
1465 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
1468 // socket_nonblock(fd);
1473 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
1479 setNoDelay(session
, 1);
1480 int oldopts
= fcntl(session
, F_GETFL
, 0);
1481 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
1483 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
1501 FD_ZERO(&write_fds
);
1504 FD_SET(session
, &read_fds
);
1506 FD_SET(serHandle
, &read_fds
);
1507 if (serHandle
> fd_max
)
1513 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
1514 if ((actual
== 0) && (actual2
== 0))
1516 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
1525 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
1526 actual2
=read(serHandle
, backwardBuffer
, sizeof(backwardBuffer
));
1529 if (errno
!= EAGAIN
)
1542 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
1550 if (FD_ISSET(session
, &read_fds
)&&(sizeof(forwardBuffer
)>actual
))
1552 // NB! Here it is important that we empty the TCP/IP read buffer
1553 // to make transmission tick right
1554 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
1557 // this will block if there is no data at all
1558 t
=read_socket(session
, forwardBuffer
+actual
, sizeof(forwardBuffer
)-actual
);
1570 /* Do not put things into the serial buffer if it has something to send
1571 * as that can cause a single byte to be sent at the time.
1575 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
1578 if (errno
!= EAGAIN
)
1582 // The serial buffer is full
1593 tcpipSent
[cur
].req
= x
;
1594 tcpipSent
[cur
].actual
= y
;
1595 tcpipSent
[cur
].req2
= x2
;
1596 tcpipSent
[cur
].actual2
= y2
;
1606 for (i
= 0; i
< 1024; i
++)
1608 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
, tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
1616 void startUart(void)
1618 cyg_thread_create(1,
1624 &zylinjtag_uart_thread_handle
,
1625 &zylinjtag_uart_thread_object
);
1626 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
1627 cyg_thread_resume(zylinjtag_uart_thread_handle
);
1632 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1634 static int current_baud
= 38400;
1637 command_print(cmd_ctx
, "%d", current_baud
);
1639 } else if (argc
!= 1)
1641 return ERROR_INVALID_ARGUMENTS
;
1644 current_baud
= atol(args
[0]);
1647 switch (current_baud
)
1650 baud
= CYGNUM_SERIAL_BAUD_9600
;
1653 baud
= CYGNUM_SERIAL_BAUD_19200
;
1656 baud
= CYGNUM_SERIAL_BAUD_38400
;
1659 baud
= CYGNUM_SERIAL_BAUD_57600
;
1662 baud
= CYGNUM_SERIAL_BAUD_115200
;
1665 baud
= CYGNUM_SERIAL_BAUD_230400
;
1668 command_print(cmd_ctx
, "unsupported baudrate");
1669 return ERROR_INVALID_ARGUMENTS
;
1672 cyg_serial_info_t buf
;
1674 //get existing serial configuration
1675 len
= sizeof(cyg_serial_info_t
);
1677 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
1678 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
, &len
);
1681 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
1686 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
, &len
);
1689 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
1696 bool logAllToSerial
= false;
1698 /* boolean parameter stored on config */
1699 bool boolParam(char *var
)
1701 bool result
= false;
1702 char *name
= alloc_printf(ZYLIN_CONFIG_DIR
"/%s", var
);
1708 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1712 result
= strncmp((char *) data
, "1", len
) == 0;
1719 command_context_t
*setup_command_handler();
1721 int add_default_dirs(void)
1723 add_script_search_dir(ZYLIN_CONFIG_DIR
);
1724 add_script_search_dir("/rom/lib/openocd");
1725 add_script_search_dir("/rom");
1729 static cyg_uint8
*ramblockdevice
;
1730 static const int ramblockdevice_size
=4096*1024;
1731 int main(int argc
, char *argv
[])
1733 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
1734 * need to allocate towards the end of the heap. */
1736 ramblockdevice
=(cyg_uint8
*)malloc(ramblockdevice_size
);
1737 memset(ramblockdevice
, 0xff, ramblockdevice_size
);
1739 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
1740 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
1741 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
1744 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
1747 diag_printf("/dev/ser0 not found\n");
1751 setPower(true); // on by default
1753 atexit(keep_webserver
);
1755 err
= mount("", "/ram", "ramfs");
1758 diag_printf("unable to mount ramfs\n");
1763 sprintf(address
, "%p", &filedata
[0]);
1764 err
= mount(address
, "/rom", "romfs");
1767 diag_printf("unable to mount /rom\n");
1770 err
= mount("", "/log", "logfs");
1773 diag_printf("unable to mount logfs\n");
1776 err
= mount("", "/tftp", "tftpfs");
1779 diag_printf("unable to mount logfs\n");
1782 log
= fopen("/log/log", "w");
1785 diag_printf("Could not open log file /ram/log\n");
1789 diag_init_putc(_zylinjtag_diag_write_char
);
1791 // We want this in the log.
1792 diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
1793 diag_printf("%s\n", ZYLIN_OPENOCD_VERSION
);
1795 copydir("/rom", "/ram/cgi");
1797 err
= mount("/dev/flash1", "/config", "jffs2");
1800 diag_printf("unable to mount jffs\n");
1804 /* are we using a ram disk instead of a flash disk? This is used
1805 * for ZY1000 live demo...
1807 * copy over flash disk to ram block device
1809 if (boolParam("ramdisk"))
1811 diag_printf("Unmounting /config from flash and using ram instead\n");
1812 err
=umount("/config");
1815 diag_printf("unable to unmount jffs\n");
1819 err
= mount("/dev/flash1", "/config2", "jffs2");
1822 diag_printf("unable to mount jffs\n");
1826 err
= mount("/dev/ram", "/config", "jffs2");
1829 diag_printf("unable to mount ram block device\n");
1833 // copydir("/config2", "/config");
1834 copyfile("/config2/ip", "/config/ip");
1835 copydir("/config2/settings", "/config/settings");
1840 /* we're not going to use a ram block disk */
1841 free(ramblockdevice
);
1845 mkdir(ZYLIN_CONFIG_DIR
, 0777);
1846 mkdir(ZYLIN_CONFIG_DIR
"/target", 0777);
1847 mkdir(ZYLIN_CONFIG_DIR
"/event", 0777);
1849 logAllToSerial
= boolParam("logserial");
1851 // We need the network & web server in case there is something wrong with
1852 // the config files that invoke exit()
1853 zylinjtag_startNetwork();
1855 /* we're going to access the jim interpreter from here on... */
1856 openocd_sleep_postlude();
1861 /* initialize commandline interface */
1862 command_context_t
*cmd_ctx
;
1863 cmd_ctx
= setup_command_handler();
1864 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1865 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1868 register_command(cmd_ctx
, NULL
, "zy1000_version", handle_zy1000_version_command
,
1869 COMMAND_EXEC
, "show zy1000 version numbers");
1871 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
1874 register_command(cmd_ctx
, NULL
, "fast_load_image", handle_fast_load_image_command
, COMMAND_ANY
,
1875 "same args as load_image, image stored in memory");
1877 register_command(cmd_ctx
, NULL
, "fast_load", handle_fast_load_command
, COMMAND_ANY
,
1878 "loads active fast load image to current target");
1880 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
1881 "display file content");
1883 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
1884 "truncate a file to 0 size");
1886 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
1887 COMMAND_ANY
, "append a variable number of strings to a file");
1889 register_command(cmd_ctx
, NULL
, "power", handle_power_command
, COMMAND_ANY
,
1890 "power <on/off> - turn power switch to target on/off. No arguments - print status.");
1892 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
1893 COMMAND_ANY
, "display available ram memory");
1895 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
1896 COMMAND_ANY
, "copy a file <from> <to>");
1898 #ifdef CYGPKG_PROFILE_GPROF
1899 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1902 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
,
1903 COMMAND_ANY
, "uart <baud> - forward uart on port 5555");
1907 errVal
= log_init(cmd_ctx
);
1908 if (errVal
!= ERROR_OK
)
1910 diag_printf("log_init() failed %d\n", errVal
);
1914 set_log_output(cmd_ctx
, log
);
1916 LOG_DEBUG("log init complete");
1918 // diag_printf("Executing config files\n");
1922 diag_printf(ZYLIN_CONFIG_DIR
"/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
1923 command_run_line(cmd_ctx
, "debug_level 3");
1926 zylinjtag_parse_config_file(cmd_ctx
, "/rom/openocd.cfg");
1929 // diag_printf() is really invoked from many more places than we trust it
1930 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1932 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1933 // fingers that it doesn't cause any crashes.
1934 diag_printf("Init complete, GDB & telnet servers launched.\n");
1935 command_set_output_handler(cmd_ctx
, zy1000_configuration_output_handler_log
, NULL
);
1936 if (!logAllToSerial
)
1941 /* handle network connections */
1942 server_loop(cmd_ctx
);
1943 openocd_sleep_prelude();
1945 /* shut server down */
1948 /* free commandline interface */
1949 command_done(cmd_ctx
);
1959 cyg_httpd_exec_cgi_tcl(char *file_name
);
1960 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1962 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1966 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1968 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1969 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1971 #include <pkgconf/system.h>
1972 #include <pkgconf/hal.h>
1973 #include <pkgconf/kernel.h>
1974 #include <pkgconf/io_fileio.h>
1975 #include <pkgconf/fs_rom.h>
1977 #include <cyg/kernel/ktypes.h> // base kernel types
1978 #include <cyg/infra/cyg_trac.h> // tracing macros
1979 #include <cyg/infra/cyg_ass.h> // assertion macros
1981 #include <sys/types.h>
1983 #include <sys/stat.h>
1992 #include <cyg/fileio/fileio.h>
1994 #include <cyg/kernel/kapi.h>
1995 #include <cyg/infra/diag.h>
1997 //==========================================================================
1998 // Eventually we want to eXecute In Place from the ROM in a protected
1999 // environment, so we'll need executables to be aligned to a boundary
2000 // suitable for MMU protection. A suitable boundary would be the 4k
2001 // boundary in all the CPU architectures I am currently aware of.
2003 // Forward definitions
2005 // Filesystem operations
2006 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
2007 static int tftpfs_umount(cyg_mtab_entry
*mte
);
2008 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2009 int mode
, cyg_file
*fte
);
2010 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2011 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2014 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
2015 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
2016 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
2018 //==========================================================================
2019 // Filesystem table entries
2021 // -------------------------------------------------------------------------
2023 // This defines the entry in the filesystem table.
2024 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2025 // we should never block in any filesystem operations.
2027 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
2032 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
2033 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
2034 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
2035 (cyg_fsop_rename
*)cyg_fileio_erofs
,
2036 (cyg_fsop_link
*)cyg_fileio_erofs
,
2037 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
2038 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
2039 (cyg_fsop_stat
*)cyg_fileio_erofs
,
2040 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
2041 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
2044 // -------------------------------------------------------------------------
2046 // This defines a single ROMFS loaded into ROM at the configured address
2048 // MTAB_ENTRY( rom_mte, // structure name
2049 // "/rom", // mount point
2050 // "romfs", // FIlesystem type
2051 // "", // hardware device
2052 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
2056 // -------------------------------------------------------------------------
2058 // This set of file operations are used for normal open files.
2060 static cyg_fileops tftpfs_fileops
=
2065 (cyg_fileop_ioctl
*)cyg_fileio_erofs
,
2069 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
2070 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
2071 (cyg_fileop_setinfo
*)cyg_fileio_erofs
,
2074 // -------------------------------------------------------------------------
2076 // Process a mount request. This mainly finds root for the
2079 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
2084 static int tftpfs_umount(cyg_mtab_entry
*mte
)
2099 static void freeTftp(struct Tftp
*t
)
2112 static const int tftpMaxSize
= 8192 * 1024;
2113 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2114 int mode
, cyg_file
*file
)
2117 tftp
= malloc(sizeof(struct Tftp
));
2120 memset(tftp
, 0, sizeof(struct Tftp
));
2122 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
2123 file
->f_type
= CYG_FILE_TYPE_FILE
;
2124 file
->f_ops
= &tftpfs_fileops
;
2129 tftp
->mem
= malloc(tftpMaxSize
);
2130 if (tftp
->mem
== NULL
)
2136 char *server
= strchr(name
, '/');
2143 tftp
->server
= malloc(server
- name
+ 1);
2144 if (tftp
->server
== NULL
)
2149 strncpy(tftp
->server
, name
, server
- name
);
2150 tftp
->server
[server
- name
] = 0;
2152 tftp
->file
= strdup(server
+ 1);
2153 if (tftp
->file
== NULL
)
2159 file
->f_data
= (CYG_ADDRWORD
) tftp
;
2164 static int fetchTftp(struct Tftp
*tftp
)
2166 if (!tftp
->readFile
)
2169 tftp
->actual
= tftp_client_get( tftp
->file
, tftp
->server
, 0, tftp
->mem
, tftpMaxSize
, TFTP_OCTET
, &err
);
2171 if (tftp
->actual
< 0)
2180 // -------------------------------------------------------------------------
2181 // tftpfs_fo_write()
2182 // Read data from file.
2185 tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2187 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2189 if (fetchTftp(tftp
) != ENOERR
)
2193 off_t pos
= fp
->f_offset
;
2195 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2197 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2198 char *buf
= (char *) iov
->iov_base
;
2199 off_t len
= iov
->iov_len
;
2201 if (len
+ pos
> tftp
->actual
)
2203 len
= tftp
->actual
- pos
;
2205 resid
+= iov
->iov_len
- len
;
2207 memcpy(buf
, tftp
->mem
+ pos
, len
);
2211 uio
->uio_resid
= resid
;
2219 tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2221 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2224 off_t pos
= fp
->f_offset
;
2226 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2228 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2229 char *buf
= (char *) iov
->iov_base
;
2230 off_t len
= iov
->iov_len
;
2232 if (len
+ pos
> tftpMaxSize
)
2234 len
= tftpMaxSize
- pos
;
2236 resid
+= iov
->iov_len
- len
;
2238 memcpy(tftp
->mem
+ pos
, buf
, len
);
2242 uio
->uio_resid
= resid
;
2251 tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
2257 // -------------------------------------------------------------------------
2259 // Close a file. We just clear out the data pointer.
2261 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
2263 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2268 tftp_client_put( tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
, TFTP_OCTET
, &error
);
2276 // -------------------------------------------------------------------------
2278 // Seek to a new file position.
2280 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
2282 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2285 if (fetchTftp(tftp
) != ENOERR
)
2291 // Pos is already where we want to be.
2295 // Add pos to current offset.
2296 pos
+= fp
->f_offset
;
2300 // Add pos to file size.
2301 pos
+= tftp
->actual
;
2308 // Check that pos is still within current file size, or at the
2310 if (pos
< 0 || pos
> tftp
->actual
)
2313 // All OK, set fp offset and return new position.
2314 *apos
= fp
->f_offset
= pos
;
2322 cyg_thread_delay(us
/ 10000 + 1);
2329 show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
2331 cyg_httpd_start_chunked("text");
2332 if (logCount
>= logSize
)
2334 cyg_httpd_write_chunked(logBuffer
+logCount
%logSize
, logSize
-logCount
%logSize
);
2336 cyg_httpd_write_chunked(logBuffer
, writePtr
);
2337 cyg_httpd_end_chunked();
2341 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
2343 // Filesystem operations
2344 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
2345 static int logfs_umount(cyg_mtab_entry
*mte
);
2346 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2347 int mode
, cyg_file
*fte
);
2349 logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2352 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
2353 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
2355 #include <cyg/io/devtab.h>
2357 //==========================================================================
2358 // Filesystem table entries
2360 // -------------------------------------------------------------------------
2362 // This defines the entry in the filesystem table.
2363 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2364 // we should never block in any filesystem operations.
2365 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
2366 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
2370 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
2371 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
2372 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
2373 (cyg_fsop_rename
*)cyg_fileio_erofs
,
2374 (cyg_fsop_link
*)cyg_fileio_erofs
,
2375 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
2376 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
2377 (cyg_fsop_stat
*)cyg_fileio_erofs
,
2378 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
2379 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
2381 // -------------------------------------------------------------------------
2383 // This set of file operations are used for normal open files.
2385 static cyg_fileops logfs_fileops
=
2387 (cyg_fileop_read
*)cyg_fileio_erofs
,
2388 (cyg_fileop_write
*)logfs_fo_write
,
2389 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
2390 (cyg_fileop_ioctl
*)cyg_fileio_erofs
,
2394 (cyg_fileop_fstat
*)cyg_fileio_erofs
,
2395 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
2396 (cyg_fileop_setinfo
*)cyg_fileio_erofs
,
2399 // -------------------------------------------------------------------------
2401 // Process a mount request. This mainly finds root for the
2404 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
2409 static int logfs_umount(cyg_mtab_entry
*mte
)
2414 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2415 int mode
, cyg_file
*file
)
2417 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
2418 file
->f_type
= CYG_FILE_TYPE_FILE
;
2419 file
->f_ops
= &logfs_fileops
;
2426 // -------------------------------------------------------------------------
2428 // Write data to file.
2431 logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2434 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2436 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2437 char *buf
= (char *) iov
->iov_base
;
2438 off_t len
= iov
->iov_len
;
2440 diag_write(buf
, len
);
2447 logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
2452 // -------------------------------------------------------------------------
2454 // Close a file. We just clear out the data pointer.
2456 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
2462 ramiodev_init( struct cyg_devtab_entry
*tab
)
2468 ramiodev_bread( cyg_io_handle_t handle
, void *buf
, cyg_uint32
*len
,
2471 if (*len
+pos
>ramblockdevice_size
)
2473 *len
=ramblockdevice_size
-pos
;
2475 memcpy(buf
, ramblockdevice
+pos
, *len
);
2480 ramiodev_bwrite( cyg_io_handle_t handle
, const void *buf
, cyg_uint32
*len
,
2483 if (((pos
%4)!=0)||(((*len
)%4)!=0))
2485 diag_printf("Unaligned write %d %d!", pos
, *len
);
2488 memcpy(ramblockdevice
+pos
, buf
, *len
);
2493 ramiodev_get_config( cyg_io_handle_t handle
,
2499 case CYG_IO_GET_CONFIG_FLASH_ERASE
:
2501 if ( *len
!= sizeof( cyg_io_flash_getconfig_erase_t
) )
2504 cyg_io_flash_getconfig_erase_t
*e
= (cyg_io_flash_getconfig_erase_t
*)buf
;
2505 char *startpos
= ramblockdevice
+ e
->offset
;
2507 if (((e
->offset
%(64*1024))!=0)||((e
->len
%(64*1024))!=0))
2509 diag_printf("Erease is not aligned %d %d\n", e
->offset
, e
->len
);
2512 memset(startpos
, 0xff, e
->len
);
2518 case CYG_IO_GET_CONFIG_FLASH_DEVSIZE
:
2520 if ( *len
!= sizeof( cyg_io_flash_getconfig_devsize_t
) )
2523 cyg_io_flash_getconfig_devsize_t
*d
=
2524 (cyg_io_flash_getconfig_devsize_t
*)buf
;
2526 d
->dev_size
= ramblockdevice_size
;
2531 case CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE
:
2533 cyg_io_flash_getconfig_blocksize_t
*b
=
2534 (cyg_io_flash_getconfig_blocksize_t
*)buf
;
2535 if ( *len
!= sizeof( cyg_io_flash_getconfig_blocksize_t
) )
2538 // offset unused for now
2539 b
->block_size
= 64*1024;
2549 ramiodev_set_config( cyg_io_handle_t handle
,
2559 } // ramiodev_set_config()
2561 // get_config/set_config should be added later to provide the other flash
2562 // operations possible, like erase etc.
2564 BLOCK_DEVIO_TABLE( cyg_io_ramdev1_ops
,
2568 &ramiodev_get_config
,
2569 &ramiodev_set_config
2573 BLOCK_DEVTAB_ENTRY( cyg_io_ramdev1
,
2576 &cyg_io_ramdev1_ops
,
2578 0, // No lookup required
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)