1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Flash Update commands File: ui_flash.c
6 * The routines in this file are used for updating the
7 * flash with new firmware.
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"
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"
63 #include "cfe_fileops.h"
65 #include "bsp_config.h"
67 #include "cfe_loader.h"
70 #include "net_ether.h"
73 #include "cfe_flashimage.h"
75 #include "addrspace.h"
80 /* *********************************************************************
82 ********************************************************************* */
85 * Of course, these things really belong somewhere else.
88 #define FLASH_STAGING_BUFFER CFG_FLASH_STAGING_BUFFER_ADDR
90 #define FLASH_STAGING_BUFFER_SIZE (1024*1024*16)
92 #define FLASH_STAGING_BUFFER_SIZE CFG_FLASH_STAGING_BUFFER_SIZE
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
);
107 /* *********************************************************************
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.
128 * 0 if ok, else error
129 ********************************************************************* */
131 int ui_init_flashcmds(void)
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"
146 "-noerase;Don't erase flash before writing|"
148 "-norescue;Don't check anything|"
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|"
157 #ifdef FLASH_PARTITION_FILL_ENABLED
158 "-fill;Fill the partition with char|"
160 "-mem;Use memory as source instead of a device");
166 /* *********************************************************************
167 * flash_crc32(buf,len)
169 * Yes, this is an Ethernet CRC. I'm lazy.
172 * buf - buffer to CRC
173 * len - length of data
177 ********************************************************************* */
179 #define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */
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);
194 /* *********************************************************************
195 * flash_validate(ptr)
197 * Validate the flash header to make sure we can program it.
200 * ptr - pointer to flash header
201 * outptr - pointer to data that we should program
202 * outsize - size of data we should program
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
;
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");
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
);
240 if ((size
== 0) || (size
> bufsize
) ||
241 ((size
+ sizeof(cfe_flashimage_t
)) < insize
)) {
242 printf("Flash image size is bogus!\n");
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
);
253 *outptr
= ptr
+ sizeof(cfe_flashimage_t
);
259 /* *********************************************************************
260 * ui_get_flashbuf(bufptr, bufsize)
262 * Figure out the location and size of the staging buffer.
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).
285 *bufptr
= (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER
);
290 below
= PHYSADDR(mem_bottomofmem
) - FLASH_STAGING_BUFFER
;
291 above
= (mem_totalsize
<< 10) - PHYSADDR(mem_topofmem
);
294 *bufptr
= (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER
);
297 *bufptr
= (uint8_t *) KERNADDR(mem_topofmem
);
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;
318 while (!(strcmp(addr_buf
, keyword
)==0));
319 if(strcmp(keyword
, "secret_code") == 0)
321 else if (strcmp(keyword
, "regulation_domain") == 0)
326 for (addr_j
=0 ; addr_j
< idx
; addr_j
++)
328 bootbuf
[0x0000+addr
+addr_j
+strlen(keyword
)] = value
[0x0+addr_j
];
334 static void ui_check_flashdev(char *in
, char *out
)
339 strcpy(out
, "flash0.0");
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
);
349 if (strncmp(in
+i
, ".trx", 4) == 0) {
350 /* Program the trx image */
351 ui_get_trx_flashdev(out
);
354 if (strncmp(in
+i
, ".boot", 5) == 0) {
355 /* Program the trx image */
356 ui_get_boot_flashdev(out
);
363 #endif /* CFG_NFLASH */
365 #ifdef CFE_FLASH_ERASE_FLASH_ENABLED
366 static int erase_range(char *flashdev
, int start
, int len
)
371 range
.range_base
= start
;
372 range
.range_length
= len
;
373 fh
= cfe_open(flashdev
);
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");
382 return CFE_ERR_IOERR
;
389 #ifdef FLASH_PARTITION_FILL_ENABLED
390 static int fill_partition(char *flashdev
, char *ptr
, int bufsize
, char c
)
393 flash_info_t flashinfo
;
396 printf("filling %s with %x \n", flashdev
, c
);
397 fh
= cfe_open(flashdev
);
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
),
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");
415 xprintf("Fill Failed!!!\n");
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
431 * cmd - command table entry
432 * argc,argv - parameters
437 ********************************************************************* */
440 static int ui_cmd_flash(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
445 #if !CFG_EMBEDDED_PIC
457 flash_info_t flashinfo
;
460 int memsrc
= 0; /* Source is memory address */
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 */
484 ui_get_flash_buf(&ptr
, &bufsize
);
486 #ifdef CFE_FLASH_ERASE_FLASH_ENABLED
487 int erase_op
= cmd_sw_isset(cmd
, "-erase");
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");
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 */
502 erase_range(flashdev
, 0, 0);
505 char *ll
= cmd_getarg(cmd
, 2);
507 xprintf("Please specify the len !!\n");
508 return CFE_ERR_INV_PARAM
;
510 int start
= atoi(ss
);
512 erase_range(flashdev
, start
, len
);
517 #ifdef FLASH_PARTITION_FILL_ENABLED
518 int fill_op
= cmd_sw_isset(cmd
,"-fill");
522 flashdev
= cmd_getarg(cmd
, 0);
523 if(flashdev
==NULL
) return CFE_ERR_INV_PARAM
;
524 c
= cmd_getarg(cmd
, 1);
528 fill_partition(flashdev
, ptr
, bufsize
, h
);
533 * Parse command line parameters
536 fname
= cmd_getarg(cmd
,0);
539 return ui_showusage(cmd
);
542 flashdev
= cmd_getarg(cmd
,1);
543 if (!flashdev
) flashdev
= "flash0.0";
545 ui_check_flashdev(flashdev
, buf
);
549 * Make sure it's a flash device.
552 res
= cfe_getdevinfo(flashdev
);
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");
580 norescue
= cmd_sw_isset(cmd
,"-norescue");
583 if (cmd_sw_value(cmd
,"-offset",&x
)) {
587 if (cmd_sw_value(cmd
,"-size",&x
)) {
591 /* Fix up the ptr and size for reading from memory
592 * and skip loading to go directly to programming
595 ptr
= (uint8_t *)xtoi(fname
);
598 xprintf("Reading from %s: ",fname
);
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
) {
612 sfd
= cfe_open(fname
);
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
),
623 flashinfo
.flash_size
= bufsize
;
627 xprintf("(size=0x%X) ",size
);
630 size
= flashinfo
.flash_size
;
633 /* Make sure we don't overrun the staging buffer */
635 if (size
> bufsize
) {
639 /* Read the flash device here. */
641 res
= cfe_read(sfd
,ptr
,size
);
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,
653 if (ptr
[res
-1] != 0xFF) break;
659 la
.la_filesys
= "raw";
660 la
.la_filename
= NULL
;
661 la
.la_device
= fname
;
662 la
.la_address
= (intptr_t) ptr
;
664 la
.la_maxsize
= bufsize
;
665 la
.la_flags
= LOADFLG_SPECADDR
;
667 res
= cfe_load_program("srec",&la
);
670 ui_showerror(res
,"Failed.");
677 res
= ui_process_url(fname
, cmd
, &la
);
679 ui_showerror(res
,"Invalid file name %s",fname
);
683 la
.la_address
= (intptr_t) ptr
;
685 la
.la_maxsize
= bufsize
;
686 la
.la_flags
= LOADFLG_SPECADDR
;
688 res
= cfe_load_program("raw",&la
);
691 ui_showerror(res
,"Failed.");
698 xprintf("Done. %d bytes read\n",res
);
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
));
710 #ifdef COMPRESSED_CFE
711 (*(unsigned long *) (ptr
+0x400) == NVRAM_MAGIC
) && ( *(unsigned long *) (ptr
) != NVRAM_MAGIC_MAC0
)
713 (*(unsigned long *) (ptr
+0x1000) == NVRAM_MAGIC
) && ( *(unsigned long *) (ptr
) != NVRAM_MAGIC_MAC0
)
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");
721 else if ( *(unsigned long *) (ptr
) == NVRAM_MAGIC_MAC0
) {
722 xprintf("Download of 0x%x bytes completed\n", copysize
);
726 /* Wait for SCODE by SJ_Yen */
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
];
738 xprintf("Write secret code = %s to FLASH\n", secretcode
);
739 replace(bootbuf
, scode
, secretcode
);
740 nvram_set("secret_code", (int8_t *)secretcode
);
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");
757 else if ( *(unsigned long *) (ptr
) == NVRAM_MAGIC_RDOM
) {
761 replace(bootbuf
, reg_dom
, RDOM
);
762 xprintf("Write RDOM = %s to FLASH \n", RDOM
);
763 nvram_set("regulation_domain", (int8_t *)RDOM
);
769 xprintf("Download of 0x%x bytes completed\n", copysize
);
770 xprintf("Not valid nvram MAGIC at all !!\n");
774 else if (copysize
>0x40000)
777 xprintf("Download of 0x%x bytes completed\n", copysize
);
778 xprintf("Write kernel and filesystem binary to FLASH \n");
783 xprintf("Downloading image time out\n");
786 #endif // RESCUE_MODE
789 * Verify the header and file's CRC.
792 if (flash_validate(ptr
,bufsize
,res
,&ptr
,©size
) < 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
);
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
),
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
) {
824 xprintf("\n\n** DO NOT TURN OFF YOUR MACHINE UNTIL THE FLASH UPDATE COMPLETES!! **\n\n");
827 if (net_getparam(NET_DEVNAME
)) {
828 xprintf("Closing network.\n");
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 */
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.
853 if ((devtype
== CFE_DEV_FLASH
) && !(flashinfo
.flash_flags
& FLASH_FLAG_NOERASE
)) {
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");
862 return CFE_ERR_IOERR
;
869 if ((parseflag
!= 0) && (parseflag
!= 1) ) {
870 for (i
=0; i
<0x40000; i
++)
876 #endif // RESCUE_MODE
882 xprintf("Programming...");
884 amtcopy
= cfe_writeblk(fh
,offset
,ptr
,copysize
);
888 xprintf("copysize=%d, amtcopy=%d \n", copysize
, amtcopy
);
889 if (copysize
== amtcopy
) {
890 xprintf("done. %d bytes written\n",amtcopy
);
892 send_rescueack(0x0006, 0x0001);
894 printf("\nBCM47XX SYSTEM RESET!!!\n\n");
896 ui_docommand("reboot");
899 ui_showerror(amtcopy
,"Failed.");
901 send_rescueack(0x0006, 0x0000);
906 if (copysize
== amtcopy
) {
907 xprintf("done. %d bytes written\n",amtcopy
);
911 ui_showerror(amtcopy
,"Failed.");
916 if (copysize
== amtcopy
) {
917 xprintf("done. %d bytes written\n",amtcopy
);
921 ui_showerror(amtcopy
,"Failed.");
924 #endif // RESCUE_MODE