zy1000 1.48 snapshot
[openocd.git] / src / ecosboard.c
1 /***************************************************************************
2 * Copyright (C) 2007-2008 by Øyvind Harboe *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "log.h"
25 #include "types.h"
26 #include "jtag.h"
27 #include "configuration.h"
28 #include "xsvf.h"
29 #include "target.h"
30 #include "flash.h"
31 #include "nand.h"
32 #include "pld.h"
33
34 #include "command.h"
35 #include "server.h"
36 #include "telnet_server.h"
37 #include "gdb_server.h"
38
39 #include <time_support.h>
40 #include <sys/time.h>
41 #include <sys/types.h>
42 #include <strings.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <errno.h>
48
49 #include <cyg/io/flash.h>
50 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
51 #include <network.h>
52
53 #include <fcntl.h>
54 #include <sys/stat.h>
55 #include <cyg/fileio/fileio.h>
56 #include <dirent.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>
68 #include "rom.h"
69 #include <sys/ioctl.h>
70 #include <sys/socket.h>
71 #include <netinet/in.h>
72 #include <net/if.h>
73 #include <arpa/inet.h>
74 #include <sys/types.h>
75 #include <sys/socket.h>
76 #include <netdb.h>
77 #include <netinet/in.h>
78 #include <unistd.h>
79 #include <arpa/inet.h>
80 #include <stdio.h>
81 #include <ifaddrs.h>
82 #include <string.h>
83
84
85 #include <unistd.h>
86 #include <stdio.h>
87 #define MAX_IFS 64
88 #if defined(CYGPKG_NET_FREEBSD_STACK)
89 #include <tftp_support.h>
90 /* posix compatibility broken*/
91 struct tftpd_fileops fileops =
92 {
93 (int (*)(const char *, int))open,
94 close,
95 (int (*)(int, const void *, int))write,
96 ( int (*)(int, void *, int))read
97 };
98
99 #endif
100
101 #define ZYLIN_VERSION "1.48"
102 #define ZYLIN_DATE __DATE__
103 #define ZYLIN_TIME __TIME__
104 /* hmmm.... we can't pick up the right # during build if we've checked this out
105 * in Eclipse... arrggghh...*/
106 #define ZYLIN_OPENOCD "$Revision$"
107 #define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME
108 #define ZYLIN_CONFIG_DIR "/config/settings"
109
110 void diag_write(char *buf, int len)
111 {
112 int j;
113 for (j = 0; j < len; j++)
114 {
115 diag_printf("%c", buf[j]);
116 }
117 }
118
119 static bool serialLog = true;
120 static bool writeLog = true;
121
122 char hwaddr[512];
123
124 struct FastLoad
125 {
126 u32 address;
127 u8 *data;
128 int length;
129
130 };
131
132 static int fastload_num;
133 static struct FastLoad *fastload;
134
135 static void free_fastload()
136 {
137 if (fastload!=NULL)
138 {
139 int i;
140 for (i=0; i<fastload_num; i++)
141 {
142 if (fastload[i].data)
143 free(fastload[i].data);
144 }
145 free(fastload);
146 fastload=NULL;
147 }
148 }
149
150
151 int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
152 {
153 u8 *buffer;
154 u32 buf_cnt;
155 u32 image_size;
156 u32 min_address=0;
157 u32 max_address=0xffffffff;
158 int i;
159 int retval;
160
161 image_t image;
162
163 duration_t duration;
164 char *duration_text;
165
166 if ((argc < 1)||(argc > 5))
167 {
168 return ERROR_COMMAND_SYNTAX_ERROR;
169 }
170
171 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
172 if (argc >= 2)
173 {
174 image.base_address_set = 1;
175 image.base_address = strtoul(args[1], NULL, 0);
176 }
177 else
178 {
179 image.base_address_set = 0;
180 }
181
182
183 image.start_address_set = 0;
184
185 if (argc>=4)
186 {
187 min_address=strtoul(args[3], NULL, 0);
188 }
189 if (argc>=5)
190 {
191 max_address=strtoul(args[4], NULL, 0)+min_address;
192 }
193
194 if (min_address>max_address)
195 {
196 return ERROR_COMMAND_SYNTAX_ERROR;
197 }
198
199 duration_start_measure(&duration);
200
201 if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
202 {
203 return ERROR_OK;
204 }
205
206 image_size = 0x0;
207 retval = ERROR_OK;
208 fastload_num=image.num_sections;
209 fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
210 if (fastload==NULL)
211 {
212 image_close(&image);
213 return ERROR_FAIL;
214 }
215 memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
216 for (i = 0; i < image.num_sections; i++)
217 {
218 buffer = malloc(image.sections[i].size);
219 if (buffer == NULL)
220 {
221 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
222 break;
223 }
224
225 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
226 {
227 free(buffer);
228 break;
229 }
230
231 u32 offset=0;
232 u32 length=buf_cnt;
233
234
235 /* DANGER!!! beware of unsigned comparision here!!! */
236
237 if ((image.sections[i].base_address+buf_cnt>=min_address)&&
238 (image.sections[i].base_address<max_address))
239 {
240 if (image.sections[i].base_address<min_address)
241 {
242 /* clip addresses below */
243 offset+=min_address-image.sections[i].base_address;
244 length-=offset;
245 }
246
247 if (image.sections[i].base_address+buf_cnt>max_address)
248 {
249 length-=(image.sections[i].base_address+buf_cnt)-max_address;
250 }
251
252 fastload[i].address=image.sections[i].base_address+offset;
253 fastload[i].data=malloc(length);
254 if (fastload[i].data==NULL)
255 {
256 free(buffer);
257 break;
258 }
259 memcpy(fastload[i].data, buffer+offset, length);
260 fastload[i].length=length;
261
262 image_size += length;
263 command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
264 }
265
266 free(buffer);
267 }
268
269 duration_stop_measure(&duration, &duration_text);
270 if (retval==ERROR_OK)
271 {
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.");
274 }
275 free(duration_text);
276
277 image_close(&image);
278
279 if (retval!=ERROR_OK)
280 {
281 free_fastload();
282 }
283
284 return retval;
285 }
286
287 int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
288 {
289 if (argc>0)
290 return ERROR_COMMAND_SYNTAX_ERROR;
291 if (fastload==NULL)
292 {
293 LOG_ERROR("No image in memory");
294 return ERROR_FAIL;
295 }
296 int i;
297 int ms=timeval_ms();
298 int size=0;
299 for (i=0; i<fastload_num;i++)
300 {
301 int retval;
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)
304 {
305 return retval;
306 }
307 size+=fastload[i].length;
308 }
309 int after=timeval_ms();
310 command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
311 return ERROR_OK;
312 }
313
314
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)
318 {
319 if (argc > 1)
320 {
321 return ERROR_COMMAND_SYNTAX_ERROR;
322 }
323 if (argc == 0)
324 {
325 command_print(cmd_ctx, ZYLIN_OPENOCD_VERSION);
326 } else if (strcmp("openocd", args[0])==0)
327 {
328 int revision;
329 revision=atol(ZYLIN_OPENOCD+strlen("XRevision: "));
330 command_print(cmd_ctx, "%d", revision);
331 } else if (strcmp("zy1000", args[0])==0)
332 {
333 command_print(cmd_ctx, "%s", ZYLIN_VERSION);
334 } else if (strcmp("date", args[0])==0)
335 {
336 command_print(cmd_ctx, "%s", ZYLIN_DATE);
337 } else
338 {
339 return ERROR_COMMAND_SYNTAX_ERROR;
340 }
341
342 return ERROR_OK;
343 }
344
345
346
347
348 extern flash_driver_t *flash_drivers[];
349 extern target_type_t *target_types[];
350
351 #ifdef CYGPKG_PROFILE_GPROF
352 #include <cyg/profile/profile.h>
353
354 extern char _stext, _etext; // Defined by the linker
355
356 static char *start_of_code=&_stext;
357 static char *end_of_code=&_etext;
358
359 void start_profile(void)
360 {
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.
374
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
379 }
380 #endif
381
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)
384 {
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");
389 if (config_file)
390 {
391 fclose(config_file);
392 int retval;
393 retval = command_run_linef(cmd_ctx, "script %s", config_file_name);
394 if (retval == ERROR_OK)
395 {
396 foundFile = true;
397 }
398 else
399 {
400 command_print(cmd_ctx, "Failed executing %s %d", config_file_name, retval);
401 }
402 }
403 else
404 {
405 command_print(cmd_ctx, "No %s found", config_file_name);
406 }
407
408 return foundFile;
409 }
410
411 extern int eth0_up;
412 static FILE *log;
413
414 static char reboot_stack[2048];
415
416
417 static void
418 zylinjtag_reboot(cyg_addrword_t data)
419 {
420 serialLog = true;
421 diag_printf("Rebooting in 100 ticks..\n");
422 cyg_thread_delay(100);
423 diag_printf("Unmounting /config..\n");
424 umount("/config");
425 diag_printf("Rebooting..\n");
426 HAL_PLATFORM_RESET();
427 }
428 static cyg_thread zylinjtag_thread_object;
429 static cyg_handle_t zylinjtag_thread_handle;
430
431 void reboot(void)
432 {
433 cyg_thread_create(1,
434 zylinjtag_reboot,
435 (cyg_addrword_t)0,
436 "reboot Thread",
437 (void *)reboot_stack,
438 sizeof(reboot_stack),
439 &zylinjtag_thread_handle,
440 &zylinjtag_thread_object);
441 cyg_thread_resume(zylinjtag_thread_handle);
442 }
443
444 int configuration_output_handler(struct command_context_s *context, const char* line)
445 {
446 diag_printf("%s", line);
447
448 return ERROR_OK;
449 }
450
451 int zy1000_configuration_output_handler_log(struct command_context_s *context, const char* line)
452 {
453 LOG_USER_N("%s", line);
454
455 return ERROR_OK;
456 }
457
458 int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
459 char **args, int argc)
460 {
461 if (argc != 1)
462 {
463 command_print(cmd_ctx, "rm <filename>");
464 return ERROR_INVALID_ARGUMENTS;
465 }
466
467 if (unlink(args[0]) != 0)
468 {
469 command_print(cmd_ctx, "failed: %d", errno);
470 }
471
472 return ERROR_OK;
473 }
474
475 int loadFile(const char *fileName, void **data, int *len);
476
477 int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
478 char **args, int argc)
479 {
480 if (argc != 1)
481 {
482 command_print(cmd_ctx, "cat <filename>");
483 return ERROR_INVALID_ARGUMENTS;
484 }
485
486 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
487 void *data;
488 int len;
489
490 int retval = loadFile(args[0], &data, &len);
491 if (retval == ERROR_OK)
492 {
493 command_print(cmd_ctx, "%s", data);
494 free(data);
495 }
496 else
497 {
498 command_print(cmd_ctx, "%s not found %d", args[0], retval);
499 }
500
501 return ERROR_OK;
502 }
503 int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
504 char **args, int argc)
505 {
506 if (argc != 1)
507 {
508 command_print(cmd_ctx, "trunc <filename>");
509 return ERROR_INVALID_ARGUMENTS;
510 }
511
512 FILE *config_file = NULL;
513 config_file = fopen(args[0], "w");
514 if (config_file != NULL)
515 fclose(config_file);
516
517 return ERROR_OK;
518 }
519
520
521 int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
522 {
523 static int prev = 0;
524 struct mallinfo info;
525
526 if (argc != 0)
527 {
528 command_print(cmd_ctx, "meminfo");
529 return ERROR_INVALID_ARGUMENTS;
530 }
531
532 info = mallinfo();
533
534 if (prev > 0)
535 {
536 command_print(cmd_ctx, "Diff: %d", prev - info.fordblks);
537 }
538 prev = info.fordblks;
539
540 command_print(cmd_ctx, "Available ram: %d", info.fordblks );
541
542 return ERROR_OK;
543 }
544
545 static bool savePower;
546
547 static void setPower(bool power)
548 {
549 savePower = power;
550 if (power)
551 {
552 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x14, 0x8);
553 } else
554 {
555 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x8);
556 }
557 }
558
559 int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
560 {
561 if (argc > 1)
562 {
563 return ERROR_INVALID_ARGUMENTS;
564 }
565
566 if (argc == 1)
567 {
568 if (strcmp(args[0], "on") == 0)
569 {
570 setPower(1);
571 }
572 else if (strcmp(args[0], "off") == 0)
573 {
574 setPower(0);
575 } else
576 {
577 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
578 return ERROR_INVALID_ARGUMENTS;
579 }
580 }
581
582 command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
583
584 return ERROR_OK;
585 }
586
587 int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
588 char **args, int argc)
589 {
590 if (argc < 1)
591 {
592 command_print(cmd_ctx,
593 "append <filename> [<string1>, [<string2>, ...]]");
594 return ERROR_INVALID_ARGUMENTS;
595 }
596
597 FILE *config_file = NULL;
598 config_file = fopen(args[0], "a");
599 if (config_file != NULL)
600 {
601 int i;
602 fseek(config_file, 0, SEEK_END);
603
604 for (i = 1; i < argc; i++)
605 {
606 fwrite(args[i], strlen(args[i]), 1, config_file);
607 if (i != argc - 1)
608 {
609 fwrite(" ", 1, 1, config_file);
610 }
611 }
612 fwrite("\n", 1, 1, config_file);
613 fclose(config_file);
614 }
615
616 return ERROR_OK;
617 }
618
619 extern int telnet_socket;
620
621 int readMore(int fd, void *data, int length)
622 {
623 /* used in select() */
624 fd_set read_fds;
625
626 /* monitor sockets for acitvity */
627 int fd_max = 1;
628 FD_ZERO(&read_fds);
629 /* listen for new connections */
630 FD_SET(fd, &read_fds);
631
632 // Maximum 5 seconds.
633 struct timeval tv;
634 tv.tv_sec = 5;
635 tv.tv_usec = 0;
636
637 int retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
638 if (retval == 0)
639 {
640 diag_printf("Timed out waiting for binary payload\n");
641 return -1;
642 }
643 if (retval != 1)
644 return -1;
645
646 return read_socket(fd, data, length);
647 }
648
649 int readAll(int fd, void *data, int length)
650 {
651 int pos = 0;
652 for (;;)
653 {
654 int actual = readMore(fd, ((char *) data) + pos, length - pos);
655 // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
656 if (actual <= 0)
657 return -1;
658 pos += actual;
659 if (pos == length)
660 break;
661 }
662 return length;
663 }
664
665 int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
666 {
667 cyg_uint32 value;
668 if (argc != 1)
669 {
670 return ERROR_INVALID_ARGUMENTS;
671 }
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);
674 return ERROR_OK;
675 }
676
677 int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
678 {
679 if (argc != 2)
680 {
681 return ERROR_INVALID_ARGUMENTS;
682 }
683 HAL_WRITE_UINT32(strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0));
684 return ERROR_OK;
685 }
686
687 int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
688 {
689 if (argc != 2)
690 {
691 return ERROR_INVALID_ARGUMENTS;
692 }
693
694 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
695 void *data;
696 int len;
697
698 int retval = loadFile(args[0], &data, &len);
699 if (retval != ERROR_OK)
700 return retval;
701
702 FILE *f = fopen(args[1], "wb");
703 if (f == NULL)
704 retval = ERROR_INVALID_ARGUMENTS;
705
706 int pos = 0;
707 for (;;)
708 {
709 int chunk = len - pos;
710 static const int maxChunk = 512 * 1024; // ~1/sec
711 if (chunk > maxChunk)
712 {
713 chunk = maxChunk;
714 }
715
716 if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
717 retval = ERROR_INVALID_ARGUMENTS;
718
719 if (retval != ERROR_OK)
720 {
721 break;
722 }
723
724 command_print(cmd_ctx, "%d", len - pos);
725
726 pos += chunk;
727
728 if (pos == len)
729 break;
730 }
731
732 if (retval == ERROR_OK)
733 {
734 command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
735 } else
736 {
737 command_print(cmd_ctx, "Failed: %d", retval);
738 }
739
740 if (data != NULL)
741 free(data);
742 if (f != NULL)
743 fclose(f);
744
745 if (retval != ERROR_OK)
746 unlink(args[1]);
747
748 return retval;
749 }
750
751 #ifdef CYGPKG_PROFILE_GPROF
752 extern void start_profile();
753
754 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
755 {
756 command_print(cmd_ctx, "Profiling started");
757 start_profile();
758 return ERROR_OK;
759 }
760
761 #endif
762
763 externC void phi_init_all_network_interfaces();
764
765 command_context_t *cmd_ctx;
766
767 static bool webRunning = false;
768
769 void keep_webserver()
770 {
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");
775 if (!webRunning)
776 reboot();
777
778 // exit() will terminate the current thread and we we'll then sleep eternally or
779 // we'll have a reboot scheduled.
780 }
781
782 extern void printDccChar(char c);
783
784 static char logBuffer[128 * 1024];
785 static const int logSize = sizeof(logBuffer);
786 int writePtr = 0;
787 int logCount = 0;
788
789 void _zylinjtag_diag_write_char(char c, void **param)
790 {
791 if (writeLog)
792 {
793 logBuffer[writePtr] = c;
794 writePtr = (writePtr + 1) % logSize;
795 logCount++;
796 }
797 if (serialLog)
798 {
799 if (c == '\n')
800 {
801 HAL_DIAG_WRITE_CHAR('\r');
802 }
803 HAL_DIAG_WRITE_CHAR(c);
804 }
805
806 #ifdef CYGPKG_HAL_ZYLIN_PHI
807 printDccChar(c);
808 #endif
809 }
810
811 #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
812
813 #define IOSIZE 512
814 static void copyfile(char *name2, char *name1)
815 {
816
817 int err;
818 char buf[IOSIZE];
819 int fd1, fd2;
820 ssize_t done, wrote;
821
822 fd1 = open(name1, O_WRONLY | O_CREAT);
823 if (fd1 < 0)
824 SHOW_RESULT( open, fd1 );
825
826 fd2 = open(name2, O_RDONLY);
827 if (fd2 < 0)
828 SHOW_RESULT( open, fd2 );
829
830 for (;;)
831 {
832 done = read(fd2, buf, IOSIZE );
833 if (done < 0)
834 {
835 SHOW_RESULT( read, done );
836 break;
837 }
838
839 if( done == 0 ) break;
840
841 wrote = write(fd1, buf, done);
842 if( wrote != done ) SHOW_RESULT( write, wrote );
843
844 if( wrote != done ) break;
845 }
846
847 err = close(fd1);
848 if( err < 0 ) SHOW_RESULT( close, err );
849
850 err = close(fd2);
851 if( err < 0 ) SHOW_RESULT( close, err );
852
853 }
854 static void copydir(char *name, char *destdir)
855 {
856 int err;
857 DIR *dirp;
858
859 dirp = opendir(destdir);
860 if (dirp==NULL)
861 {
862 mkdir(destdir, 0777);
863 } else
864 {
865 err = closedir(dirp);
866 }
867
868 dirp = opendir(name);
869 if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
870
871 for (;;)
872 {
873 struct dirent *entry = readdir(dirp);
874
875 if (entry == NULL)
876 break;
877
878 if (strcmp(entry->d_name, ".") == 0)
879 continue;
880 if (strcmp(entry->d_name, "..") == 0)
881 continue;
882
883 bool isDir = false;
884 struct stat buf;
885 char fullPath[PATH_MAX];
886 strncpy(fullPath, name, PATH_MAX);
887 strcat(fullPath, "/");
888 strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
889
890 if (stat(fullPath, &buf) == -1)
891 {
892 diag_printf("unable to read status from %s", fullPath);
893 break;
894 }
895 isDir = S_ISDIR(buf.st_mode) != 0;
896
897 if (isDir)
898 continue;
899
900 // diag_printf("<INFO>: entry %14s",entry->d_name);
901 char fullname[PATH_MAX];
902 char fullname2[PATH_MAX];
903
904 strcpy(fullname, name);
905 strcat(fullname, "/");
906 strcat(fullname, entry->d_name);
907
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);
913
914 // diag_printf("\n");
915 }
916
917 err = closedir(dirp);
918 if( err < 0 ) SHOW_RESULT( stat, err );
919 }
920
921 #if 0
922 MTAB_ENTRY( romfs_mte1,
923 "/rom",
924 "romfs",
925 "",
926 (CYG_ADDRWORD) &filedata[0] );
927 #endif
928
929 void openocd_sleep_prelude()
930 {
931 cyg_mutex_unlock(&httpstate.jim_lock);
932 }
933
934 void openocd_sleep_postlude()
935 {
936 cyg_mutex_lock(&httpstate.jim_lock);
937 }
938
939
940 void format(void)
941 {
942 diag_printf("Formatting JFFS2...\n");
943
944 cyg_io_handle_t handle;
945
946 Cyg_ErrNo err;
947 err = cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, &handle);
948 if (err != ENOERR)
949 {
950 diag_printf("Flash Error cyg_io_lookup: %d\n", err);
951 reboot();
952 }
953
954
955 cyg_uint32 len;
956 cyg_io_flash_getconfig_devsize_t ds;
957 len = sizeof (ds);
958 err = cyg_io_get_config(handle,
959 CYG_IO_GET_CONFIG_FLASH_DEVSIZE, &ds, &len);
960 if (err != ENOERR)
961 {
962 diag_printf("Flash error cyg_io_get_config %d\n", err);
963 reboot();
964 }
965
966 cyg_io_flash_getconfig_erase_t e;
967 void *err_addr;
968 len = sizeof (e);
969
970 e.offset = 0;
971 e.len = ds.dev_size;
972 e.err_address = &err_addr;
973
974 diag_printf("Formatting 0x%08x bytes\n", ds.dev_size);
975 err = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_FLASH_ERASE,
976 &e, &len);
977 if (err != ENOERR)
978 {
979 diag_printf("Flash erase error %d offset 0x%p\n", err, err_addr);
980 reboot();
981 }
982
983 diag_printf("Flash formatted successfully\n");
984
985 reboot();
986 }
987
988
989
990 static int
991 zylinjtag_Jim_Command_format_jffs2(Jim_Interp *interp,
992 int argc,
993 Jim_Obj * const *argv)
994 {
995 if (argc != 1)
996 {
997 return JIM_ERR;
998 }
999
1000 format();
1001 for(;;);
1002 }
1003
1004
1005 static int
1006 zylinjtag_Jim_Command_rm(Jim_Interp *interp,
1007 int argc,
1008 Jim_Obj * const *argv)
1009 {
1010 int del;
1011 if (argc != 2)
1012 {
1013 Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
1014 return JIM_ERR;
1015 }
1016
1017 del = 0;
1018 if (unlink(Jim_GetString(argv[1], NULL)) == 0)
1019 del = 1;
1020 if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
1021 del = 1;
1022
1023 return del ? JIM_OK : JIM_ERR;
1024 }
1025
1026 static int zylinjtag_Jim_Command_threads(Jim_Interp *interp, int argc,
1027 Jim_Obj * const *argv)
1028 {
1029 cyg_handle_t thread = 0;
1030 cyg_uint16 id = 0;
1031 Jim_Obj *threads = Jim_NewListObj(interp, NULL, 0);
1032
1033 /* Loop over the threads, and generate a table row for
1034 * each.
1035 */
1036 while (cyg_thread_get_next(&thread, &id))
1037 {
1038 Jim_Obj *threadObj = Jim_NewListObj(interp, NULL, 0);
1039
1040 cyg_thread_info info;
1041 char *state_string;
1042
1043 cyg_thread_get_info(thread, id, &info);
1044
1045 if (info.name == NULL)
1046 info.name = "<no name>";
1047
1048 Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
1049 info.name, strlen(info.name)));
1050
1051 /* Translate the state into a string.
1052 */
1053 if (info.state == 0)
1054 state_string = "RUN";
1055 else if (info.state & 0x04)
1056 state_string = "SUSP";
1057 else
1058 switch (info.state & 0x1b)
1059 {
1060 case 0x01:
1061 state_string = "SLEEP";
1062 break;
1063 case 0x02:
1064 state_string = "CNTSLEEP";
1065 break;
1066 case 0x08:
1067 state_string = "CREATE";
1068 break;
1069 case 0x10:
1070 state_string = "EXIT";
1071 break;
1072 default:
1073 state_string = "????";
1074 break;
1075 }
1076
1077 Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
1078 state_string, strlen(state_string)));
1079
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));
1083
1084 Jim_ListAppendElement(interp, threads, threadObj);
1085 }
1086 Jim_SetResult( interp, threads);
1087
1088 return JIM_OK;
1089 }
1090
1091
1092 static int
1093 zylinjtag_Jim_Command_ls(Jim_Interp *interp,
1094 int argc,
1095 Jim_Obj * const *argv)
1096 {
1097 if (argc != 2)
1098 {
1099 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
1100 return JIM_ERR;
1101 }
1102
1103 char *name = (char*) Jim_GetString(argv[1], NULL);
1104
1105 DIR *dirp = NULL;
1106 dirp = opendir(name);
1107 if (dirp == NULL)
1108 {
1109 return JIM_ERR;
1110 }
1111 Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
1112
1113 for (;;)
1114 {
1115 struct dirent *entry = NULL;
1116 entry = readdir(dirp);
1117 if (entry == NULL)
1118 break;
1119
1120 if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
1121 continue;
1122
1123 Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
1124 }
1125 closedir(dirp);
1126
1127 Jim_SetResult(interp, objPtr);
1128
1129 return JIM_OK;
1130 }
1131
1132
1133 static int
1134 zylinjtag_Jim_Command_getmem(Jim_Interp *interp,
1135 int argc,
1136 Jim_Obj * const *argv)
1137 {
1138 if (argc != 3)
1139 {
1140 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
1141 return JIM_ERR;
1142 }
1143
1144 long address;
1145 long length;
1146 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1147 return JIM_ERR;
1148 if (Jim_GetLong(interp, argv[2], &length) != JIM_OK)
1149 return JIM_ERR;
1150
1151 if (length < 0 && length > (4096 * 1024))
1152 {
1153 Jim_WrongNumArgs(interp, 1, argv, "getmem ?dir?");
1154 return JIM_ERR;
1155 }
1156
1157 void *mem = malloc(length);
1158 if (mem == NULL)
1159 return JIM_ERR;
1160
1161 target_t *target = get_current_target(cmd_ctx);
1162
1163 int retval;
1164 int size = 1;
1165 int count = length;
1166 if ((address % 4 == 0) && (count % 4 == 0))
1167 {
1168 size = 4;
1169 count /= 4;
1170 }
1171
1172 if ((retval = target->type->read_memory(target, address, size, count, mem)) != ERROR_OK)
1173 {
1174 free(mem);
1175 return JIM_ERR;
1176 }
1177
1178 Jim_Obj *objPtr = Jim_NewStringObj(interp, mem, length);
1179 Jim_SetResult(interp, objPtr);
1180
1181 free(mem);
1182
1183 return JIM_OK;
1184 }
1185
1186 static int
1187 zylinjtag_Jim_Command_peek(Jim_Interp *interp,
1188 int argc,
1189 Jim_Obj * const *argv)
1190 {
1191 if (argc != 2)
1192 {
1193 Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
1194 return JIM_ERR;
1195 }
1196
1197 long address;
1198 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1199 return JIM_ERR;
1200
1201 int value = *((volatile int *) address);
1202
1203 Jim_SetResult(interp, Jim_NewIntObj(interp, value));
1204
1205 return JIM_OK;
1206 }
1207
1208 static int
1209 zylinjtag_Jim_Command_poke(Jim_Interp *interp,
1210 int argc,
1211 Jim_Obj * const *argv)
1212 {
1213 if (argc != 3)
1214 {
1215 Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
1216 return JIM_ERR;
1217 }
1218
1219 long address;
1220 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1221 return JIM_ERR;
1222 long value;
1223 if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
1224 return JIM_ERR;
1225
1226 *((volatile int *) address) = value;
1227
1228 return JIM_OK;
1229 }
1230
1231
1232
1233 static int
1234 zylinjtag_Jim_Command_flash(Jim_Interp *interp,
1235 int argc,
1236 Jim_Obj * const *argv)
1237 {
1238 int retval;
1239 u32 base = 0;
1240 flash_bank_t *t = get_flash_bank_by_num_noprobe(0);
1241 if (t != NULL)
1242 {
1243 base = t->base;
1244 retval = JIM_OK;
1245 } else
1246 {
1247 retval = JIM_ERR;
1248 }
1249
1250 if (retval == JIM_OK)
1251 {
1252 Jim_SetResult(interp, Jim_NewIntObj(interp, base));
1253 }
1254
1255 return retval;
1256 }
1257
1258
1259
1260
1261
1262 static int
1263 zylinjtag_Jim_Command_log(Jim_Interp *interp,
1264 int argc,
1265 Jim_Obj * const *argv)
1266 {
1267 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1268
1269 if (logCount >= logSize)
1270 {
1271 Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer+logCount%logSize, logSize-logCount%logSize);
1272 }
1273 Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);
1274
1275 Jim_SetResult(interp, tclOutput);
1276 return JIM_OK;
1277 }
1278
1279 static int
1280 zylinjtag_Jim_Command_reboot(Jim_Interp *interp,
1281 int argc,
1282 Jim_Obj * const *argv)
1283 {
1284 reboot();
1285 return JIM_OK;
1286 }
1287
1288 static int
1289 zylinjtag_Jim_Command_mac(Jim_Interp *interp,
1290 int argc,
1291 Jim_Obj * const *argv)
1292 {
1293
1294 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1295
1296 Jim_AppendString(httpstate.jim_interp, tclOutput, hwaddr, strlen(hwaddr));
1297
1298 Jim_SetResult(interp, tclOutput);
1299
1300 return JIM_OK;
1301 }
1302
1303 static int
1304 zylinjtag_Jim_Command_ip(Jim_Interp *interp,
1305 int argc,
1306 Jim_Obj * const *argv)
1307 {
1308 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1309
1310 struct ifaddrs *ifa = NULL, *ifp = NULL;
1311
1312 if (getifaddrs(&ifp) < 0)
1313 {
1314 return JIM_ERR;
1315 }
1316
1317 for (ifa = ifp; ifa; ifa = ifa->ifa_next)
1318 {
1319 char ip[200];
1320 socklen_t salen;
1321
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);
1326 else
1327 continue;
1328
1329 if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
1330 NI_NUMERICHOST) < 0)
1331 {
1332 continue;
1333 }
1334
1335 Jim_AppendString(httpstate.jim_interp, tclOutput, ip, strlen(ip));
1336 break;
1337
1338 }
1339
1340 freeifaddrs(ifp);
1341
1342 Jim_SetResult(interp, tclOutput);
1343
1344 return JIM_OK;
1345 }
1346
1347 extern Jim_Interp *interp;
1348
1349
1350 static void zylinjtag_startNetwork()
1351 {
1352 // Bring TCP/IP up immediately before we're ready to accept commands.
1353 //
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();
1357 #else
1358 lwip_init();
1359 #endif
1360 if (!eth0_up)
1361 {
1362 diag_printf("Network not up and running\n");
1363 exit(-1);
1364 }
1365 #if defined(CYGPKG_NET_FREEBSD_STACK)
1366 /*start TFTP*/
1367 tftpd_start(69, &fileops);
1368 #endif
1369
1370 cyg_httpd_init_tcl_interpreter();
1371
1372 interp = httpstate.jim_interp;
1373
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);
1386
1387 cyg_httpd_start();
1388
1389 webRunning = true;
1390
1391 diag_printf("Web server running\n");
1392
1393 int s;
1394 struct ifreq ifr;
1395 s = socket(AF_INET, SOCK_DGRAM, 0);
1396 if (s >= 0)
1397 {
1398 strcpy(ifr.ifr_name, "eth0");
1399 int res;
1400 res = ioctl(s, SIOCGIFHWADDR, &ifr);
1401 close(s);
1402
1403 if (res < 0)
1404 {
1405 diag_printf("Can't obtain MAC address\n");
1406 reboot();
1407 }
1408 }
1409
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]);
1417
1418
1419 discover_message=alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr);
1420
1421 discover_launch();
1422 }
1423
1424
1425
1426
1427
1428 static void
1429 print_exception_handler(cyg_addrword_t data, cyg_code_t exception, cyg_addrword_t info)
1430 {
1431 writeLog = false;
1432 serialLog = true;
1433 char *infoStr = "unknown";
1434 switch (exception)
1435 {
1436 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1437 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:
1438 infoStr = "undefined instruction";
1439 break;
1440 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:
1441 infoStr = "software interrupt";
1442 break;
1443 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:
1444 infoStr = "abort prefetch";
1445 break;
1446 case CYGNUM_HAL_VECTOR_ABORT_DATA:
1447 infoStr = "abort data";
1448 break;
1449 #endif
1450 default:
1451 break;
1452 }
1453
1454 diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
1455
1456 diag_printf("Dumping log\n---\n");
1457 if (logCount >= logSize)
1458 {
1459 diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);
1460 }
1461 diag_write(logBuffer, writePtr);
1462
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();
1467
1468 }
1469
1470 static void setHandler(cyg_code_t exception)
1471 {
1472 cyg_exception_handler_t *old_handler;
1473 cyg_addrword_t old_data;
1474
1475 cyg_exception_set_handler(exception,
1476 print_exception_handler,
1477 0,
1478 &old_handler,
1479 &old_data);
1480 }
1481
1482 static cyg_thread zylinjtag_uart_thread_object;
1483 static cyg_handle_t zylinjtag_uart_thread_handle;
1484 static char uart_stack[4096];
1485
1486 static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
1487 static char backwardBuffer[1024];
1488
1489
1490 void setNoDelay(int session, int flag)
1491 {
1492 #if 1
1493 // This decreases latency dramatically for e.g. GDB load which
1494 // does not have a sliding window protocol
1495 //
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
1498 // overloaded...
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
1503 cruft */
1504 sizeof(int)); /* length of option value */
1505 #endif
1506 }
1507
1508 struct
1509 {
1510 int req;
1511 int actual;
1512 int req2;
1513 int actual2;
1514 } tcpipSent[512 * 1024];
1515 int cur;
1516
1517 static void
1518 zylinjtag_uart(cyg_addrword_t data)
1519 {
1520 int so_reuseaddr_option = 1;
1521
1522 int fd;
1523 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1524 {
1525 LOG_ERROR("error creating socket: %s", strerror(errno));
1526 exit(-1);
1527 }
1528
1529 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
1530
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);
1538
1539 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
1540 {
1541 LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
1542 exit(-1);
1543 }
1544
1545 if (listen(fd, 1) == -1)
1546 {
1547 LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
1548 exit(-1);
1549 }
1550 // socket_nonblock(fd);
1551
1552
1553 for (;;)
1554 {
1555 int session = accept(fd, (struct sockaddr *) &sin, &address_size);
1556 if (session < 0)
1557 {
1558 continue;
1559 }
1560
1561 setNoDelay(session, 1);
1562 int oldopts = fcntl(session, F_GETFL, 0);
1563 fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
1564
1565 int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);
1566 if (serHandle < 0)
1567 {
1568 close(session);
1569 continue;
1570 }
1571
1572 #ifdef CYGPKG_PROFILE_GPROF
1573 start_profile();
1574 #endif
1575 int actual = 0;
1576 int actual2 = 0;
1577 int pos, pos2;
1578 pos = 0;
1579 pos2 = 0;
1580 cur = 0;
1581 for (;;)
1582 {
1583 fd_set write_fds;
1584 fd_set read_fds;
1585 FD_ZERO(&write_fds);
1586 FD_ZERO(&read_fds);
1587 int fd_max = -1;
1588 FD_SET(session, &read_fds);
1589 fd_max = session;
1590 FD_SET(serHandle, &read_fds);
1591 if (serHandle > fd_max)
1592 {
1593 fd_max = serHandle;
1594 }
1595 /* Wait... */
1596
1597 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
1598 if ((actual == 0) && (actual2 == 0))
1599 {
1600 int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);
1601 if (retval <= 0)
1602 {
1603 break;
1604 }
1605 }
1606
1607 if (actual2 <= 0)
1608 {
1609 memset(backwardBuffer, 's', sizeof(backwardBuffer));
1610 actual2=read(serHandle, backwardBuffer, sizeof(backwardBuffer));
1611 if (actual2 < 0)
1612 {
1613 if (errno != EAGAIN)
1614 {
1615 goto closeSession;
1616 }
1617 actual2 = 0;
1618 }
1619 pos2 = 0;
1620 }
1621
1622 int x = actual2;
1623 int y = 0;
1624 if (actual2 > 0)
1625 {
1626 int written = write(session, backwardBuffer + pos2, actual2);
1627 if (written <= 0)
1628 goto closeSession;
1629 actual2 -= written;
1630 pos2 += written;
1631 y = written;
1632 }
1633
1634 if (FD_ISSET(session, &read_fds)&&(sizeof(forwardBuffer)>actual))
1635 {
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);
1639 pos = 0;
1640 int t;
1641 // this will block if there is no data at all
1642 t=read_socket(session, forwardBuffer+actual, sizeof(forwardBuffer)-actual);
1643 if (t <= 0)
1644 {
1645 goto closeSession;
1646 }
1647 actual += t;
1648 }
1649
1650 int x2 = actual;
1651 int y2 = 0;
1652 if (actual > 0)
1653 {
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.
1656 *
1657 *
1658 */
1659 int written = write(serHandle, forwardBuffer + pos, actual);
1660 if (written < 0)
1661 {
1662 if (errno != EAGAIN)
1663 {
1664 goto closeSession;
1665 }
1666 // The serial buffer is full
1667 written = 0;
1668 } else
1669 {
1670 actual -= written;
1671 pos += written;
1672 }
1673 y2 = written;
1674 }
1675 if (cur < 1024)
1676 {
1677 tcpipSent[cur].req = x;
1678 tcpipSent[cur].actual = y;
1679 tcpipSent[cur].req2 = x2;
1680 tcpipSent[cur].actual2 = y2;
1681 cur++;
1682 }
1683
1684 }
1685 closeSession:
1686 close(session);
1687 close(serHandle);
1688
1689 int i;
1690 for (i = 0; i < 1024; i++)
1691 {
1692 diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual, tcpipSent[i].req2, tcpipSent[i].actual2);
1693
1694 }
1695 }
1696 close(fd);
1697
1698 }
1699
1700 void startUart(void)
1701 {
1702 cyg_thread_create(1,
1703 zylinjtag_uart,
1704 (cyg_addrword_t)0,
1705 "uart thread",
1706 (void *)uart_stack,
1707 sizeof(uart_stack),
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);
1712 }
1713
1714
1715
1716 int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1717 {
1718 static int current_baud = 38400;
1719 if (argc == 0)
1720 {
1721 command_print(cmd_ctx, "%d", current_baud);
1722 return ERROR_OK;
1723 } else if (argc != 1)
1724 {
1725 return ERROR_INVALID_ARGUMENTS;
1726 }
1727
1728 current_baud = atol(args[0]);
1729
1730 int baud;
1731 switch (current_baud)
1732 {
1733 case 9600:
1734 baud = CYGNUM_SERIAL_BAUD_9600;
1735 break;
1736 case 19200:
1737 baud = CYGNUM_SERIAL_BAUD_19200;
1738 break;
1739 case 38400:
1740 baud = CYGNUM_SERIAL_BAUD_38400;
1741 break;
1742 case 57600:
1743 baud = CYGNUM_SERIAL_BAUD_57600;
1744 break;
1745 case 115200:
1746 baud = CYGNUM_SERIAL_BAUD_115200;
1747 break;
1748 case 230400:
1749 baud = CYGNUM_SERIAL_BAUD_230400;
1750 break;
1751 default:
1752 command_print(cmd_ctx, "unsupported baudrate");
1753 return ERROR_INVALID_ARGUMENTS;
1754 }
1755
1756 cyg_serial_info_t buf;
1757 cyg_uint32 len = 1;
1758 //get existing serial configuration
1759 len = sizeof(cyg_serial_info_t);
1760 int err;
1761 cyg_io_handle_t serial_handle;
1762
1763 err = cyg_io_lookup("/dev/ser0", &serial_handle);
1764 if (err != ENOERR)
1765 {
1766 LOG_ERROR("/dev/ser0 not found\n");
1767 return ERROR_FAIL;
1768 }
1769
1770
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);
1773 if (err != ENOERR)
1774 {
1775 command_print(cmd_ctx, "Failed to get serial port settings %d", err);
1776 return ERROR_OK;
1777 }
1778 buf.baud = baud;
1779
1780 err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf, &len);
1781 if (err != ENOERR)
1782 {
1783 command_print(cmd_ctx, "Failed to set serial port settings %d", err);
1784 return ERROR_OK;
1785 }
1786
1787 return ERROR_OK;
1788 }
1789
1790 bool logAllToSerial = false;
1791
1792 /* boolean parameter stored on config */
1793 bool boolParam(char *var)
1794 {
1795 bool result = false;
1796 char *name = alloc_printf(ZYLIN_CONFIG_DIR "/%s", var);
1797 if (name == NULL)
1798 return result;
1799
1800 void *data;
1801 int len;
1802 if (loadFile(name, &data, &len) == ERROR_OK)
1803 {
1804 if (len > 1)
1805 len = 1;
1806 result = strncmp((char *) data, "1", len) == 0;
1807 free(data);
1808 }
1809 free(name);
1810 return result;
1811 }
1812
1813 command_context_t *setup_command_handler();
1814
1815 int add_default_dirs(void)
1816 {
1817 add_script_search_dir(ZYLIN_CONFIG_DIR);
1818 add_script_search_dir("/rom/lib/openocd");
1819 add_script_search_dir("/rom");
1820 return ERROR_OK;
1821 }
1822
1823 static cyg_uint8 *ramblockdevice;
1824 static const int ramblockdevice_size=4096*1024;
1825 int main(int argc, char *argv[])
1826 {
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. */
1829
1830 ramblockdevice=(cyg_uint8 *)malloc(ramblockdevice_size);
1831 memset(ramblockdevice, 0xff, ramblockdevice_size);
1832
1833
1834
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);
1839 #endif
1840
1841 int err;
1842
1843 setPower(true); // on by default
1844
1845 atexit(keep_webserver);
1846
1847 err = mount("", "/ram", "ramfs");
1848 if (err < 0)
1849 {
1850 diag_printf("unable to mount ramfs\n");
1851 }
1852 chdir("/ram");
1853
1854 char address[16];
1855 sprintf(address, "%p", &filedata[0]);
1856 err = mount(address, "/rom", "romfs");
1857 if (err < 0)
1858 {
1859 diag_printf("unable to mount /rom\n");
1860 }
1861
1862 err = mount("", "/log", "logfs");
1863 if (err < 0)
1864 {
1865 diag_printf("unable to mount logfs\n");
1866 }
1867
1868 err = mount("", "/tftp", "tftpfs");
1869 if (err < 0)
1870 {
1871 diag_printf("unable to mount logfs\n");
1872 }
1873
1874 log = fopen("/log/log", "w");
1875 if (log == NULL)
1876 {
1877 diag_printf("Could not open log file /ram/log\n");
1878 exit(-1);
1879 }
1880
1881 diag_init_putc(_zylinjtag_diag_write_char);
1882
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);
1886
1887 copydir("/rom", "/ram/cgi");
1888
1889 err = mount("/dev/flash1", "/config", "jffs2");
1890 if (err < 0)
1891 {
1892 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1893 err = mount("", "/config", "ramfs");
1894 if (err<0)
1895 {
1896 diag_printf("unable to mount /config as ramdisk.\n");
1897 reboot();
1898 }
1899 } else
1900 {
1901 /* are we using a ram disk instead of a flash disk? This is used
1902 * for ZY1000 live demo...
1903 *
1904 * copy over flash disk to ram block device
1905 */
1906 if (boolParam("ramdisk"))
1907 {
1908 diag_printf("Unmounting /config from flash and using ram instead\n");
1909 err=umount("/config");
1910 if (err < 0)
1911 {
1912 diag_printf("unable to unmount jffs\n");
1913 reboot();
1914 }
1915
1916 err = mount("/dev/flash1", "/config2", "jffs2");
1917 if (err < 0)
1918 {
1919 diag_printf("unable to mount jffs\n");
1920 reboot();
1921 }
1922
1923 err = mount("", "/config", "ramfs");
1924 if (err < 0)
1925 {
1926 diag_printf("unable to mount ram block device\n");
1927 reboot();
1928 }
1929
1930 // copydir("/config2", "/config");
1931 copyfile("/config2/ip", "/config/ip");
1932 copydir("/config2/settings", "/config/settings");
1933
1934 umount("/config2");
1935 } else
1936 {
1937 /* we're not going to use a ram block disk */
1938 free(ramblockdevice);
1939 }
1940 }
1941
1942
1943 mkdir(ZYLIN_CONFIG_DIR, 0777);
1944 mkdir(ZYLIN_CONFIG_DIR "/target", 0777);
1945 mkdir(ZYLIN_CONFIG_DIR "/event", 0777);
1946
1947 logAllToSerial = boolParam("logserial");
1948
1949 // We need the network & web server in case there is something wrong with
1950 // the config files that invoke exit()
1951 zylinjtag_startNetwork();
1952
1953 /* we're going to access the jim interpreter from here on... */
1954 openocd_sleep_postlude();
1955 startUart();
1956
1957 add_default_dirs();
1958
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);
1964
1965
1966 register_command(cmd_ctx, NULL, "zy1000_version", handle_zy1000_version_command,
1967 COMMAND_EXEC, "show zy1000 version numbers");
1968
1969 register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
1970 "remove file");
1971
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");
1974
1975 register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
1976 "loads active fast load image to current target");
1977
1978 register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
1979 "display file content");
1980
1981 register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
1982 "truncate a file to 0 size");
1983
1984 register_command(cmd_ctx, NULL, "append_file", handle_append_command,
1985 COMMAND_ANY, "append a variable number of strings to a file");
1986
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.");
1989
1990 register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
1991 COMMAND_ANY, "display available ram memory");
1992
1993 register_command(cmd_ctx, NULL, "cp", handle_cp_command,
1994 COMMAND_ANY, "copy a file <from> <to>");
1995
1996 #ifdef CYGPKG_PROFILE_GPROF
1997 register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,
1998 COMMAND_ANY, NULL);
1999 #endif
2000 register_command(cmd_ctx, NULL, "uart", handle_uart_command,
2001 COMMAND_ANY, "uart <baud> - forward uart on port 5555");
2002
2003
2004 int errVal;
2005 errVal = log_init(cmd_ctx);
2006 if (errVal != ERROR_OK)
2007 {
2008 diag_printf("log_init() failed %d\n", errVal);
2009 exit(-1);
2010 }
2011
2012 set_log_output(cmd_ctx, log);
2013
2014 LOG_DEBUG("log init complete");
2015
2016 // diag_printf("Executing config files\n");
2017
2018 if (logAllToSerial)
2019 {
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");
2022 }
2023
2024 zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
2025
2026 // FIX!!! Yuk!
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*).
2029 //
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)
2035 {
2036 serialLog = false;
2037 }
2038
2039 /* handle network connections */
2040 server_loop(cmd_ctx);
2041 openocd_sleep_prelude();
2042
2043 /* shut server down */
2044 server_quit();
2045
2046 /* free commandline interface */
2047 command_done(cmd_ctx);
2048 umount("/config");
2049
2050 exit(0);
2051 for (;;);
2052 }
2053
2054
2055
2056 cyg_int32
2057 cyg_httpd_exec_cgi_tcl(char *file_name);
2058 cyg_int32 homeForm(CYG_HTTPD_STATE *p)
2059 {
2060 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
2061 return 0;
2062 }
2063
2064 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);
2065
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");
2068
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>
2074
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
2078 #include <unistd.h>
2079 #include <sys/types.h>
2080 #include <fcntl.h>
2081 #include <sys/stat.h>
2082 #include <errno.h>
2083 #include <dirent.h>
2084
2085 #include <stdarg.h>
2086 #include <stdio.h>
2087 #include <stdlib.h>
2088 #include <string.h>
2089
2090 #include <cyg/fileio/fileio.h>
2091
2092 #include <cyg/kernel/kapi.h>
2093 #include <cyg/infra/diag.h>
2094
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.
2100
2101 // Forward definitions
2102
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);
2110
2111 // File operations
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);
2115
2116 //==========================================================================
2117 // Filesystem table entries
2118
2119 // -------------------------------------------------------------------------
2120 // Fstab entry.
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.
2124 #if 1
2125 FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0,
2126 CYG_SYNCMODE_NONE,
2127 tftpfs_mount,
2128 tftpfs_umount,
2129 tftpfs_open,
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);
2140 #endif
2141
2142 // -------------------------------------------------------------------------
2143 // mtab entry.
2144 // This defines a single ROMFS loaded into ROM at the configured address
2145 //
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
2151 // );
2152
2153
2154 // -------------------------------------------------------------------------
2155 // File operations.
2156 // This set of file operations are used for normal open files.
2157
2158 static cyg_fileops tftpfs_fileops =
2159 {
2160 tftpfs_fo_read,
2161 tftpfs_fo_write,
2162 tftpfs_fo_lseek,
2163 (cyg_fileop_ioctl *)cyg_fileio_erofs,
2164 cyg_fileio_seltrue,
2165 tftpfs_fo_fsync,
2166 tftpfs_fo_close,
2167 (cyg_fileop_fstat *) cyg_fileio_erofs,
2168 (cyg_fileop_getinfo *) cyg_fileio_erofs,
2169 (cyg_fileop_setinfo *)cyg_fileio_erofs,
2170 };
2171
2172 // -------------------------------------------------------------------------
2173 // tftpfs_mount()
2174 // Process a mount request. This mainly finds root for the
2175 // filesystem.
2176
2177 static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
2178 {
2179 return ENOERR;
2180 }
2181
2182 static int tftpfs_umount(cyg_mtab_entry *mte)
2183 {
2184 return ENOERR;
2185 }
2186
2187 struct Tftp
2188 {
2189 int write;
2190 int readFile;
2191 cyg_uint8 *mem;
2192 int actual;
2193 char *server;
2194 char *file;
2195 };
2196
2197 static void freeTftp(struct Tftp *t)
2198 {
2199 if (t == NULL)
2200 return;
2201 if (t->mem)
2202 free(t->mem);
2203 if (t->server)
2204 free(t->server);
2205 if (t->file)
2206 free(t->file);
2207 free(t);
2208 }
2209
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)
2213 {
2214 struct Tftp *tftp;
2215 tftp = malloc(sizeof(struct Tftp));
2216 if (tftp == NULL)
2217 return EMFILE;
2218 memset(tftp, 0, sizeof(struct Tftp));
2219
2220 file->f_flag |= mode & CYG_FILE_MODE_MASK;
2221 file->f_type = CYG_FILE_TYPE_FILE;
2222 file->f_ops = &tftpfs_fileops;
2223 file->f_offset = 0;
2224 file->f_data = 0;
2225 file->f_xops = 0;
2226
2227 tftp->mem = malloc(tftpMaxSize);
2228 if (tftp->mem == NULL)
2229 {
2230 freeTftp(tftp);
2231 return EMFILE;
2232 }
2233
2234 char *server = strchr(name, '/');
2235 if (server == NULL)
2236 {
2237 freeTftp(tftp);
2238 return EMFILE;
2239 }
2240
2241 tftp->server = malloc(server - name + 1);
2242 if (tftp->server == NULL)
2243 {
2244 freeTftp(tftp);
2245 return EMFILE;
2246 }
2247 strncpy(tftp->server, name, server - name);
2248 tftp->server[server - name] = 0;
2249
2250 tftp->file = strdup(server + 1);
2251 if (tftp->file == NULL)
2252 {
2253 freeTftp(tftp);
2254 return EMFILE;
2255 }
2256
2257 file->f_data = (CYG_ADDRWORD) tftp;
2258
2259 return ENOERR;
2260 }
2261
2262 static int fetchTftp(struct Tftp *tftp)
2263 {
2264 if (!tftp->readFile)
2265 {
2266 int err;
2267 tftp->actual = tftp_client_get( tftp->file, tftp->server, 0, tftp->mem, tftpMaxSize, TFTP_OCTET, &err);
2268
2269 if (tftp->actual < 0)
2270 {
2271 return EMFILE;
2272 }
2273 tftp->readFile = 1;
2274 }
2275 return ENOERR;
2276 }
2277
2278 // -------------------------------------------------------------------------
2279 // tftpfs_fo_write()
2280 // Read data from file.
2281
2282 static int
2283 tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2284 {
2285 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2286
2287 if (fetchTftp(tftp) != ENOERR)
2288 return EMFILE;
2289
2290 int i;
2291 off_t pos = fp->f_offset;
2292 int resid = 0;
2293 for (i = 0; i < uio->uio_iovcnt; i++)
2294 {
2295 cyg_iovec *iov = &uio->uio_iov[i];
2296 char *buf = (char *) iov->iov_base;
2297 off_t len = iov->iov_len;
2298
2299 if (len + pos > tftp->actual)
2300 {
2301 len = tftp->actual - pos;
2302 }
2303 resid += iov->iov_len - len;
2304
2305 memcpy(buf, tftp->mem + pos, len);
2306 pos += len;
2307
2308 }
2309 uio->uio_resid = resid;
2310 fp->f_offset = pos;
2311
2312 return ENOERR;
2313 }
2314
2315
2316 static int
2317 tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2318 {
2319 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2320
2321 int i;
2322 off_t pos = fp->f_offset;
2323 int resid = 0;
2324 for (i = 0; i < uio->uio_iovcnt; i++)
2325 {
2326 cyg_iovec *iov = &uio->uio_iov[i];
2327 char *buf = (char *) iov->iov_base;
2328 off_t len = iov->iov_len;
2329
2330 if (len + pos > tftpMaxSize)
2331 {
2332 len = tftpMaxSize - pos;
2333 }
2334 resid += iov->iov_len - len;
2335
2336 memcpy(tftp->mem + pos, buf, len);
2337 pos += len;
2338
2339 }
2340 uio->uio_resid = resid;
2341 fp->f_offset = pos;
2342
2343 tftp->write = 1;
2344
2345 return ENOERR;
2346 }
2347
2348 static int
2349 tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
2350 {
2351 int error = ENOERR;
2352 return error;
2353 }
2354
2355 // -------------------------------------------------------------------------
2356 // romfs_fo_close()
2357 // Close a file. We just clear out the data pointer.
2358
2359 static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)
2360 {
2361 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2362 int error = ENOERR;
2363
2364 if (tftp->write)
2365 {
2366 tftp_client_put( tftp->file, tftp->server, 0, tftp->mem, fp->f_offset, TFTP_OCTET, &error);
2367 }
2368
2369 freeTftp(tftp);
2370 fp->f_data = 0;
2371 return error;
2372 }
2373
2374 // -------------------------------------------------------------------------
2375 // romfs_fo_lseek()
2376 // Seek to a new file position.
2377
2378 static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)
2379 {
2380 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2381 off_t pos = *apos;
2382
2383 if (fetchTftp(tftp) != ENOERR)
2384 return EMFILE;
2385
2386 switch (whence)
2387 {
2388 case SEEK_SET:
2389 // Pos is already where we want to be.
2390 break;
2391
2392 case SEEK_CUR:
2393 // Add pos to current offset.
2394 pos += fp->f_offset;
2395 break;
2396
2397 case SEEK_END:
2398 // Add pos to file size.
2399 pos += tftp->actual;
2400 break;
2401
2402 default:
2403 return EINVAL;
2404 }
2405
2406 // Check that pos is still within current file size, or at the
2407 // very end.
2408 if (pos < 0 || pos > tftp->actual)
2409 return EINVAL;
2410
2411 // All OK, set fp offset and return new position.
2412 *apos = fp->f_offset = pos;
2413
2414 return ENOERR;
2415 }
2416
2417 void usleep(int us)
2418 {
2419 if (us > 10000)
2420 cyg_thread_delay(us / 10000 + 1);
2421 else
2422 HAL_DELAY_US(us);
2423 }
2424
2425 // Chunked version.
2426 cyg_int32
2427 show_log_entry(CYG_HTTPD_STATE *phttpstate)
2428 {
2429 cyg_httpd_start_chunked("text");
2430 if (logCount >= logSize)
2431 {
2432 cyg_httpd_write_chunked(logBuffer+logCount%logSize, logSize-logCount%logSize);
2433 }
2434 cyg_httpd_write_chunked(logBuffer, writePtr);
2435 cyg_httpd_end_chunked();
2436 return -1;
2437 }
2438
2439 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);
2440
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);
2446 static int
2447 logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
2448
2449 // File operations
2450 static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
2451 static int logfs_fo_close(struct CYG_FILE_TAG *fp);
2452
2453 #include <cyg/io/devtab.h>
2454
2455 //==========================================================================
2456 // Filesystem table entries
2457
2458 // -------------------------------------------------------------------------
2459 // Fstab entry.
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,
2465 logfs_mount,
2466 logfs_umount,
2467 logfs_open,
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);
2478
2479 // -------------------------------------------------------------------------
2480 // File operations.
2481 // This set of file operations are used for normal open files.
2482
2483 static cyg_fileops logfs_fileops =
2484 {
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,
2489 cyg_fileio_seltrue,
2490 logfs_fo_fsync,
2491 logfs_fo_close,
2492 (cyg_fileop_fstat *)cyg_fileio_erofs,
2493 (cyg_fileop_getinfo *) cyg_fileio_erofs,
2494 (cyg_fileop_setinfo *)cyg_fileio_erofs,
2495 };
2496
2497 // -------------------------------------------------------------------------
2498 // logfs_mount()
2499 // Process a mount request. This mainly finds root for the
2500 // filesystem.
2501
2502 static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
2503 {
2504 return ENOERR;
2505 }
2506
2507 static int logfs_umount(cyg_mtab_entry *mte)
2508 {
2509 return ENOERR;
2510 }
2511
2512 static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2513 int mode, cyg_file *file)
2514 {
2515 file->f_flag |= mode & CYG_FILE_MODE_MASK;
2516 file->f_type = CYG_FILE_TYPE_FILE;
2517 file->f_ops = &logfs_fileops;
2518 file->f_offset = 0;
2519 file->f_data = 0;
2520 file->f_xops = 0;
2521 return ENOERR;
2522 }
2523
2524 // -------------------------------------------------------------------------
2525 // logfs_fo_write()
2526 // Write data to file.
2527
2528 static int
2529 logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2530 {
2531 int i;
2532 for (i = 0; i < uio->uio_iovcnt; i++)
2533 {
2534 cyg_iovec *iov = &uio->uio_iov[i];
2535 char *buf = (char *) iov->iov_base;
2536 off_t len = iov->iov_len;
2537
2538 diag_write(buf, len);
2539 }
2540 uio->uio_resid = 0;
2541
2542 return ENOERR;
2543 }
2544 static int
2545 logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
2546 {
2547 return ENOERR;
2548 }
2549
2550 // -------------------------------------------------------------------------
2551 // romfs_fo_close()
2552 // Close a file. We just clear out the data pointer.
2553
2554 static int logfs_fo_close(struct CYG_FILE_TAG *fp)
2555 {
2556 return ENOERR;
2557 }
2558

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)