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