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;
132 static int fastload_num
;
133 static struct FastLoad
*fastload
;
135 static void free_fastload()
140 for (i
=0; i
<fastload_num
; i
++)
142 if (fastload
[i
].data
)
143 free(fastload
[i
].data
);
151 int handle_fast_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
157 u32 max_address
=0xffffffff;
166 if ((argc
< 1)||(argc
> 5))
168 return ERROR_COMMAND_SYNTAX_ERROR
;
171 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
174 image
.base_address_set
= 1;
175 image
.base_address
= strtoul(args
[1], NULL
, 0);
179 image
.base_address_set
= 0;
183 image
.start_address_set
= 0;
187 min_address
=strtoul(args
[3], NULL
, 0);
191 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
194 if (min_address
>max_address
)
196 return ERROR_COMMAND_SYNTAX_ERROR
;
199 duration_start_measure(&duration
);
201 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
208 fastload_num
=image
.num_sections
;
209 fastload
=(struct FastLoad
*)malloc(sizeof(struct FastLoad
)*image
.num_sections
);
215 memset(fastload
, 0, sizeof(struct FastLoad
)*image
.num_sections
);
216 for (i
= 0; i
< image
.num_sections
; i
++)
218 buffer
= malloc(image
.sections
[i
].size
);
221 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
225 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
235 /* DANGER!!! beware of unsigned comparision here!!! */
237 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
238 (image
.sections
[i
].base_address
<max_address
))
240 if (image
.sections
[i
].base_address
<min_address
)
242 /* clip addresses below */
243 offset
+=min_address
-image
.sections
[i
].base_address
;
247 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
249 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
252 fastload
[i
].address
=image
.sections
[i
].base_address
+offset
;
253 fastload
[i
].data
=malloc(length
);
254 if (fastload
[i
].data
==NULL
)
259 memcpy(fastload
[i
].data
, buffer
+offset
, length
);
260 fastload
[i
].length
=length
;
262 image_size
+= length
;
263 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
269 duration_stop_measure(&duration
, &duration_text
);
270 if (retval
==ERROR_OK
)
272 command_print(cmd_ctx
, "Loaded %u bytes in %s", image_size
, duration_text
);
273 command_print(cmd_ctx
, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
279 if (retval
!=ERROR_OK
)
287 int handle_fast_load_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
290 return ERROR_COMMAND_SYNTAX_ERROR
;
293 LOG_ERROR("No image in memory");
299 for (i
=0; i
<fastload_num
;i
++)
302 target_t
*target
= get_current_target(cmd_ctx
);
303 if ((retval
= target_write_buffer(target
, fastload
[i
].address
, fastload
[i
].length
, fastload
[i
].data
)) != ERROR_OK
)
307 size
+=fastload
[i
].length
;
309 int after
=timeval_ms();
310 command_print(cmd_ctx
, "Loaded image %f kBytes/s", (float)(size
/1024.0)/((float)(after
-ms
)/1000.0));
315 /* Give TELNET a way to find out what version this is */
316 int handle_zy1000_version_command(struct command_context_s
*cmd_ctx
, char *cmd
,
317 char **args
, int argc
)
321 return ERROR_COMMAND_SYNTAX_ERROR
;
325 command_print(cmd_ctx
, ZYLIN_OPENOCD_VERSION
);
326 } else if (strcmp("openocd", args
[0])==0)
329 revision
=atol(ZYLIN_OPENOCD
+strlen("XRevision: "));
330 command_print(cmd_ctx
, "%d", revision
);
331 } else if (strcmp("zy1000", args
[0])==0)
333 command_print(cmd_ctx
, "%s", ZYLIN_VERSION
);
334 } else if (strcmp("date", args
[0])==0)
336 command_print(cmd_ctx
, "%s", ZYLIN_DATE
);
339 return ERROR_COMMAND_SYNTAX_ERROR
;
345 extern flash_driver_t
*flash_drivers
[];
346 extern target_type_t
*target_types
[];
348 #ifdef CYGPKG_PROFILE_GPROF
349 #include <cyg/profile/profile.h>
351 extern char _stext
, _etext
; // Defined by the linker
353 void start_profile(void)
355 // This starts up the system-wide profiling, gathering
356 // profile information on all of the code, with a 16 byte
357 // "bucket" size, at a rate of 100us/profile hit.
358 // Note: a bucket size of 16 will give pretty good function
359 // resolution. Much smaller and the buffer becomes
360 // much too large for very little gain.
361 // Note: a timer period of 100us is also a reasonable
362 // compromise. Any smaller and the overhead of
363 // handling the timter (profile) interrupt could
364 // swamp the system. A fast processor might get
365 // by with a smaller value, but a slow one could
366 // even be swamped by this value. If the value is
367 // too large, the usefulness of the profile is reduced.
369 // no more interrupts than 1/10ms.
370 // profile_on(&_stext, &_etext, 16, 10000); // DRAM
371 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
372 profile_on(0, &_etext
, 16, 10000); // SRAM & DRAM
376 // launch GDB server if a config file exists
377 bool zylinjtag_parse_config_file(struct command_context_s
*cmd_ctx
, const char *config_file_name
)
379 bool foundFile
= false;
380 FILE *config_file
= NULL
;
381 command_print(cmd_ctx
, "executing config file %s", config_file_name
);
382 config_file
= fopen(config_file_name
, "r");
387 retval
= command_run_linef(cmd_ctx
, "script %s", config_file_name
);
388 if (retval
== ERROR_OK
)
394 command_print(cmd_ctx
, "Failed executing %s %d", config_file_name
, retval
);
399 command_print(cmd_ctx
, "No %s found", config_file_name
);
408 static char reboot_stack
[2048];
412 zylinjtag_reboot(cyg_addrword_t data
)
415 diag_printf("Rebooting in 100 ticks..\n");
416 cyg_thread_delay(100);
417 diag_printf("Unmounting /config..\n");
419 diag_printf("Rebooting..\n");
420 HAL_PLATFORM_RESET();
422 static cyg_thread zylinjtag_thread_object
;
423 static cyg_handle_t zylinjtag_thread_handle
;
431 (void *)reboot_stack
,
432 sizeof(reboot_stack
),
433 &zylinjtag_thread_handle
,
434 &zylinjtag_thread_object
);
435 cyg_thread_resume(zylinjtag_thread_handle
);
438 int configuration_output_handler(struct command_context_s
*context
, const char* line
)
440 diag_printf("%s", line
);
445 int zy1000_configuration_output_handler_log(struct command_context_s
*context
, const char* line
)
447 LOG_USER_N("%s", line
);
452 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
453 char **args
, int argc
)
457 command_print(cmd_ctx
, "rm <filename>");
458 return ERROR_INVALID_ARGUMENTS
;
461 if (unlink(args
[0]) != 0)
463 command_print(cmd_ctx
, "failed: %d", errno
);
469 int loadFile(const char *fileName
, void **data
, int *len
);
471 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
472 char **args
, int argc
)
476 command_print(cmd_ctx
, "cat <filename>");
477 return ERROR_INVALID_ARGUMENTS
;
480 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
484 int retval
= loadFile(args
[0], &data
, &len
);
485 if (retval
== ERROR_OK
)
487 command_print(cmd_ctx
, "%s", data
);
492 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
497 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
498 char **args
, int argc
)
502 command_print(cmd_ctx
, "trunc <filename>");
503 return ERROR_INVALID_ARGUMENTS
;
506 FILE *config_file
= NULL
;
507 config_file
= fopen(args
[0], "w");
508 if (config_file
!= NULL
)
515 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
518 struct mallinfo info
;
522 command_print(cmd_ctx
, "meminfo");
523 return ERROR_INVALID_ARGUMENTS
;
530 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
532 prev
= info
.fordblks
;
534 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
539 static bool savePower
;
541 static void setPower(bool power
)
546 HAL_WRITE_UINT32(ZY1000_JTAG_BASE
+0x14, 0x8);
549 HAL_WRITE_UINT32(ZY1000_JTAG_BASE
+0x10, 0x8);
553 int handle_power_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
557 return ERROR_INVALID_ARGUMENTS
;
562 if (strcmp(args
[0], "on") == 0)
566 else if (strcmp(args
[0], "off") == 0)
571 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
572 return ERROR_INVALID_ARGUMENTS
;
576 command_print(cmd_ctx
, "Target power %s", savePower
? "on" : "off");
581 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
582 char **args
, int argc
)
586 command_print(cmd_ctx
,
587 "append <filename> [<string1>, [<string2>, ...]]");
588 return ERROR_INVALID_ARGUMENTS
;
591 FILE *config_file
= NULL
;
592 config_file
= fopen(args
[0], "a");
593 if (config_file
!= NULL
)
596 fseek(config_file
, 0, SEEK_END
);
598 for (i
= 1; i
< argc
; i
++)
600 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
603 fwrite(" ", 1, 1, config_file
);
606 fwrite("\n", 1, 1, config_file
);
613 extern int telnet_socket
;
615 int readMore(int fd
, void *data
, int length
)
617 /* used in select() */
620 /* monitor sockets for acitvity */
623 /* listen for new connections */
624 FD_SET(fd
, &read_fds
);
626 // Maximum 5 seconds.
631 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
634 diag_printf("Timed out waiting for binary payload\n");
640 return read_socket(fd
, data
, length
);
643 int readAll(int fd
, void *data
, int length
)
648 int actual
= readMore(fd
, ((char *) data
) + pos
, length
- pos
);
649 // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
659 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
664 return ERROR_INVALID_ARGUMENTS
;
666 HAL_READ_UINT32(strtoul(args
[0], NULL
, 0), value
);
667 command_print(cmd_ctx
, "0x%x : 0x%x", strtoul(args
[0], NULL
, 0), value
);
671 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
675 return ERROR_INVALID_ARGUMENTS
;
677 HAL_WRITE_UINT32(strtoul(args
[0], NULL
, 0), strtoul(args
[1], NULL
, 0));
681 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
685 return ERROR_INVALID_ARGUMENTS
;
688 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
692 int retval
= loadFile(args
[0], &data
, &len
);
693 if (retval
!= ERROR_OK
)
696 FILE *f
= fopen(args
[1], "wb");
698 retval
= ERROR_INVALID_ARGUMENTS
;
703 int chunk
= len
- pos
;
704 static const int maxChunk
= 512 * 1024; // ~1/sec
705 if (chunk
> maxChunk
)
710 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
711 retval
= ERROR_INVALID_ARGUMENTS
;
713 if (retval
!= ERROR_OK
)
718 command_print(cmd_ctx
, "%d", len
- pos
);
726 if (retval
== ERROR_OK
)
728 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
731 command_print(cmd_ctx
, "Failed: %d", retval
);
739 if (retval
!= ERROR_OK
)
745 #ifdef CYGPKG_PROFILE_GPROF
746 extern void start_profile();
748 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
750 command_print(cmd_ctx
, "Profiling started");
757 externC
void phi_init_all_network_interfaces();
759 command_context_t
*cmd_ctx
;
761 static bool webRunning
= false;
763 void keep_webserver()
765 // Target initialisation is only attempted at startup, so we sleep forever and
766 // let the http server bail us out(i.e. get config files set up).
767 diag_printf("OpenOCD has invoked exit().\n"
768 "Use web server to correct any configuration settings and reboot.\n");
772 // exit() will terminate the current thread and we we'll then sleep eternally or
773 // we'll have a reboot scheduled.
776 extern void printDccChar(char c
);
778 static char logBuffer
[128 * 1024];
779 static const int logSize
= sizeof(logBuffer
);
783 void _zylinjtag_diag_write_char(char c
, void **param
)
787 logBuffer
[writePtr
] = c
;
788 writePtr
= (writePtr
+ 1) % logSize
;
795 HAL_DIAG_WRITE_CHAR('\r');
797 HAL_DIAG_WRITE_CHAR(c
);
800 #ifdef CYGPKG_HAL_ZYLIN_PHI
805 #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
808 static void copyfile(char *name2
, char *name1
)
816 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
818 SHOW_RESULT( open
, fd1
);
820 fd2
= open(name2
, O_RDONLY
);
822 SHOW_RESULT( open
, fd2
);
826 done
= read(fd2
, buf
, IOSIZE
);
829 SHOW_RESULT( read
, done
);
833 if( done
== 0 ) break;
835 wrote
= write(fd1
, buf
, done
);
836 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
838 if( wrote
!= done
) break;
842 if( err
< 0 ) SHOW_RESULT( close
, err
);
845 if( err
< 0 ) SHOW_RESULT( close
, err
);
848 static void copydir(char *name
, char *destdir
)
853 dirp
= opendir(destdir
);
856 mkdir(destdir
, 0777);
859 err
= closedir(dirp
);
862 dirp
= opendir(name
);
863 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
867 struct dirent
*entry
= readdir(dirp
);
872 if (strcmp(entry
->d_name
, ".") == 0)
874 if (strcmp(entry
->d_name
, "..") == 0)
879 char fullPath
[PATH_MAX
];
880 strncpy(fullPath
, name
, PATH_MAX
);
881 strcat(fullPath
, "/");
882 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
884 if (stat(fullPath
, &buf
) == -1)
886 diag_printf("unable to read status from %s", fullPath
);
889 isDir
= S_ISDIR(buf
.st_mode
) != 0;
894 // diag_printf("<INFO>: entry %14s",entry->d_name);
895 char fullname
[PATH_MAX
];
896 char fullname2
[PATH_MAX
];
898 strcpy(fullname
, name
);
899 strcat(fullname
, "/");
900 strcat(fullname
, entry
->d_name
);
902 strcpy(fullname2
, destdir
);
903 strcat(fullname2
, "/");
904 strcat(fullname2
, entry
->d_name
);
905 // diag_printf("from %s to %s\n", fullname, fullname2);
906 copyfile(fullname
, fullname2
);
908 // diag_printf("\n");
911 err
= closedir(dirp
);
912 if( err
< 0 ) SHOW_RESULT( stat
, err
);
916 MTAB_ENTRY( romfs_mte1
,
920 (CYG_ADDRWORD
) &filedata
[0] );
923 void openocd_sleep_prelude()
925 cyg_mutex_unlock(&httpstate
.jim_lock
);
928 void openocd_sleep_postlude()
930 cyg_mutex_lock(&httpstate
.jim_lock
);
934 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
936 Jim_Obj
* const *argv
)
941 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
946 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
948 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
951 return del
? JIM_OK
: JIM_ERR
;
954 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
955 Jim_Obj
* const *argv
)
957 cyg_handle_t thread
= 0;
959 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
961 /* Loop over the threads, and generate a table row for
964 while (cyg_thread_get_next(&thread
, &id
))
966 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
968 cyg_thread_info info
;
971 cyg_thread_get_info(thread
, id
, &info
);
973 if (info
.name
== NULL
)
974 info
.name
= "<no name>";
976 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
977 info
.name
, strlen(info
.name
)));
979 /* Translate the state into a string.
982 state_string
= "RUN";
983 else if (info
.state
& 0x04)
984 state_string
= "SUSP";
986 switch (info
.state
& 0x1b)
989 state_string
= "SLEEP";
992 state_string
= "CNTSLEEP";
995 state_string
= "CREATE";
998 state_string
= "EXIT";
1001 state_string
= "????";
1005 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
1006 state_string
, strlen(state_string
)));
1008 Jim_ListAppendElement (interp
, threadObj
, Jim_NewIntObj(interp
, id
));
1009 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, info
.set_pri
));
1010 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, info
.cur_pri
));
1012 Jim_ListAppendElement(interp
, threads
, threadObj
);
1014 Jim_SetResult( interp
, threads
);
1021 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
1023 Jim_Obj
* const *argv
)
1027 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
1031 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
1034 dirp
= opendir(name
);
1039 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
1043 struct dirent
*entry
= NULL
;
1044 entry
= readdir(dirp
);
1048 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
1051 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
1055 Jim_SetResult(interp
, objPtr
);
1062 zylinjtag_Jim_Command_getmem(Jim_Interp
*interp
,
1064 Jim_Obj
* const *argv
)
1068 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
1074 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1076 if (Jim_GetLong(interp
, argv
[2], &length
) != JIM_OK
)
1079 if (length
< 0 && length
> (4096 * 1024))
1081 Jim_WrongNumArgs(interp
, 1, argv
, "getmem ?dir?");
1085 void *mem
= malloc(length
);
1089 target_t
*target
= get_current_target(cmd_ctx
);
1094 if ((address
% 4 == 0) && (count
% 4 == 0))
1100 if ((retval
= target
->type
->read_memory(target
, address
, size
, count
, mem
)) != ERROR_OK
)
1106 Jim_Obj
*objPtr
= Jim_NewStringObj(interp
, mem
, length
);
1107 Jim_SetResult(interp
, objPtr
);
1115 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
1117 Jim_Obj
* const *argv
)
1121 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
1126 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1129 int value
= *((volatile int *) address
);
1131 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
1137 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
1139 Jim_Obj
* const *argv
)
1143 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
1148 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1151 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
1154 *((volatile int *) address
) = value
;
1162 zylinjtag_Jim_Command_flash(Jim_Interp
*interp
,
1164 Jim_Obj
* const *argv
)
1168 flash_bank_t
*t
= get_flash_bank_by_num_noprobe(0);
1178 if (retval
== JIM_OK
)
1180 Jim_SetResult(interp
, Jim_NewIntObj(interp
, base
));
1191 zylinjtag_Jim_Command_log(Jim_Interp
*interp
,
1193 Jim_Obj
* const *argv
)
1195 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1197 if (logCount
>= logSize
)
1199 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+logCount
%logSize
, logSize
-logCount
%logSize
);
1201 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
1203 Jim_SetResult(interp
, tclOutput
);
1208 zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
,
1210 Jim_Obj
* const *argv
)
1217 zylinjtag_Jim_Command_mac(Jim_Interp
*interp
,
1219 Jim_Obj
* const *argv
)
1222 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1224 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, hwaddr
, strlen(hwaddr
));
1226 Jim_SetResult(interp
, tclOutput
);
1232 zylinjtag_Jim_Command_ip(Jim_Interp
*interp
,
1234 Jim_Obj
* const *argv
)
1236 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1238 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
1240 if (getifaddrs(&ifp
) < 0)
1245 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
1250 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1251 salen
= sizeof(struct sockaddr_in
);
1252 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1253 salen
= sizeof(struct sockaddr_in6
);
1257 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
1258 NI_NUMERICHOST
) < 0)
1263 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, ip
, strlen(ip
));
1270 Jim_SetResult(interp
, tclOutput
);
1275 extern Jim_Interp
*interp
;
1278 static void zylinjtag_startNetwork()
1280 // Bring TCP/IP up immediately before we're ready to accept commands.
1282 // That is as soon as a PING responds, we're accepting telnet sessions.
1283 #if defined(CYGPKG_NET_FREEBSD_STACK)
1284 phi_init_all_network_interfaces();
1290 diag_printf("Network not up and running\n");
1293 #if defined(CYGPKG_NET_FREEBSD_STACK)
1295 tftpd_start(69, &fileops
);
1298 cyg_httpd_init_tcl_interpreter();
1300 interp
= httpstate
.jim_interp
;
1302 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
, NULL
, NULL
);
1303 Jim_CreateCommand(httpstate
.jim_interp
, "reboot", zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
1304 Jim_CreateCommand(httpstate
.jim_interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
1305 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_flash", zylinjtag_Jim_Command_flash
, NULL
, NULL
);
1306 Jim_CreateCommand(httpstate
.jim_interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
1307 Jim_CreateCommand(httpstate
.jim_interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
1308 Jim_CreateCommand(httpstate
.jim_interp
, "threads", zylinjtag_Jim_Command_threads
, NULL
, NULL
);
1309 Jim_CreateCommand(httpstate
.jim_interp
, "getmem", zylinjtag_Jim_Command_getmem
, NULL
, NULL
);
1310 Jim_CreateCommand(httpstate
.jim_interp
, "mac", zylinjtag_Jim_Command_mac
, NULL
, NULL
);
1311 Jim_CreateCommand(httpstate
.jim_interp
, "ip", zylinjtag_Jim_Command_ip
, NULL
, NULL
);
1312 Jim_CreateCommand(httpstate
.jim_interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
1318 diag_printf("Web server running\n");
1322 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
1325 strcpy(ifr
.ifr_name
, "eth0");
1327 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
1332 diag_printf("Can't obtain MAC address\n");
1337 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
1338 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
1339 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
1340 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
1341 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
1342 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
1343 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
1346 discover_message
=alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
1356 print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
, cyg_addrword_t info
)
1360 char *infoStr
= "unknown";
1363 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1364 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
1365 infoStr
= "undefined instruction";
1367 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
1368 infoStr
= "software interrupt";
1370 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
1371 infoStr
= "abort prefetch";
1373 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
1374 infoStr
= "abort data";
1381 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
1383 diag_printf("Dumping log\n---\n");
1384 if (logCount
>= logSize
)
1386 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
1388 diag_write(logBuffer
, writePtr
);
1390 diag_printf("---\nLogdump complete.\n");
1391 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
1392 diag_printf("\n---\nRebooting\n");
1393 HAL_PLATFORM_RESET();
1397 static void setHandler(cyg_code_t exception
)
1399 cyg_exception_handler_t
*old_handler
;
1400 cyg_addrword_t old_data
;
1402 cyg_exception_set_handler(exception
,
1403 print_exception_handler
,
1409 static cyg_thread zylinjtag_uart_thread_object
;
1410 static cyg_handle_t zylinjtag_uart_thread_handle
;
1411 static char uart_stack
[4096];
1413 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
1414 static char backwardBuffer
[1024];
1417 void setNoDelay(int session
, int flag
)
1420 // This decreases latency dramatically for e.g. GDB load which
1421 // does not have a sliding window protocol
1423 // Can cause *lots* of TCP/IP packets to be sent and it would have
1424 // to be enabled/disabled on the fly to avoid the CPU being
1426 setsockopt(session
, /* socket affected */
1427 IPPROTO_TCP
, /* set option at TCP level */
1428 TCP_NODELAY
, /* name of option */
1429 (char *) &flag
, /* the cast is historical
1431 sizeof(int)); /* length of option value */
1441 } tcpipSent
[512 * 1024];
1445 zylinjtag_uart(cyg_addrword_t data
)
1447 int so_reuseaddr_option
= 1;
1450 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
1452 LOG_ERROR("error creating socket: %s", strerror(errno
));
1456 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
1458 struct sockaddr_in sin
;
1459 unsigned int address_size
;
1460 address_size
= sizeof(sin
);
1461 memset(&sin
, 0, sizeof(sin
));
1462 sin
.sin_family
= AF_INET
;
1463 sin
.sin_addr
.s_addr
= INADDR_ANY
;
1464 sin
.sin_port
= htons(5555);
1466 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
1468 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
1472 if (listen(fd
, 1) == -1)
1474 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
1477 // socket_nonblock(fd);
1482 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
1488 setNoDelay(session
, 1);
1489 int oldopts
= fcntl(session
, F_GETFL
, 0);
1490 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
1492 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
1499 #ifdef CYGPKG_PROFILE_GPROF
1512 FD_ZERO(&write_fds
);
1515 FD_SET(session
, &read_fds
);
1517 FD_SET(serHandle
, &read_fds
);
1518 if (serHandle
> fd_max
)
1524 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
1525 if ((actual
== 0) && (actual2
== 0))
1527 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
1536 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
1537 actual2
=read(serHandle
, backwardBuffer
, sizeof(backwardBuffer
));
1540 if (errno
!= EAGAIN
)
1553 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
1561 if (FD_ISSET(session
, &read_fds
)&&(sizeof(forwardBuffer
)>actual
))
1563 // NB! Here it is important that we empty the TCP/IP read buffer
1564 // to make transmission tick right
1565 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
1568 // this will block if there is no data at all
1569 t
=read_socket(session
, forwardBuffer
+actual
, sizeof(forwardBuffer
)-actual
);
1581 /* Do not put things into the serial buffer if it has something to send
1582 * as that can cause a single byte to be sent at the time.
1586 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
1589 if (errno
!= EAGAIN
)
1593 // The serial buffer is full
1604 tcpipSent
[cur
].req
= x
;
1605 tcpipSent
[cur
].actual
= y
;
1606 tcpipSent
[cur
].req2
= x2
;
1607 tcpipSent
[cur
].actual2
= y2
;
1617 for (i
= 0; i
< 1024; i
++)
1619 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
, tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
1627 void startUart(void)
1629 cyg_thread_create(1,
1635 &zylinjtag_uart_thread_handle
,
1636 &zylinjtag_uart_thread_object
);
1637 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
1638 cyg_thread_resume(zylinjtag_uart_thread_handle
);
1643 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1645 static int current_baud
= 38400;
1648 command_print(cmd_ctx
, "%d", current_baud
);
1650 } else if (argc
!= 1)
1652 return ERROR_INVALID_ARGUMENTS
;
1655 current_baud
= atol(args
[0]);
1658 switch (current_baud
)
1661 baud
= CYGNUM_SERIAL_BAUD_9600
;
1664 baud
= CYGNUM_SERIAL_BAUD_19200
;
1667 baud
= CYGNUM_SERIAL_BAUD_38400
;
1670 baud
= CYGNUM_SERIAL_BAUD_57600
;
1673 baud
= CYGNUM_SERIAL_BAUD_115200
;
1676 baud
= CYGNUM_SERIAL_BAUD_230400
;
1679 command_print(cmd_ctx
, "unsupported baudrate");
1680 return ERROR_INVALID_ARGUMENTS
;
1683 cyg_serial_info_t buf
;
1685 //get existing serial configuration
1686 len
= sizeof(cyg_serial_info_t
);
1688 cyg_io_handle_t serial_handle
;
1690 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
1693 LOG_ERROR("/dev/ser0 not found\n");
1698 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
1699 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
, &len
);
1702 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
1707 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
, &len
);
1710 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
1717 bool logAllToSerial
= false;
1719 /* boolean parameter stored on config */
1720 bool boolParam(char *var
)
1722 bool result
= false;
1723 char *name
= alloc_printf(ZYLIN_CONFIG_DIR
"/%s", var
);
1729 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1733 result
= strncmp((char *) data
, "1", len
) == 0;
1740 command_context_t
*setup_command_handler();
1742 int add_default_dirs(void)
1744 add_script_search_dir(ZYLIN_CONFIG_DIR
);
1745 add_script_search_dir("/rom/lib/openocd");
1746 add_script_search_dir("/rom");
1750 static cyg_uint8
*ramblockdevice
;
1751 static const int ramblockdevice_size
=4096*1024;
1752 int main(int argc
, char *argv
[])
1754 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
1755 * need to allocate towards the end of the heap. */
1757 ramblockdevice
=(cyg_uint8
*)malloc(ramblockdevice_size
);
1758 memset(ramblockdevice
, 0xff, ramblockdevice_size
);
1762 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1763 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
1764 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
1765 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
1770 setPower(true); // on by default
1772 atexit(keep_webserver
);
1774 err
= mount("", "/ram", "ramfs");
1777 diag_printf("unable to mount ramfs\n");
1782 sprintf(address
, "%p", &filedata
[0]);
1783 err
= mount(address
, "/rom", "romfs");
1786 diag_printf("unable to mount /rom\n");
1789 err
= mount("", "/log", "logfs");
1792 diag_printf("unable to mount logfs\n");
1795 err
= mount("", "/tftp", "tftpfs");
1798 diag_printf("unable to mount logfs\n");
1801 log
= fopen("/log/log", "w");
1804 diag_printf("Could not open log file /ram/log\n");
1808 diag_init_putc(_zylinjtag_diag_write_char
);
1810 // We want this in the log.
1811 diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
1812 diag_printf("%s\n", ZYLIN_OPENOCD_VERSION
);
1814 copydir("/rom", "/ram/cgi");
1816 err
= mount("/dev/flash1", "/config", "jffs2");
1819 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1820 err
= mount("", "/config", "ramfs");
1823 diag_printf("unable to mount /config as ramdisk.\n");
1828 /* are we using a ram disk instead of a flash disk? This is used
1829 * for ZY1000 live demo...
1831 * copy over flash disk to ram block device
1833 if (boolParam("ramdisk"))
1835 diag_printf("Unmounting /config from flash and using ram instead\n");
1836 err
=umount("/config");
1839 diag_printf("unable to unmount jffs\n");
1843 err
= mount("/dev/flash1", "/config2", "jffs2");
1846 diag_printf("unable to mount jffs\n");
1850 err
= mount("/dev/ram", "/config", "jffs2");
1853 diag_printf("unable to mount ram block device\n");
1857 // copydir("/config2", "/config");
1858 copyfile("/config2/ip", "/config/ip");
1859 copydir("/config2/settings", "/config/settings");
1864 /* we're not going to use a ram block disk */
1865 free(ramblockdevice
);
1870 mkdir(ZYLIN_CONFIG_DIR
, 0777);
1871 mkdir(ZYLIN_CONFIG_DIR
"/target", 0777);
1872 mkdir(ZYLIN_CONFIG_DIR
"/event", 0777);
1874 logAllToSerial
= boolParam("logserial");
1876 // We need the network & web server in case there is something wrong with
1877 // the config files that invoke exit()
1878 zylinjtag_startNetwork();
1880 /* we're going to access the jim interpreter from here on... */
1881 openocd_sleep_postlude();
1886 /* initialize commandline interface */
1887 command_context_t
*cmd_ctx
;
1888 cmd_ctx
= setup_command_handler();
1889 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1890 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1893 register_command(cmd_ctx
, NULL
, "zy1000_version", handle_zy1000_version_command
,
1894 COMMAND_EXEC
, "show zy1000 version numbers");
1896 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
1899 register_command(cmd_ctx
, NULL
, "fast_load_image", handle_fast_load_image_command
, COMMAND_ANY
,
1900 "same args as load_image, image stored in memory");
1902 register_command(cmd_ctx
, NULL
, "fast_load", handle_fast_load_command
, COMMAND_ANY
,
1903 "loads active fast load image to current target");
1905 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
1906 "display file content");
1908 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
1909 "truncate a file to 0 size");
1911 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
1912 COMMAND_ANY
, "append a variable number of strings to a file");
1914 register_command(cmd_ctx
, NULL
, "power", handle_power_command
, COMMAND_ANY
,
1915 "power <on/off> - turn power switch to target on/off. No arguments - print status.");
1917 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
1918 COMMAND_ANY
, "display available ram memory");
1920 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
1921 COMMAND_ANY
, "copy a file <from> <to>");
1923 #ifdef CYGPKG_PROFILE_GPROF
1924 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
1927 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
,
1928 COMMAND_ANY
, "uart <baud> - forward uart on port 5555");
1932 errVal
= log_init(cmd_ctx
);
1933 if (errVal
!= ERROR_OK
)
1935 diag_printf("log_init() failed %d\n", errVal
);
1939 set_log_output(cmd_ctx
, log
);
1941 LOG_DEBUG("log init complete");
1943 // diag_printf("Executing config files\n");
1947 diag_printf(ZYLIN_CONFIG_DIR
"/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
1948 command_run_line(cmd_ctx
, "debug_level 3");
1951 zylinjtag_parse_config_file(cmd_ctx
, "/rom/openocd.cfg");
1954 // diag_printf() is really invoked from many more places than we trust it
1955 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
1957 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
1958 // fingers that it doesn't cause any crashes.
1959 diag_printf("Init complete, GDB & telnet servers launched.\n");
1960 command_set_output_handler(cmd_ctx
, zy1000_configuration_output_handler_log
, NULL
);
1961 if (!logAllToSerial
)
1966 /* handle network connections */
1967 server_loop(cmd_ctx
);
1968 openocd_sleep_prelude();
1970 /* shut server down */
1973 /* free commandline interface */
1974 command_done(cmd_ctx
);
1984 cyg_httpd_exec_cgi_tcl(char *file_name
);
1985 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
1987 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
1991 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
1993 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
1994 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
1996 #include <pkgconf/system.h>
1997 #include <pkgconf/hal.h>
1998 #include <pkgconf/kernel.h>
1999 #include <pkgconf/io_fileio.h>
2000 #include <pkgconf/fs_rom.h>
2002 #include <cyg/kernel/ktypes.h> // base kernel types
2003 #include <cyg/infra/cyg_trac.h> // tracing macros
2004 #include <cyg/infra/cyg_ass.h> // assertion macros
2006 #include <sys/types.h>
2008 #include <sys/stat.h>
2017 #include <cyg/fileio/fileio.h>
2019 #include <cyg/kernel/kapi.h>
2020 #include <cyg/infra/diag.h>
2022 //==========================================================================
2023 // Eventually we want to eXecute In Place from the ROM in a protected
2024 // environment, so we'll need executables to be aligned to a boundary
2025 // suitable for MMU protection. A suitable boundary would be the 4k
2026 // boundary in all the CPU architectures I am currently aware of.
2028 // Forward definitions
2030 // Filesystem operations
2031 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
2032 static int tftpfs_umount(cyg_mtab_entry
*mte
);
2033 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2034 int mode
, cyg_file
*fte
);
2035 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2036 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2039 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
2040 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
2041 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
2043 //==========================================================================
2044 // Filesystem table entries
2046 // -------------------------------------------------------------------------
2048 // This defines the entry in the filesystem table.
2049 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2050 // we should never block in any filesystem operations.
2052 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
2057 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
2058 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
2059 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
2060 (cyg_fsop_rename
*)cyg_fileio_erofs
,
2061 (cyg_fsop_link
*)cyg_fileio_erofs
,
2062 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
2063 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
2064 (cyg_fsop_stat
*)cyg_fileio_erofs
,
2065 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
2066 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
2069 // -------------------------------------------------------------------------
2071 // This defines a single ROMFS loaded into ROM at the configured address
2073 // MTAB_ENTRY( rom_mte, // structure name
2074 // "/rom", // mount point
2075 // "romfs", // FIlesystem type
2076 // "", // hardware device
2077 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
2081 // -------------------------------------------------------------------------
2083 // This set of file operations are used for normal open files.
2085 static cyg_fileops tftpfs_fileops
=
2090 (cyg_fileop_ioctl
*)cyg_fileio_erofs
,
2094 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
2095 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
2096 (cyg_fileop_setinfo
*)cyg_fileio_erofs
,
2099 // -------------------------------------------------------------------------
2101 // Process a mount request. This mainly finds root for the
2104 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
2109 static int tftpfs_umount(cyg_mtab_entry
*mte
)
2124 static void freeTftp(struct Tftp
*t
)
2137 static const int tftpMaxSize
= 8192 * 1024;
2138 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2139 int mode
, cyg_file
*file
)
2142 tftp
= malloc(sizeof(struct Tftp
));
2145 memset(tftp
, 0, sizeof(struct Tftp
));
2147 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
2148 file
->f_type
= CYG_FILE_TYPE_FILE
;
2149 file
->f_ops
= &tftpfs_fileops
;
2154 tftp
->mem
= malloc(tftpMaxSize
);
2155 if (tftp
->mem
== NULL
)
2161 char *server
= strchr(name
, '/');
2168 tftp
->server
= malloc(server
- name
+ 1);
2169 if (tftp
->server
== NULL
)
2174 strncpy(tftp
->server
, name
, server
- name
);
2175 tftp
->server
[server
- name
] = 0;
2177 tftp
->file
= strdup(server
+ 1);
2178 if (tftp
->file
== NULL
)
2184 file
->f_data
= (CYG_ADDRWORD
) tftp
;
2189 static int fetchTftp(struct Tftp
*tftp
)
2191 if (!tftp
->readFile
)
2194 tftp
->actual
= tftp_client_get( tftp
->file
, tftp
->server
, 0, tftp
->mem
, tftpMaxSize
, TFTP_OCTET
, &err
);
2196 if (tftp
->actual
< 0)
2205 // -------------------------------------------------------------------------
2206 // tftpfs_fo_write()
2207 // Read data from file.
2210 tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2212 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2214 if (fetchTftp(tftp
) != ENOERR
)
2218 off_t pos
= fp
->f_offset
;
2220 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2222 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2223 char *buf
= (char *) iov
->iov_base
;
2224 off_t len
= iov
->iov_len
;
2226 if (len
+ pos
> tftp
->actual
)
2228 len
= tftp
->actual
- pos
;
2230 resid
+= iov
->iov_len
- len
;
2232 memcpy(buf
, tftp
->mem
+ pos
, len
);
2236 uio
->uio_resid
= resid
;
2244 tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2246 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2249 off_t pos
= fp
->f_offset
;
2251 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2253 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2254 char *buf
= (char *) iov
->iov_base
;
2255 off_t len
= iov
->iov_len
;
2257 if (len
+ pos
> tftpMaxSize
)
2259 len
= tftpMaxSize
- pos
;
2261 resid
+= iov
->iov_len
- len
;
2263 memcpy(tftp
->mem
+ pos
, buf
, len
);
2267 uio
->uio_resid
= resid
;
2276 tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
2282 // -------------------------------------------------------------------------
2284 // Close a file. We just clear out the data pointer.
2286 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
2288 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2293 tftp_client_put( tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
, TFTP_OCTET
, &error
);
2301 // -------------------------------------------------------------------------
2303 // Seek to a new file position.
2305 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
2307 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2310 if (fetchTftp(tftp
) != ENOERR
)
2316 // Pos is already where we want to be.
2320 // Add pos to current offset.
2321 pos
+= fp
->f_offset
;
2325 // Add pos to file size.
2326 pos
+= tftp
->actual
;
2333 // Check that pos is still within current file size, or at the
2335 if (pos
< 0 || pos
> tftp
->actual
)
2338 // All OK, set fp offset and return new position.
2339 *apos
= fp
->f_offset
= pos
;
2347 cyg_thread_delay(us
/ 10000 + 1);
2354 show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
2356 cyg_httpd_start_chunked("text");
2357 if (logCount
>= logSize
)
2359 cyg_httpd_write_chunked(logBuffer
+logCount
%logSize
, logSize
-logCount
%logSize
);
2361 cyg_httpd_write_chunked(logBuffer
, writePtr
);
2362 cyg_httpd_end_chunked();
2366 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
2368 // Filesystem operations
2369 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
2370 static int logfs_umount(cyg_mtab_entry
*mte
);
2371 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2372 int mode
, cyg_file
*fte
);
2374 logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2377 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
2378 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
2380 #include <cyg/io/devtab.h>
2382 //==========================================================================
2383 // Filesystem table entries
2385 // -------------------------------------------------------------------------
2387 // This defines the entry in the filesystem table.
2388 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2389 // we should never block in any filesystem operations.
2390 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
2391 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
2395 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
2396 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
2397 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
2398 (cyg_fsop_rename
*)cyg_fileio_erofs
,
2399 (cyg_fsop_link
*)cyg_fileio_erofs
,
2400 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
2401 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
2402 (cyg_fsop_stat
*)cyg_fileio_erofs
,
2403 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
2404 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
2406 // -------------------------------------------------------------------------
2408 // This set of file operations are used for normal open files.
2410 static cyg_fileops logfs_fileops
=
2412 (cyg_fileop_read
*)cyg_fileio_erofs
,
2413 (cyg_fileop_write
*)logfs_fo_write
,
2414 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
2415 (cyg_fileop_ioctl
*)cyg_fileio_erofs
,
2419 (cyg_fileop_fstat
*)cyg_fileio_erofs
,
2420 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
2421 (cyg_fileop_setinfo
*)cyg_fileio_erofs
,
2424 // -------------------------------------------------------------------------
2426 // Process a mount request. This mainly finds root for the
2429 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
2434 static int logfs_umount(cyg_mtab_entry
*mte
)
2439 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2440 int mode
, cyg_file
*file
)
2442 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
2443 file
->f_type
= CYG_FILE_TYPE_FILE
;
2444 file
->f_ops
= &logfs_fileops
;
2451 // -------------------------------------------------------------------------
2453 // Write data to file.
2456 logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2459 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2461 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2462 char *buf
= (char *) iov
->iov_base
;
2463 off_t len
= iov
->iov_len
;
2465 diag_write(buf
, len
);
2472 logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
2477 // -------------------------------------------------------------------------
2479 // Close a file. We just clear out the data pointer.
2481 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
2487 ramiodev_init( struct cyg_devtab_entry
*tab
)
2493 ramiodev_bread( cyg_io_handle_t handle
, void *buf
, cyg_uint32
*len
,
2496 if (*len
+pos
>ramblockdevice_size
)
2498 *len
=ramblockdevice_size
-pos
;
2500 memcpy(buf
, ramblockdevice
+pos
, *len
);
2505 ramiodev_bwrite( cyg_io_handle_t handle
, const void *buf
, cyg_uint32
*len
,
2508 if (((pos
%4)!=0)||(((*len
)%4)!=0))
2510 diag_printf("Unaligned write %d %d!", pos
, *len
);
2513 memcpy(ramblockdevice
+pos
, buf
, *len
);
2518 ramiodev_get_config( cyg_io_handle_t handle
,
2524 case CYG_IO_GET_CONFIG_FLASH_ERASE
:
2526 if ( *len
!= sizeof( cyg_io_flash_getconfig_erase_t
) )
2529 cyg_io_flash_getconfig_erase_t
*e
= (cyg_io_flash_getconfig_erase_t
*)buf
;
2530 char *startpos
= ramblockdevice
+ e
->offset
;
2532 if (((e
->offset
%(64*1024))!=0)||((e
->len
%(64*1024))!=0))
2534 diag_printf("Erease is not aligned %d %d\n", e
->offset
, e
->len
);
2537 memset(startpos
, 0xff, e
->len
);
2543 case CYG_IO_GET_CONFIG_FLASH_DEVSIZE
:
2545 if ( *len
!= sizeof( cyg_io_flash_getconfig_devsize_t
) )
2548 cyg_io_flash_getconfig_devsize_t
*d
=
2549 (cyg_io_flash_getconfig_devsize_t
*)buf
;
2551 d
->dev_size
= ramblockdevice_size
;
2556 case CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE
:
2558 cyg_io_flash_getconfig_blocksize_t
*b
=
2559 (cyg_io_flash_getconfig_blocksize_t
*)buf
;
2560 if ( *len
!= sizeof( cyg_io_flash_getconfig_blocksize_t
) )
2563 // offset unused for now
2564 b
->block_size
= 64*1024;
2574 ramiodev_set_config( cyg_io_handle_t handle
,
2584 } // ramiodev_set_config()
2586 // get_config/set_config should be added later to provide the other flash
2587 // operations possible, like erase etc.
2589 BLOCK_DEVIO_TABLE( cyg_io_ramdev1_ops
,
2593 &ramiodev_get_config
,
2594 &ramiodev_set_config
2598 BLOCK_DEVTAB_ENTRY( cyg_io_ramdev1
,
2601 &cyg_io_ramdev1_ops
,
2603 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)