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