wip
[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.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"
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 void start_profile(void)
357 {
358 // This starts up the system-wide profiling, gathering
359 // profile information on all of the code, with a 16 byte
360 // "bucket" size, at a rate of 100us/profile hit.
361 // Note: a bucket size of 16 will give pretty good function
362 // resolution. Much smaller and the buffer becomes
363 // much too large for very little gain.
364 // Note: a timer period of 100us is also a reasonable
365 // compromise. Any smaller and the overhead of
366 // handling the timter (profile) interrupt could
367 // swamp the system. A fast processor might get
368 // by with a smaller value, but a slow one could
369 // even be swamped by this value. If the value is
370 // too large, the usefulness of the profile is reduced.
371
372 // no more interrupts than 1/10ms.
373 // profile_on(&_stext, &_etext, 16, 10000); // DRAM
374 //profile_on((void *)0, (void *)0x40000, 16, 10000); // SRAM
375 profile_on(0, &_etext, 16, 10000); // SRAM & DRAM
376 }
377 #endif
378
379 // launch GDB server if a config file exists
380 bool zylinjtag_parse_config_file(struct command_context_s *cmd_ctx, const char *config_file_name)
381 {
382 bool foundFile = false;
383 FILE *config_file = NULL;
384 command_print(cmd_ctx, "executing config file %s", config_file_name);
385 config_file = fopen(config_file_name, "r");
386 if (config_file)
387 {
388 fclose(config_file);
389 int retval;
390 retval = command_run_linef(cmd_ctx, "script %s", config_file_name);
391 if (retval == ERROR_OK)
392 {
393 foundFile = true;
394 }
395 else
396 {
397 command_print(cmd_ctx, "Failed executing %s %d", config_file_name, retval);
398 }
399 }
400 else
401 {
402 command_print(cmd_ctx, "No %s found", config_file_name);
403 }
404
405 return foundFile;
406 }
407
408 extern int eth0_up;
409 static FILE *log;
410
411 static char reboot_stack[2048];
412
413
414 static void
415 zylinjtag_reboot(cyg_addrword_t data)
416 {
417 serialLog = true;
418 diag_printf("Rebooting in 100 ticks..\n");
419 cyg_thread_delay(100);
420 diag_printf("Unmounting /config..\n");
421 umount("/config");
422 diag_printf("Rebooting..\n");
423 HAL_PLATFORM_RESET();
424 }
425 static cyg_thread zylinjtag_thread_object;
426 static cyg_handle_t zylinjtag_thread_handle;
427
428 void reboot(void)
429 {
430 cyg_thread_create(1,
431 zylinjtag_reboot,
432 (cyg_addrword_t)0,
433 "reboot Thread",
434 (void *)reboot_stack,
435 sizeof(reboot_stack),
436 &zylinjtag_thread_handle,
437 &zylinjtag_thread_object);
438 cyg_thread_resume(zylinjtag_thread_handle);
439 }
440
441 int configuration_output_handler(struct command_context_s *context, const char* line)
442 {
443 diag_printf("%s", line);
444
445 return ERROR_OK;
446 }
447
448 int zy1000_configuration_output_handler_log(struct command_context_s *context, const char* line)
449 {
450 LOG_USER_N("%s", line);
451
452 return ERROR_OK;
453 }
454
455 int handle_rm_command(struct command_context_s *cmd_ctx, char *cmd,
456 char **args, int argc)
457 {
458 if (argc != 1)
459 {
460 command_print(cmd_ctx, "rm <filename>");
461 return ERROR_INVALID_ARGUMENTS;
462 }
463
464 if (unlink(args[0]) != 0)
465 {
466 command_print(cmd_ctx, "failed: %d", errno);
467 }
468
469 return ERROR_OK;
470 }
471
472 int loadFile(const char *fileName, void **data, int *len);
473
474 int handle_cat_command(struct command_context_s *cmd_ctx, char *cmd,
475 char **args, int argc)
476 {
477 if (argc != 1)
478 {
479 command_print(cmd_ctx, "cat <filename>");
480 return ERROR_INVALID_ARGUMENTS;
481 }
482
483 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
484 void *data;
485 int len;
486
487 int retval = loadFile(args[0], &data, &len);
488 if (retval == ERROR_OK)
489 {
490 command_print(cmd_ctx, "%s", data);
491 free(data);
492 }
493 else
494 {
495 command_print(cmd_ctx, "%s not found %d", args[0], retval);
496 }
497
498 return ERROR_OK;
499 }
500 int handle_trunc_command(struct command_context_s *cmd_ctx, char *cmd,
501 char **args, int argc)
502 {
503 if (argc != 1)
504 {
505 command_print(cmd_ctx, "trunc <filename>");
506 return ERROR_INVALID_ARGUMENTS;
507 }
508
509 FILE *config_file = NULL;
510 config_file = fopen(args[0], "w");
511 if (config_file != NULL)
512 fclose(config_file);
513
514 return ERROR_OK;
515 }
516
517
518 int handle_meminfo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
519 {
520 static int prev = 0;
521 struct mallinfo info;
522
523 if (argc != 0)
524 {
525 command_print(cmd_ctx, "meminfo");
526 return ERROR_INVALID_ARGUMENTS;
527 }
528
529 info = mallinfo();
530
531 if (prev > 0)
532 {
533 command_print(cmd_ctx, "Diff: %d", prev - info.fordblks);
534 }
535 prev = info.fordblks;
536
537 command_print(cmd_ctx, "Available ram: %d", info.fordblks );
538
539 return ERROR_OK;
540 }
541
542 static bool savePower;
543
544 static void setPower(bool power)
545 {
546 savePower = power;
547 if (power)
548 {
549 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x14, 0x8);
550 } else
551 {
552 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x8);
553 }
554 }
555
556 int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
557 {
558 if (argc > 1)
559 {
560 return ERROR_INVALID_ARGUMENTS;
561 }
562
563 if (argc == 1)
564 {
565 if (strcmp(args[0], "on") == 0)
566 {
567 setPower(1);
568 }
569 else if (strcmp(args[0], "off") == 0)
570 {
571 setPower(0);
572 } else
573 {
574 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
575 return ERROR_INVALID_ARGUMENTS;
576 }
577 }
578
579 command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
580
581 return ERROR_OK;
582 }
583
584 int handle_append_command(struct command_context_s *cmd_ctx, char *cmd,
585 char **args, int argc)
586 {
587 if (argc < 1)
588 {
589 command_print(cmd_ctx,
590 "append <filename> [<string1>, [<string2>, ...]]");
591 return ERROR_INVALID_ARGUMENTS;
592 }
593
594 FILE *config_file = NULL;
595 config_file = fopen(args[0], "a");
596 if (config_file != NULL)
597 {
598 int i;
599 fseek(config_file, 0, SEEK_END);
600
601 for (i = 1; i < argc; i++)
602 {
603 fwrite(args[i], strlen(args[i]), 1, config_file);
604 if (i != argc - 1)
605 {
606 fwrite(" ", 1, 1, config_file);
607 }
608 }
609 fwrite("\n", 1, 1, config_file);
610 fclose(config_file);
611 }
612
613 return ERROR_OK;
614 }
615
616 extern int telnet_socket;
617
618 int readMore(int fd, void *data, int length)
619 {
620 /* used in select() */
621 fd_set read_fds;
622
623 /* monitor sockets for acitvity */
624 int fd_max = 1;
625 FD_ZERO(&read_fds);
626 /* listen for new connections */
627 FD_SET(fd, &read_fds);
628
629 // Maximum 5 seconds.
630 struct timeval tv;
631 tv.tv_sec = 5;
632 tv.tv_usec = 0;
633
634 int retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
635 if (retval == 0)
636 {
637 diag_printf("Timed out waiting for binary payload\n");
638 return -1;
639 }
640 if (retval != 1)
641 return -1;
642
643 return read_socket(fd, data, length);
644 }
645
646 int readAll(int fd, void *data, int length)
647 {
648 int pos = 0;
649 for (;;)
650 {
651 int actual = readMore(fd, ((char *) data) + pos, length - pos);
652 // diag_printf("Read %d bytes(pos=%d, length=%d)\n", actual, pos, length);
653 if (actual <= 0)
654 return -1;
655 pos += actual;
656 if (pos == length)
657 break;
658 }
659 return length;
660 }
661
662 int handle_peek_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
663 {
664 cyg_uint32 value;
665 if (argc != 1)
666 {
667 return ERROR_INVALID_ARGUMENTS;
668 }
669 HAL_READ_UINT32(strtoul(args[0], NULL, 0), value);
670 command_print(cmd_ctx, "0x%x : 0x%x", strtoul(args[0], NULL, 0), value);
671 return ERROR_OK;
672 }
673
674 int handle_poke_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
675 {
676 if (argc != 2)
677 {
678 return ERROR_INVALID_ARGUMENTS;
679 }
680 HAL_WRITE_UINT32(strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0));
681 return ERROR_OK;
682 }
683
684 int handle_cp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
685 {
686 if (argc != 2)
687 {
688 return ERROR_INVALID_ARGUMENTS;
689 }
690
691 // NOTE!!! we only have line printing capability so we print the entire file as a single line.
692 void *data;
693 int len;
694
695 int retval = loadFile(args[0], &data, &len);
696 if (retval != ERROR_OK)
697 return retval;
698
699 FILE *f = fopen(args[1], "wb");
700 if (f == NULL)
701 retval = ERROR_INVALID_ARGUMENTS;
702
703 int pos = 0;
704 for (;;)
705 {
706 int chunk = len - pos;
707 static const int maxChunk = 512 * 1024; // ~1/sec
708 if (chunk > maxChunk)
709 {
710 chunk = maxChunk;
711 }
712
713 if ((retval==ERROR_OK)&&(fwrite(((char *)data)+pos, 1, chunk, f)!=chunk))
714 retval = ERROR_INVALID_ARGUMENTS;
715
716 if (retval != ERROR_OK)
717 {
718 break;
719 }
720
721 command_print(cmd_ctx, "%d", len - pos);
722
723 pos += chunk;
724
725 if (pos == len)
726 break;
727 }
728
729 if (retval == ERROR_OK)
730 {
731 command_print(cmd_ctx, "Copied %s to %s", args[0], args[1]);
732 } else
733 {
734 command_print(cmd_ctx, "Failed: %d", retval);
735 }
736
737 if (data != NULL)
738 free(data);
739 if (f != NULL)
740 fclose(f);
741
742 if (retval != ERROR_OK)
743 unlink(args[1]);
744
745 return retval;
746 }
747
748 #ifdef CYGPKG_PROFILE_GPROF
749 extern void start_profile();
750
751 int eCosBoard_handle_eCosBoard_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
752 {
753 command_print(cmd_ctx, "Profiling started");
754 start_profile();
755 return ERROR_OK;
756 }
757
758 #endif
759
760 externC void phi_init_all_network_interfaces();
761
762 command_context_t *cmd_ctx;
763
764 static bool webRunning = false;
765
766 void keep_webserver()
767 {
768 // Target initialisation is only attempted at startup, so we sleep forever and
769 // let the http server bail us out(i.e. get config files set up).
770 diag_printf("OpenOCD has invoked exit().\n"
771 "Use web server to correct any configuration settings and reboot.\n");
772 if (!webRunning)
773 reboot();
774
775 // exit() will terminate the current thread and we we'll then sleep eternally or
776 // we'll have a reboot scheduled.
777 }
778
779 extern void printDccChar(char c);
780
781 static char logBuffer[128 * 1024];
782 static const int logSize = sizeof(logBuffer);
783 int writePtr = 0;
784 int logCount = 0;
785
786 void _zylinjtag_diag_write_char(char c, void **param)
787 {
788 if (writeLog)
789 {
790 logBuffer[writePtr] = c;
791 writePtr = (writePtr + 1) % logSize;
792 logCount++;
793 }
794 if (serialLog)
795 {
796 if (c == '\n')
797 {
798 HAL_DIAG_WRITE_CHAR('\r');
799 }
800 HAL_DIAG_WRITE_CHAR(c);
801 }
802
803 #ifdef CYGPKG_HAL_ZYLIN_PHI
804 printDccChar(c);
805 #endif
806 }
807
808 #define SHOW_RESULT(a, b) diag_printf(#a " failed %d\n", (int)b)
809
810 #define IOSIZE 512
811 static void copyfile(char *name2, char *name1)
812 {
813
814 int err;
815 char buf[IOSIZE];
816 int fd1, fd2;
817 ssize_t done, wrote;
818
819 fd1 = open(name1, O_WRONLY | O_CREAT);
820 if (fd1 < 0)
821 SHOW_RESULT( open, fd1 );
822
823 fd2 = open(name2, O_RDONLY);
824 if (fd2 < 0)
825 SHOW_RESULT( open, fd2 );
826
827 for (;;)
828 {
829 done = read(fd2, buf, IOSIZE );
830 if (done < 0)
831 {
832 SHOW_RESULT( read, done );
833 break;
834 }
835
836 if( done == 0 ) break;
837
838 wrote = write(fd1, buf, done);
839 if( wrote != done ) SHOW_RESULT( write, wrote );
840
841 if( wrote != done ) break;
842 }
843
844 err = close(fd1);
845 if( err < 0 ) SHOW_RESULT( close, err );
846
847 err = close(fd2);
848 if( err < 0 ) SHOW_RESULT( close, err );
849
850 }
851 static void copydir(char *name, char *destdir)
852 {
853 int err;
854 DIR *dirp;
855
856 dirp = opendir(destdir);
857 if (dirp==NULL)
858 {
859 mkdir(destdir, 0777);
860 } else
861 {
862 err = closedir(dirp);
863 }
864
865 dirp = opendir(name);
866 if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
867
868 for (;;)
869 {
870 struct dirent *entry = readdir(dirp);
871
872 if (entry == NULL)
873 break;
874
875 if (strcmp(entry->d_name, ".") == 0)
876 continue;
877 if (strcmp(entry->d_name, "..") == 0)
878 continue;
879
880 bool isDir = false;
881 struct stat buf;
882 char fullPath[PATH_MAX];
883 strncpy(fullPath, name, PATH_MAX);
884 strcat(fullPath, "/");
885 strncat(fullPath, entry->d_name, PATH_MAX - strlen(fullPath));
886
887 if (stat(fullPath, &buf) == -1)
888 {
889 diag_printf("unable to read status from %s", fullPath);
890 break;
891 }
892 isDir = S_ISDIR(buf.st_mode) != 0;
893
894 if (isDir)
895 continue;
896
897 // diag_printf("<INFO>: entry %14s",entry->d_name);
898 char fullname[PATH_MAX];
899 char fullname2[PATH_MAX];
900
901 strcpy(fullname, name);
902 strcat(fullname, "/");
903 strcat(fullname, entry->d_name);
904
905 strcpy(fullname2, destdir);
906 strcat(fullname2, "/");
907 strcat(fullname2, entry->d_name);
908 // diag_printf("from %s to %s\n", fullname, fullname2);
909 copyfile(fullname, fullname2);
910
911 // diag_printf("\n");
912 }
913
914 err = closedir(dirp);
915 if( err < 0 ) SHOW_RESULT( stat, err );
916 }
917
918 #if 0
919 MTAB_ENTRY( romfs_mte1,
920 "/rom",
921 "romfs",
922 "",
923 (CYG_ADDRWORD) &filedata[0] );
924 #endif
925
926 void openocd_sleep_prelude()
927 {
928 cyg_mutex_unlock(&httpstate.jim_lock);
929 }
930
931 void openocd_sleep_postlude()
932 {
933 cyg_mutex_lock(&httpstate.jim_lock);
934 }
935
936
937 void format(void)
938 {
939 diag_printf("Formatting JFFS2...\n");
940
941 cyg_io_handle_t handle;
942
943 Cyg_ErrNo err;
944 err = cyg_io_lookup(CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, &handle);
945 if (err != ENOERR)
946 {
947 diag_printf("Flash Error cyg_io_lookup: %d\n", err);
948 reboot();
949 }
950
951
952 cyg_uint32 len;
953 cyg_io_flash_getconfig_devsize_t ds;
954 len = sizeof (ds);
955 err = cyg_io_get_config(handle,
956 CYG_IO_GET_CONFIG_FLASH_DEVSIZE, &ds, &len);
957 if (err != ENOERR)
958 {
959 diag_printf("Flash error cyg_io_get_config %d\n", err);
960 reboot();
961 }
962
963 cyg_io_flash_getconfig_erase_t e;
964 void *err_addr;
965 len = sizeof (e);
966
967 e.offset = 0;
968 e.len = ds.dev_size;
969 e.err_address = &err_addr;
970
971 diag_printf("Formatting 0x%08x bytes\n", ds.dev_size);
972 err = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_FLASH_ERASE,
973 &e, &len);
974 if (err != ENOERR)
975 {
976 diag_printf("Flash erase error %d offset 0x%p\n", err, err_addr);
977 reboot();
978 }
979
980 diag_printf("Flash formatted successfully\n");
981
982 reboot();
983 }
984
985
986
987 static int
988 zylinjtag_Jim_Command_format_jffs2(Jim_Interp *interp,
989 int argc,
990 Jim_Obj * const *argv)
991 {
992 int del;
993 if (argc != 1)
994 {
995 return JIM_ERR;
996 }
997
998 format();
999 }
1000
1001
1002 static int
1003 zylinjtag_Jim_Command_rm(Jim_Interp *interp,
1004 int argc,
1005 Jim_Obj * const *argv)
1006 {
1007 int del;
1008 if (argc != 2)
1009 {
1010 Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
1011 return JIM_ERR;
1012 }
1013
1014 del = 0;
1015 if (unlink(Jim_GetString(argv[1], NULL)) == 0)
1016 del = 1;
1017 if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
1018 del = 1;
1019
1020 return del ? JIM_OK : JIM_ERR;
1021 }
1022
1023 static int zylinjtag_Jim_Command_threads(Jim_Interp *interp, int argc,
1024 Jim_Obj * const *argv)
1025 {
1026 cyg_handle_t thread = 0;
1027 cyg_uint16 id = 0;
1028 Jim_Obj *threads = Jim_NewListObj(interp, NULL, 0);
1029
1030 /* Loop over the threads, and generate a table row for
1031 * each.
1032 */
1033 while (cyg_thread_get_next(&thread, &id))
1034 {
1035 Jim_Obj *threadObj = Jim_NewListObj(interp, NULL, 0);
1036
1037 cyg_thread_info info;
1038 char *state_string;
1039
1040 cyg_thread_get_info(thread, id, &info);
1041
1042 if (info.name == NULL)
1043 info.name = "<no name>";
1044
1045 Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
1046 info.name, strlen(info.name)));
1047
1048 /* Translate the state into a string.
1049 */
1050 if (info.state == 0)
1051 state_string = "RUN";
1052 else if (info.state & 0x04)
1053 state_string = "SUSP";
1054 else
1055 switch (info.state & 0x1b)
1056 {
1057 case 0x01:
1058 state_string = "SLEEP";
1059 break;
1060 case 0x02:
1061 state_string = "CNTSLEEP";
1062 break;
1063 case 0x08:
1064 state_string = "CREATE";
1065 break;
1066 case 0x10:
1067 state_string = "EXIT";
1068 break;
1069 default:
1070 state_string = "????";
1071 break;
1072 }
1073
1074 Jim_ListAppendElement(interp, threadObj, Jim_NewStringObj(interp,
1075 state_string, strlen(state_string)));
1076
1077 Jim_ListAppendElement (interp, threadObj, Jim_NewIntObj(interp, id));
1078 Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, info.set_pri));
1079 Jim_ListAppendElement(interp, threadObj, Jim_NewIntObj(interp, info.cur_pri));
1080
1081 Jim_ListAppendElement(interp, threads, threadObj);
1082 }
1083 Jim_SetResult( interp, threads);
1084
1085 return JIM_OK;
1086 }
1087
1088
1089 static int
1090 zylinjtag_Jim_Command_ls(Jim_Interp *interp,
1091 int argc,
1092 Jim_Obj * const *argv)
1093 {
1094 if (argc != 2)
1095 {
1096 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
1097 return JIM_ERR;
1098 }
1099
1100 char *name = (char*) Jim_GetString(argv[1], NULL);
1101
1102 DIR *dirp = NULL;
1103 dirp = opendir(name);
1104 if (dirp == NULL)
1105 {
1106 return JIM_ERR;
1107 }
1108 Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
1109
1110 for (;;)
1111 {
1112 struct dirent *entry = NULL;
1113 entry = readdir(dirp);
1114 if (entry == NULL)
1115 break;
1116
1117 if ((strcmp(".", entry->d_name)==0)||(strcmp("..", entry->d_name)==0))
1118 continue;
1119
1120 Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name)));
1121 }
1122 closedir(dirp);
1123
1124 Jim_SetResult(interp, objPtr);
1125
1126 return JIM_OK;
1127 }
1128
1129
1130 static int
1131 zylinjtag_Jim_Command_getmem(Jim_Interp *interp,
1132 int argc,
1133 Jim_Obj * const *argv)
1134 {
1135 if (argc != 3)
1136 {
1137 Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?");
1138 return JIM_ERR;
1139 }
1140
1141 long address;
1142 long length;
1143 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1144 return JIM_ERR;
1145 if (Jim_GetLong(interp, argv[2], &length) != JIM_OK)
1146 return JIM_ERR;
1147
1148 if (length < 0 && length > (4096 * 1024))
1149 {
1150 Jim_WrongNumArgs(interp, 1, argv, "getmem ?dir?");
1151 return JIM_ERR;
1152 }
1153
1154 void *mem = malloc(length);
1155 if (mem == NULL)
1156 return JIM_ERR;
1157
1158 target_t *target = get_current_target(cmd_ctx);
1159
1160 int retval;
1161 int size = 1;
1162 int count = length;
1163 if ((address % 4 == 0) && (count % 4 == 0))
1164 {
1165 size = 4;
1166 count /= 4;
1167 }
1168
1169 if ((retval = target->type->read_memory(target, address, size, count, mem)) != ERROR_OK)
1170 {
1171 free(mem);
1172 return JIM_ERR;
1173 }
1174
1175 Jim_Obj *objPtr = Jim_NewStringObj(interp, mem, length);
1176 Jim_SetResult(interp, objPtr);
1177
1178 free(mem);
1179
1180 return JIM_OK;
1181 }
1182
1183 static int
1184 zylinjtag_Jim_Command_peek(Jim_Interp *interp,
1185 int argc,
1186 Jim_Obj * const *argv)
1187 {
1188 if (argc != 2)
1189 {
1190 Jim_WrongNumArgs(interp, 1, argv, "peek ?address?");
1191 return JIM_ERR;
1192 }
1193
1194 long address;
1195 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1196 return JIM_ERR;
1197
1198 int value = *((volatile int *) address);
1199
1200 Jim_SetResult(interp, Jim_NewIntObj(interp, value));
1201
1202 return JIM_OK;
1203 }
1204
1205 static int
1206 zylinjtag_Jim_Command_poke(Jim_Interp *interp,
1207 int argc,
1208 Jim_Obj * const *argv)
1209 {
1210 if (argc != 3)
1211 {
1212 Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?");
1213 return JIM_ERR;
1214 }
1215
1216 long address;
1217 if (Jim_GetLong(interp, argv[1], &address) != JIM_OK)
1218 return JIM_ERR;
1219 long value;
1220 if (Jim_GetLong(interp, argv[2], &value) != JIM_OK)
1221 return JIM_ERR;
1222
1223 *((volatile int *) address) = value;
1224
1225 return JIM_OK;
1226 }
1227
1228
1229
1230 static int
1231 zylinjtag_Jim_Command_flash(Jim_Interp *interp,
1232 int argc,
1233 Jim_Obj * const *argv)
1234 {
1235 int retval;
1236 u32 base = 0;
1237 flash_bank_t *t = get_flash_bank_by_num_noprobe(0);
1238 if (t != NULL)
1239 {
1240 base = t->base;
1241 retval = JIM_OK;
1242 } else
1243 {
1244 retval = JIM_ERR;
1245 }
1246
1247 if (retval == JIM_OK)
1248 {
1249 Jim_SetResult(interp, Jim_NewIntObj(interp, base));
1250 }
1251
1252 return retval;
1253 }
1254
1255
1256
1257
1258
1259 static int
1260 zylinjtag_Jim_Command_log(Jim_Interp *interp,
1261 int argc,
1262 Jim_Obj * const *argv)
1263 {
1264 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1265
1266 if (logCount >= logSize)
1267 {
1268 Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer+logCount%logSize, logSize-logCount%logSize);
1269 }
1270 Jim_AppendString(httpstate.jim_interp, tclOutput, logBuffer, writePtr);
1271
1272 Jim_SetResult(interp, tclOutput);
1273 return JIM_OK;
1274 }
1275
1276 static int
1277 zylinjtag_Jim_Command_reboot(Jim_Interp *interp,
1278 int argc,
1279 Jim_Obj * const *argv)
1280 {
1281 reboot();
1282 return JIM_OK;
1283 }
1284
1285 static int
1286 zylinjtag_Jim_Command_mac(Jim_Interp *interp,
1287 int argc,
1288 Jim_Obj * const *argv)
1289 {
1290
1291 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1292
1293 Jim_AppendString(httpstate.jim_interp, tclOutput, hwaddr, strlen(hwaddr));
1294
1295 Jim_SetResult(interp, tclOutput);
1296
1297 return JIM_OK;
1298 }
1299
1300 static int
1301 zylinjtag_Jim_Command_ip(Jim_Interp *interp,
1302 int argc,
1303 Jim_Obj * const *argv)
1304 {
1305 Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
1306
1307 struct ifaddrs *ifa = NULL, *ifp = NULL;
1308
1309 if (getifaddrs(&ifp) < 0)
1310 {
1311 return JIM_ERR;
1312 }
1313
1314 for (ifa = ifp; ifa; ifa = ifa->ifa_next)
1315 {
1316 char ip[200];
1317 socklen_t salen;
1318
1319 if (ifa->ifa_addr->sa_family == AF_INET)
1320 salen = sizeof(struct sockaddr_in);
1321 else if (ifa->ifa_addr->sa_family == AF_INET6)
1322 salen = sizeof(struct sockaddr_in6);
1323 else
1324 continue;
1325
1326 if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0,
1327 NI_NUMERICHOST) < 0)
1328 {
1329 continue;
1330 }
1331
1332 Jim_AppendString(httpstate.jim_interp, tclOutput, ip, strlen(ip));
1333 break;
1334
1335 }
1336
1337 freeifaddrs(ifp);
1338
1339 Jim_SetResult(interp, tclOutput);
1340
1341 return JIM_OK;
1342 }
1343
1344 extern Jim_Interp *interp;
1345
1346
1347 static void zylinjtag_startNetwork()
1348 {
1349 // Bring TCP/IP up immediately before we're ready to accept commands.
1350 //
1351 // That is as soon as a PING responds, we're accepting telnet sessions.
1352 #if defined(CYGPKG_NET_FREEBSD_STACK)
1353 phi_init_all_network_interfaces();
1354 #else
1355 lwip_init();
1356 #endif
1357 if (!eth0_up)
1358 {
1359 diag_printf("Network not up and running\n");
1360 exit(-1);
1361 }
1362 #if defined(CYGPKG_NET_FREEBSD_STACK)
1363 /*start TFTP*/
1364 tftpd_start(69, &fileops);
1365 #endif
1366
1367 cyg_httpd_init_tcl_interpreter();
1368
1369 interp = httpstate.jim_interp;
1370
1371 Jim_CreateCommand(httpstate.jim_interp, "log", zylinjtag_Jim_Command_log, NULL, NULL);
1372 Jim_CreateCommand(httpstate.jim_interp, "reboot", zylinjtag_Jim_Command_reboot, NULL, NULL);
1373 Jim_CreateCommand(httpstate.jim_interp, "peek", zylinjtag_Jim_Command_peek, NULL, NULL);
1374 Jim_CreateCommand(httpstate.jim_interp, "zy1000_flash", zylinjtag_Jim_Command_flash, NULL, NULL);
1375 Jim_CreateCommand(httpstate.jim_interp, "poke", zylinjtag_Jim_Command_poke, NULL, NULL);
1376 Jim_CreateCommand(httpstate.jim_interp, "ls", zylinjtag_Jim_Command_ls, NULL, NULL);
1377 Jim_CreateCommand(httpstate.jim_interp, "threads", zylinjtag_Jim_Command_threads, NULL, NULL);
1378 Jim_CreateCommand(httpstate.jim_interp, "getmem", zylinjtag_Jim_Command_getmem, NULL, NULL);
1379 Jim_CreateCommand(httpstate.jim_interp, "mac", zylinjtag_Jim_Command_mac, NULL, NULL);
1380 Jim_CreateCommand(httpstate.jim_interp, "ip", zylinjtag_Jim_Command_ip, NULL, NULL);
1381 Jim_CreateCommand(httpstate.jim_interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
1382 Jim_CreateCommand(httpstate.jim_interp, "format_jffs2", zylinjtag_Jim_Command_format_jffs2, NULL, NULL);
1383
1384 cyg_httpd_start();
1385
1386 webRunning = true;
1387
1388 diag_printf("Web server running\n");
1389
1390 int s;
1391 struct ifreq ifr;
1392 s = socket(AF_INET, SOCK_DGRAM, 0);
1393 if (s >= 0)
1394 {
1395 strcpy(ifr.ifr_name, "eth0");
1396 int res;
1397 res = ioctl(s, SIOCGIFHWADDR, &ifr);
1398 close(s);
1399
1400 if (res < 0)
1401 {
1402 diag_printf("Can't obtain MAC address\n");
1403 reboot();
1404 }
1405 }
1406
1407 sprintf(hwaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
1408 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[0],
1409 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[1],
1410 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[2],
1411 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[3],
1412 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[4],
1413 (int) ((unsigned char *) &ifr.ifr_hwaddr.sa_data)[5]);
1414
1415
1416 discover_message=alloc_printf("ZY1000 Zylin JTAG debugger MAC %s", hwaddr);
1417
1418 discover_launch();
1419 }
1420
1421
1422
1423
1424
1425 static void
1426 print_exception_handler(cyg_addrword_t data, cyg_code_t exception, cyg_addrword_t info)
1427 {
1428 writeLog = false;
1429 serialLog = true;
1430 char *infoStr = "unknown";
1431 switch (exception)
1432 {
1433 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1434 case CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION:
1435 infoStr = "undefined instruction";
1436 break;
1437 case CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT:
1438 infoStr = "software interrupt";
1439 break;
1440 case CYGNUM_HAL_VECTOR_ABORT_PREFETCH:
1441 infoStr = "abort prefetch";
1442 break;
1443 case CYGNUM_HAL_VECTOR_ABORT_DATA:
1444 infoStr = "abort data";
1445 break;
1446 #endif
1447 default:
1448 break;
1449 }
1450
1451 diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
1452
1453 diag_printf("Dumping log\n---\n");
1454 if (logCount >= logSize)
1455 {
1456 diag_write(logBuffer + logCount % logSize, logSize - logCount % logSize);
1457 }
1458 diag_write(logBuffer, writePtr);
1459
1460 diag_printf("---\nLogdump complete.\n");
1461 diag_printf("Exception: %08x(%s) %08x\n", exception, infoStr, info);
1462 diag_printf("\n---\nRebooting\n");
1463 HAL_PLATFORM_RESET();
1464
1465 }
1466
1467 static void setHandler(cyg_code_t exception)
1468 {
1469 cyg_exception_handler_t *old_handler;
1470 cyg_addrword_t old_data;
1471
1472 cyg_exception_set_handler(exception,
1473 print_exception_handler,
1474 0,
1475 &old_handler,
1476 &old_data);
1477 }
1478
1479 static cyg_thread zylinjtag_uart_thread_object;
1480 static cyg_handle_t zylinjtag_uart_thread_handle;
1481 static char uart_stack[4096];
1482
1483 static char forwardBuffer[1024]; // NB! must be smaller than a TCP/IP packet!!!!!
1484 static char backwardBuffer[1024];
1485
1486
1487 void setNoDelay(int session, int flag)
1488 {
1489 #if 1
1490 // This decreases latency dramatically for e.g. GDB load which
1491 // does not have a sliding window protocol
1492 //
1493 // Can cause *lots* of TCP/IP packets to be sent and it would have
1494 // to be enabled/disabled on the fly to avoid the CPU being
1495 // overloaded...
1496 setsockopt(session, /* socket affected */
1497 IPPROTO_TCP, /* set option at TCP level */
1498 TCP_NODELAY, /* name of option */
1499 (char *) &flag, /* the cast is historical
1500 cruft */
1501 sizeof(int)); /* length of option value */
1502 #endif
1503 }
1504
1505 struct
1506 {
1507 int req;
1508 int actual;
1509 int req2;
1510 int actual2;
1511 } tcpipSent[512 * 1024];
1512 int cur;
1513
1514 static void
1515 zylinjtag_uart(cyg_addrword_t data)
1516 {
1517 int so_reuseaddr_option = 1;
1518
1519 int fd;
1520 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1521 {
1522 LOG_ERROR("error creating socket: %s", strerror(errno));
1523 exit(-1);
1524 }
1525
1526 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
1527
1528 struct sockaddr_in sin;
1529 unsigned int address_size;
1530 address_size = sizeof(sin);
1531 memset(&sin, 0, sizeof(sin));
1532 sin.sin_family = AF_INET;
1533 sin.sin_addr.s_addr = INADDR_ANY;
1534 sin.sin_port = htons(5555);
1535
1536 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
1537 {
1538 LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
1539 exit(-1);
1540 }
1541
1542 if (listen(fd, 1) == -1)
1543 {
1544 LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
1545 exit(-1);
1546 }
1547 // socket_nonblock(fd);
1548
1549
1550 for (;;)
1551 {
1552 int session = accept(fd, (struct sockaddr *) &sin, &address_size);
1553 if (session < 0)
1554 {
1555 continue;
1556 }
1557
1558 setNoDelay(session, 1);
1559 int oldopts = fcntl(session, F_GETFL, 0);
1560 fcntl(session, F_SETFL, oldopts | O_NONBLOCK); //
1561
1562 int serHandle = open("/dev/ser0", O_RDWR | O_NONBLOCK);
1563 if (serHandle < 0)
1564 {
1565 close(session);
1566 continue;
1567 }
1568
1569 #ifdef CYGPKG_PROFILE_GPROF
1570 start_profile();
1571 #endif
1572 int actual = 0;
1573 int actual2 = 0;
1574 int pos, pos2;
1575 pos = 0;
1576 pos2 = 0;
1577 cur = 0;
1578 for (;;)
1579 {
1580 fd_set write_fds;
1581 fd_set read_fds;
1582 FD_ZERO(&write_fds);
1583 FD_ZERO(&read_fds);
1584 int fd_max = -1;
1585 FD_SET(session, &read_fds);
1586 fd_max = session;
1587 FD_SET(serHandle, &read_fds);
1588 if (serHandle > fd_max)
1589 {
1590 fd_max = serHandle;
1591 }
1592 /* Wait... */
1593
1594 cyg_thread_delay(5); // 50ms fixed delay to wait for data to be sent/received
1595 if ((actual == 0) && (actual2 == 0))
1596 {
1597 int retval = select(fd_max + 1, &read_fds, NULL, NULL, NULL);
1598 if (retval <= 0)
1599 {
1600 break;
1601 }
1602 }
1603
1604 if (actual2 <= 0)
1605 {
1606 memset(backwardBuffer, 's', sizeof(backwardBuffer));
1607 actual2=read(serHandle, backwardBuffer, sizeof(backwardBuffer));
1608 if (actual2 < 0)
1609 {
1610 if (errno != EAGAIN)
1611 {
1612 goto closeSession;
1613 }
1614 actual2 = 0;
1615 }
1616 pos2 = 0;
1617 }
1618
1619 int x = actual2;
1620 int y = 0;
1621 if (actual2 > 0)
1622 {
1623 int written = write(session, backwardBuffer + pos2, actual2);
1624 if (written <= 0)
1625 goto closeSession;
1626 actual2 -= written;
1627 pos2 += written;
1628 y = written;
1629 }
1630
1631 if (FD_ISSET(session, &read_fds)&&(sizeof(forwardBuffer)>actual))
1632 {
1633 // NB! Here it is important that we empty the TCP/IP read buffer
1634 // to make transmission tick right
1635 memmove(forwardBuffer, forwardBuffer + pos, actual);
1636 pos = 0;
1637 int t;
1638 // this will block if there is no data at all
1639 t=read_socket(session, forwardBuffer+actual, sizeof(forwardBuffer)-actual);
1640 if (t <= 0)
1641 {
1642 goto closeSession;
1643 }
1644 actual += t;
1645 }
1646
1647 int x2 = actual;
1648 int y2 = 0;
1649 if (actual > 0)
1650 {
1651 /* Do not put things into the serial buffer if it has something to send
1652 * as that can cause a single byte to be sent at the time.
1653 *
1654 *
1655 */
1656 int written = write(serHandle, forwardBuffer + pos, actual);
1657 if (written < 0)
1658 {
1659 if (errno != EAGAIN)
1660 {
1661 goto closeSession;
1662 }
1663 // The serial buffer is full
1664 written = 0;
1665 } else
1666 {
1667 actual -= written;
1668 pos += written;
1669 }
1670 y2 = written;
1671 }
1672 if (cur < 1024)
1673 {
1674 tcpipSent[cur].req = x;
1675 tcpipSent[cur].actual = y;
1676 tcpipSent[cur].req2 = x2;
1677 tcpipSent[cur].actual2 = y2;
1678 cur++;
1679 }
1680
1681 }
1682 closeSession:
1683 close(session);
1684 close(serHandle);
1685
1686 int i;
1687 for (i = 0; i < 1024; i++)
1688 {
1689 diag_printf("%d %d %d %d\n", tcpipSent[i].req, tcpipSent[i].actual, tcpipSent[i].req2, tcpipSent[i].actual2);
1690
1691 }
1692 }
1693 close(fd);
1694
1695 }
1696
1697 void startUart(void)
1698 {
1699 cyg_thread_create(1,
1700 zylinjtag_uart,
1701 (cyg_addrword_t)0,
1702 "uart thread",
1703 (void *)uart_stack,
1704 sizeof(uart_stack),
1705 &zylinjtag_uart_thread_handle,
1706 &zylinjtag_uart_thread_object);
1707 cyg_thread_set_priority(zylinjtag_uart_thread_handle, 1); // low priority as it sits in a busy loop
1708 cyg_thread_resume(zylinjtag_uart_thread_handle);
1709 }
1710
1711
1712
1713 int handle_uart_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1714 {
1715 static int current_baud = 38400;
1716 if (argc == 0)
1717 {
1718 command_print(cmd_ctx, "%d", current_baud);
1719 return ERROR_OK;
1720 } else if (argc != 1)
1721 {
1722 return ERROR_INVALID_ARGUMENTS;
1723 }
1724
1725 current_baud = atol(args[0]);
1726
1727 int baud;
1728 switch (current_baud)
1729 {
1730 case 9600:
1731 baud = CYGNUM_SERIAL_BAUD_9600;
1732 break;
1733 case 19200:
1734 baud = CYGNUM_SERIAL_BAUD_19200;
1735 break;
1736 case 38400:
1737 baud = CYGNUM_SERIAL_BAUD_38400;
1738 break;
1739 case 57600:
1740 baud = CYGNUM_SERIAL_BAUD_57600;
1741 break;
1742 case 115200:
1743 baud = CYGNUM_SERIAL_BAUD_115200;
1744 break;
1745 case 230400:
1746 baud = CYGNUM_SERIAL_BAUD_230400;
1747 break;
1748 default:
1749 command_print(cmd_ctx, "unsupported baudrate");
1750 return ERROR_INVALID_ARGUMENTS;
1751 }
1752
1753 cyg_serial_info_t buf;
1754 cyg_uint32 len = 1;
1755 //get existing serial configuration
1756 len = sizeof(cyg_serial_info_t);
1757 int err;
1758 cyg_io_handle_t serial_handle;
1759
1760 err = cyg_io_lookup("/dev/ser0", &serial_handle);
1761 if (err != ENOERR)
1762 {
1763 LOG_ERROR("/dev/ser0 not found\n");
1764 return ERROR_FAIL;
1765 }
1766
1767
1768 err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buf, &len);
1769 err = cyg_io_get_config(serial_handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &buf, &len);
1770 if (err != ENOERR)
1771 {
1772 command_print(cmd_ctx, "Failed to get serial port settings %d", err);
1773 return ERROR_OK;
1774 }
1775 buf.baud = baud;
1776
1777 err = cyg_io_set_config(serial_handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &buf, &len);
1778 if (err != ENOERR)
1779 {
1780 command_print(cmd_ctx, "Failed to set serial port settings %d", err);
1781 return ERROR_OK;
1782 }
1783
1784 return ERROR_OK;
1785 }
1786
1787 bool logAllToSerial = false;
1788
1789 /* boolean parameter stored on config */
1790 bool boolParam(char *var)
1791 {
1792 bool result = false;
1793 char *name = alloc_printf(ZYLIN_CONFIG_DIR "/%s", var);
1794 if (name == NULL)
1795 return result;
1796
1797 void *data;
1798 int len;
1799 if (loadFile(name, &data, &len) == ERROR_OK)
1800 {
1801 if (len > 1)
1802 len = 1;
1803 result = strncmp((char *) data, "1", len) == 0;
1804 free(data);
1805 }
1806 free(name);
1807 return result;
1808 }
1809
1810 command_context_t *setup_command_handler();
1811
1812 int add_default_dirs(void)
1813 {
1814 add_script_search_dir(ZYLIN_CONFIG_DIR);
1815 add_script_search_dir("/rom/lib/openocd");
1816 add_script_search_dir("/rom");
1817 return ERROR_OK;
1818 }
1819
1820 static cyg_uint8 *ramblockdevice;
1821 static const int ramblockdevice_size=4096*1024;
1822 int main(int argc, char *argv[])
1823 {
1824 /* ramblockdevice will be the same address every time. The deflate app uses a buffer 16mBytes out, so we
1825 * need to allocate towards the end of the heap. */
1826
1827 ramblockdevice=(cyg_uint8 *)malloc(ramblockdevice_size);
1828 memset(ramblockdevice, 0xff, ramblockdevice_size);
1829
1830
1831
1832 #ifdef CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
1833 setHandler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION);
1834 setHandler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH);
1835 setHandler(CYGNUM_HAL_VECTOR_ABORT_DATA);
1836 #endif
1837
1838 int err;
1839
1840 setPower(true); // on by default
1841
1842 atexit(keep_webserver);
1843
1844 err = mount("", "/ram", "ramfs");
1845 if (err < 0)
1846 {
1847 diag_printf("unable to mount ramfs\n");
1848 }
1849 chdir("/ram");
1850
1851 char address[16];
1852 sprintf(address, "%p", &filedata[0]);
1853 err = mount(address, "/rom", "romfs");
1854 if (err < 0)
1855 {
1856 diag_printf("unable to mount /rom\n");
1857 }
1858
1859 err = mount("", "/log", "logfs");
1860 if (err < 0)
1861 {
1862 diag_printf("unable to mount logfs\n");
1863 }
1864
1865 err = mount("", "/tftp", "tftpfs");
1866 if (err < 0)
1867 {
1868 diag_printf("unable to mount logfs\n");
1869 }
1870
1871 log = fopen("/log/log", "w");
1872 if (log == NULL)
1873 {
1874 diag_printf("Could not open log file /ram/log\n");
1875 exit(-1);
1876 }
1877
1878 diag_init_putc(_zylinjtag_diag_write_char);
1879
1880 // We want this in the log.
1881 diag_printf("Zylin ZY1000. Copyright Zylin AS 2007-2008.\n");
1882 diag_printf("%s\n", ZYLIN_OPENOCD_VERSION);
1883
1884 copydir("/rom", "/ram/cgi");
1885
1886 err = mount("/dev/flash1", "/config", "jffs2");
1887 if (err < 0)
1888 {
1889 diag_printf("unable to mount jffs2, falling back to ram disk..\n");
1890 err = mount("", "/config", "ramfs");
1891 if (err<0)
1892 {
1893 diag_printf("unable to mount /config as ramdisk.\n");
1894 reboot();
1895 }
1896 } else
1897 {
1898 /* are we using a ram disk instead of a flash disk? This is used
1899 * for ZY1000 live demo...
1900 *
1901 * copy over flash disk to ram block device
1902 */
1903 if (boolParam("ramdisk"))
1904 {
1905 diag_printf("Unmounting /config from flash and using ram instead\n");
1906 err=umount("/config");
1907 if (err < 0)
1908 {
1909 diag_printf("unable to unmount jffs\n");
1910 reboot();
1911 }
1912
1913 err = mount("/dev/flash1", "/config2", "jffs2");
1914 if (err < 0)
1915 {
1916 diag_printf("unable to mount jffs\n");
1917 reboot();
1918 }
1919
1920 err = mount("/dev/ram", "/config", "jffs2");
1921 if (err < 0)
1922 {
1923 diag_printf("unable to mount ram block device\n");
1924 reboot();
1925 }
1926
1927 // copydir("/config2", "/config");
1928 copyfile("/config2/ip", "/config/ip");
1929 copydir("/config2/settings", "/config/settings");
1930
1931 umount("/config2");
1932 } else
1933 {
1934 /* we're not going to use a ram block disk */
1935 free(ramblockdevice);
1936 }
1937 }
1938
1939
1940 mkdir(ZYLIN_CONFIG_DIR, 0777);
1941 mkdir(ZYLIN_CONFIG_DIR "/target", 0777);
1942 mkdir(ZYLIN_CONFIG_DIR "/event", 0777);
1943
1944 logAllToSerial = boolParam("logserial");
1945
1946 // We need the network & web server in case there is something wrong with
1947 // the config files that invoke exit()
1948 zylinjtag_startNetwork();
1949
1950 /* we're going to access the jim interpreter from here on... */
1951 openocd_sleep_postlude();
1952 startUart();
1953
1954 add_default_dirs();
1955
1956 /* initialize commandline interface */
1957 command_context_t *cmd_ctx;
1958 cmd_ctx = setup_command_handler();
1959 command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
1960 command_context_mode(cmd_ctx, COMMAND_CONFIG);
1961
1962
1963 register_command(cmd_ctx, NULL, "zy1000_version", handle_zy1000_version_command,
1964 COMMAND_EXEC, "show zy1000 version numbers");
1965
1966 register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
1967 "remove file");
1968
1969 register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
1970 "same args as load_image, image stored in memory");
1971
1972 register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
1973 "loads active fast load image to current target");
1974
1975 register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
1976 "display file content");
1977
1978 register_command(cmd_ctx, NULL, "trunc", handle_trunc_command, COMMAND_ANY,
1979 "truncate a file to 0 size");
1980
1981 register_command(cmd_ctx, NULL, "append_file", handle_append_command,
1982 COMMAND_ANY, "append a variable number of strings to a file");
1983
1984 register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
1985 "power <on/off> - turn power switch to target on/off. No arguments - print status.");
1986
1987 register_command(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
1988 COMMAND_ANY, "display available ram memory");
1989
1990 register_command(cmd_ctx, NULL, "cp", handle_cp_command,
1991 COMMAND_ANY, "copy a file <from> <to>");
1992
1993 #ifdef CYGPKG_PROFILE_GPROF
1994 register_command(cmd_ctx, NULL, "ecosboard_profile", eCosBoard_handle_eCosBoard_profile_command,
1995 COMMAND_ANY, NULL);
1996 #endif
1997 register_command(cmd_ctx, NULL, "uart", handle_uart_command,
1998 COMMAND_ANY, "uart <baud> - forward uart on port 5555");
1999
2000
2001 int errVal;
2002 errVal = log_init(cmd_ctx);
2003 if (errVal != ERROR_OK)
2004 {
2005 diag_printf("log_init() failed %d\n", errVal);
2006 exit(-1);
2007 }
2008
2009 set_log_output(cmd_ctx, log);
2010
2011 LOG_DEBUG("log init complete");
2012
2013 // diag_printf("Executing config files\n");
2014
2015 if (logAllToSerial)
2016 {
2017 diag_printf(ZYLIN_CONFIG_DIR "/logserial=1 => sending log output to serial port using \"debug_level 3\" as default.\n");
2018 command_run_line(cmd_ctx, "debug_level 3");
2019 }
2020
2021 zylinjtag_parse_config_file(cmd_ctx, "/rom/openocd.cfg");
2022
2023 // FIX!!! Yuk!
2024 // diag_printf() is really invoked from many more places than we trust it
2025 // not to cause instabilities(e.g. invoking fputc() from an interrupt is *BAD*).
2026 //
2027 // Disabling it here is safe and gives us enough logged debug output for now. Crossing
2028 // fingers that it doesn't cause any crashes.
2029 diag_printf("Init complete, GDB & telnet servers launched.\n");
2030 command_set_output_handler(cmd_ctx, zy1000_configuration_output_handler_log, NULL);
2031 if (!logAllToSerial)
2032 {
2033 serialLog = false;
2034 }
2035
2036 /* handle network connections */
2037 server_loop(cmd_ctx);
2038 openocd_sleep_prelude();
2039
2040 /* shut server down */
2041 server_quit();
2042
2043 /* free commandline interface */
2044 command_done(cmd_ctx);
2045 umount("/config");
2046
2047 exit(0);
2048 for (;;);
2049 }
2050
2051
2052
2053 cyg_int32
2054 cyg_httpd_exec_cgi_tcl(char *file_name);
2055 cyg_int32 homeForm(CYG_HTTPD_STATE *p)
2056 {
2057 cyg_httpd_exec_cgi_tcl("/ram/cgi/index.tcl");
2058 return 0;
2059 }
2060
2061 CYG_HTTPD_HANDLER_TABLE_ENTRY(root_label, "/", homeForm);
2062
2063 CYG_HTTPD_MIME_TABLE_ENTRY(text_mime_label, "text", "text/plain");
2064 CYG_HTTPD_MIME_TABLE_ENTRY(bin_mime_label, "bin", "application/octet-stream");
2065
2066 #include <pkgconf/system.h>
2067 #include <pkgconf/hal.h>
2068 #include <pkgconf/kernel.h>
2069 #include <pkgconf/io_fileio.h>
2070 #include <pkgconf/fs_rom.h>
2071
2072 #include <cyg/kernel/ktypes.h> // base kernel types
2073 #include <cyg/infra/cyg_trac.h> // tracing macros
2074 #include <cyg/infra/cyg_ass.h> // assertion macros
2075 #include <unistd.h>
2076 #include <sys/types.h>
2077 #include <fcntl.h>
2078 #include <sys/stat.h>
2079 #include <errno.h>
2080 #include <dirent.h>
2081
2082 #include <stdarg.h>
2083 #include <stdio.h>
2084 #include <stdlib.h>
2085 #include <string.h>
2086
2087 #include <cyg/fileio/fileio.h>
2088
2089 #include <cyg/kernel/kapi.h>
2090 #include <cyg/infra/diag.h>
2091
2092 //==========================================================================
2093 // Eventually we want to eXecute In Place from the ROM in a protected
2094 // environment, so we'll need executables to be aligned to a boundary
2095 // suitable for MMU protection. A suitable boundary would be the 4k
2096 // boundary in all the CPU architectures I am currently aware of.
2097
2098 // Forward definitions
2099
2100 // Filesystem operations
2101 static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
2102 static int tftpfs_umount(cyg_mtab_entry *mte);
2103 static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2104 int mode, cyg_file *fte);
2105 static int tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
2106 static int tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
2107
2108 // File operations
2109 static int tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
2110 static int tftpfs_fo_close(struct CYG_FILE_TAG *fp);
2111 static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence);
2112
2113 //==========================================================================
2114 // Filesystem table entries
2115
2116 // -------------------------------------------------------------------------
2117 // Fstab entry.
2118 // This defines the entry in the filesystem table.
2119 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2120 // we should never block in any filesystem operations.
2121 #if 1
2122 FSTAB_ENTRY( tftpfs_fste, "tftpfs", 0,
2123 CYG_SYNCMODE_NONE,
2124 tftpfs_mount,
2125 tftpfs_umount,
2126 tftpfs_open,
2127 (cyg_fsop_unlink *)cyg_fileio_erofs,
2128 (cyg_fsop_mkdir *)cyg_fileio_erofs,
2129 (cyg_fsop_rmdir *)cyg_fileio_erofs,
2130 (cyg_fsop_rename *)cyg_fileio_erofs,
2131 (cyg_fsop_link *)cyg_fileio_erofs,
2132 (cyg_fsop_opendir *)cyg_fileio_erofs,
2133 (cyg_fsop_chdir *)cyg_fileio_erofs,
2134 (cyg_fsop_stat *)cyg_fileio_erofs,
2135 (cyg_fsop_getinfo *)cyg_fileio_erofs,
2136 (cyg_fsop_setinfo *)cyg_fileio_erofs);
2137 #endif
2138
2139 // -------------------------------------------------------------------------
2140 // mtab entry.
2141 // This defines a single ROMFS loaded into ROM at the configured address
2142 //
2143 // MTAB_ENTRY( rom_mte, // structure name
2144 // "/rom", // mount point
2145 // "romfs", // FIlesystem type
2146 // "", // hardware device
2147 // (CYG_ADDRWORD) CYGNUM_FS_ROM_BASE_ADDRESS // Address in ROM
2148 // );
2149
2150
2151 // -------------------------------------------------------------------------
2152 // File operations.
2153 // This set of file operations are used for normal open files.
2154
2155 static cyg_fileops tftpfs_fileops =
2156 {
2157 tftpfs_fo_read,
2158 tftpfs_fo_write,
2159 tftpfs_fo_lseek,
2160 (cyg_fileop_ioctl *)cyg_fileio_erofs,
2161 cyg_fileio_seltrue,
2162 tftpfs_fo_fsync,
2163 tftpfs_fo_close,
2164 (cyg_fileop_fstat *) cyg_fileio_erofs,
2165 (cyg_fileop_getinfo *) cyg_fileio_erofs,
2166 (cyg_fileop_setinfo *)cyg_fileio_erofs,
2167 };
2168
2169 // -------------------------------------------------------------------------
2170 // tftpfs_mount()
2171 // Process a mount request. This mainly finds root for the
2172 // filesystem.
2173
2174 static int tftpfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
2175 {
2176 return ENOERR;
2177 }
2178
2179 static int tftpfs_umount(cyg_mtab_entry *mte)
2180 {
2181 return ENOERR;
2182 }
2183
2184 struct Tftp
2185 {
2186 int write;
2187 int readFile;
2188 cyg_uint8 *mem;
2189 int actual;
2190 char *server;
2191 char *file;
2192 };
2193
2194 static void freeTftp(struct Tftp *t)
2195 {
2196 if (t == NULL)
2197 return;
2198 if (t->mem)
2199 free(t->mem);
2200 if (t->server)
2201 free(t->server);
2202 if (t->file)
2203 free(t->file);
2204 free(t);
2205 }
2206
2207 static const int tftpMaxSize = 8192 * 1024;
2208 static int tftpfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2209 int mode, cyg_file *file)
2210 {
2211 struct Tftp *tftp;
2212 tftp = malloc(sizeof(struct Tftp));
2213 if (tftp == NULL)
2214 return EMFILE;
2215 memset(tftp, 0, sizeof(struct Tftp));
2216
2217 file->f_flag |= mode & CYG_FILE_MODE_MASK;
2218 file->f_type = CYG_FILE_TYPE_FILE;
2219 file->f_ops = &tftpfs_fileops;
2220 file->f_offset = 0;
2221 file->f_data = 0;
2222 file->f_xops = 0;
2223
2224 tftp->mem = malloc(tftpMaxSize);
2225 if (tftp->mem == NULL)
2226 {
2227 freeTftp(tftp);
2228 return EMFILE;
2229 }
2230
2231 char *server = strchr(name, '/');
2232 if (server == NULL)
2233 {
2234 freeTftp(tftp);
2235 return EMFILE;
2236 }
2237
2238 tftp->server = malloc(server - name + 1);
2239 if (tftp->server == NULL)
2240 {
2241 freeTftp(tftp);
2242 return EMFILE;
2243 }
2244 strncpy(tftp->server, name, server - name);
2245 tftp->server[server - name] = 0;
2246
2247 tftp->file = strdup(server + 1);
2248 if (tftp->file == NULL)
2249 {
2250 freeTftp(tftp);
2251 return EMFILE;
2252 }
2253
2254 file->f_data = (CYG_ADDRWORD) tftp;
2255
2256 return ENOERR;
2257 }
2258
2259 static int fetchTftp(struct Tftp *tftp)
2260 {
2261 if (!tftp->readFile)
2262 {
2263 int err;
2264 tftp->actual = tftp_client_get( tftp->file, tftp->server, 0, tftp->mem, tftpMaxSize, TFTP_OCTET, &err);
2265
2266 if (tftp->actual < 0)
2267 {
2268 return EMFILE;
2269 }
2270 tftp->readFile = 1;
2271 }
2272 return ENOERR;
2273 }
2274
2275 // -------------------------------------------------------------------------
2276 // tftpfs_fo_write()
2277 // Read data from file.
2278
2279 static int
2280 tftpfs_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2281 {
2282 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2283
2284 if (fetchTftp(tftp) != ENOERR)
2285 return EMFILE;
2286
2287 int i;
2288 off_t pos = fp->f_offset;
2289 int resid = 0;
2290 for (i = 0; i < uio->uio_iovcnt; i++)
2291 {
2292 cyg_iovec *iov = &uio->uio_iov[i];
2293 char *buf = (char *) iov->iov_base;
2294 off_t len = iov->iov_len;
2295
2296 if (len + pos > tftp->actual)
2297 {
2298 len = tftp->actual - pos;
2299 }
2300 resid += iov->iov_len - len;
2301
2302 memcpy(buf, tftp->mem + pos, len);
2303 pos += len;
2304
2305 }
2306 uio->uio_resid = resid;
2307 fp->f_offset = pos;
2308
2309 return ENOERR;
2310 }
2311
2312
2313 static int
2314 tftpfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2315 {
2316 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2317
2318 int i;
2319 off_t pos = fp->f_offset;
2320 int resid = 0;
2321 for (i = 0; i < uio->uio_iovcnt; i++)
2322 {
2323 cyg_iovec *iov = &uio->uio_iov[i];
2324 char *buf = (char *) iov->iov_base;
2325 off_t len = iov->iov_len;
2326
2327 if (len + pos > tftpMaxSize)
2328 {
2329 len = tftpMaxSize - pos;
2330 }
2331 resid += iov->iov_len - len;
2332
2333 memcpy(tftp->mem + pos, buf, len);
2334 pos += len;
2335
2336 }
2337 uio->uio_resid = resid;
2338 fp->f_offset = pos;
2339
2340 tftp->write = 1;
2341
2342 return ENOERR;
2343 }
2344
2345 static int
2346 tftpfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
2347 {
2348 int error = ENOERR;
2349 return error;
2350 }
2351
2352 // -------------------------------------------------------------------------
2353 // romfs_fo_close()
2354 // Close a file. We just clear out the data pointer.
2355
2356 static int tftpfs_fo_close(struct CYG_FILE_TAG *fp)
2357 {
2358 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2359 int error = ENOERR;
2360
2361 if (tftp->write)
2362 {
2363 tftp_client_put( tftp->file, tftp->server, 0, tftp->mem, fp->f_offset, TFTP_OCTET, &error);
2364 }
2365
2366 freeTftp(tftp);
2367 fp->f_data = 0;
2368 return error;
2369 }
2370
2371 // -------------------------------------------------------------------------
2372 // romfs_fo_lseek()
2373 // Seek to a new file position.
2374
2375 static int tftpfs_fo_lseek(struct CYG_FILE_TAG *fp, off_t *apos, int whence)
2376 {
2377 struct Tftp *tftp = (struct Tftp *) fp->f_data;
2378 off_t pos = *apos;
2379
2380 if (fetchTftp(tftp) != ENOERR)
2381 return EMFILE;
2382
2383 switch (whence)
2384 {
2385 case SEEK_SET:
2386 // Pos is already where we want to be.
2387 break;
2388
2389 case SEEK_CUR:
2390 // Add pos to current offset.
2391 pos += fp->f_offset;
2392 break;
2393
2394 case SEEK_END:
2395 // Add pos to file size.
2396 pos += tftp->actual;
2397 break;
2398
2399 default:
2400 return EINVAL;
2401 }
2402
2403 // Check that pos is still within current file size, or at the
2404 // very end.
2405 if (pos < 0 || pos > tftp->actual)
2406 return EINVAL;
2407
2408 // All OK, set fp offset and return new position.
2409 *apos = fp->f_offset = pos;
2410
2411 return ENOERR;
2412 }
2413
2414 void usleep(int us)
2415 {
2416 if (us > 10000)
2417 cyg_thread_delay(us / 10000 + 1);
2418 else
2419 HAL_DELAY_US(us);
2420 }
2421
2422 // Chunked version.
2423 cyg_int32
2424 show_log_entry(CYG_HTTPD_STATE *phttpstate)
2425 {
2426 cyg_httpd_start_chunked("text");
2427 if (logCount >= logSize)
2428 {
2429 cyg_httpd_write_chunked(logBuffer+logCount%logSize, logSize-logCount%logSize);
2430 }
2431 cyg_httpd_write_chunked(logBuffer, writePtr);
2432 cyg_httpd_end_chunked();
2433 return -1;
2434 }
2435
2436 CYG_HTTPD_HANDLER_TABLE_ENTRY(show_log, "/ram/log", show_log_entry);
2437
2438 // Filesystem operations
2439 static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte);
2440 static int logfs_umount(cyg_mtab_entry *mte);
2441 static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2442 int mode, cyg_file *fte);
2443 static int
2444 logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
2445
2446 // File operations
2447 static int logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode);
2448 static int logfs_fo_close(struct CYG_FILE_TAG *fp);
2449
2450 #include <cyg/io/devtab.h>
2451
2452 //==========================================================================
2453 // Filesystem table entries
2454
2455 // -------------------------------------------------------------------------
2456 // Fstab entry.
2457 // This defines the entry in the filesystem table.
2458 // For simplicity we use _FILESYSTEM synchronization for all accesses since
2459 // we should never block in any filesystem operations.
2460 FSTAB_ENTRY( logfs_fste, "logfs", 0,
2461 CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,
2462 logfs_mount,
2463 logfs_umount,
2464 logfs_open,
2465 (cyg_fsop_unlink *)cyg_fileio_erofs,
2466 (cyg_fsop_mkdir *)cyg_fileio_erofs,
2467 (cyg_fsop_rmdir *)cyg_fileio_erofs,
2468 (cyg_fsop_rename *)cyg_fileio_erofs,
2469 (cyg_fsop_link *)cyg_fileio_erofs,
2470 (cyg_fsop_opendir *)cyg_fileio_erofs,
2471 (cyg_fsop_chdir *)cyg_fileio_erofs,
2472 (cyg_fsop_stat *)cyg_fileio_erofs,
2473 (cyg_fsop_getinfo *)cyg_fileio_erofs,
2474 (cyg_fsop_setinfo *)cyg_fileio_erofs);
2475
2476 // -------------------------------------------------------------------------
2477 // File operations.
2478 // This set of file operations are used for normal open files.
2479
2480 static cyg_fileops logfs_fileops =
2481 {
2482 (cyg_fileop_read *)cyg_fileio_erofs,
2483 (cyg_fileop_write *)logfs_fo_write,
2484 (cyg_fileop_lseek *) cyg_fileio_erofs,
2485 (cyg_fileop_ioctl *)cyg_fileio_erofs,
2486 cyg_fileio_seltrue,
2487 logfs_fo_fsync,
2488 logfs_fo_close,
2489 (cyg_fileop_fstat *)cyg_fileio_erofs,
2490 (cyg_fileop_getinfo *) cyg_fileio_erofs,
2491 (cyg_fileop_setinfo *)cyg_fileio_erofs,
2492 };
2493
2494 // -------------------------------------------------------------------------
2495 // logfs_mount()
2496 // Process a mount request. This mainly finds root for the
2497 // filesystem.
2498
2499 static int logfs_mount(cyg_fstab_entry *fste, cyg_mtab_entry *mte)
2500 {
2501 return ENOERR;
2502 }
2503
2504 static int logfs_umount(cyg_mtab_entry *mte)
2505 {
2506 return ENOERR;
2507 }
2508
2509 static int logfs_open(cyg_mtab_entry *mte, cyg_dir dir, const char *name,
2510 int mode, cyg_file *file)
2511 {
2512 file->f_flag |= mode & CYG_FILE_MODE_MASK;
2513 file->f_type = CYG_FILE_TYPE_FILE;
2514 file->f_ops = &logfs_fileops;
2515 file->f_offset = 0;
2516 file->f_data = 0;
2517 file->f_xops = 0;
2518 return ENOERR;
2519 }
2520
2521 // -------------------------------------------------------------------------
2522 // logfs_fo_write()
2523 // Write data to file.
2524
2525 static int
2526 logfs_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
2527 {
2528 int i;
2529 for (i = 0; i < uio->uio_iovcnt; i++)
2530 {
2531 cyg_iovec *iov = &uio->uio_iov[i];
2532 char *buf = (char *) iov->iov_base;
2533 off_t len = iov->iov_len;
2534
2535 diag_write(buf, len);
2536 }
2537 uio->uio_resid = 0;
2538
2539 return ENOERR;
2540 }
2541 static int
2542 logfs_fo_fsync(struct CYG_FILE_TAG *fp, int mode)
2543 {
2544 return ENOERR;
2545 }
2546
2547 // -------------------------------------------------------------------------
2548 // romfs_fo_close()
2549 // Close a file. We just clear out the data pointer.
2550
2551 static int logfs_fo_close(struct CYG_FILE_TAG *fp)
2552 {
2553 return ENOERR;
2554 }
2555
2556 static bool
2557 ramiodev_init( struct cyg_devtab_entry *tab )
2558 {
2559 return true;
2560 }
2561
2562 static Cyg_ErrNo
2563 ramiodev_bread( cyg_io_handle_t handle, void *buf, cyg_uint32 *len,
2564 cyg_uint32 pos)
2565 {
2566 if (*len+pos>ramblockdevice_size)
2567 {
2568 *len=ramblockdevice_size-pos;
2569 }
2570 memcpy(buf, ramblockdevice+pos, *len);
2571 return ENOERR;
2572 }
2573
2574 static Cyg_ErrNo
2575 ramiodev_bwrite( cyg_io_handle_t handle, const void *buf, cyg_uint32 *len,
2576 cyg_uint32 pos )
2577 {
2578 if (((pos%4)!=0)||(((*len)%4)!=0))
2579 {
2580 diag_printf("Unaligned write %d %d!", pos, *len);
2581 }
2582
2583 memcpy(ramblockdevice+pos, buf, *len);
2584 return ENOERR;
2585 }
2586
2587 static Cyg_ErrNo
2588 ramiodev_get_config( cyg_io_handle_t handle,
2589 cyg_uint32 key,
2590 void* buf,
2591 cyg_uint32* len)
2592 {
2593 switch (key) {
2594 case CYG_IO_GET_CONFIG_FLASH_ERASE:
2595 {
2596 if ( *len != sizeof( cyg_io_flash_getconfig_erase_t ) )
2597 return -EINVAL;
2598 {
2599 cyg_io_flash_getconfig_erase_t *e = (cyg_io_flash_getconfig_erase_t *)buf;
2600 char *startpos = ramblockdevice + e->offset;
2601
2602 if (((e->offset%(64*1024))!=0)||((e->len%(64*1024))!=0))
2603 {
2604 diag_printf("Erease is not aligned %d %d\n", e->offset, e->len);
2605 }
2606
2607 memset(startpos, 0xff, e->len);
2608
2609 e->flasherr = 0;
2610 }
2611 return ENOERR;
2612 }
2613 case CYG_IO_GET_CONFIG_FLASH_DEVSIZE:
2614 {
2615 if ( *len != sizeof( cyg_io_flash_getconfig_devsize_t ) )
2616 return -EINVAL;
2617 {
2618 cyg_io_flash_getconfig_devsize_t *d =
2619 (cyg_io_flash_getconfig_devsize_t *)buf;
2620
2621 d->dev_size = ramblockdevice_size;
2622 }
2623 return ENOERR;
2624 }
2625
2626 case CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE:
2627 {
2628 cyg_io_flash_getconfig_blocksize_t *b =
2629 (cyg_io_flash_getconfig_blocksize_t *)buf;
2630 if ( *len != sizeof( cyg_io_flash_getconfig_blocksize_t ) )
2631 return -EINVAL;
2632
2633 // offset unused for now
2634 b->block_size = 64*1024;
2635 return ENOERR;
2636 }
2637
2638 default:
2639 return -EINVAL;
2640 }
2641 }
2642
2643 static Cyg_ErrNo
2644 ramiodev_set_config( cyg_io_handle_t handle,
2645 cyg_uint32 key,
2646 const void* buf,
2647 cyg_uint32* len)
2648 {
2649
2650 switch (key) {
2651 default:
2652 return -EINVAL;
2653 }
2654 } // ramiodev_set_config()
2655
2656 // get_config/set_config should be added later to provide the other flash
2657 // operations possible, like erase etc.
2658
2659 BLOCK_DEVIO_TABLE( cyg_io_ramdev1_ops,
2660 &ramiodev_bwrite,
2661 &ramiodev_bread,
2662 0, // no select
2663 &ramiodev_get_config,
2664 &ramiodev_set_config
2665 );
2666
2667
2668 BLOCK_DEVTAB_ENTRY( cyg_io_ramdev1,
2669 "/dev/ram",
2670 0,
2671 &cyg_io_ramdev1_ops,
2672 &ramiodev_init,
2673 0, // No lookup required
2674 NULL );

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)