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
;
348 extern flash_driver_t
*flash_drivers
[];
349 extern target_type_t
*target_types
[];
351 #ifdef CYGPKG_PROFILE_GPROF
352 #include <cyg/profile/profile.h>
354 extern char _stext
, _etext
; // Defined by the linker
356 static char *start_of_code
=&_stext
;
357 static char *end_of_code
=&_etext
;
359 void start_profile(void)
361 // This starts up the system-wide profiling, gathering
362 // profile information on all of the code, with a 16 byte
363 // "bucket" size, at a rate of 100us/profile hit.
364 // Note: a bucket size of 16 will give pretty good function
365 // resolution. Much smaller and the buffer becomes
366 // much too large for very little gain.
367 // Note: a timer period of 100us is also a reasonable
368 // compromise. Any smaller and the overhead of
369 // handling the timter (profile) interrupt could
370 // swamp the system. A fast processor might get
371 // by with a smaller value, but a slow one could
372 // even be swamped by this value. If the value is
373 // too large, the usefulness of the profile is reduced.
375 // no more interrupts than 1/10ms.
376 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
377 // profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
378 profile_on(start_of_code
, end_of_code
, 16, 10000); // Nios DRAM
382 // launch GDB server if a config file exists
383 bool zylinjtag_parse_config_file(struct command_context_s
*cmd_ctx
, const char *config_file_name
)
385 bool foundFile
= false;
386 FILE *config_file
= NULL
;
387 command_print(cmd_ctx
, "executing config file %s", config_file_name
);
388 config_file
= fopen(config_file_name
, "r");
393 retval
= command_run_linef(cmd_ctx
, "script %s", config_file_name
);
394 if (retval
== ERROR_OK
)
400 command_print(cmd_ctx
, "Failed executing %s %d", config_file_name
, retval
);
405 command_print(cmd_ctx
, "No %s found", config_file_name
);
414 static char reboot_stack
[2048];
418 zylinjtag_reboot(cyg_addrword_t data
)
421 diag_printf("Rebooting in 100 ticks..\n");
422 cyg_thread_delay(100);
423 diag_printf("Unmounting /config..\n");
425 diag_printf("Rebooting..\n");
426 HAL_PLATFORM_RESET();
428 static cyg_thread zylinjtag_thread_object
;
429 static cyg_handle_t zylinjtag_thread_handle
;
437 (void *)reboot_stack
,
438 sizeof(reboot_stack
),
439 &zylinjtag_thread_handle
,
440 &zylinjtag_thread_object
);
441 cyg_thread_resume(zylinjtag_thread_handle
);
444 int configuration_output_handler(struct command_context_s
*context
, const char* line
)
446 diag_printf("%s", line
);
451 int zy1000_configuration_output_handler_log(struct command_context_s
*context
, const char* line
)
453 LOG_USER_N("%s", line
);
458 int handle_rm_command(struct command_context_s
*cmd_ctx
, char *cmd
,
459 char **args
, int argc
)
463 command_print(cmd_ctx
, "rm <filename>");
464 return ERROR_INVALID_ARGUMENTS
;
467 if (unlink(args
[0]) != 0)
469 command_print(cmd_ctx
, "failed: %d", errno
);
475 int loadFile(const char *fileName
, void **data
, int *len
);
477 int handle_cat_command(struct command_context_s
*cmd_ctx
, char *cmd
,
478 char **args
, int argc
)
482 command_print(cmd_ctx
, "cat <filename>");
483 return ERROR_INVALID_ARGUMENTS
;
486 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
490 int retval
= loadFile(args
[0], &data
, &len
);
491 if (retval
== ERROR_OK
)
493 command_print(cmd_ctx
, "%s", data
);
498 command_print(cmd_ctx
, "%s not found %d", args
[0], retval
);
503 int handle_trunc_command(struct command_context_s
*cmd_ctx
, char *cmd
,
504 char **args
, int argc
)
508 command_print(cmd_ctx
, "trunc <filename>");
509 return ERROR_INVALID_ARGUMENTS
;
512 FILE *config_file
= NULL
;
513 config_file
= fopen(args
[0], "w");
514 if (config_file
!= NULL
)
521 int handle_meminfo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
524 struct mallinfo info
;
528 command_print(cmd_ctx
, "meminfo");
529 return ERROR_INVALID_ARGUMENTS
;
536 command_print(cmd_ctx
, "Diff: %d", prev
- info
.fordblks
);
538 prev
= info
.fordblks
;
540 command_print(cmd_ctx
, "Available ram: %d", info
.fordblks
);
545 static bool savePower
;
547 static void setPower(bool power
)
552 HAL_WRITE_UINT32(ZY1000_JTAG_BASE
+0x14, 0x8);
555 HAL_WRITE_UINT32(ZY1000_JTAG_BASE
+0x10, 0x8);
559 int handle_power_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
563 return ERROR_INVALID_ARGUMENTS
;
568 if (strcmp(args
[0], "on") == 0)
572 else if (strcmp(args
[0], "off") == 0)
577 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
578 return ERROR_INVALID_ARGUMENTS
;
582 command_print(cmd_ctx
, "Target power %s", savePower
? "on" : "off");
587 int handle_append_command(struct command_context_s
*cmd_ctx
, char *cmd
,
588 char **args
, int argc
)
592 command_print(cmd_ctx
,
593 "append <filename> [<string1>, [<string2>, ...]]");
594 return ERROR_INVALID_ARGUMENTS
;
597 FILE *config_file
= NULL
;
598 config_file
= fopen(args
[0], "a");
599 if (config_file
!= NULL
)
602 fseek(config_file
, 0, SEEK_END
);
604 for (i
= 1; i
< argc
; i
++)
606 fwrite(args
[i
], strlen(args
[i
]), 1, config_file
);
609 fwrite(" ", 1, 1, config_file
);
612 fwrite("\n", 1, 1, config_file
);
619 extern int telnet_socket
;
621 int readMore(int fd
, void *data
, int length
)
623 /* used in select() */
626 /* monitor sockets for acitvity */
629 /* listen for new connections */
630 FD_SET(fd
, &read_fds
);
632 // Maximum 5 seconds.
637 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
640 diag_printf("Timed out waiting for binary payload\n");
646 return read_socket(fd
, data
, length
);
649 int readAll(int fd
, void *data
, int length
)
654 int actual
= readMore(fd
, ((char *) data
) + pos
, length
- pos
);
655 // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
665 int handle_peek_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
670 return ERROR_INVALID_ARGUMENTS
;
672 HAL_READ_UINT32(strtoul(args
[0], NULL
, 0), value
);
673 command_print(cmd_ctx
, "0x%x : 0x%x", strtoul(args
[0], NULL
, 0), value
);
677 int handle_poke_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
681 return ERROR_INVALID_ARGUMENTS
;
683 HAL_WRITE_UINT32(strtoul(args
[0], NULL
, 0), strtoul(args
[1], NULL
, 0));
687 int handle_cp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
691 return ERROR_INVALID_ARGUMENTS
;
694 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
698 int retval
= loadFile(args
[0], &data
, &len
);
699 if (retval
!= ERROR_OK
)
702 FILE *f
= fopen(args
[1], "wb");
704 retval
= ERROR_INVALID_ARGUMENTS
;
709 int chunk
= len
- pos
;
710 static const int maxChunk
= 512 * 1024; // ~1/sec
711 if (chunk
> maxChunk
)
716 if ((retval
==ERROR_OK
)&&(fwrite(((char *)data
)+pos
, 1, chunk
, f
)!=chunk
))
717 retval
= ERROR_INVALID_ARGUMENTS
;
719 if (retval
!= ERROR_OK
)
724 command_print(cmd_ctx
, "%d", len
- pos
);
732 if (retval
== ERROR_OK
)
734 command_print(cmd_ctx
, "Copied %s to %s", args
[0], args
[1]);
737 command_print(cmd_ctx
, "Failed: %d", retval
);
745 if (retval
!= ERROR_OK
)
751 #ifdef CYGPKG_PROFILE_GPROF
752 extern void start_profile();
754 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
756 command_print(cmd_ctx
, "Profiling started");
763 externC
void phi_init_all_network_interfaces();
765 command_context_t
*cmd_ctx
;
767 static bool webRunning
= false;
769 void keep_webserver()
771 // Target initialisation is only attempted at startup, so we sleep forever and
772 // let the http server bail us out(i.e. get config files set up).
773 diag_printf("OpenOCD has invoked exit().\n"
774 "Use web server to correct any configuration settings and reboot.\n");
778 // exit() will terminate the current thread and we we'll then sleep eternally or
779 // we'll have a reboot scheduled.
782 extern void printDccChar(char c
);
784 static char logBuffer
[128 * 1024];
785 static const int logSize
= sizeof(logBuffer
);
789 void _zylinjtag_diag_write_char(char c
, void **param
)
793 logBuffer
[writePtr
] = c
;
794 writePtr
= (writePtr
+ 1) % logSize
;
801 HAL_DIAG_WRITE_CHAR('\r');
803 HAL_DIAG_WRITE_CHAR(c
);
806 #ifdef CYGPKG_HAL_ZYLIN_PHI
811 #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
814 static void copyfile(char *name2
, char *name1
)
822 fd1
= open(name1
, O_WRONLY
| O_CREAT
);
824 SHOW_RESULT( open
, fd1
);
826 fd2
= open(name2
, O_RDONLY
);
828 SHOW_RESULT( open
, fd2
);
832 done
= read(fd2
, buf
, IOSIZE
);
835 SHOW_RESULT( read
, done
);
839 if( done
== 0 ) break;
841 wrote
= write(fd1
, buf
, done
);
842 if( wrote
!= done
) SHOW_RESULT( write
, wrote
);
844 if( wrote
!= done
) break;
848 if( err
< 0 ) SHOW_RESULT( close
, err
);
851 if( err
< 0 ) SHOW_RESULT( close
, err
);
854 static void copydir(char *name
, char *destdir
)
859 dirp
= opendir(destdir
);
862 mkdir(destdir
, 0777);
865 err
= closedir(dirp
);
868 dirp
= opendir(name
);
869 if( dirp
== NULL
) SHOW_RESULT( opendir
, -1 );
873 struct dirent
*entry
= readdir(dirp
);
878 if (strcmp(entry
->d_name
, ".") == 0)
880 if (strcmp(entry
->d_name
, "..") == 0)
885 char fullPath
[PATH_MAX
];
886 strncpy(fullPath
, name
, PATH_MAX
);
887 strcat(fullPath
, "/");
888 strncat(fullPath
, entry
->d_name
, PATH_MAX
- strlen(fullPath
));
890 if (stat(fullPath
, &buf
) == -1)
892 diag_printf("unable to read status from %s", fullPath
);
895 isDir
= S_ISDIR(buf
.st_mode
) != 0;
900 // diag_printf("<INFO>: entry %14s",entry->d_name);
901 char fullname
[PATH_MAX
];
902 char fullname2
[PATH_MAX
];
904 strcpy(fullname
, name
);
905 strcat(fullname
, "/");
906 strcat(fullname
, entry
->d_name
);
908 strcpy(fullname2
, destdir
);
909 strcat(fullname2
, "/");
910 strcat(fullname2
, entry
->d_name
);
911 // diag_printf("from %s to %s\n", fullname, fullname2);
912 copyfile(fullname
, fullname2
);
914 // diag_printf("\n");
917 err
= closedir(dirp
);
918 if( err
< 0 ) SHOW_RESULT( stat
, err
);
922 MTAB_ENTRY( romfs_mte1
,
926 (CYG_ADDRWORD
) &filedata
[0] );
929 void openocd_sleep_prelude()
931 cyg_mutex_unlock(&httpstate
.jim_lock
);
934 void openocd_sleep_postlude()
936 cyg_mutex_lock(&httpstate
.jim_lock
);
942 diag_printf("Formatting JFFS2...\n");
944 cyg_io_handle_t handle
;
947 err
= cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1
, &handle
);
950 diag_printf("Flash Error cyg_io_lookup: %d\n", err
);
956 cyg_io_flash_getconfig_devsize_t ds
;
958 err
= cyg_io_get_config(handle
,
959 CYG_IO_GET_CONFIG_FLASH_DEVSIZE
, &ds
, &len
);
962 diag_printf("Flash error cyg_io_get_config %d\n", err
);
966 cyg_io_flash_getconfig_erase_t e
;
972 e
.err_address
= &err_addr
;
974 diag_printf("Formatting 0x%08x bytes\n", ds
.dev_size
);
975 err
= cyg_io_get_config(handle
, CYG_IO_GET_CONFIG_FLASH_ERASE
,
979 diag_printf("Flash erase error %d offset 0x%p\n", err
, err_addr
);
983 diag_printf("Flash formatted successfully\n");
991 zylinjtag_Jim_Command_format_jffs2(Jim_Interp
*interp
,
993 Jim_Obj
* const *argv
)
1006 zylinjtag_Jim_Command_rm(Jim_Interp
*interp
,
1008 Jim_Obj
* const *argv
)
1013 Jim_WrongNumArgs(interp
, 1, argv
, "rm ?dirorfile?");
1018 if (unlink(Jim_GetString(argv
[1], NULL
)) == 0)
1020 if (rmdir(Jim_GetString(argv
[1], NULL
)) == 0)
1023 return del
? JIM_OK
: JIM_ERR
;
1026 static int zylinjtag_Jim_Command_threads(Jim_Interp
*interp
, int argc
,
1027 Jim_Obj
* const *argv
)
1029 cyg_handle_t thread
= 0;
1031 Jim_Obj
*threads
= Jim_NewListObj(interp
, NULL
, 0);
1033 /* Loop over the threads, and generate a table row for
1036 while (cyg_thread_get_next(&thread
, &id
))
1038 Jim_Obj
*threadObj
= Jim_NewListObj(interp
, NULL
, 0);
1040 cyg_thread_info info
;
1043 cyg_thread_get_info(thread
, id
, &info
);
1045 if (info
.name
== NULL
)
1046 info
.name
= "<no name>";
1048 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
1049 info
.name
, strlen(info
.name
)));
1051 /* Translate the state into a string.
1053 if (info
.state
== 0)
1054 state_string
= "RUN";
1055 else if (info
.state
& 0x04)
1056 state_string
= "SUSP";
1058 switch (info
.state
& 0x1b)
1061 state_string
= "SLEEP";
1064 state_string
= "CNTSLEEP";
1067 state_string
= "CREATE";
1070 state_string
= "EXIT";
1073 state_string
= "????";
1077 Jim_ListAppendElement(interp
, threadObj
, Jim_NewStringObj(interp
,
1078 state_string
, strlen(state_string
)));
1080 Jim_ListAppendElement (interp
, threadObj
, Jim_NewIntObj(interp
, id
));
1081 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, info
.set_pri
));
1082 Jim_ListAppendElement(interp
, threadObj
, Jim_NewIntObj(interp
, info
.cur_pri
));
1084 Jim_ListAppendElement(interp
, threads
, threadObj
);
1086 Jim_SetResult( interp
, threads
);
1093 zylinjtag_Jim_Command_ls(Jim_Interp
*interp
,
1095 Jim_Obj
* const *argv
)
1099 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
1103 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
1106 dirp
= opendir(name
);
1111 Jim_Obj
*objPtr
= Jim_NewListObj(interp
, NULL
, 0);
1115 struct dirent
*entry
= NULL
;
1116 entry
= readdir(dirp
);
1120 if ((strcmp(".", entry
->d_name
)==0)||(strcmp("..", entry
->d_name
)==0))
1123 Jim_ListAppendElement(interp
, objPtr
, Jim_NewStringObj(interp
, entry
->d_name
, strlen(entry
->d_name
)));
1127 Jim_SetResult(interp
, objPtr
);
1134 zylinjtag_Jim_Command_getmem(Jim_Interp
*interp
,
1136 Jim_Obj
* const *argv
)
1140 Jim_WrongNumArgs(interp
, 1, argv
, "ls ?dir?");
1146 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1148 if (Jim_GetLong(interp
, argv
[2], &length
) != JIM_OK
)
1151 if (length
< 0 && length
> (4096 * 1024))
1153 Jim_WrongNumArgs(interp
, 1, argv
, "getmem ?dir?");
1157 void *mem
= malloc(length
);
1161 target_t
*target
= get_current_target(cmd_ctx
);
1166 if ((address
% 4 == 0) && (count
% 4 == 0))
1172 if ((retval
= target
->type
->read_memory(target
, address
, size
, count
, mem
)) != ERROR_OK
)
1178 Jim_Obj
*objPtr
= Jim_NewStringObj(interp
, mem
, length
);
1179 Jim_SetResult(interp
, objPtr
);
1187 zylinjtag_Jim_Command_peek(Jim_Interp
*interp
,
1189 Jim_Obj
* const *argv
)
1193 Jim_WrongNumArgs(interp
, 1, argv
, "peek ?address?");
1198 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1201 int value
= *((volatile int *) address
);
1203 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
1209 zylinjtag_Jim_Command_poke(Jim_Interp
*interp
,
1211 Jim_Obj
* const *argv
)
1215 Jim_WrongNumArgs(interp
, 1, argv
, "poke ?address? ?value?");
1220 if (Jim_GetLong(interp
, argv
[1], &address
) != JIM_OK
)
1223 if (Jim_GetLong(interp
, argv
[2], &value
) != JIM_OK
)
1226 *((volatile int *) address
) = value
;
1234 zylinjtag_Jim_Command_flash(Jim_Interp
*interp
,
1236 Jim_Obj
* const *argv
)
1240 flash_bank_t
*t
= get_flash_bank_by_num_noprobe(0);
1250 if (retval
== JIM_OK
)
1252 Jim_SetResult(interp
, Jim_NewIntObj(interp
, base
));
1263 zylinjtag_Jim_Command_log(Jim_Interp
*interp
,
1265 Jim_Obj
* const *argv
)
1267 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1269 if (logCount
>= logSize
)
1271 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
+logCount
%logSize
, logSize
-logCount
%logSize
);
1273 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, logBuffer
, writePtr
);
1275 Jim_SetResult(interp
, tclOutput
);
1280 zylinjtag_Jim_Command_reboot(Jim_Interp
*interp
,
1282 Jim_Obj
* const *argv
)
1289 zylinjtag_Jim_Command_mac(Jim_Interp
*interp
,
1291 Jim_Obj
* const *argv
)
1294 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1296 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, hwaddr
, strlen(hwaddr
));
1298 Jim_SetResult(interp
, tclOutput
);
1304 zylinjtag_Jim_Command_ip(Jim_Interp
*interp
,
1306 Jim_Obj
* const *argv
)
1308 Jim_Obj
*tclOutput
= Jim_NewStringObj(interp
, "", 0);
1310 struct ifaddrs
*ifa
= NULL
, *ifp
= NULL
;
1312 if (getifaddrs(&ifp
) < 0)
1317 for (ifa
= ifp
; ifa
; ifa
= ifa
->ifa_next
)
1322 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1323 salen
= sizeof(struct sockaddr_in
);
1324 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1325 salen
= sizeof(struct sockaddr_in6
);
1329 if (getnameinfo(ifa
->ifa_addr
, salen
, ip
, sizeof(ip
), NULL
, 0,
1330 NI_NUMERICHOST
) < 0)
1335 Jim_AppendString(httpstate
.jim_interp
, tclOutput
, ip
, strlen(ip
));
1342 Jim_SetResult(interp
, tclOutput
);
1347 extern Jim_Interp
*interp
;
1350 static void zylinjtag_startNetwork()
1352 // Bring TCP/IP up immediately before we're ready to accept commands.
1354 // That is as soon as a PING responds, we're accepting telnet sessions.
1355 #if defined(CYGPKG_NET_FREEBSD_STACK)
1356 phi_init_all_network_interfaces();
1362 diag_printf("Network not up and running\n");
1365 #if defined(CYGPKG_NET_FREEBSD_STACK)
1367 tftpd_start(69, &fileops
);
1370 cyg_httpd_init_tcl_interpreter();
1372 interp
= httpstate
.jim_interp
;
1374 Jim_CreateCommand(httpstate
.jim_interp
, "log", zylinjtag_Jim_Command_log
, NULL
, NULL
);
1375 Jim_CreateCommand(httpstate
.jim_interp
, "reboot", zylinjtag_Jim_Command_reboot
, NULL
, NULL
);
1376 Jim_CreateCommand(httpstate
.jim_interp
, "peek", zylinjtag_Jim_Command_peek
, NULL
, NULL
);
1377 Jim_CreateCommand(httpstate
.jim_interp
, "zy1000_flash", zylinjtag_Jim_Command_flash
, NULL
, NULL
);
1378 Jim_CreateCommand(httpstate
.jim_interp
, "poke", zylinjtag_Jim_Command_poke
, NULL
, NULL
);
1379 Jim_CreateCommand(httpstate
.jim_interp
, "ls", zylinjtag_Jim_Command_ls
, NULL
, NULL
);
1380 Jim_CreateCommand(httpstate
.jim_interp
, "threads", zylinjtag_Jim_Command_threads
, NULL
, NULL
);
1381 Jim_CreateCommand(httpstate
.jim_interp
, "getmem", zylinjtag_Jim_Command_getmem
, NULL
, NULL
);
1382 Jim_CreateCommand(httpstate
.jim_interp
, "mac", zylinjtag_Jim_Command_mac
, NULL
, NULL
);
1383 Jim_CreateCommand(httpstate
.jim_interp
, "ip", zylinjtag_Jim_Command_ip
, NULL
, NULL
);
1384 Jim_CreateCommand(httpstate
.jim_interp
, "rm", zylinjtag_Jim_Command_rm
, NULL
, NULL
);
1385 Jim_CreateCommand(httpstate
.jim_interp
, "format_jffs2", zylinjtag_Jim_Command_format_jffs2
, NULL
, NULL
);
1391 diag_printf("Web server running\n");
1395 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
1398 strcpy(ifr
.ifr_name
, "eth0");
1400 res
= ioctl(s
, SIOCGIFHWADDR
, &ifr
);
1405 diag_printf("Can't obtain MAC address\n");
1410 sprintf(hwaddr
, "%02x:%02x:%02x:%02x:%02x:%02x",
1411 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[0],
1412 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[1],
1413 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[2],
1414 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[3],
1415 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[4],
1416 (int) ((unsigned char *) &ifr
.ifr_hwaddr
.sa_data
)[5]);
1419 discover_message
=alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr
);
1429 print_exception_handler(cyg_addrword_t data
, cyg_code_t exception
, cyg_addrword_t info
)
1433 char *infoStr
= "unknown";
1436 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1437 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
:
1438 infoStr
= "undefined instruction";
1440 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
:
1441 infoStr
= "software interrupt";
1443 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH
:
1444 infoStr
= "abort prefetch";
1446 case CYGNUM_HAL_VECTOR_ABORT_DATA
:
1447 infoStr
= "abort data";
1454 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
1456 diag_printf("Dumping log\n---\n");
1457 if (logCount
>= logSize
)
1459 diag_write(logBuffer
+ logCount
% logSize
, logSize
- logCount
% logSize
);
1461 diag_write(logBuffer
, writePtr
);
1463 diag_printf("---\nLogdump complete.\n");
1464 diag_printf("Exception: %08x(%s) %08x\n", exception
, infoStr
, info
);
1465 diag_printf("\n---\nRebooting\n");
1466 HAL_PLATFORM_RESET();
1470 static void setHandler(cyg_code_t exception
)
1472 cyg_exception_handler_t
*old_handler
;
1473 cyg_addrword_t old_data
;
1475 cyg_exception_set_handler(exception
,
1476 print_exception_handler
,
1482 static cyg_thread zylinjtag_uart_thread_object
;
1483 static cyg_handle_t zylinjtag_uart_thread_handle
;
1484 static char uart_stack
[4096];
1486 static char forwardBuffer
[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
1487 static char backwardBuffer
[1024];
1490 void setNoDelay(int session
, int flag
)
1493 // This decreases latency dramatically for e.g. GDB load which
1494 // does not have a sliding window protocol
1496 // Can cause *lots* of TCP/IP packets to be sent and it would have
1497 // to be enabled/disabled on the fly to avoid the CPU being
1499 setsockopt(session
, /* socket affected */
1500 IPPROTO_TCP
, /* set option at TCP level */
1501 TCP_NODELAY
, /* name of option */
1502 (char *) &flag
, /* the cast is historical
1504 sizeof(int)); /* length of option value */
1514 } tcpipSent
[512 * 1024];
1518 zylinjtag_uart(cyg_addrword_t data
)
1520 int so_reuseaddr_option
= 1;
1523 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
1525 LOG_ERROR("error creating socket: %s", strerror(errno
));
1529 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
1531 struct sockaddr_in sin
;
1532 unsigned int address_size
;
1533 address_size
= sizeof(sin
);
1534 memset(&sin
, 0, sizeof(sin
));
1535 sin
.sin_family
= AF_INET
;
1536 sin
.sin_addr
.s_addr
= INADDR_ANY
;
1537 sin
.sin_port
= htons(5555);
1539 if (bind(fd
, (struct sockaddr
*) &sin
, sizeof(sin
)) == -1)
1541 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
1545 if (listen(fd
, 1) == -1)
1547 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
1550 // socket_nonblock(fd);
1555 int session
= accept(fd
, (struct sockaddr
*) &sin
, &address_size
);
1561 setNoDelay(session
, 1);
1562 int oldopts
= fcntl(session
, F_GETFL
, 0);
1563 fcntl(session
, F_SETFL
, oldopts
| O_NONBLOCK
); //
1565 int serHandle
= open("/dev/ser0", O_RDWR
| O_NONBLOCK
);
1572 #ifdef CYGPKG_PROFILE_GPROF
1585 FD_ZERO(&write_fds
);
1588 FD_SET(session
, &read_fds
);
1590 FD_SET(serHandle
, &read_fds
);
1591 if (serHandle
> fd_max
)
1597 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
1598 if ((actual
== 0) && (actual2
== 0))
1600 int retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, NULL
);
1609 memset(backwardBuffer
, 's', sizeof(backwardBuffer
));
1610 actual2
=read(serHandle
, backwardBuffer
, sizeof(backwardBuffer
));
1613 if (errno
!= EAGAIN
)
1626 int written
= write(session
, backwardBuffer
+ pos2
, actual2
);
1634 if (FD_ISSET(session
, &read_fds
)&&(sizeof(forwardBuffer
)>actual
))
1636 // NB! Here it is important that we empty the TCP/IP read buffer
1637 // to make transmission tick right
1638 memmove(forwardBuffer
, forwardBuffer
+ pos
, actual
);
1641 // this will block if there is no data at all
1642 t
=read_socket(session
, forwardBuffer
+actual
, sizeof(forwardBuffer
)-actual
);
1654 /* Do not put things into the serial buffer if it has something to send
1655 * as that can cause a single byte to be sent at the time.
1659 int written
= write(serHandle
, forwardBuffer
+ pos
, actual
);
1662 if (errno
!= EAGAIN
)
1666 // The serial buffer is full
1677 tcpipSent
[cur
].req
= x
;
1678 tcpipSent
[cur
].actual
= y
;
1679 tcpipSent
[cur
].req2
= x2
;
1680 tcpipSent
[cur
].actual2
= y2
;
1690 for (i
= 0; i
< 1024; i
++)
1692 diag_printf("%d %d %d %d\n", tcpipSent
[i
].req
, tcpipSent
[i
].actual
, tcpipSent
[i
].req2
, tcpipSent
[i
].actual2
);
1700 void startUart(void)
1702 cyg_thread_create(1,
1708 &zylinjtag_uart_thread_handle
,
1709 &zylinjtag_uart_thread_object
);
1710 cyg_thread_set_priority(zylinjtag_uart_thread_handle
, 1); // low priority as it sits in a busy loop
1711 cyg_thread_resume(zylinjtag_uart_thread_handle
);
1716 int handle_uart_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1718 static int current_baud
= 38400;
1721 command_print(cmd_ctx
, "%d", current_baud
);
1723 } else if (argc
!= 1)
1725 return ERROR_INVALID_ARGUMENTS
;
1728 current_baud
= atol(args
[0]);
1731 switch (current_baud
)
1734 baud
= CYGNUM_SERIAL_BAUD_9600
;
1737 baud
= CYGNUM_SERIAL_BAUD_19200
;
1740 baud
= CYGNUM_SERIAL_BAUD_38400
;
1743 baud
= CYGNUM_SERIAL_BAUD_57600
;
1746 baud
= CYGNUM_SERIAL_BAUD_115200
;
1749 baud
= CYGNUM_SERIAL_BAUD_230400
;
1752 command_print(cmd_ctx
, "unsupported baudrate");
1753 return ERROR_INVALID_ARGUMENTS
;
1756 cyg_serial_info_t buf
;
1758 //get existing serial configuration
1759 len
= sizeof(cyg_serial_info_t
);
1761 cyg_io_handle_t serial_handle
;
1763 err
= cyg_io_lookup("/dev/ser0", &serial_handle
);
1766 LOG_ERROR("/dev/ser0 not found\n");
1771 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
, &buf
, &len
);
1772 err
= cyg_io_get_config(serial_handle
, CYG_IO_GET_CONFIG_SERIAL_INFO
, &buf
, &len
);
1775 command_print(cmd_ctx
, "Failed to get serial port settings %d", err
);
1780 err
= cyg_io_set_config(serial_handle
, CYG_IO_SET_CONFIG_SERIAL_INFO
, &buf
, &len
);
1783 command_print(cmd_ctx
, "Failed to set serial port settings %d", err
);
1790 bool logAllToSerial
= false;
1792 /* boolean parameter stored on config */
1793 bool boolParam(char *var
)
1795 bool result
= false;
1796 char *name
= alloc_printf(ZYLIN_CONFIG_DIR
"/%s", var
);
1802 if (loadFile(name
, &data
, &len
) == ERROR_OK
)
1806 result
= strncmp((char *) data
, "1", len
) == 0;
1813 command_context_t
*setup_command_handler();
1815 int add_default_dirs(void)
1817 add_script_search_dir(ZYLIN_CONFIG_DIR
);
1818 add_script_search_dir("/rom/lib/openocd");
1819 add_script_search_dir("/rom");
1823 static cyg_uint8
*ramblockdevice
;
1824 static const int ramblockdevice_size
=4096*1024;
1825 int main(int argc
, char *argv
[])
1827 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
1828 * need to allocate towards the end of the heap. */
1830 ramblockdevice
=(cyg_uint8
*)malloc(ramblockdevice_size
);
1831 memset(ramblockdevice
, 0xff, ramblockdevice_size
);
1835 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1836 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
);
1837 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH
);
1838 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA
);
1843 setPower(true); // on by default
1845 atexit(keep_webserver
);
1847 err
= mount("", "/ram", "ramfs");
1850 diag_printf("unable to mount ramfs\n");
1855 sprintf(address
, "%p", &filedata
[0]);
1856 err
= mount(address
, "/rom", "romfs");
1859 diag_printf("unable to mount /rom\n");
1862 err
= mount("", "/log", "logfs");
1865 diag_printf("unable to mount logfs\n");
1868 err
= mount("", "/tftp", "tftpfs");
1871 diag_printf("unable to mount logfs\n");
1874 log
= fopen("/log/log", "w");
1877 diag_printf("Could not open log file /ram/log\n");
1881 diag_init_putc(_zylinjtag_diag_write_char
);
1883 // We want this in the log.
1884 diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
1885 diag_printf("%s\n", ZYLIN_OPENOCD_VERSION
);
1887 copydir("/rom", "/ram/cgi");
1889 err
= mount("/dev/flash1", "/config", "jffs2");
1892 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1893 err
= mount("", "/config", "ramfs");
1896 diag_printf("unable to mount /config as ramdisk.\n");
1901 /* are we using a ram disk instead of a flash disk? This is used
1902 * for ZY1000 live demo...
1904 * copy over flash disk to ram block device
1906 if (boolParam("ramdisk"))
1908 diag_printf("Unmounting /config from flash and using ram instead\n");
1909 err
=umount("/config");
1912 diag_printf("unable to unmount jffs\n");
1916 err
= mount("/dev/flash1", "/config2", "jffs2");
1919 diag_printf("unable to mount jffs\n");
1923 err
= mount("", "/config", "ramfs");
1926 diag_printf("unable to mount ram block device\n");
1930 // copydir("/config2", "/config");
1931 copyfile("/config2/ip", "/config/ip");
1932 copydir("/config2/settings", "/config/settings");
1937 /* we're not going to use a ram block disk */
1938 free(ramblockdevice
);
1943 mkdir(ZYLIN_CONFIG_DIR
, 0777);
1944 mkdir(ZYLIN_CONFIG_DIR
"/target", 0777);
1945 mkdir(ZYLIN_CONFIG_DIR
"/event", 0777);
1947 logAllToSerial
= boolParam("logserial");
1949 // We need the network & web server in case there is something wrong with
1950 // the config files that invoke exit()
1951 zylinjtag_startNetwork();
1953 /* we're going to access the jim interpreter from here on... */
1954 openocd_sleep_postlude();
1959 /* initialize commandline interface */
1960 command_context_t
*cmd_ctx
;
1961 cmd_ctx
= setup_command_handler();
1962 command_set_output_handler(cmd_ctx
, configuration_output_handler
, NULL
);
1963 command_context_mode(cmd_ctx
, COMMAND_CONFIG
);
1966 register_command(cmd_ctx
, NULL
, "zy1000_version", handle_zy1000_version_command
,
1967 COMMAND_EXEC
, "show zy1000 version numbers");
1969 register_command(cmd_ctx
, NULL
, "rm", handle_rm_command
, COMMAND_ANY
,
1972 register_command(cmd_ctx
, NULL
, "fast_load_image", handle_fast_load_image_command
, COMMAND_ANY
,
1973 "same args as load_image, image stored in memory");
1975 register_command(cmd_ctx
, NULL
, "fast_load", handle_fast_load_command
, COMMAND_ANY
,
1976 "loads active fast load image to current target");
1978 register_command(cmd_ctx
, NULL
, "cat", handle_cat_command
, COMMAND_ANY
,
1979 "display file content");
1981 register_command(cmd_ctx
, NULL
, "trunc", handle_trunc_command
, COMMAND_ANY
,
1982 "truncate a file to 0 size");
1984 register_command(cmd_ctx
, NULL
, "append_file", handle_append_command
,
1985 COMMAND_ANY
, "append a variable number of strings to a file");
1987 register_command(cmd_ctx
, NULL
, "power", handle_power_command
, COMMAND_ANY
,
1988 "power <on/off> - turn power switch to target on/off. No arguments - print status.");
1990 register_command(cmd_ctx
, NULL
, "meminfo", handle_meminfo_command
,
1991 COMMAND_ANY
, "display available ram memory");
1993 register_command(cmd_ctx
, NULL
, "cp", handle_cp_command
,
1994 COMMAND_ANY
, "copy a file <from> <to>");
1996 #ifdef CYGPKG_PROFILE_GPROF
1997 register_command(cmd_ctx
, NULL
, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command
,
2000 register_command(cmd_ctx
, NULL
, "uart", handle_uart_command
,
2001 COMMAND_ANY
, "uart <baud> - forward uart on port 5555");
2005 errVal
= log_init(cmd_ctx
);
2006 if (errVal
!= ERROR_OK
)
2008 diag_printf("log_init() failed %d\n", errVal
);
2012 set_log_output(cmd_ctx
, log
);
2014 LOG_DEBUG("log init complete");
2016 // diag_printf("Executing config files\n");
2020 diag_printf(ZYLIN_CONFIG_DIR
"/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
2021 command_run_line(cmd_ctx
, "debug_level 3");
2024 zylinjtag_parse_config_file(cmd_ctx
, "/rom/openocd.cfg");
2027 // diag_printf() is really invoked from many more places than we trust it
2028 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
2030 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
2031 // fingers that it doesn't cause any crashes.
2032 diag_printf("Init complete, GDB & telnet servers launched.\n");
2033 command_set_output_handler(cmd_ctx
, zy1000_configuration_output_handler_log
, NULL
);
2034 if (!logAllToSerial
)
2039 /* handle network connections */
2040 server_loop(cmd_ctx
);
2041 openocd_sleep_prelude();
2043 /* shut server down */
2046 /* free commandline interface */
2047 command_done(cmd_ctx
);
2057 cyg_httpd_exec_cgi_tcl(char *file_name
);
2058 cyg_int32
homeForm(CYG_HTTPD_STATE
*p
)
2060 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
2064 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label
, "/", homeForm
);
2066 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label
, "text", "text/plain");
2067 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label
, "bin", "application/octet-stream");
2069 #include <pkgconf/system.h>
2070 #include <pkgconf/hal.h>
2071 #include <pkgconf/kernel.h>
2072 #include <pkgconf/io_fileio.h>
2073 #include <pkgconf/fs_rom.h>
2075 #include <cyg/kernel/ktypes.h> // base kernel types
2076 #include <cyg/infra/cyg_trac.h> // tracing macros
2077 #include <cyg/infra/cyg_ass.h> // assertion macros
2079 #include <sys/types.h>
2081 #include <sys/stat.h>
2090 #include <cyg/fileio/fileio.h>
2092 #include <cyg/kernel/kapi.h>
2093 #include <cyg/infra/diag.h>
2095 //==========================================================================
2096 // Eventually we want to eXecute In Place from the ROM in a protected
2097 // environment, so we'll need executables to be aligned to a boundary
2098 // suitable for MMU protection. A suitable boundary would be the 4k
2099 // boundary in all the CPU architectures I am currently aware of.
2101 // Forward definitions
2103 // Filesystem operations
2104 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
2105 static int tftpfs_umount(cyg_mtab_entry
*mte
);
2106 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2107 int mode
, cyg_file
*fte
);
2108 static int tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2109 static int tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2112 static int tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
2113 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
);
2114 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
);
2116 //==========================================================================
2117 // Filesystem table entries
2119 // -------------------------------------------------------------------------
2121 // This defines the entry in the filesystem table.
2122 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2123 // we should never block in any filesystem operations.
2125 FSTAB_ENTRY( tftpfs_fste
, "tftpfs", 0,
2130 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
2131 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
2132 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
2133 (cyg_fsop_rename
*)cyg_fileio_erofs
,
2134 (cyg_fsop_link
*)cyg_fileio_erofs
,
2135 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
2136 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
2137 (cyg_fsop_stat
*)cyg_fileio_erofs
,
2138 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
2139 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
2142 // -------------------------------------------------------------------------
2144 // This defines a single ROMFS loaded into ROM at the configured address
2146 // MTAB_ENTRY( rom_mte, // structure name
2147 // "/rom", // mount point
2148 // "romfs", // FIlesystem type
2149 // "", // hardware device
2150 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
2154 // -------------------------------------------------------------------------
2156 // This set of file operations are used for normal open files.
2158 static cyg_fileops tftpfs_fileops
=
2163 (cyg_fileop_ioctl
*)cyg_fileio_erofs
,
2167 (cyg_fileop_fstat
*) cyg_fileio_erofs
,
2168 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
2169 (cyg_fileop_setinfo
*)cyg_fileio_erofs
,
2172 // -------------------------------------------------------------------------
2174 // Process a mount request. This mainly finds root for the
2177 static int tftpfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
2182 static int tftpfs_umount(cyg_mtab_entry
*mte
)
2197 static void freeTftp(struct Tftp
*t
)
2210 static const int tftpMaxSize
= 8192 * 1024;
2211 static int tftpfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2212 int mode
, cyg_file
*file
)
2215 tftp
= malloc(sizeof(struct Tftp
));
2218 memset(tftp
, 0, sizeof(struct Tftp
));
2220 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
2221 file
->f_type
= CYG_FILE_TYPE_FILE
;
2222 file
->f_ops
= &tftpfs_fileops
;
2227 tftp
->mem
= malloc(tftpMaxSize
);
2228 if (tftp
->mem
== NULL
)
2234 char *server
= strchr(name
, '/');
2241 tftp
->server
= malloc(server
- name
+ 1);
2242 if (tftp
->server
== NULL
)
2247 strncpy(tftp
->server
, name
, server
- name
);
2248 tftp
->server
[server
- name
] = 0;
2250 tftp
->file
= strdup(server
+ 1);
2251 if (tftp
->file
== NULL
)
2257 file
->f_data
= (CYG_ADDRWORD
) tftp
;
2262 static int fetchTftp(struct Tftp
*tftp
)
2264 if (!tftp
->readFile
)
2267 tftp
->actual
= tftp_client_get( tftp
->file
, tftp
->server
, 0, tftp
->mem
, tftpMaxSize
, TFTP_OCTET
, &err
);
2269 if (tftp
->actual
< 0)
2278 // -------------------------------------------------------------------------
2279 // tftpfs_fo_write()
2280 // Read data from file.
2283 tftpfs_fo_read(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2285 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2287 if (fetchTftp(tftp
) != ENOERR
)
2291 off_t pos
= fp
->f_offset
;
2293 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2295 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2296 char *buf
= (char *) iov
->iov_base
;
2297 off_t len
= iov
->iov_len
;
2299 if (len
+ pos
> tftp
->actual
)
2301 len
= tftp
->actual
- pos
;
2303 resid
+= iov
->iov_len
- len
;
2305 memcpy(buf
, tftp
->mem
+ pos
, len
);
2309 uio
->uio_resid
= resid
;
2317 tftpfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2319 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2322 off_t pos
= fp
->f_offset
;
2324 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2326 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2327 char *buf
= (char *) iov
->iov_base
;
2328 off_t len
= iov
->iov_len
;
2330 if (len
+ pos
> tftpMaxSize
)
2332 len
= tftpMaxSize
- pos
;
2334 resid
+= iov
->iov_len
- len
;
2336 memcpy(tftp
->mem
+ pos
, buf
, len
);
2340 uio
->uio_resid
= resid
;
2349 tftpfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
2355 // -------------------------------------------------------------------------
2357 // Close a file. We just clear out the data pointer.
2359 static int tftpfs_fo_close(struct CYG_FILE_TAG
*fp
)
2361 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2366 tftp_client_put( tftp
->file
, tftp
->server
, 0, tftp
->mem
, fp
->f_offset
, TFTP_OCTET
, &error
);
2374 // -------------------------------------------------------------------------
2376 // Seek to a new file position.
2378 static int tftpfs_fo_lseek(struct CYG_FILE_TAG
*fp
, off_t
*apos
, int whence
)
2380 struct Tftp
*tftp
= (struct Tftp
*) fp
->f_data
;
2383 if (fetchTftp(tftp
) != ENOERR
)
2389 // Pos is already where we want to be.
2393 // Add pos to current offset.
2394 pos
+= fp
->f_offset
;
2398 // Add pos to file size.
2399 pos
+= tftp
->actual
;
2406 // Check that pos is still within current file size, or at the
2408 if (pos
< 0 || pos
> tftp
->actual
)
2411 // All OK, set fp offset and return new position.
2412 *apos
= fp
->f_offset
= pos
;
2420 cyg_thread_delay(us
/ 10000 + 1);
2427 show_log_entry(CYG_HTTPD_STATE
*phttpstate
)
2429 cyg_httpd_start_chunked("text");
2430 if (logCount
>= logSize
)
2432 cyg_httpd_write_chunked(logBuffer
+logCount
%logSize
, logSize
-logCount
%logSize
);
2434 cyg_httpd_write_chunked(logBuffer
, writePtr
);
2435 cyg_httpd_end_chunked();
2439 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log
, "/ram/log", show_log_entry
);
2441 // Filesystem operations
2442 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
);
2443 static int logfs_umount(cyg_mtab_entry
*mte
);
2444 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2445 int mode
, cyg_file
*fte
);
2447 logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
);
2450 static int logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
);
2451 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
);
2453 #include <cyg/io/devtab.h>
2455 //==========================================================================
2456 // Filesystem table entries
2458 // -------------------------------------------------------------------------
2460 // This defines the entry in the filesystem table.
2461 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2462 // we should never block in any filesystem operations.
2463 FSTAB_ENTRY( logfs_fste
, "logfs", 0,
2464 CYG_SYNCMODE_FILE_FILESYSTEM
|CYG_SYNCMODE_IO_FILESYSTEM
,
2468 (cyg_fsop_unlink
*)cyg_fileio_erofs
,
2469 (cyg_fsop_mkdir
*)cyg_fileio_erofs
,
2470 (cyg_fsop_rmdir
*)cyg_fileio_erofs
,
2471 (cyg_fsop_rename
*)cyg_fileio_erofs
,
2472 (cyg_fsop_link
*)cyg_fileio_erofs
,
2473 (cyg_fsop_opendir
*)cyg_fileio_erofs
,
2474 (cyg_fsop_chdir
*)cyg_fileio_erofs
,
2475 (cyg_fsop_stat
*)cyg_fileio_erofs
,
2476 (cyg_fsop_getinfo
*)cyg_fileio_erofs
,
2477 (cyg_fsop_setinfo
*)cyg_fileio_erofs
);
2479 // -------------------------------------------------------------------------
2481 // This set of file operations are used for normal open files.
2483 static cyg_fileops logfs_fileops
=
2485 (cyg_fileop_read
*)cyg_fileio_erofs
,
2486 (cyg_fileop_write
*)logfs_fo_write
,
2487 (cyg_fileop_lseek
*) cyg_fileio_erofs
,
2488 (cyg_fileop_ioctl
*)cyg_fileio_erofs
,
2492 (cyg_fileop_fstat
*)cyg_fileio_erofs
,
2493 (cyg_fileop_getinfo
*) cyg_fileio_erofs
,
2494 (cyg_fileop_setinfo
*)cyg_fileio_erofs
,
2497 // -------------------------------------------------------------------------
2499 // Process a mount request. This mainly finds root for the
2502 static int logfs_mount(cyg_fstab_entry
*fste
, cyg_mtab_entry
*mte
)
2507 static int logfs_umount(cyg_mtab_entry
*mte
)
2512 static int logfs_open(cyg_mtab_entry
*mte
, cyg_dir dir
, const char *name
,
2513 int mode
, cyg_file
*file
)
2515 file
->f_flag
|= mode
& CYG_FILE_MODE_MASK
;
2516 file
->f_type
= CYG_FILE_TYPE_FILE
;
2517 file
->f_ops
= &logfs_fileops
;
2524 // -------------------------------------------------------------------------
2526 // Write data to file.
2529 logfs_fo_write(struct CYG_FILE_TAG
*fp
, struct CYG_UIO_TAG
*uio
)
2532 for (i
= 0; i
< uio
->uio_iovcnt
; i
++)
2534 cyg_iovec
*iov
= &uio
->uio_iov
[i
];
2535 char *buf
= (char *) iov
->iov_base
;
2536 off_t len
= iov
->iov_len
;
2538 diag_write(buf
, len
);
2545 logfs_fo_fsync(struct CYG_FILE_TAG
*fp
, int mode
)
2550 // -------------------------------------------------------------------------
2552 // Close a file. We just clear out the data pointer.
2554 static int logfs_fo_close(struct CYG_FILE_TAG
*fp
)
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)