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