RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / cfe / cfe / ui / ui_flash.c
blobe8aa30fe85225bb02415d153dc87ff927de4a7bc
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Flash Update commands File: ui_flash.c
5 *
6 * The routines in this file are used for updating the
7 * flash with new firmware.
8 *
9 * Author: Mitch Lichtenberg (mpl@broadcom.com)
11 *********************************************************************
13 * Copyright 2000,2001,2002,2003
14 * Broadcom Corporation. All rights reserved.
16 * This software is furnished under license and may be used and
17 * copied only in accordance with the following terms and
18 * conditions. Subject to these conditions, you may download,
19 * copy, install, use, modify and distribute modified or unmodified
20 * copies of this software in source and/or binary form. No title
21 * or ownership is transferred hereby.
23 * 1) Any source code used, modified or distributed must reproduce
24 * and retain this copyright notice and list of conditions
25 * as they appear in the source file.
27 * 2) No right is granted to use any trade name, trademark, or
28 * logo of Broadcom Corporation. The "Broadcom Corporation"
29 * name may not be used to endorse or promote products derived
30 * from this software without the prior written permission of
31 * Broadcom Corporation.
33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGE.
46 ********************************************************************* */
48 #include "lib_types.h"
49 #include "lib_string.h"
50 #include "lib_queue.h"
51 #include "lib_malloc.h"
52 #include "lib_printf.h"
54 #include "cfe_iocb.h"
55 #include "cfe_devfuncs.h"
56 #include "cfe_ioctl.h"
57 #include "cfe_timer.h"
58 #include "cfe_error.h"
60 #include "ui_command.h"
61 #include "cfe.h"
63 #include "cfe_fileops.h"
64 #include "cfe_boot.h"
65 #include "bsp_config.h"
67 #include "cfe_loader.h"
69 #include "net_ebuf.h"
70 #include "net_ether.h"
71 #include "net_api.h"
73 #include "cfe_flashimage.h"
75 #include "addrspace.h"
76 #include "initdata.h"
77 #include "url.h"
80 /* *********************************************************************
81 * Constants
82 ********************************************************************* */
85 * Of course, these things really belong somewhere else.
88 #define FLASH_STAGING_BUFFER CFG_FLASH_STAGING_BUFFER_ADDR
89 #ifdef _FLASHPROG_
90 #define FLASH_STAGING_BUFFER_SIZE (1024*1024*16)
91 #else
92 #define FLASH_STAGING_BUFFER_SIZE CFG_FLASH_STAGING_BUFFER_SIZE
93 #endif
95 #ifdef RESCUE_MODE
96 #include <bcmnvram.h>
97 #define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
98 #define NVRAM_MAGIC_MAC0 0x3043414D /* 'MAC0' Added by PaN */
99 #define NVRAM_MAGIC_MAC1 0x3143414D /* 'MAC1' Added by PaN */
100 #define NVRAM_MAGIC_RDOM 0x4D4F4452 /* 'RDOM' Added by PaN */
101 #define NVRAM_MAGIC_ASUS 0x53555341 /* 'ASUS' Added by PaN */
102 #define NVRAM_MAGIC_SCODE 0x45444F4353 /* 'SCODE' Added by Yen */
103 extern int send_rescueack(unsigned short no, unsigned short lo);
104 void replace(uint8_t *bootbuf, char *keyword, uint8_t *value);
105 #endif
107 /* *********************************************************************
108 * Exerns
109 ********************************************************************* */
111 extern int cfe_iocb_dispatch(cfe_iocb_t *iocb);
113 int ui_init_flashcmds(void);
114 static int ui_cmd_flash(ui_cmdline_t *cmd,int argc,char *argv[]);
115 unsigned int flash_crc32(const unsigned char *databuf, unsigned int datalen);
116 void ui_get_flash_buf(uint8_t **bufptr, int *bufsize);
119 /* *********************************************************************
120 * ui_init_flashcmds()
122 * Initialize the flash commands, add them to the table.
124 * Input parameters:
125 * nothing
127 * Return value:
128 * 0 if ok, else error
129 ********************************************************************* */
131 int ui_init_flashcmds(void)
133 cmd_addcmd("flash",
134 ui_cmd_flash,
135 NULL,
136 "Update a flash memory device",
137 "flash [options] filename [flashdevice]\n\n"
138 "Copies data from a source file name or device to a flash memory device.\n"
139 "The source device can be a disk file (FAT filesystem), a remote file\n"
140 "(TFTP) or a flash device. The destination device may be a flash or eeprom.\n"
141 #if !CFG_EMBEDDED_PIC
142 "If the destination device is your boot flash (usually flash0), the flash\n"
143 "command will restart the firmware after the flash update is complete\n"
144 #endif
146 "-noerase;Don't erase flash before writing|"
147 #ifdef RESCUE_MODE
148 "-norescue;Don't check anything|"
149 #endif
150 "-offset=*;Begin programming at this offset in the flash device|"
151 "-size=*;Size of source device when programming from flash to flash|"
152 "-noheader;Override header verification, flash binary without checking|"
153 #if CFE_FLASH_ERASE_FLASH_ENABLED
154 "-forceflash;Dangerous Command, Don't use if you don't know what you do|"
155 "-erase;Erase the partition, can set the offset and length|"
156 #endif
157 #ifdef FLASH_PARTITION_FILL_ENABLED
158 "-fill;Fill the partition with char|"
159 #endif
160 "-mem;Use memory as source instead of a device");
163 return 0;
166 /* *********************************************************************
167 * flash_crc32(buf,len)
169 * Yes, this is an Ethernet CRC. I'm lazy.
171 * Input parameters:
172 * buf - buffer to CRC
173 * len - length of data
175 * Return value:
176 * CRC-32
177 ********************************************************************* */
179 #define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */
180 unsigned int
181 flash_crc32(const unsigned char *databuf, unsigned int datalen)
183 unsigned int idx, bit, data, crc = 0xFFFFFFFFUL;
185 for (idx = 0; idx < datalen; idx++) {
186 for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) {
187 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0);
191 return crc;
194 /* *********************************************************************
195 * flash_validate(ptr)
197 * Validate the flash header to make sure we can program it.
199 * Input parameters:
200 * ptr - pointer to flash header
201 * outptr - pointer to data that we should program
202 * outsize - size of data we should program
204 * Return value:
205 * 0 if ok
206 * else error occured
207 ********************************************************************* */
209 #define GET32(x) (((uint32_t) (x[0] << 24)) | \
210 ((uint32_t) (x[1] << 16)) | \
211 ((uint32_t) (x[2] << 8)) | \
212 ((uint32_t) (x[3] << 0)))
214 static int flash_validate(uint8_t *ptr,int bufsize,int insize,uint8_t **outptr,int *outsize)
216 cfe_flashimage_t *hdr = (cfe_flashimage_t *) ptr;
217 uint32_t size;
218 uint32_t flags;
219 uint32_t hdrcrc;
220 uint32_t calccrc;
222 if (memcmp(hdr->seal,CFE_IMAGE_SEAL,sizeof(hdr->seal)) != 0) {
223 printf("Invalid header seal. This is not a CFE flash image.\n");
224 return -1;
227 printf("Flash image contains CFE version %d.%d.%d for board '%s'\n",
228 hdr->majver,hdr->minver,hdr->ecover,hdr->boardname);
230 size = GET32(hdr->size);
231 flags = GET32(hdr->flags);
232 hdrcrc = GET32(hdr->crc);
233 printf("Flash image is %d bytes, flags %08X, CRC %08X\n",size,flags,hdrcrc);
235 if (strcmp(CFG_BOARDNAME,(int8_t *)hdr->boardname) != 0) {
236 printf("This flash image is not appropriate for board type '%s'\n",CFG_BOARDNAME);
237 return -1;
240 if ((size == 0) || (size > bufsize) ||
241 ((size + sizeof(cfe_flashimage_t)) < insize)) {
242 printf("Flash image size is bogus!\n");
243 return -1;
246 calccrc = flash_crc32(ptr + sizeof(cfe_flashimage_t),size);
248 if (calccrc != hdrcrc) {
249 printf("CRC is incorrect. Calculated CRC is %08X\n",calccrc);
250 return -1;
253 *outptr = ptr + sizeof(cfe_flashimage_t);
254 *outsize = size;
255 return 0;
259 /* *********************************************************************
260 * ui_get_flashbuf(bufptr, bufsize)
262 * Figure out the location and size of the staging buffer.
264 * Input parameters:
265 * bufptr - address to return buffer location
266 * bufsize - address to return buffer size
267 ********************************************************************* */
270 void ui_get_flash_buf(uint8_t **bufptr, int *bufsize)
272 int size = FLASH_STAGING_BUFFER_SIZE;
275 * Get the address of the staging buffer. We can't
276 * allocate the space from the heap to store the
277 * new flash image, because the heap may not be big
278 * enough. So, if FLASH_STAGING_BUFFER_SIZE is non-zero
279 * then just use it and FLASH_STAGING_BUFFER; else
280 * use the larger of (mem_bottomofmem - FLASH_STAGING_BUFFER)
281 * and (mem_totalsize - mem_topofmem).
284 if (size > 0) {
285 *bufptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER);
286 *bufsize = size;
287 } else {
288 int below, above;
290 below = PHYSADDR(mem_bottomofmem) - FLASH_STAGING_BUFFER;
291 above = (mem_totalsize << 10) - PHYSADDR(mem_topofmem);
293 if (below > above) {
294 *bufptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER);
295 *bufsize = below;
296 } else {
297 *bufptr = (uint8_t *) KERNADDR(mem_topofmem);
298 *bufsize = above;
303 #ifdef RESCUE_MODE
304 void replace(uint8_t *bootbuf, char *keyword, uint8_t *value)
306 int addr=0, addr_i=0, addr_j=0, idx=0;
307 int wordlen=strlen(keyword);
308 char addr_buf[wordlen];
311 for(addr_i=0;addr_i<strlen(keyword);addr_i++)
313 addr_buf[0x0+addr_i]=bootbuf[0x0000+addr+addr_i];
315 addr_buf[wordlen]=0x00;
316 addr++;
318 while (!(strcmp(addr_buf, keyword)==0));
319 if(strcmp(keyword, "secret_code") == 0)
320 idx = 8;
321 else if (strcmp(keyword, "regulation_domain") == 0)
322 idx = 6;
323 else
324 idx = 17;
326 for (addr_j=0 ; addr_j < idx ; addr_j++)
328 bootbuf[0x0000+addr+addr_j+strlen(keyword)] = value[0x0+addr_j];
331 #endif
333 #ifdef CFG_NFLASH
334 static void ui_check_flashdev(char *in, char *out)
336 int i;
338 if (!in) {
339 strcpy(out, "flash0.0");
340 return;
342 for (i=0 ; i< strlen(in) ; i++) {
343 if (strncmp(in+i, ".trx2", 5) == 0) {
344 /* Program the trx image */
345 ui_get_trx_flashdev(out);
346 strcat(out,"2");
347 return;
349 if (strncmp(in+i, ".trx", 4) == 0) {
350 /* Program the trx image */
351 ui_get_trx_flashdev(out);
352 return;
354 if (strncmp(in+i, ".boot", 5) == 0) {
355 /* Program the trx image */
356 ui_get_boot_flashdev(out);
357 return;
360 strcpy(out, in);
361 return;
363 #endif /* CFG_NFLASH */
365 #ifdef CFE_FLASH_ERASE_FLASH_ENABLED
366 static int erase_range(char *flashdev, int start, int len)
368 flash_range_t range;
369 int fh;
371 range.range_base = start;
372 range.range_length = len;
373 fh = cfe_open(flashdev);
374 if (fh < 0) {
375 xprintf("Could not open device '%s'\n",flashdev);
376 return CFE_ERR_DEVNOTFOUND;
378 if (cfe_ioctl(fh,IOCTL_FLASH_ERASE_RANGE,
379 (uint8_t *) &range,sizeof(range),NULL,0) != 0) {
380 xprintf("Failed to erase the flash\n");
381 cfe_close(fh);
382 return CFE_ERR_IOERR;
384 cfe_close(fh);
385 return 0;
387 #endif
389 #ifdef FLASH_PARTITION_FILL_ENABLED
390 static int fill_partition(char *flashdev, char *ptr, int bufsize, char c)
392 int fh=-1;
393 flash_info_t flashinfo;
394 int erased_size=0;
396 printf("filling %s with %x \n", flashdev, c);
397 fh = cfe_open(flashdev);
398 if (fh < 0) {
399 xprintf("Could not open device '%s'\n",flashdev);
400 return CFE_ERR_DEVNOTFOUND;
403 if (cfe_ioctl(fh,IOCTL_FLASH_PARTITION_INFO,
404 (unsigned char *) &flashinfo,
405 sizeof(flash_info_t),
406 NULL,0) == 0) {
407 printf("flash base=%llx, size=%x\n", flashinfo.flash_base, flashinfo.flash_size);
410 memset(ptr, c, bufsize);
411 erased_size = cfe_writeblk(fh, 0, (unsigned char *)ptr, flashinfo.flash_size);
412 if(erased_size == flashinfo.flash_size) {
413 xprintf("Fill Done!!\n");
414 } else {
415 xprintf("Fill Failed!!!\n");
417 cfe_close(fh);
418 return 0;
421 #endif
423 /* *********************************************************************
424 * ui_cmd_flash(cmd,argc,argv)
426 * The 'flash' command lives here. Program the boot flash,
427 * or if a device name is specified, program the alternate
428 * flash device.
430 * Input parameters:
431 * cmd - command table entry
432 * argc,argv - parameters
434 * Return value:
435 * 0 if ok
436 * else error
437 ********************************************************************* */
440 static int ui_cmd_flash(ui_cmdline_t *cmd,int argc,char *argv[])
442 uint8_t *ptr = NULL;
443 int fh;
444 int res;
445 #if !CFG_EMBEDDED_PIC
446 int retlen;
447 #endif
448 char *fname;
449 char *flashdev;
450 cfe_loadargs_t la;
451 int amtcopy;
452 int devtype;
453 int srcdevtype;
454 int chkheader;
455 int sfd;
456 int copysize;
457 flash_info_t flashinfo;
458 int offset = 0;
459 int noerase = 0;
460 int memsrc = 0; /* Source is memory address */
461 char *x;
462 int size = 0;
463 int bufsize = 0;
464 #ifdef CFG_NFLASH
465 char buf[16];
466 #endif
467 #ifdef RESCUE_MODE
468 int norescue = 0;
469 uint8_t bootbuf[0x40000];
470 uint8_t MAC0[18], RDOM[7], secretcode[9];
471 int i = 0, parseflag=0, j=0;
472 char *et0mac="et0macaddr";
473 char *reg_dom="regulation_domain";
474 char *il0mac="macaddr"; // For BCM4718 series
475 char *scode = "secret_code";
476 uint8_t SCODE[5] = {0x53, 0x43, 0x4F, 0x44, 0x45};
477 #endif // RESCUE_MODE
479 /* Get staging buffer */
480 memsrc = cmd_sw_isset(cmd,"-mem");
482 /* If memory is not being used as a source, then get staging buffer */
483 if (!memsrc)
484 ui_get_flash_buf(&ptr, &bufsize);
486 #ifdef CFE_FLASH_ERASE_FLASH_ENABLED
487 int erase_op = cmd_sw_isset(cmd, "-erase");
488 if (erase_op) {
489 flashdev = cmd_getarg(cmd, 0);
490 if (flashdev == NULL) return CFE_ERR_INV_PARAM;
491 if (!strncmp(flashdev, "flash0.boot", 30) || !strncmp(flashdev, "flash1.boot", 30)) {
492 xprintf("!! Erase the boot sector is dangerous!!:");
493 int forceflash = cmd_sw_isset(cmd,"-forceflash");
494 if (!forceflash) {
495 xprintf("Reject !!\n");
496 return CFE_ERR_INV_PARAM;
499 char *ss = cmd_getarg(cmd, 1);
500 /* 0 start address and 0 len viewed as erase whole partiton */
501 if (ss == NULL) {
502 erase_range(flashdev, 0, 0);
503 return CFE_OK;
505 char *ll = cmd_getarg(cmd, 2);
506 if (ll == NULL) {
507 xprintf("Please specify the len !!\n");
508 return CFE_ERR_INV_PARAM;
510 int start = atoi(ss);
511 int len = atoi(ll);
512 erase_range(flashdev, start, len);
513 return CFE_OK;
515 #endif
517 #ifdef FLASH_PARTITION_FILL_ENABLED
518 int fill_op = cmd_sw_isset(cmd,"-fill");
519 if(fill_op) {
520 char *c=0;
521 int h=0;
522 flashdev = cmd_getarg(cmd, 0);
523 if(flashdev==NULL) return CFE_ERR_INV_PARAM;
524 c = cmd_getarg(cmd, 1);
525 if(c != NULL) {
526 h = atoi(c);
528 fill_partition(flashdev, ptr, bufsize, h);
529 return CFE_OK;
531 #endif
533 * Parse command line parameters
536 fname = cmd_getarg(cmd,0);
538 if (!fname) {
539 return ui_showusage(cmd);
542 flashdev = cmd_getarg(cmd,1);
543 if (!flashdev) flashdev = "flash0.0";
544 #ifdef CFG_NFLASH
545 ui_check_flashdev(flashdev, buf);
546 flashdev = buf;
547 #endif
549 * Make sure it's a flash device.
552 res = cfe_getdevinfo(flashdev);
553 if (res < 0) {
554 return ui_showerror(CFE_ERR_DEVNOTFOUND,flashdev);
557 devtype = res & CFE_DEV_MASK;
559 if ((res != CFE_DEV_FLASH) && (res != CFE_DEV_NVRAM)) {
560 xprintf("Device '%s' is not a flash or eeprom device.\n",flashdev);
561 return CFE_ERR_INV_PARAM;
565 * We shouldn't really allow this, but there are some circumstances
566 * where you might want to bypass the header check and shoot
567 * yourself in the foot.
568 * Switch normally not supplied, so chkheader will be TRUE.
571 chkheader = !cmd_sw_isset(cmd,"-noheader");
574 * Check for some obscure options here.
577 noerase = cmd_sw_isset(cmd,"-noerase");
579 #ifdef RESCUE_MODE
580 norescue = cmd_sw_isset(cmd,"-norescue");
581 #endif
583 if (cmd_sw_value(cmd,"-offset",&x)) {
584 offset = atoi(x);
587 if (cmd_sw_value(cmd,"-size",&x)) {
588 size = atoi(x);
591 /* Fix up the ptr and size for reading from memory
592 * and skip loading to go directly to programming
594 if (memsrc) {
595 ptr = (uint8_t *)xtoi(fname);
596 bufsize = size;
597 res = size;
598 xprintf("Reading from %s: ",fname);
599 goto program;
603 * Read the new flash image from the source device
606 srcdevtype = cfe_getdevinfo(fname) & CFE_DEV_MASK;
608 xprintf("Reading %s: ",fname);
610 switch (srcdevtype) {
611 case CFE_DEV_FLASH:
612 sfd = cfe_open(fname);
613 if (sfd < 0) {
614 return ui_showerror(sfd,"Could not open source device");
616 memset(ptr,0xFF,bufsize);
619 if (cfe_ioctl(sfd,IOCTL_FLASH_GETINFO,
620 (unsigned char *) &flashinfo,
621 sizeof(flash_info_t),
622 &res,0) != 0) {
623 flashinfo.flash_size = bufsize;
626 if (size > 0) {
627 xprintf("(size=0x%X) ",size);
629 else {
630 size = flashinfo.flash_size;
633 /* Make sure we don't overrun the staging buffer */
635 if (size > bufsize) {
636 size = bufsize;
639 /* Read the flash device here. */
641 res = cfe_read(sfd,ptr,size);
643 cfe_close(sfd);
644 if (res < 0) {
645 return ui_showerror(res,"Could not read from flash");
647 chkheader = FALSE; /* no header to check */
649 * Search for non-0xFF byte at the end. This will work because
650 * flashes get erased to all FF's, we pre-fill our buffer to FF's,
652 while (res > 0) {
653 if (ptr[res-1] != 0xFF) break;
654 res--;
656 break;
658 case CFE_DEV_SERIAL:
659 la.la_filesys = "raw";
660 la.la_filename = NULL;
661 la.la_device = fname;
662 la.la_address = (intptr_t) ptr;
663 la.la_options = 0;
664 la.la_maxsize = bufsize;
665 la.la_flags = LOADFLG_SPECADDR;
667 res = cfe_load_program("srec",&la);
669 if (res < 0) {
670 ui_showerror(res,"Failed.");
671 return res;
673 break;
675 default:
677 res = ui_process_url(fname, cmd, &la);
678 if (res < 0) {
679 ui_showerror(res,"Invalid file name %s",fname);
680 return res;
683 la.la_address = (intptr_t) ptr;
684 la.la_options = 0;
685 la.la_maxsize = bufsize;
686 la.la_flags = LOADFLG_SPECADDR;
688 res = cfe_load_program("raw",&la);
690 if (res < 0) {
691 ui_showerror(res,"Failed.");
692 return res;
694 break;
698 xprintf("Done. %d bytes read\n",res);
700 program:
701 copysize = res;
703 #ifdef RESCUE_MODE
704 if (norescue == 0) {
705 if (copysize>0 && copysize<=0x40000) {
706 strcpy(flashdev, "flash1.boot");
707 for (i=0; i<0x40000; i++)
708 bootbuf[i] = (*(unsigned char *) (0xbfc00000+i));
709 if (
710 #ifdef COMPRESSED_CFE
711 (*(unsigned long *) (ptr+0x400) == NVRAM_MAGIC) && ( *(unsigned long *) (ptr) != NVRAM_MAGIC_MAC0)
712 #else
713 (*(unsigned long *) (ptr+0x1000) == NVRAM_MAGIC) && ( *(unsigned long *) (ptr) != NVRAM_MAGIC_MAC0)
714 #endif
715 && (*(unsigned long *) (ptr) != NVRAM_MAGIC_MAC1) && (*(unsigned long *) (ptr) != NVRAM_MAGIC_RDOM )
716 && (*(unsigned long *) (ptr) != NVRAM_MAGIC_ASUS )) {
717 xprintf(".Download of 0x%x bytes Completed\n", copysize);
718 xprintf("Write bootloader binary to FLASH (0xbfc00000)\n");
719 parseflag=1;
721 else if ( *(unsigned long *) (ptr) == NVRAM_MAGIC_MAC0 ) {
722 xprintf("Download of 0x%x bytes completed\n", copysize);
723 for (i=0; i<17; i++)
724 MAC0[i] = ptr[4+i];
725 MAC0[i]='\0';
726 /* Wait for SCODE by SJ_Yen */
727 i=i+4;
728 if ((ptr[i] == SCODE[0]) &&
729 (ptr [i+1] == SCODE[1]) &&
730 (ptr [i+2] == SCODE[2]) &&
731 (ptr [i+3] == SCODE[3]) &&
732 (ptr [i+4] == SCODE[4]) ) {
733 for (i = 26 ; i < 34; i++) {
734 secretcode[j] = ptr [i];
735 j++;
737 secretcode[j]='\0';
738 xprintf("Write secret code = %s to FLASH\n", secretcode);
739 replace(bootbuf, scode, secretcode);
740 nvram_set("secret_code", (int8_t *)secretcode);
741 nvram_commit();
743 /* End Yen */
745 replace(bootbuf, et0mac, MAC0);
746 replace(bootbuf, il0mac, MAC0);
748 xprintf("Write MAC0 = %s to FLASH \n", MAC0);
749 xprintf("set nvram: et0macaddr=%s\n", MAC0);
750 nvram_set("et0macaddr", (int8_t *)MAC0);
751 xprintf("set nvram: et0macaddr=%s\n", MAC0);
752 nvram_set("macaddr", (int8_t *)MAC0);
753 xprintf("nvram commit\n");
754 nvram_commit();
755 parseflag=2;
757 else if ( *(unsigned long *) (ptr) == NVRAM_MAGIC_RDOM ) {
758 for (i=0; i<6; i++)
759 RDOM[i] = ptr[4+i];
760 RDOM[i] = '\0';
761 replace(bootbuf, reg_dom, RDOM);
762 xprintf("Write RDOM = %s to FLASH \n", RDOM);
763 nvram_set("regulation_domain", (int8_t *)RDOM);
764 nvram_commit();
765 parseflag=3;
767 else {
768 parseflag=-1;
769 xprintf("Download of 0x%x bytes completed\n", copysize);
770 xprintf("Not valid nvram MAGIC at all !!\n");
771 copysize = 0;
774 else if (copysize>0x40000)
776 parseflag=0;
777 xprintf("Download of 0x%x bytes completed\n", copysize);
778 xprintf("Write kernel and filesystem binary to FLASH \n");
780 else {
781 parseflag=-1;
782 copysize = 0;
783 xprintf("Downloading image time out\n");
785 } // No-rescue
786 #endif // RESCUE_MODE
789 * Verify the header and file's CRC.
791 if (chkheader) {
792 if (flash_validate(ptr,bufsize,res,&ptr,&copysize) < 0) return -1;
795 if (copysize == 0) return 0; /* 0 bytes, don't flash */
798 * Open the destination flash device.
801 fh = cfe_open(flashdev);
802 if (fh < 0) {
803 xprintf("Could not open device '%s'\n",flashdev);
804 return CFE_ERR_DEVNOTFOUND;
807 if (cfe_ioctl(fh,IOCTL_FLASH_GETINFO,
808 (unsigned char *) &flashinfo,
809 sizeof(flash_info_t),
810 &res,0) == 0) {
811 /* Truncate write if source size is greater than flash size */
812 if ((copysize + offset) > flashinfo.flash_size) {
813 copysize = flashinfo.flash_size - offset;
818 * If overwriting the boot flash, we need to use the special IOCTL
819 * that will force a reboot after writing the flash.
822 if (flashinfo.flash_flags & FLASH_FLAG_INUSE) {
823 #if CFG_EMBEDDED_PIC
824 xprintf("\n\n** DO NOT TURN OFF YOUR MACHINE UNTIL THE FLASH UPDATE COMPLETES!! **\n\n");
825 #else
826 #if CFG_NETWORK
827 if (net_getparam(NET_DEVNAME)) {
828 xprintf("Closing network.\n");
829 net_uninit();
831 #endif
832 xprintf("Rewriting boot flash device '%s'\n",flashdev);
833 xprintf("\n\n**DO NOT TURN OFF YOUR MACHINE UNTIL IT REBOOTS!**\n\n");
834 cfe_ioctl(fh,IOCTL_FLASH_WRITE_ALL, ptr,copysize,&retlen,0);
835 /* should not return */
836 return CFE_ERR;
837 #endif
841 * Otherwise: it's not the flash we're using right
842 * now, so we can be more verbose about things, and
843 * more importantly, we can return to the command
844 * prompt without rebooting!
848 * Erase the flash, if the device requires it. Our new flash
849 * driver does the copy/merge/erase for us.
852 if (!noerase) {
853 if ((devtype == CFE_DEV_FLASH) && !(flashinfo.flash_flags & FLASH_FLAG_NOERASE)) {
854 flash_range_t range;
855 range.range_base = offset;
856 range.range_length = copysize;
857 xprintf("Erasing flash...");
858 if (cfe_ioctl(fh,IOCTL_FLASH_ERASE_RANGE,
859 (uint8_t *) &range,sizeof(range),NULL,0) != 0) {
860 printf("Failed to erase the flash\n");
861 cfe_close(fh);
862 return CFE_ERR_IOERR;
867 #ifdef RESCUE_MODE
868 if (norescue == 0) {
869 if ((parseflag != 0) && (parseflag != 1) ) {
870 for (i=0; i<0x40000; i++)
871 ptr[i] = bootbuf[i];
873 if (parseflag != 0)
874 copysize = 0x40000;
876 #endif // RESCUE_MODE
879 * Program the flash
882 xprintf("Programming...");
884 amtcopy = cfe_writeblk(fh,offset,ptr,copysize);
886 #ifdef RESCUE_MODE
887 if(norescue == 0) {
888 xprintf("copysize=%d, amtcopy=%d \n", copysize, amtcopy);
889 if (copysize == amtcopy) {
890 xprintf("done. %d bytes written\n",amtcopy);
891 for (i=0; i<6; i++)
892 send_rescueack(0x0006, 0x0001);
893 res = 0;
894 printf("\nBCM47XX SYSTEM RESET!!!\n\n");
895 cfe_close(fh);
896 ui_docommand("reboot");
898 else {
899 ui_showerror(amtcopy,"Failed.");
900 for (i=0; i<6; i++)
901 send_rescueack(0x0006, 0x0000);
902 res = CFE_ERR_IOERR;
905 else {
906 if (copysize == amtcopy) {
907 xprintf("done. %d bytes written\n",amtcopy);
908 res = 0;
910 else {
911 ui_showerror(amtcopy,"Failed.");
912 res = CFE_ERR_IOERR;
915 #else
916 if (copysize == amtcopy) {
917 xprintf("done. %d bytes written\n",amtcopy);
918 res = 0;
920 else {
921 ui_showerror(amtcopy,"Failed.");
922 res = CFE_ERR_IOERR;
924 #endif // RESCUE_MODE
927 * done!
930 cfe_close(fh);
932 return res;