bootloader: menu is now displayed in all cases
[nios2ecos.git] / bootloader / bootloader / bootloader.cpp
blobe0fc2b3de637f20eeff88bdda1d57fdb9cf31560
1 //========================================================================
2 // ####ECOSGPLCOPYRIGHTBEGIN####
3 // -------------------------------------------
4 // This file is part of eCos, the Embedded Configurable Operating System.
5 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
6 //
7 // eCos is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 2 or (at your option) any later
10 // version.
12 // eCos is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with eCos; if not, write to the Free Software Foundation, Inc.,
19 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 // As a special exception, if other files instantiate templates or use
22 // macros or inline functions from this file, or you compile this file
23 // and link it with other works to produce a work based on this file,
24 // this file does not by itself cause the resulting work to be covered by
25 // the GNU General Public License. However the source code for this file
26 // must still be made available in accordance with section (3) of the GNU
27 // General Public License v2.
29 // This exception does not invalidate any other reasons why a work based
30 // on this file might be covered by the GNU General Public License.
31 // -------------------------------------------
32 // ####ECOSGPLCOPYRIGHTEND####
33 //========================================================================
34 #include <cyg/hal/io.h>
35 #include <cyg/hal/system.h>
37 #include <sys/stat.h>
40 #include "addresses.h"
41 #include "bootloader.h"
43 //#include <phi_network_support.h>
45 static char FIRMWARE_FILE[] = "/ram/firmware.phi";
46 static char BOOTLOADER_FILE[] = "/ram/bootloader.phi";
47 static char FPGA_FILE[] = "/ram/fpga.phi";
48 static char IP_FILE[] = "/config/ip";
49 static char MAC_FILE[] = "/config/mac";
50 static const int WRITE_BUF_SIZE = 4096;
51 static char WRITE_BUF[WRITE_BUF_SIZE];
53 int ser = -1;
54 FILE *ser_fp;
56 static void writeMac(cyg_uint8 mac[6]);
57 static void writeFile(const char *fileName, const char *string);
58 static bool hasMacAddress();
59 static void printMACAddress();
61 #define LENGTH 8
63 void cleaning()
65 fclose(ser_fp);
66 close(ser);
70 bool getChar(char *key)
72 fd_set rfds;
73 int retval;
75 /* Watch stdin (fd 0) to see when it has input. */
76 FD_ZERO(&rfds);
77 FD_SET(ser, &rfds);
79 retval = select(1, &rfds, NULL, NULL, NULL);
80 /* Don't rely on the value of tv now! */
81 if (retval)
83 if (FD_ISSET(ser, &rfds))
85 if (read(ser, key, 1) == 1)
87 return true;
91 return false;
94 bool waitChar1(int seconds, char *key)
96 fd_set rfds;
97 struct timeval tv;
98 int retval;
99 static char chr[1024];
101 /* Watch stdin (fd 0) to see when it has input. */
102 FD_ZERO(&rfds);
103 FD_SET(ser, &rfds);
104 /* Wait this long seconds. */
105 tv.tv_sec = seconds;
106 tv.tv_usec = 0;
108 retval = select(1, &rfds, NULL, NULL, &tv);
109 /* Don't rely on the value of tv now! */
110 if (retval)
112 if (FD_ISSET(ser, &rfds))
113 { // linux, for win see getChar
114 if (read(ser, chr, 1024) > 0)
116 *key = chr[0];
117 return true;
120 return true;
124 return false;
127 bool waitChar(int seconds, char *key)
129 fd_set rfds;
130 struct timeval tv;
131 int retval;
133 /* Watch stdin (fd 0) to see when it has input. */
134 FD_ZERO(&rfds);
135 FD_SET(ser, &rfds);
137 /* Wait this long seconds. */
138 tv.tv_sec = seconds;
139 tv.tv_usec = 0;
141 retval = select(1, &rfds, NULL, NULL, &tv);
142 /* Don't rely on the value of tv now! */
143 if (retval)
145 if (FD_ISSET(ser, &rfds))
147 if (read(ser, key, 1) == 1)
149 return true;
153 return false;
156 void reset(void)
158 fprintf(ser_fp, "Resetting\r\n");
159 umount("/config");
160 cleaning();
161 IOWR(REMOTE_UPDATE_BASE, 0x20, 0x1);
164 void openSerial()
166 ser = open(UART_0_NAME, O_RDWR|O_SYNC|O_NONBLOCK);
167 if (ser < 0)
169 diag_printf("Serial device problems %s\r\n", UART_0_NAME);
170 reset();
173 ser_fp = fdopen(ser, "r+");
175 if (ser_fp == NULL)
177 diag_printf("Serial device problems %s\r\n", UART_0_NAME);
178 reset();
182 void format(void)
184 fprintf(ser_fp, "Formatting JFFS2...\r\n");
185 int stat;
186 void *err_addr;
188 if ((stat = flash_init(0)) != 0)
190 fprintf(ser_fp, "Flash Error flash_init: \r\n");
193 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
194 if ((stat = flash_unlock((void *) EXT_FLASH_BASE, EXT_FLASH_SPAN,
195 (void **) &err_addr)) != 0)
197 fprintf(ser_fp, "Flash Error flash_unlock: %d\r\n", stat);
199 #endif
201 fprintf(ser_fp, "Formatting 0x%08x bytes\r\n", JFFS2_LENGTH);
202 if ((stat = flash_erase((void *) (EXT_FLASH_BASE + JFFS2_OFFSET), JFFS2_LENGTH,
203 (void **) &err_addr)) != 0)
205 fprintf(ser_fp, "Flash Error flash_erase: %d\r\n", stat);
208 fprintf(ser_fp, "Flash formatted successfully\r\n");
209 reset();
212 int firmwareFile, fpgaFile;
214 static bool expect(const char *string, bool resetOnFailure = true)
216 // fprintf(ser_fp, "Expecting \"%s\"\r\n", string);
217 for (size_t i = 0; i < strlen(string); i++)
219 char t;
220 if (read(firmwareFile, &t, 1) != 1)
222 fprintf(ser_fp, "Error: reading firmware file %d, expecting \"%s\"\r\n",
223 errno, string);
224 if (resetOnFailure)
226 reset();
228 else
230 lseek(firmwareFile, -1, SEEK_CUR);
231 return false;
234 if (t != string[i])
236 if (resetOnFailure)
238 fprintf(ser_fp,
239 "Unexpected data in firmware file while expecting \"%s\"\r\n",
240 string);
241 reset();
243 else
245 lseek(firmwareFile, -1, SEEK_CUR);
246 return false;
250 return true;
253 /* read integer which is terminated by whitespace or eof */
254 int readInt(void)
256 char buf[32];
257 size_t i;
258 i = 0;
259 for (;;)
261 if (i >= sizeof(buf))
263 fprintf(ser_fp, "Error: reading string. Too long %d\r\n", (int) i);
264 reset();
267 char t;
268 int actual;
269 actual = read(firmwareFile, &t, 1);
270 if (actual < 0)
272 fprintf(ser_fp, "Error: reading integer %d\r\n", errno);
273 reset();
275 if (actual == 1)
277 if (!isspace((int) t))
279 buf[i++] = t;
281 else
283 break;
286 else if (actual == 0)
288 break;
290 else
292 fprintf(ser_fp, "Error: reading integer\r\n");
293 reset();
296 buf[i] = 0;
297 return atoi(buf);
300 void appendPadding(char* buffer, int start, int length)
302 int i;
303 for (i = 0; i < length; i++)
305 buffer[start + i] = 0xFF;
309 static void upgradeBootloader()
311 /* Do we have a pending bootloader update? */
312 if ((firmwareFile = open(BOOTLOADER_FILE, O_RDONLY)) > 0)
314 fprintf(ser_fp, "Single shot bootloader update in progress\r\n");
316 /* if (!expect("ZylinPhiBootloader\r\n", false))
318 close(firmwareFile);
319 fprintf(ser_fp, "Corrupt bootloader image uploaded. Safely aborting bootloader update.\r\n");
320 remove(BOOTLOADER_FILE);
321 reset();
324 cyg_uint8 *bootloaderAddr = (cyg_uint8 *) (EXT_FLASH_BASE
325 + FACTORY_FPGA_OFFSET);
326 struct stat results;
328 if (stat(BOOTLOADER_FILE, &results) == 0)
330 fprintf(ser_fp, "size %ld\r\n", results.st_size);
333 printMACAddress();
334 bool hasMac = hasMacAddress();
336 int stat;
337 void *err_addr;
338 fprintf(ser_fp, "Erasing flash...");
339 if ((stat = flash_erase((void *) (bootloaderAddr), APPLICATION_FPGA_OFFSET
340 - FACTORY_FPGA_OFFSET, (void **) &err_addr)) != 0)
342 fprintf(ser_fp, "Error: erasing bootloader %p: %d\r\n", err_addr, stat);
343 reset();
345 fprintf(ser_fp, "done\r\n");
347 char buf[1024];
348 int actual;
349 while ((actual = read(firmwareFile, buf, sizeof(buf))) > 0)
351 int stat;
352 void *err_addr;
353 int rem = actual % LENGTH;
354 if (rem != 0)
356 rem = LENGTH - rem;
357 appendPadding(buf, actual, rem);
360 if ((stat
361 = FLASH_PROGRAM(bootloaderAddr, buf, actual + rem, (void **)&err_addr))
362 != 0)
364 fprintf(ser_fp, "Error: writing bootloader data at %p: %d\r\n", err_addr,
365 stat);
366 reset();
369 bootloaderAddr += actual;
372 close(firmwareFile);
374 if (actual < 0)
376 fprintf(ser_fp, "Error: catastrophic failure. Bootloader corrupt %d.\r\n",
377 errno);
378 remove(BOOTLOADER_FILE);
379 reset();
382 if (hasMac)
384 // FIX!!! This won't work. If we ever type the wrong mac number, we're screwed.
385 // fprintf(ser_fp, "Updating mac address");
386 // writeMac(mac);
389 fprintf(ser_fp, "Bootloader successfully updated.\r\n");
390 remove(BOOTLOADER_FILE);
391 reset();
395 static void upgradeFirmware()
397 /* Do we have a pending firmware update? */
398 if ((firmwareFile = open(FIRMWARE_FILE, O_RDONLY)) > 0)
400 fprintf(ser_fp, "Firmware update in progress\r\n");
402 /* if (!expect("ZylinPhiBootloader\r\n", false))
404 close(firmwareFile);
405 fprintf(ser_fp, "Corrupt bootloader image uploaded. Safely aborting bootloader update.\r\n");
406 remove(BOOTLOADER_FILE);
407 reset();
410 cyg_uint8 *firmwareAddr = (cyg_uint8 *) (EXT_FLASH_BASE
411 + APPLICATION_FPGA_OFFSET);
412 struct stat results;
414 if (stat(FIRMWARE_FILE, &results) == 0)
416 fprintf(ser_fp, "size %ld\r\n", results.st_size);
419 printMACAddress();
420 bool hasMac = hasMacAddress();
422 int stat;
423 void *err_addr;
424 fprintf(ser_fp, "Erasing flash...");
425 if ((stat = flash_erase((void *) (firmwareAddr), BOOTLOADER_OFFSET
426 - APPLICATION_FPGA_OFFSET, (void **) &err_addr)) != 0)
428 fprintf(ser_fp, "Error: erasing firmware %p: %d\r\n", err_addr, stat);
429 reset();
431 fprintf(ser_fp, "done\r\n");
433 char buf[1024];
434 int actual;
435 while ((actual = read(firmwareFile, buf, sizeof(buf))) > 0)
437 int stat;
438 void *err_addr;
439 int rem = actual % LENGTH;
440 if (rem != 0)
442 rem = LENGTH - rem;
443 appendPadding(buf, actual, rem);
446 if ((stat
447 = FLASH_PROGRAM(firmwareAddr, buf, actual + rem, (void **)&err_addr))
448 != 0)
450 fprintf(ser_fp, "Error: writing bootloader data at %p: %d\r\n", err_addr,
451 stat);
452 reset();
455 firmwareAddr += actual;
458 close(firmwareFile);
460 if (actual < 0)
462 fprintf(ser_fp, "Error: catastrophic failure. Bootloader corrupt %d.\r\n",
463 errno);
464 remove(FIRMWARE_FILE);
465 reset();
468 if (hasMac)
470 // FIX!!! This won't work. If we ever type the wrong mac number, we're screwed.
471 // fprintf(ser_fp, "Updating mac address");
472 // writeMac(mac);
475 fprintf(ser_fp, "Firmware successfully updated.\r\n");
476 remove(FIRMWARE_FILE);
477 reset();
481 static void upgradeFPGA(int start, int stop)
483 /* Do we have a pending FPGA update? */
484 if ((fpgaFile = open(FPGA_FILE, O_RDONLY)) > 0)
486 fprintf(ser_fp, "FPGA update in progress\r\n");
488 /* if (!expect("ZylinPhiBootloader\r\n", false))
490 close(firmwareFile);
491 fprintf(ser_fp, "Corrupt bootloader image uploaded. Safely aborting bootloader update.\r\n");
492 remove(BOOTLOADER_FILE);
493 reset();
496 cyg_uint8 *fpgaAddr = (cyg_uint8 *) (EXT_FLASH_BASE + start);
497 struct stat results;
499 if (stat(FPGA_FILE, &results) == 0)
501 fprintf(ser_fp, "size %ld\r\n", results.st_size);
504 printMACAddress();
505 bool hasMac = hasMacAddress();
507 int stat;
508 void *err_addr;
509 fprintf(ser_fp, "Erasing flash...from %0x size %0x", fpgaAddr, stop - start);
510 if ((stat = flash_erase((void *) (fpgaAddr), stop - start,
511 (void **) &err_addr)) != 0)
513 fprintf(ser_fp, "Error: erasing fpga %p: %d\r\n", err_addr, stat);
514 reset();
516 fprintf(ser_fp, "done\r\n");
518 char buf[1024];
519 int actual;
520 while ((actual = read(fpgaFile, buf, sizeof(buf))) > 0)
522 int stat;
523 void *err_addr;
525 int rem = actual % LENGTH;
526 if (rem != 0)
528 rem = LENGTH - rem;
529 appendPadding(buf, actual, rem);
532 fprintf(ser_fp, "%d\r\n", fpgaAddr);
533 if ((stat
534 = FLASH_PROGRAM(fpgaAddr, buf, actual + rem, (void **)&err_addr))
535 != 0)
537 fprintf(ser_fp, "Error: writing fpga data at %p: %d\r\n", err_addr, stat);
538 reset();
541 fpgaAddr += actual;
544 close(fpgaFile);
546 if (actual < 0)
548 fprintf(ser_fp, "Error: catastrophic failure. fpga corrupt %d.\r\n", errno);
549 remove(FPGA_FILE);
550 reset();
553 if (hasMac)
555 // FIX!!! This won't work. If we ever type the wrong mac number, we're screwed.
556 // fprintf(ser_fp, "Updating mac address");
557 // writeMac(mac);
560 fprintf(ser_fp, "FPGA successfully updated. %d\r\n", actual);
561 remove(FPGA_FILE);
562 reset();
566 // Read a string in from serial port and reset if
567 // anything goes wrong.
568 static void readLine(char *buffer,
569 // Including terminating \0
570 int maxLen)
572 int index = 0;
573 for (;;)
575 char c = 0;
576 getChar(&c);
577 switch (c)
579 case 0x3:
580 fprintf(ser_fp, "\r\nCtrl-c pressed\r\n");
581 reset();
582 case '\n':
583 case '\r':
584 if (index == 0)
586 fprintf(ser_fp, "\r\nEmpty string not allowed\r\n");
587 reset();
589 buffer[index] = '\0';
590 fprintf(ser_fp, "\r\n");
591 return;
592 // backspace
593 case 0x08:
594 if (index > 0)
596 index--;
597 fprintf(ser_fp, "%c %c", c, c);
599 break;
600 default:
601 if (index >= (maxLen - 1))
603 fprintf(ser_fp, "\r\nString too long\r\n");
604 reset();
606 fprintf(ser_fp, "%c", c);
607 buffer[index] = c;
608 index++;
609 break;
614 static void getFileName(char *name, int maxLen)
616 readLine(name, maxLen);
619 static void wrongMAC()
621 fprintf(ser_fp, "Wrong MAC address syntax\r\n");
622 reset();
625 static int getMacAddress(char* buffer)
627 buffer[0] = 0;
628 buffer[12] = 0;
630 int fd = open(MAC_FILE, O_RDONLY);
631 if (fd < 0)
633 fprintf(ser_fp, "Could not open %s\r\n", MAC_FILE);
634 return fd;
637 for (int i = 0; i < 12; i++)
639 char c;
640 int actual;
641 actual = read(fd, &c, 1);
642 if (actual < 0)
644 fprintf(ser_fp, "\r\nFailed while reading %s\r\n", MAC_FILE);
645 reset();
647 if (actual != 1)
648 break;
649 buffer[i] = c;
651 close(fd);
652 fprintf(ser_fp, "\r\n");
653 return fd;
657 static cyg_uint8 * transformMacAddress(char* buffer, cyg_uint8 mac_addr[6])
659 mac_addr[0] = 0;
660 mac_addr[1] = 0;
661 mac_addr[2] = 0;
662 mac_addr[3] = 0;
663 mac_addr[4] = 0;
664 mac_addr[5] = 0;
666 if (strlen(buffer) != 12)
668 wrongMAC();
671 for (size_t i = 0; i < strlen(buffer); i++)
673 char c = buffer[i];
674 if (('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c
675 <= 'F'))
677 cyg_uint32 val;
678 sscanf(&c, "%x", &val);
679 mac_addr[i / 2] += (val << (4 * ((i + 1) % 2)));
682 else
684 wrongMAC();
687 return mac_addr;
691 static bool hasMacAddress()
694 cyg_uint8* mac = (cyg_uint8 *) (EXT_FLASH_BASE + FACTORY_FPGA_OFFSET - 6);
695 int i;
696 cyg_uint8 ret = 0xFF;
697 for(int i = 0; i < 6; i++)
699 ret = ret & mac[i];
701 return ret != 0xFF;
705 static void printMACAddress()
707 if (hasMacAddress())
709 cyg_uint8* mac = (cyg_uint8 *) (EXT_FLASH_BASE + FACTORY_FPGA_OFFSET - 6);
710 fprintf(ser_fp, "Mac address %02x:%02x:%02x:%02x:%02x:%02x\r\n", mac[0],
711 mac[1], mac[2], mac[3], mac[4], mac[5]);
713 else
714 fprintf(ser_fp, "Mac address not set\r\n");
717 static void changeMac()
719 char mac[13];
720 cyg_uint8 ui_mac[6];
722 fprintf(ser_fp, "Enter the mac address in the format XXXXXXXXXXXX \r\n");
723 readLine(mac, sizeof(mac));
725 transformMacAddress(mac, ui_mac);
726 fprintf(ser_fp, "Mac address %02x:%02x:%02x:%02x:%02x:%02x\r\n", ui_mac[0],
727 ui_mac[1], ui_mac[2], ui_mac[3], ui_mac[4], ui_mac[5]);
729 int stat;
730 void *err_addr;
732 cyg_uint8 *macAddr = (cyg_uint8 *) (EXT_FLASH_BASE + FACTORY_FPGA_OFFSET - 6);
734 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
735 if ((stat = flash_unlock((void *) macAddr, 6,
736 (void **) &err_addr)) != 0)
738 fprintf(ser_fp, "Flash Error flash_unlock: %d\r\n", stat);
740 #endif
742 if ((stat = flash_erase((void *) (macAddr), 6, (void **) &err_addr)) != 0)
744 printf("Error: erasing bootloader %p: %d\n", err_addr, stat);
745 reset();
747 printf("erasing done\n");
749 if ((stat = FLASH_PROGRAM(macAddr, ui_mac, 6, (void **)&err_addr))
750 != 0)
752 printf("Error: writing bootloader data at %p: %d\n", err_addr, stat);
753 reset();
758 static void writeFile(const char *fileName, const char *string)
760 if (strlen(string) == 0)
762 unlink(fileName);
764 else
766 int fd = creat(fileName, O_CREAT | O_TRUNC);
767 if (fd < 0)
769 fprintf(ser_fp, "unable to create %s\r\n", fileName);
771 else
773 write(fd, string, strlen(string));
774 close(fd);
779 static void enterParameter()
781 char name[81];
782 char param[128];
783 //get IP
784 fprintf(ser_fp, "Enter file name: ");
785 readLine(name, sizeof(name));
786 fprintf(ser_fp, "Enter parameter: ");
787 readLine(param, sizeof(param));
788 writeFile(name, param);
792 static void showParameter()
794 char name[81];
795 //get IP
796 fprintf(ser_fp, "Enter filename: ");
797 readLine(name, sizeof(name));
799 int param;
800 if ((param = open(name, O_RDONLY)) < 0)
802 fprintf(ser_fp, "Could not open %s\r\n", name);
805 fprintf(ser_fp, "Displaying up to 1024 bytes of that parameter\r\n");
806 for (int i = 0; i < 1024; i++)
808 char c;
809 int actual;
810 actual = read(param, &c, 1);
811 if (actual < 0)
813 fprintf(ser_fp, "\r\nFailed while reading %s\r\n", name);
814 reset();
816 if (actual != 1)
817 break;
818 fprintf(ser_fp, "%c", c);
820 fprintf(ser_fp, "\r\n");
824 static void changeIP()
826 char ip[81];
827 //get IP
828 fprintf(ser_fp,
829 "\r\nEnter ip, mask and gateway(optional) (x.x.x.x,y.y.y.y[,z.z.z.z]): ");
830 readLine(ip, sizeof(ip));
831 writeFile(IP_FILE, ip);
834 static void ymodemUpload(const char *fileName)
836 int err = 0;
838 fprintf(ser_fp, "Start Ymodem upload of %s\r\n", fileName);
840 connection_info_t connection;
841 memset(&connection, 0, sizeof(connection));
842 connection.mode = xyzModem_ymodem;
844 fprintf(ser_fp, "connection over %s\r\n", fileName);
846 if (xyzModem_stream_open(&connection, &err) == 0)
848 firmwareFile = creat(fileName, O_TRUNC | O_CREAT);
849 if (firmwareFile < 0)
851 int t = errno;
853 // close yModem connection so we can see error message in HyperTerminal
854 int moreError;
855 xyzModem_stream_close(&moreError);
857 fprintf(ser_fp, "Could not create firmware file %d\r\n", t);
858 reset();
861 int err;
862 bool ok = false;
863 bool abortedByWrite = false;
865 /* make sure we don't write too small blocks as this will
866 * increase memory usage catastrophically when reading the file
868 int actual;
869 int pos = 0;
870 int ii = 0;
871 for (;;)
873 err = 0;
874 actual = xyzModem_stream_read(WRITE_BUF + pos, sizeof(WRITE_BUF)
875 - pos, &err);
876 if (actual < 0)
878 break;
881 if (((actual == 0) && (pos > 0)) || ((actual + pos)
882 > (WRITE_BUF_SIZE - 0x100)))
884 int written = write(firmwareFile, WRITE_BUF, actual + pos);
885 if (written < (actual + pos))
887 fprintf(ser_fp, "Writing %s failed %d\r\n", fileName, errno);
888 abortedByWrite = true;
889 break;
891 pos = 0;
893 else
895 pos += actual;
897 if (actual == 0)
899 break;
903 int moreError;
904 xyzModem_stream_close(&moreError);
906 if ((!abortedByWrite) && (actual == 0) && (err == 0))
908 fprintf(ser_fp, "\r\nFirmware successfully uploaded\r\n");
909 ok = true;
912 close(firmwareFile);
914 if (!ok)
916 remove(fileName);
917 if (!abortedByWrite)
919 fprintf(ser_fp, "\r\nFirmware upload failed: %s\r\n", xyzModem_error(err));
925 static void selectFile(char *fileName)
927 int index = 0;
928 char *names[10]; //max 10 files
929 DIR* fs = opendir("/config");
930 char key = 0;
931 for (index = 0; index < 10;)
933 struct dirent *entry = readdir(fs);
934 int len = 0;
935 if (entry == NULL)
936 break;
937 len = strlen(entry->d_name);
938 if (len > 4 && (entry->d_name[len - 4] == '.' && ((entry->d_name[len
939 - 3] == 'p' && entry->d_name[len - 2] == 'h'
940 && entry->d_name[len - 1] == 'i') || (entry->d_name[len - 3]
941 == 'z' && entry->d_name[len - 2] == 'p' && entry->d_name[len
942 - 1] == 'u'))))
944 fprintf(ser_fp, "%d. %s\r\n", index, entry->d_name);
945 names[index] = (char *) malloc(strlen(entry->d_name) + 1);
946 if (names[index] == NULL)
948 fprintf(ser_fp, "ERROR, not enough memory. Resetting...");
949 reset();
951 strcpy(names[index], entry->d_name);
952 index++;
955 fprintf(ser_fp, "Type in the index of the file you want to select (0 - %d)", index
956 - 1);
957 getChar(&key);
958 if (!(key >= '0' && key <= '9' || key - '0' > index - 1))
960 fprintf(ser_fp, "No such app\r\n");
961 reset();
963 fprintf(ser_fp, "\r\n");
965 strcpy(fileName, "/config/");
966 strcat(fileName, names[key - '0']);
969 void mountJFFS2()
971 Cyg_ErrNo err = 0;
972 err = cyg_flash_init(NULL);
973 if (err)
975 fprintf(ser_fp, "cyg_flash_init error %d\r\n ", err);
978 cyg_flashaddr_t err_address;
980 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
981 if ((err = flash_unlock((void *) EXT_FLASH_BASE, EXT_FLASH_SPAN,
982 (void **) &err_address)) != 0)
984 fprintf(ser_fp, "Flash Error flash_unlock: %d\r\n", err);
985 return;
987 #endif
989 // std::ostringstream s;
990 // s << "/dev/flash/0/" << JFFS2_OFFSET << "," << JFFS2_LENGTH;
992 std::string fis = "/dev/flash/0/";
993 char number[9];
994 number[8] = 0;
995 sprintf(number, "0X%0x", JFFS2_OFFSET);
996 fis += number;
997 fis += ",";
998 sprintf(number, "0X%0x", JFFS2_LENGTH);
999 fis += number;
1000 fprintf(ser_fp, "%s\r\n", fis.c_str());
1002 err = mount(fis.c_str(), "/config", "jffs2");
1004 if (err < 0)
1006 fprintf(ser_fp, "JFFS2 mounting error %d\r\n", err);
1007 format();
1009 fprintf(ser_fp, "mounted jffs2\r\n");
1012 void mountRamFS()
1014 Cyg_ErrNo err = 0;
1016 err = mount("", "/ram", "ramfs");
1018 if (err < 0)
1020 fprintf(ser_fp, "RAMFS mounting error %d\r\n", err);
1021 format();
1023 fprintf(ser_fp, "mounted ramfs just fine\r\n");
1024 fprintf(ser_fp, "testing file write/read/delete\r\n");
1025 FILE* pf = fopen("/ram/tralala.txt", "w+");
1026 if (pf == NULL)
1028 fprintf(ser_fp, "unable to create/open file\r\n");
1029 return;
1031 fclose(pf);
1034 void printAvailableRAM()
1036 struct mallinfo info;
1037 info = mallinfo();
1038 fprintf(ser_fp, "Available RAM: %d\r\n", info.fordblks);
1041 int menu()
1043 char fileName[NAME_MAX];
1045 fprintf(ser_fp, "Bootloader. Copyright FSF 2006-2010 All rights reserved\r\n");
1046 fprintf(ser_fp, "Version unknown %s %s\r\n", __DATE__, __TIME__);
1048 // cyg_exception_handler_t *old;
1049 // cyg_addrword_t oldData;
1050 // cyg_exception_set_handler(CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION, exception_handler, 0, &old, &oldData);
1051 // cyg_exception_set_handler(CYGNUM_HAL_VECTOR_ABORT_PREFETCH, exception_handler, 0, &old, &oldData);
1052 // cyg_exception_set_handler( CYGNUM_HAL_VECTOR_ABORT_DATA, exception_handler, 0, &old, &oldData);
1054 mountJFFS2();
1055 mountRamFS();
1057 printMACAddress();
1059 printAvailableRAM();
1061 //extern void phi_init_all_network_interfaces(void);
1062 // CYGPKG_PHI_NET
1063 // phi_init_all_network_interfaces();
1066 start_menu:
1068 fprintf(ser_fp, "Press <space> for advanced help\r\n");
1069 if (hasMacAddress())
1071 fprintf(ser_fp, "Press <i> to set static IP address\r\n");
1072 fprintf(ser_fp, "Press <enter> to start Ymodem upload of firmware\r\n");
1074 else
1076 fprintf(ser_fp, "Press <m> to set MAC address\r\n");
1079 //use default firmware file name
1080 strcpy(fileName, FIRMWARE_FILE);
1081 char key;
1082 waitMoreChar: if (waitChar(2, &key))
1084 switch (key)
1086 case 'S':
1087 selectFile(fileName);
1088 break;
1089 case 'F':
1090 format();
1091 reset();
1092 break;
1093 case 'i':
1094 case 'I':
1095 changeIP();
1096 reset();
1097 case 'P':
1098 enterParameter();
1099 goto start_menu;
1100 case 'D':
1101 showParameter();
1102 goto start_menu;
1103 case 'E':
1104 fprintf(ser_fp, "File name: ");
1105 getFileName(fileName, sizeof(fileName));
1106 ymodemUpload(fileName);
1107 reset();
1108 case '\r':
1109 fprintf(ser_fp, "Default firmware file update\r\n");
1110 ymodemUpload(FIRMWARE_FILE); //fall through
1111 break;
1112 case 'Y':
1113 fprintf(ser_fp, "Single shot bootloader update\r\n");
1114 ymodemUpload(BOOTLOADER_FILE); //fall through
1115 break;
1116 case 'A':
1117 fprintf(ser_fp, "FPGA image update\r\n");
1118 ymodemUpload(FPGA_FILE); //fall through
1119 break;
1120 case ' ':
1121 fprintf(ser_fp, "Press <F> format flash\r\n");
1122 fprintf(ser_fp,
1123 "Press <E> to start Ymodem upload of firmware to a specified file name\r\n");
1124 fprintf(ser_fp, "Press <Y> to start single shot update of bootloader\r\n");
1125 fprintf(ser_fp, "Press <A> to start update of FPGA image\r\n");
1126 fprintf(ser_fp, "Press <P> set parameter\r\n");
1127 fprintf(ser_fp, "Press <D> show parameter\r\n");
1128 goto waitMoreChar;
1130 default:
1131 /* ignore unknown keys... */
1132 break;
1134 if(!hasMacAddress())
1136 if ((key == 'M') || (key == 'm'))
1138 changeMac();
1143 upgradeFPGA(FACTORY_FPGA_OFFSET, APPLICATION_FPGA_OFFSET);
1144 upgradeBootloader();
1145 upgradeFirmware();
1147 if (!hasMacAddress())
1149 /* do not allow running application without mac address */
1150 //reset();
1153 umount("/config");
1154 umount("/ram");
1156 return 0;
1159 /********************************************************************************
1160 * Function: CycloneIII_Reconfig
1161 * Purpose: Uses the ALT_REMOTE_UPDATE megafunction to reconfigure a Cyclone III FPGA.
1162 * Parameters:
1163 * remote_update_base - base address of the remote update controller
1164 * flash_base - base address of flash device
1165 * reconfig_offset - offset in flash from which to reconfigure
1166 * watchdog_timeout - 29-bit watchdog timeout value
1167 * width_of_flash - data-width of flash device
1168 * Returns: 0 ( but never exits since it reconfigures the FPGA )
1169 ****************************************************************************/
1170 int CycloneIIIReconfig(int remote_update_base, int flash_base,
1171 int reconfig_offset, int watchdog_timeout, int width_of_flash)
1173 int offset_shift, addr;
1174 int tmp;
1175 // Obtain upper 12 bits of 29-bit watchdog timeout value
1176 watchdog_timeout = watchdog_timeout >> 17;
1177 // Only enable the watchdog timer if its timeout value is greater than 0.
1178 if (watchdog_timeout > 0)
1180 // Set the watchdog timeout value
1181 IOWR( remote_update_base, 0x2, watchdog_timeout );
1183 else
1185 // Disable the watchdog timer
1186 IOWR( remote_update_base, 0x3, 0 );
1189 tmp = IORD( remote_update_base, 0x0 );
1191 tmp = IORD( remote_update_base, 0xF );
1193 // Calculate how much to shift the reconfig offset location:
1194 // width_of_flash == 8->offset_shift = 2.
1195 // width_of_flash == 16->offset_shift = 3
1196 offset_shift = ((width_of_flash / 8) + 1);
1197 // Write the offset of the desired reconfiguration image in flash
1198 IOWR( remote_update_base, 0x4, reconfig_offset >> offset_shift );
1200 addr = IORD( remote_update_base, 0x4);
1201 // Perform the reconfiguration by setting bit 0 in the
1202 // control/status register
1203 IOWR( remote_update_base, 0x20, 0x1 );
1204 return (0);
1207 int needReset()
1209 int tmp = IORD(REMOTE_UPDATE_BASE, 0x0);
1210 return !tmp;
1213 int main()
1215 openSerial();
1217 fprintf(ser_fp, "Main\r\n");
1219 if (needReset())
1221 menu();
1223 fprintf(ser_fp, "Reconfigure and reboot\r\n");
1224 cleaning();
1225 CycloneIIIReconfig(REMOTE_UPDATE_BASE, EXT_FLASH_BASE,
1226 APPLICATION_FPGA_OFFSET, 0, 16);
1228 // launch application!
1229 fprintf(ser_fp, "Jump to deflate application\r\n");
1230 cleaning();
1231 cyg_interrupt_disable();
1232 ((void(*)(void)) (EXT_FLASH_BASE + DEFLATOR_OFFSET))();
1233 for (;;)
1234 ; // never reached