diff options
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c')
-rwxr-xr-x | cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c | 1878 |
1 files changed, 1878 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c new file mode 100755 index 0000000..111e73f --- /dev/null +++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c @@ -0,0 +1,1878 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * + * bcm63xx board specific routines and commands. + * + * by: seanl + * + * April 1, 2002 + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "bcm63xx_util.h" +#include "flash_api.h" +#include "jffs2.h" + +/* Foxconn add start by Cliff Wang, 03/23/2010 */ +#include "tftpd.h" + +#include "net_nmrp.h" + + +extern int nmrp_server_detected; +extern unsigned long cfe_sdramsize; +extern int ui_init_tftpdcmds(void); +int verify_checksum(char *buf, unsigned long buf_len, unsigned long chksum); +/* Foxconn add end by Cliff Wang, 03/23/2010 */ + +#define je16_to_cpu(x) ((x).v16) +#define je32_to_cpu(x) ((x).v32) +#define FLASH_STAGING_BUFFER BOARD_IMAGE_DOWNLOAD_ADDRESS +#define FLASH_STAGING_BUFFER_SIZE BOARD_IMAGE_DOWNLOAD_SIZE + +extern int decompressLZMA(unsigned char *in, unsigned insize, unsigned char *out, unsigned outsize); + +// global +int g_processing_cmd = 0; + +char fakeConsole[2] = " "; + +/* Foxconn add start by Jenny Zhao, 07/02/2008*/ +struct image_header +{ + unsigned long magic; /* magic */ + unsigned long header_len; /* Length of header */ + unsigned char reserved[8]; + unsigned long kernel_chksum; /* Kernel image chksum */ + unsigned long rootfs_chksum; /* rootfs image chksum */ + unsigned long kernel_len; /* Length of kernel */ + unsigned long rootfs_len; /* Length of rootfs */ + unsigned long image_chksum; /* checksum across length of image */ + unsigned long header_chksum; /* checksum across length of header */ +}; + +#define swap32(val) \ + ((unsigned int)( \ + (((unsigned int)(val) & (unsigned int)0x000000ffUL)) | \ + (((unsigned int)(val) & (unsigned int)0x0000ff00UL)) | \ + (((unsigned int)(val) & (unsigned int)0x00ff0000UL)) | \ + (((unsigned int)(val) & (unsigned int)0xff000000UL)) )) + +/* pling added 12/04/2008, define the Foxconn board ID length */ +#define FOXCONN_BOARD_ID_LEN 64 +/* Foxconn add end by Jenny Zhao, 07/02/2008*/ + +static int ui_cmd_set_board_param(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int ret = 0; + int i = 0; + int reset = 0; + + if(!argc) + { + reset += setBoardParam(); + } + + while(argc && !ret) + { + if(!strcmp(argv[i], "g")) + { + reset += setGponBoardParam(); + } + else { + /*Setup WPS Device Pin*/ + if(!strcmp(argv[i], "w")) + { + reset += setWpsDevicePinBoardParam(); + } + else + { + ret = -1; + } + } + + argc--; + i++; + } + + if(reset) + softReset(); + + return ret; +} + +static int ui_cmd_reset(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + softReset(); + return 0; +} + +// return 0 if 'y' +int yesno(void) +{ + char ans[5]; + + printf(" (y/n):"); + console_readline ("", ans, sizeof (ans)); + if (ans[0] != 'y') + return -1; + + return 0; +} + +// erase Persistent sector +static int ui_cmd_erase_psi(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + printf("Erase persisten storage data?"); + if (yesno()) + return -1; + + kerSysErasePsi(); + + return 0; +} + +static int ui_cmd_erase_nand(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + +#if (INC_NAND_FLASH_DRIVER==1) + char *flag; + int i, blk_end; + + flag = cmd_getarg(cmd,0); + + if (!flag) + { + printf("'e b' to reinitialize NAND flash or 'e a' to erase kernel\n"); + return 0; + } + + switch (*flag) + { + case 'b': + printf("Reinitialize NAND flash?"); + if (yesno()) + return 0; + printf("\nNow think carefully. Do you really,\n" + "really want to reinitialize the NAND flag?"); + if (yesno()) + return 0; + flash_sector_erase_int(NAND_REINIT_FLASH); + break; + case 'a': + printf("Erase NAND flash? The modem will not be able to boot from " + "flash"); + if (yesno()) + return 0; + + blk_end = flash_get_numsectors(); + for (i = 1; i < blk_end; i++) + { + printf("."); + flash_sector_erase_int(i); + } + printf("\n"); + break; + case 's': + { + extern void dump_spare(void); + dump_spare(); + } + break; + + case 'r': + { + extern unsigned char *mem_topofmem; + unsigned char *buf = (unsigned char *) mem_topofmem + 1024; + char *pszLen = cmd_getarg(cmd, 2); + int len = (pszLen) ? atoi(pszLen) : 64; + char *pszBlk = cmd_getarg(cmd, 1); + if( flash_read_buf(atoi(pszBlk), 0, buf, 16 * 1024) > 0 ) + { + void ui_dumpaddr( unsigned char *pAddr, int nLen ); + printf("block read into buffer at 0x%8.8lx\n", (unsigned long)buf); + ui_dumpaddr(buf, len); /* dump first few bytes */ + } + else + printf("block NOT read into buffer at 0x%8.8lx\n",(unsigned long)buf); + /* Can break into JTAG now to view entire block contents. */ + } + break; + default: + printf("Erase [n]vram, [p]ersistent storage or [a]ll flash except bootrom\nusage: e [n/p/a]\n"); + return 0; + } +#elif (INC_SPI_PROG_NAND==1) + char *flag; + int i, blk_end; + + flash_change_flash_type(FLASH_IFC_NAND); + + flag = cmd_getarg(cmd,0); + + if (!flag) + { + printf("'n b' to reinitialize NAND flash or 'n a' to erase kernel on NAND\n"); + goto finish; + } + + switch (*flag) + { + case 'b': + printf("Reinitialize NAND flash?"); + if (yesno()) + goto finish; + printf("\nNow think carefully. Do you really,\n" + "really want to reinitialize the NAND flag?"); + if (yesno()) + goto finish; + flash_sector_erase_int(NAND_REINIT_FLASH); + break; + case 'a': + printf("Erase NAND flash? The modem will not be able to boot from " + "flash"); + if (yesno()) + goto finish; + + blk_end = flash_get_numsectors(); + for (i = 1; i < blk_end; i++) + { + printf("."); + flash_sector_erase_int(i); + } + printf("\n"); + break; + case 's': + { + extern void dump_spare(void); + dump_spare(); + } + break; + + case 'r': + { + extern unsigned char *mem_topofmem; + unsigned char *buf = (unsigned char *) mem_topofmem + 1024; + char *pszBlk = cmd_getarg(cmd, 1); + if( flash_read_buf(atoi(pszBlk), 0, buf, 16 * 1024) > 0 ) + { + void ui_dumpaddr( unsigned char *pAddr, int nLen ); + printf("block read into buffer at 0x%8.8lx\n", (unsigned long)buf); + ui_dumpaddr(buf, 64); /* dump first few bytes */ + } + else + printf("block NOT read into buffer at 0x%8.8lx\n",(unsigned long)buf); + /* Can break into JTAG now to view entire block contents. */ + } + break; + default: + printf("Erase [n]vram, [p]ersistent storage or [a]ll flash except bootrom on NAND\nusage: n [n/p/a]\n"); + } +finish: + flash_change_flash_type(FLASH_IFC_SPI); + +#endif + + return 0; +} + +// erase some sectors +static int ui_cmd_erase(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + + //FILE_TAG cfeTag; + PFILE_TAG pTag; + char *flag; + int i, blk_start, blk_end; + + flag = cmd_getarg(cmd,0); + + if (!flag) + { + printf("Erase [n]vram, [p]ersistent storage or [a]ll flash except bootrom\nusage: e [n/p/a]\n"); + return 0; + } + + switch (*flag) + { + case 'b': + printf("Erase boot loader?"); + if (yesno()) + return 0; + printf("\nNow think carefully. Do you really,\n" + "really want to erase the boot loader?"); + if (yesno()) + return 0; + flash_sector_erase_int(0); + break; + case 'n': + printf("Erase nvram?"); + if (yesno()) + return 0; + kerSysEraseNvRam(); + softReset(); + break; + case 'a': + + printf("Erase all flash (except bootrom)?"); + if (yesno()) + return 0; + + blk_end = flash_get_numsectors(); + if ((pTag = getTagFromPartition(1)) != NULL) + blk_start = flash_get_blk(atoi(pTag->rootfsAddress) + BOOT_OFFSET); + else // just erase all after cfe + { + FLASH_ADDR_INFO flash_info; + + kerSysFlashAddrInfoGet(&flash_info); + for( blk_start = 0, i = 0; i<flash_info.flash_rootfs_start_offset && + blk_start < blk_end; blk_start++ ) + { + i += flash_get_sector_size(blk_start); + } + printf("No image tag found. Erase the blocks start at [%d]\n", + blk_start); + } + if( blk_start > 0 ) + { + for (i = blk_start; i < blk_end; i++) + { + printf("."); + flash_sector_erase_int(i); + } + printf("\n"); + } + + /* Preserve the NVRAM fields that are used in the 'b' command. */ + softReset(); + break; + case 'p': + ui_cmd_erase_psi(cmd,argc,argv); + break; + default: + printf("Erase [n]vram, [p]ersistent storage or [a]ll flash except bootrom\nusage: e [n/p/a]\n"); + return 0; + } + + return 0; +} + + +static int loadRaw(char *hostImageName, uint8_t *ptr) +{ + cfe_loadargs_t la; + int res; + + printf("Loading %s ...\n", hostImageName); + + // tftp only + la.la_filesys = "tftp"; + la.la_filename = hostImageName; + la.la_device = NULL; + la.la_address = (long)ptr; + la.la_options = NULL; + la.la_maxsize = FLASH_STAGING_BUFFER_SIZE; + la.la_flags = LOADFLG_SPECADDR; + + res = bcm63xx_cfe_rawload(&la); + if (res < 0) + { + ui_showerror(res, "Loading failed."); + return res; + } + printf("Finished loading %d bytes\n", res); + + return res; +} + +// flash the image +static int ui_cmd_flash_image(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; + char *imageName; + int res; + uint8_t *ptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER); + + g_processing_cmd = 1; + + imageName = cmd_getarg(cmd, 0); + + if (imageName) + { + if (strchr(imageName, ':')) + strcpy(hostImageName, imageName); + else + { + strcpy(hostImageName, bootInfo.hostIp); + strcat(hostImageName, ":"); + strcat(hostImageName, imageName); + } + } + else // use default flash file name + { + strcpy(hostImageName, bootInfo.hostIp); + strcat(hostImageName, ":"); + strcat(hostImageName, bootInfo.flashFileName); + } + + if ((res = loadRaw(hostImageName, ptr)) < 0) + { + g_processing_cmd = 0; + return res; + } + + // check and flash image + res = flashImage(ptr); + + if( res == 0 ) + { + char *p; + NVRAM_DATA nvramData; + + readNvramData(&nvramData); + + for( p = nvramData.szBootline; p[2] != '\0'; p++ ) { + if( p[0] == 'r' && p[1] == '=' && p[2] == 'h' ) + { + /* Change boot source to "boot from flash". */ + p[2] = 'f'; + writeNvramData(&nvramData); + break; + } + } + softReset(); + } + + g_processing_cmd = 0; + return( res ); +} + +static int ui_cmd_write_chk_image(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; + char *imageName; + uint8_t *ptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER); + int res; + struct image_header *header; + unsigned long image_len, image_chksum; + + unsigned long header_len = 0; + unsigned long board_id_len = 0; + char board_id[FOX_BOARD_ID_MAX_LEN]; + uint8_t *tmp; + + g_processing_cmd = 1; + + imageName = cmd_getarg(cmd, 0); + if (!imageName) + return ui_showusage(cmd); + + if (strchr(imageName, ':')) + strcpy(hostImageName, imageName); + else + { + strcpy(hostImageName, bootInfo.hostIp); + strcat(hostImageName, ":"); + strcat(hostImageName, imageName); + } + + if ((res = loadRaw(hostImageName, ptr)) < 0) + { + g_processing_cmd = 0; + return res; + } + + /* check chk file */ + header = (struct image_header *)ptr; + header_len = swap32(header->header_len); + image_len = swap32(header->kernel_len); + image_chksum = swap32(header->kernel_chksum); + board_id_len = header_len - sizeof(struct image_header); + + memset(board_id, 0, sizeof(board_id)); + memcpy(board_id, header+1, board_id_len); + + printf("total:%d header:%d kernel:%d \n", res, header_len, image_len); + + tmp = ptr; + ptr += header_len; + res -= header_len; + + if (verify_checksum((char*)ptr, image_len, image_chksum)) { + printf("fail to comapre checksum ... \n "); + return CFE_ERR_BADIMAGE; + } + + memcpy(tmp, ptr, res); + + // check and flash image + res = writeWholeImage(tmp, res); + + printf("Finished flashing image.\n"); +/* + if (res == 0) + { + softReset(); + } +*/ + g_processing_cmd = 0; + return( res ); +} + +// write the whole image +static int ui_cmd_write_whole_image(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; + char *imageName; + uint8_t *ptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER); + int res; + + g_processing_cmd = 1; + + imageName = cmd_getarg(cmd, 0); + if (!imageName) + return ui_showusage(cmd); + + if (strchr(imageName, ':')) + strcpy(hostImageName, imageName); + else + { + strcpy(hostImageName, bootInfo.hostIp); + strcat(hostImageName, ":"); + strcat(hostImageName, imageName); + } + + if ((res = loadRaw(hostImageName, ptr)) < 0) + { + g_processing_cmd = 0; + return res; + } + + // check and flash image + res = writeWholeImage(ptr, res); + + printf("Finished flashing image.\n"); + + if (res == 0) + { + softReset(); + } + + g_processing_cmd = 0; + return( res ); +} + + +static int ui_cmd_flash_router_image(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; + char *imageName; + uint8_t *ptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER); + +#if (INC_NAND_FLASH_DRIVER==1) + uint8_t *tmp; +#endif + + int res; + + char board_id[FOX_BOARD_ID_MAX_LEN]; //Silver + int update=0; + char board_id_test[PROJECT_ID_LEN]; + +#if (INC_NAND_FLASH_DRIVER==1) + NVRAM_DATA nvramData; +#endif + + imageName = cmd_getarg(cmd, 0); + if (!imageName) + return ui_showusage(cmd); + + if (strchr(imageName, ':')) + strcpy(hostImageName, imageName); + else + { + strcpy(hostImageName, ""); + strcat(hostImageName, ":"); + strcat(hostImageName, ""); + } + + set_tftpd_state(TFTPD_STATE_WAIT_IMAGE); + if ((res = loadRaw(hostImageName, ptr)) < 0) { + printf("fail to load raw file ... \n"); + return res; + } + + if ( nmrp_server_detected == 0) + { + set_tftpd_state(TFTPD_STATE_OFF); // Foxconn added to turn on RED. + setPowerOnLedOn(); // Foxconn added to turn on RED. + } + + /* Foxconn add start by Jenny Zhao, 07/02/2008*/ + if (1) { + struct image_header *header; + unsigned long image_len, image_chksum; + + unsigned long header_len = 0; + unsigned long board_id_len = 0; + + header = (struct image_header *)ptr; + header_len = swap32(header->header_len); + image_len = swap32(header->kernel_len); + image_chksum = swap32(header->kernel_chksum); + /* Check Board ID first */ + board_id_len = header_len - sizeof(struct image_header); + memset(board_id, 0, sizeof(board_id)); + //for(i=0;i<board_id_len;i++) + /* printf("copy board id ... \n"); */ + + //memcpy(board_id, board_id_test, board_id_len); +#if (INC_NAND_FLASH_DRIVER==1) + readNvramData(&nvramData); + if ( nvramData.szFirmwareUpgradeBoardId != NULL ) + memcpy(board_id_test, nvramData.szFirmwareUpgradeBoardId, PROJECT_ID_LEN); +#else + kerSysReadFromFlash(board_id_test, BOARD_DATA_ADDR, PROJECT_ID_LEN); +#endif + /* printf("bboard id is (%s)\n", board_id_test); */ + + memcpy(board_id, header+1, board_id_len); + + /* printf("iboard id is (%s)\n", board_id); */ + +/* disable board_id checking + if (verify_board_id(board_id)) { + printf("Check board id fail: (%s)\n", board_id); + return CFE_ERR_BADIMAGE; + } +*/ + /* Check image checksum */ +#ifdef _DEBUG + xprintf("len = 0x%08X\n", image_len); + xprintf("chksum = 0x%08X\n", image_chksum); + xprintf("header_len = 0x%08X\n", header_len); +#endif + +#if (INC_NAND_FLASH_DRIVER==1) + tmp = ptr; + res -= header_len; +#endif + + ptr += header_len; + + if (verify_checksum((char*)ptr, image_len, image_chksum)) { + printf("fail to comapre checksum ... \n "); + return CFE_ERR_BADIMAGE; + } + } + + /* Foxconn add end by Jenny Zhao, 07/02/2008*/ + if(nmrp_server_detected==1) // in NMRP mode + { + printf(">>> kerSysBcmImageSet= 0x%x\n", FLASH_IMAGE_START_ADDR); +#if (INC_NAND_FLASH_DRIVER==1) + memcpy(tmp, ptr, res); + if ((res = writeWholeImage(tmp, res) )!= 0) +#else + if ((res = kerSysBcmImageSet(FLASH_IMAGE_START_ADDR, ptr, res, 0)) != 0) +#endif + printf("Failed to flash image. Error: %d\n", res); + else + { + /* Foxconn added start, Silver Shih for burn board Id */ + if( strlen(board_id) < FOX_BOARD_ID_MAX_LEN) + { + if(strcmp(board_id_test, board_id) != 0) + //if (strcmp((char *)BOARD_DATA_ADDR, board_id) != 0) + { + //printf("board id not match, addr:0x%x\n", BOARD_DATA_ADDR); + //5 is indicated to burn board id +#if (INC_NAND_FLASH_DRIVER==0) + kerSysBcmImageSet(BOARD_DATA_ADDR, (unsigned char *)board_id, strlen(board_id)+1 , 5); +#endif + } + } + /* Foxconn added end, Silver Shih for burn board Id */ + + update=1; + printf("Finished flashing image in NMRP mode.\n"); + } + } + /* Foxconn added start pling 12/04/2008, for 'tftpd' */ +#if (INC_NAND_FLASH_DRIVER==0) + else if ((res = kerSysBcmImageSet(FLASH_IMAGE_START_ADDR, ptr, res, 0)) != 0) + printf("Failed to flash image. Error: %d\n", res); +#endif + else + printf("finishing flash image for flashimage command ... \n"); + + /* Foxconn added end pling 12/04/2008 */ + if (res == 0) + { + char *p; + NVRAM_DATA nvramData; + + readNvramData(&nvramData); + + memcpy(nvramData.szFirmwareUpgradeBoardId, board_id, strlen(board_id)); + + for( p = nvramData.szBootline; p[2] != '\0'; p++ ) { + if( p[0] == 'r' && p[1] == '=' && p[2] == 'h' ) + { + /* Change boot source to "boot from flash". */ + p[2] = 'f'; + //writeNvramData(&nvramData); + break; + } + } + writeNvramData(&nvramData); + // softReset(); //remove by EricHuang + } + + if (nmrp_server_detected==1 && update==1) //NMRP mode + { + // Restore to factory default. + printf("try to restore to default, addr=0x%x\n", BOARD_FOXNVRAM_ADDR); +#if (INC_NAND_FLASH_DRIVER==0) + kerSysBcmImageSet(BOARD_FOXNVRAM_ADDR, (unsigned char *)"", 0x10000 , 5); +#endif + } + + return( res ); +} + +/************************************************************************ + * cfe_go(la) + * + * Starts a previously loaded program. cfe_loadargs.la_entrypt + * must be set to the entry point of the program to be started + * + * Input parameters: + * la - loader args + * + * Return value: + * does not return + ********************************************************************* */ + +void cfe_go(cfe_loadargs_t *la) +{ + if (la->la_entrypt == 0) { + xprintf("No program has been loaded.\n"); + return; + } + + if (net_getparam(NET_DEVNAME)) { + xprintf("Closing network.\n"); + net_uninit(); + } + + xprintf("Starting program at 0x%p\n",la->la_entrypt); + + setPowerOnLedOn(); + + cfe_start(la->la_entrypt); +} + +static int bootImage(char *fileSys, char *device, int zflag, char *imageName) +{ + cfe_loadargs_t la; + int res; + + // elf only + la.la_filesys = fileSys; + la.la_filename = imageName; + la.la_device = device; + la.la_options = 0; + la.la_maxsize = 0; + la.la_address = 0; + la.la_flags = zflag; + + res = bcm63xx_cfe_elfload(&la); + if (res != 0) + return res; + + if (la.la_flags & LOADFLG_NOISY) + xprintf("Entry at 0x%p\n",la.la_entrypt); + if ((la.la_flags & LOADFLG_EXECUTE) && (la.la_entrypt != 0)) { + cfe_go(&la); + } + + return res; +} + +// Compressed image head format in Big Endia: +// 1) Text Start address: 4 bytes +// 2) Program Entry point: 4 bytes +// 3) Compress image Length: 4 bytes +// 4) Compress data starts: compressed data +static int bootCompressedImage(unsigned int *puiCmpImage, int retry) +{ + unsigned char *pucSrc; + unsigned char *pucDst; + unsigned char *pucEntry; + unsigned int dataLen; + int ret = 0; + cfe_loadargs_t la; + + if( (unsigned long) puiCmpImage > FLASH_BASE ) + { + /* Boot compressed image from flash. */ + unsigned int *puiOrigCmpImage = puiCmpImage; + unsigned int *puiNewCmpImage = NULL; + unsigned int *puiOldCmpImage = NULL; + unsigned int *puiFs = NULL; + PFILE_TAG pTag1 = getTagFromPartition(1); + PFILE_TAG pTag2 = getTagFromPartition(2); + PFILE_TAG pCurTag = NULL; + unsigned int *puiImg= NULL; + int nImgLen = 0; + unsigned long ulCrc, ulImgCrc; + + if( pTag1 && pTag2 ) + { + /* Two images are on flash. Determine which one is being booted. */ + PFILE_TAG pNewTag = NULL; + PFILE_TAG pOldTag = NULL; + int seq1 = atoi(pTag1->imageSequence); + int seq2 = atoi(pTag2->imageSequence); + + if( seq1 > seq2 ) + { + pNewTag = pTag1; + pOldTag = pTag2; + } + else + { + pNewTag = pTag2; + pOldTag = pTag1; + } + + puiNewCmpImage = (unsigned int *) + (atoi(pNewTag->kernelAddress) + BOOT_OFFSET); + puiOldCmpImage = (unsigned int *) + (atoi(pOldTag->kernelAddress) + BOOT_OFFSET); + + if( puiOrigCmpImage == puiOldCmpImage ) + { + printf("Booting from previous image (0x%8.8lx) ...\n", + (unsigned long) atoi(pOldTag->rootfsAddress) + + BOOT_OFFSET - TAG_LEN); + pCurTag = pOldTag; + } + else + { + printf("Booting from latest image (0x%8.8lx) ...\n", + (unsigned long) atoi(pNewTag->rootfsAddress) + + BOOT_OFFSET - TAG_LEN); + pCurTag = pNewTag; + } + } + else + if( pTag1 || pTag2 ) + { + /* Only one image on flash. */ + pCurTag = (pTag1) ? pTag1 : pTag2; + printf("Booting from only image (0x%8.8lx) ...\n", + (unsigned long) atoi(pCurTag->rootfsAddress) + + BOOT_OFFSET - TAG_LEN); + } + else + { + /* No image on flash. */ + printf("No valid boot image\n"); + ret = -1; + } + + if( ret == 0 ) + { + /* Copy compressed image to SDRAM. */ + extern unsigned char *mem_topofmem; + FLASH_ADDR_INFO info; + unsigned char *pDest = (unsigned char *) mem_topofmem + 1024; + unsigned char *pImgEnd; + + kerSysFlashAddrInfoGet( &info ); + pImgEnd = flash_get_memptr( info.flash_meta_start_blk ); + kerSysReadFromFlash( pDest, (unsigned long) puiCmpImage, + (unsigned long) pImgEnd - (unsigned long) puiCmpImage ); + + puiCmpImage = (unsigned int *) pDest; + + /* Copy file system to SDRAM. */ + pDest += (unsigned long) pImgEnd - (unsigned long) + puiOrigCmpImage + 1024; + kerSysReadFromFlash( pDest, (unsigned long) + atoi(pCurTag->rootfsAddress) + BOOT_OFFSET, + atoi(pCurTag->rootfsLen)); + + puiFs = (unsigned int *) pDest; + + pucDst = (unsigned char *) *puiCmpImage; + pucEntry = (unsigned char *) *(puiCmpImage + 1); + dataLen = (unsigned int) *(puiCmpImage + 2); + pucSrc = (unsigned char*) (puiCmpImage + 3); + + printf("Code Address: 0x%08X, Entry Address: 0x%08x\n", + (unsigned int) pucDst, (unsigned int) pucEntry); + + + /* Check Linux file system CRC */ + ulImgCrc = *(unsigned long *) (pCurTag->imageValidationToken + + CRC_LEN); + if( ulImgCrc ) + { + if( puiFs ) + puiImg = puiFs; + else + { + puiImg = (unsigned int *) (atoi(pCurTag->rootfsAddress) + + BOOT_OFFSET); + } + nImgLen = atoi(pCurTag->rootfsLen); + + ulCrc = CRC32_INIT_VALUE; + ulCrc = getCrc32((unsigned char *) puiImg, (UINT32) nImgLen, ulCrc); + if( ulCrc != ulImgCrc) + { + printf("Linux file system CRC error. Corrupted image?\n"); + ret = -1; + } + } + + /* Check Linux kernel CRC */ + ulImgCrc = *(unsigned long *) (pCurTag->imageValidationToken + + (CRC_LEN * 2)); + if( ulImgCrc ) + { + puiImg = (unsigned int *) puiCmpImage; + nImgLen = atoi(pCurTag->kernelLen); + + ulCrc = CRC32_INIT_VALUE; + ulCrc = getCrc32((unsigned char *) puiImg, (UINT32) nImgLen, ulCrc); + if( ulCrc != ulImgCrc) + { + printf("Linux kernel CRC error. Corrupted image?\n"); + ret = -1; + } + } + + if( ret == 0 ) + { + ret = decompressLZMA(pucSrc, dataLen, pucDst, 23*1024*1024); + if (ret != 0) + printf("Failed to decompress image. Corrupted image?\n"); + } + + if (ret != 0) + { + /* Try to boot from the other flash image, if one exists. */ + if( retry == TRUE && pTag1 && pTag2 ) + { + int blk = 0; + unsigned char *pBase = flash_get_memptr(0); + unsigned int *flash_addr_kernel; + FLASH_ADDR_INFO flash_info; + + /* The boot image is bad. Erase the sector with the tag so + * the image is not tried in subsequent boots. + */ + kerSysFlashAddrInfoGet(&flash_info); + if( pCurTag == pTag1 ) + { + blk = flash_get_blk((int)(pBase + + flash_info.flash_rootfs_start_offset)); + } + else + if( pCurTag == pTag2 ) + { + blk = flash_get_blk((int) (pBase + + (flash_get_total_size()/2))); + } + + if( blk ) + flash_sector_erase_int(blk); + + /* Boot from the other flash image. */ + if( puiOrigCmpImage == puiOldCmpImage ) + flash_addr_kernel = puiNewCmpImage; + else + flash_addr_kernel = puiOldCmpImage; + + ret = bootCompressedImage( flash_addr_kernel, FALSE ); + } + } + else + { + printf("Decompression OK!\n"); + la.la_entrypt = (long) pucEntry; + printf("Entry at 0x%p\n",la.la_entrypt); + cfe_go(&la); // never return... + } + + } + } + else + { + /* Boot compressed image that was downloaded to RAM. */ + pucDst = (unsigned char *) *puiCmpImage; + pucEntry = (unsigned char *) *(puiCmpImage + 1); + dataLen = (unsigned int) *(puiCmpImage + 2); + pucSrc = (unsigned char*) (puiCmpImage + 3); + + printf("Code Address: 0x%08X, Entry Address: 0x%08x\n", + (unsigned int) pucDst, (unsigned int) pucEntry); + + ret = decompressLZMA(pucSrc, dataLen, pucDst, 23*1024*1024); + if (ret == 0) + { + printf("Decompression OK!\n"); + la.la_entrypt = (long) pucEntry; + printf("Entry at 0x%p\n",la.la_entrypt); + cfe_go(&la); // never return... + } + else + printf("Failed on decompression. Corrupted image?\n"); + } + + return ret; +} + +static int bootNandImageFromRootfs(int start_blk, int end_blk) +{ + extern unsigned char *mem_topofmem; + char fname[] = NAND_FLASH_BOOT_IMAGE_NAME; + int fname_len = strlen(fname); + int len = flash_get_sector_size(0); + unsigned char *buf = (unsigned char *) mem_topofmem + 1024; + unsigned char *pDest = (unsigned char *) buf + len; + unsigned long *pulDest = (unsigned long *) pDest; + unsigned char *p; + unsigned long version = 0; + unsigned long ino = 0; + int i, done; + struct jffs2_raw_dirent *pdir; + struct jffs2_raw_inode *pino; + int ret = 0; + + /* Find the directory entry. */ + for( i = start_blk, done = 0; i < end_blk && done == 0; i++ ) + { + if( flash_read_buf(i, 0, buf, len) > 0 ) + { + p = buf; + while( p < buf + len ) + { + pdir = (struct jffs2_raw_dirent *) p; + if( je16_to_cpu(pdir->magic) == JFFS2_MAGIC_BITMASK ) + { + if( je16_to_cpu(pdir->nodetype) == JFFS2_NODETYPE_DIRENT && + fname_len == pdir->nsize && + !memcmp(fname, pdir->name, fname_len) ) + { + if( je32_to_cpu(pdir->version) > version ) + { + if( (ino = je32_to_cpu(pdir->ino)) != 0 ) + { + version = je32_to_cpu(pdir->version); + + /* Setting 'done = 1' assumes there is only one + * version of the directory entry. This may not + * be correct if the file is updated after it + * was initially flashed. + * + * TBD. Look for a higher version of the + * directory entry without searching the entire + * flash part. + */ + done = 1; + break; + } + } + } + + p += (je32_to_cpu(pdir->totlen) + 0x03) & ~0x03; + } + else + break; + } + } + } + + if( version ) + { + unsigned char *pucSrc; + unsigned char *pucDst; + unsigned char *pucEntry; + unsigned int dataLen; + unsigned long cur_isize = 0; + + /* Get the file contents. */ + for( i = start_blk, done = 0; i < end_blk && done == 0; i++ ) + { + if( flash_read_buf(i, 0, buf, len) > 0 ) + { + p = buf; + while( p < buf + len ) + { + pino = (struct jffs2_raw_inode *) p; + if( je16_to_cpu(pino->magic) == JFFS2_MAGIC_BITMASK ) + { + if(je16_to_cpu(pino->nodetype)==JFFS2_NODETYPE_INODE && + je32_to_cpu(pino->ino) == ino) + { + unsigned long size = je32_to_cpu(pino->dsize); + unsigned long ofs = je32_to_cpu(pino->offset); + unsigned long isize = je32_to_cpu(pino->isize); + + if( size ) + { + memcpy(pDest + ofs, pino->data, size); + if( (cur_isize += size) >= isize ) + { + done = 1; + break; + } + } + } + + p += (je32_to_cpu(pino->totlen) + 0x03) & ~0x03; + } + else + break; + } + } + } + + pucDst = (unsigned char *) *pulDest; + pucEntry = (unsigned char *) *(pulDest + 1); + dataLen = (unsigned int) *(pulDest + 2); + pucSrc = (unsigned char *) (pulDest + 3); + + ret = decompressLZMA(pucSrc, dataLen, pucDst, 23*1024*1024); + if (ret != 0) + printf("Failed to decompress image. Corrupted image?\n"); + else + { + cfe_loadargs_t la; + + /* Save the rootfs offset of the rootfs that the Linux image + * is loaded from at the memory location before the Linux load + * address. The Linux image uses this value to determine the + * the rootfs to use. + */ + *(unsigned long *) (pucDst - 4) = (start_blk * len) / 1024; + + printf("Decompression OK!\n"); + la.la_entrypt = (long) pucEntry; + printf("Entry at 0x%p\n",la.la_entrypt); + cfe_go(&la); // never return... + } + } + else + printf("ERROR: A JFFS2 directory entry for %s was not found.\n",fname); + + return( ret ); +} + +static int bootNandImage(void) +{ + int ret = -1; + char *msgA, *msgB; + PFILE_TAG pTag1 = getTagFromPartition(1); + PFILE_TAG pTag2 = getTagFromPartition(2); + int seq1 = (pTag1) ? atoi(pTag1->imageSequence) : -1; + int seq2 = (pTag2) ? atoi(pTag2->imageSequence) : -1; + int start_blk, end_blk, rootfsA, rootfsB; + int len = flash_get_sector_size(0) / 1024; + NVRAM_DATA nvramData; + + readNvramData(&nvramData); + validateNandPartTbl(&nvramData); + + if( pTag1 && pTag2 ) + { + if( bootInfo.bootPartition == BOOT_LATEST_IMAGE ) + { + msgA = "Booting from latest image (0x%8.8lx) ...\n"; + msgB = "Booting from previous image (0x%8.8lx) ...\n"; + rootfsA = (seq2 > seq1) ? NP_ROOTFS_2 : NP_ROOTFS_1; + } + else /* Boot from the previous image. */ + { + msgA = "Booting from previous image (0x%8.8lx) ...\n"; + msgB = "Booting from latest image (0x%8.8lx) ...\n"; + rootfsA = (seq2 <= seq1) ? NP_ROOTFS_2 : NP_ROOTFS_1; + } + + rootfsB = (rootfsA == NP_ROOTFS_2) ? NP_ROOTFS_1 : NP_ROOTFS_2; + start_blk = nvramData.ulNandPartOfsKb[rootfsA] / len; + end_blk = start_blk + + (nvramData.ulNandPartSizeKb[rootfsA] / len); + printf(msgA, FLASH_BASE + (nvramData.ulNandPartOfsKb[rootfsA] * 1024)); + if( (ret = bootNandImageFromRootfs(start_blk, end_blk)) != 0 ) + { + start_blk = nvramData.ulNandPartOfsKb[rootfsB] / len; + end_blk = start_blk + + (nvramData.ulNandPartSizeKb[rootfsB] / len); + printf(msgB, FLASH_BASE+(nvramData.ulNandPartOfsKb[rootfsB]*1024)); + if( (ret = bootNandImageFromRootfs(start_blk, end_blk)) != 0 ) + printf("Unable to boot image.\n"); + } + } + else + { + if( pTag1 ) + rootfsA = NP_ROOTFS_1; + else + if( pTag2 ) + rootfsA = NP_ROOTFS_2; + + if( pTag1 || pTag2 ) + { + start_blk = nvramData.ulNandPartOfsKb[rootfsA] / len; + end_blk = start_blk + + (nvramData.ulNandPartSizeKb[rootfsA] / len); + printf("Booting from only image (0x%8.8lx) ...\n", + FLASH_BASE + (nvramData.ulNandPartOfsKb[rootfsA] * 1024)); + if( (ret = bootNandImageFromRootfs(start_blk, end_blk)) != 0 ) + printf("Unable to boot image.\n"); + } + else + printf("No image found.\n"); + } + + return( ret ); +} + +static int autoRun(char *imageName) +{ + char ipImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; + int ret; + + if (bootInfo.runFrom == 'f' && !imageName) + { + if (!imageName) + { + if( flash_get_flash_type() != FLASH_IFC_NAND ) + { + PFILE_TAG pTag = getBootImageTag(); + int flash_addr_kernel = atoi(pTag->kernelAddress) + BOOT_OFFSET; + + ret = bootCompressedImage((unsigned int *)flash_addr_kernel, TRUE); + } + else + ret = bootNandImage(); + } + else + printf("Image name not allowed for boot from flash.\n"); + } + else // loading from host + { + if (imageName) + { + if (strchr(imageName, ':')) + strcpy(ipImageName, imageName); + else + { + strcpy(ipImageName, bootInfo.hostIp); + strcat(ipImageName, ":"); + strcat(ipImageName, imageName); + } + } + else // use default host file name + { + strcpy(ipImageName, bootInfo.hostIp); + strcat(ipImageName, ":"); + strcat(ipImageName, bootInfo.hostFileName); + } + + // try uncompressed image first + ret = bootImage("tftp", "eth0", LOADFLG_EXECUTE | LOADFLG_NOISY, ipImageName); + + if( ret == CFE_ERR_NOTELF ) + { + uint8_t *ptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER); + // next try as a compressed image + printf("Retry loading it as a compressed image.\n"); + if ((ret = loadRaw(ipImageName, ptr)) > 0) + bootCompressedImage((unsigned int *) ptr, TRUE); + } + } + + return ret; +} + + +// run program from compressed image in flash or from tftped program from host +static int ui_cmd_run_program(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int ret; + + if( getBootImageTag() || bootInfo.runFrom == 'r' ) + { + char *imageName; + + imageName = cmd_getarg(cmd, 0); + g_processing_cmd = 1; + ret = autoRun(imageName); + } + else + { + printf("ERROR: There is not a valid image to boot from.\n"); + ret = CFE_ERR_FILENOTFOUND; + } + + return( ret ); +} + + +static int ui_cmd_print_system_info(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + return printSysInfo(); +} + +static int ui_cmd_change_bootline(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + return changeBootLine(); +} + +static int ui_cmd_set_afe_id(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + return changeAfeId(); +} + +void ui_dumpaddr( unsigned char *pAddr, int nLen ); +void ui_dumpaddr( unsigned char *pAddr, int nLen ) +{ + static char szHexChars[] = "0123456789abcdef"; + char szLine[80]; + char *p = szLine; + unsigned char ch, *q; + int i = 0, j, size = 0; + unsigned long ul; + unsigned short us; + + if( ((unsigned long) pAddr & 0xff000000) == 0xff000000 || + ((unsigned long) pAddr & 0xff000000) == 0xb0000000 ) + { + if (nLen == 2) { + pAddr = (unsigned char *) ((unsigned long) pAddr & ~0x01); + } else if (nLen != 1) { + /* keeping the old logic as is. */ + if( ((unsigned long) pAddr & 0x03) != 0 ) + nLen += 4; + pAddr = (unsigned char *) ((unsigned long) pAddr & ~0x03); + } + } + while( nLen > 0 ) + { + sprintf( szLine, "%8.8lx: ", (unsigned long) pAddr ); + p = szLine + strlen(szLine); + + if( ((unsigned long) pAddr & 0xff000000) == 0xff000000 || + ((unsigned long) pAddr & 0xff000000) == 0xb0000000 ) + { + for(i = 0; i < 6 && nLen > 0; i += sizeof(long), nLen -= sizeof(long)) + { + if (nLen == 1) { + q = pAddr; + size = 1; + } else if (nLen == 2) { + us = *(unsigned short *)pAddr; + q = (unsigned char *) &us; + size = 2; + } else { + ul = *(unsigned long *) &pAddr[i]; + q = (unsigned char *) &ul; + size = sizeof(long); + } + for( j = 0; j < size; j++ ) + { + *p++ = szHexChars[q[j] >> 4]; + *p++ = szHexChars[q[j] & 0x0f]; + } + *p++ = ' '; + } + } + else + { + for(i = 0; i < 16 && nLen > 0; i++, nLen-- ) + { + ch = pAddr[i]; + + *p++ = szHexChars[ch >> 4]; + *p++ = szHexChars[ch & 0x0f]; + *p++ = ' '; + } + } + + for( j = 0; j < 16 - i; j++ ) + *p++ = ' ', *p++ = ' ', *p++ = ' '; + + *p++ = ' ', *p++ = ' ', *p++ = ' '; + + for( j = 0; j < i; j++ ) + { + ch = pAddr[j]; + *p++ = (ch >= ' ' && ch <= '~') ? ch : '.'; + } + + *p++ = '\0'; + printf( "%s\r\n", szLine ); + + pAddr += i; + } + printf( "\r\n" ); +} /* ui_dumpaddr */ + +static int ui_cmd_dump_mem(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *pszAddr = cmd_getarg(cmd, 0); + char *pszLen = cmd_getarg(cmd, 1); + if( pszAddr && pszLen ) + ui_dumpaddr((unsigned char *) xtoi(pszAddr), atoi(pszLen)); + else + printf("dm address_in_hex length_in_decimal\n"); + + return( 0 ); +} + +static int ui_cmd_set_mem(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *pszAddr = cmd_getarg(cmd, 0); + char *pszValue = cmd_getarg(cmd, 1); + char *pszSize = cmd_getarg(cmd, 2); + if( pszAddr && pszValue && pszSize ) + { + unsigned long ulAddr = (unsigned long) xtoi(pszAddr); + unsigned long ulValue = (unsigned long) atoi(pszValue); + int nSize = atoi(pszSize); + unsigned long *pul = (unsigned long *) ulAddr; + unsigned short *pus = (unsigned short *) ulAddr; + unsigned char *puc = (unsigned char *) ulAddr; + switch( nSize ) + { + case 4: + *pul = (unsigned long) ulValue; + break; + + case 2: + *pus = (unsigned short) ulValue; + break; + + case 1: + *puc = (unsigned char) ulValue; + break; + + default: + printf("sm address_in_hex value_in_hex size_4_2_or_1"); + break; + } + + ui_dumpaddr((unsigned char *) ulAddr, 4); + } + else + printf("sm address_in_hex value_in_hex size_4_2_or_1"); + + return( 0 ); +} + +static int ui_cmd_check_mem(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + #define RAM_BASE_ADDRESS 0xa0000000 + #define BOOT_CODE_SIZE 256 * 1024 // 256KB + #define CFE_MEM_SPACE 0xa0400000 + #define CFE_MEM_SIZE 4*1024*1024 // 4MB + #define MEMORY_SIZE 32*1024*1024 // 32MB + #define MAGIC_NUMBER 0xacacacac + + #define NAND_SECTOR_SIZE (16*1024) // 16KB + #define NAND_TEST_SIZE (30*1024*1024) // 30MB + + unsigned char *addr = NULL; + int pass=1; + +#if 0 + unsigned int buf1[NAND_SECTOR_SIZE/4]; + unsigned int buf2[NAND_SECTOR_SIZE/4]; + int i, j; +#endif + + printf("Verifying DRAM access...\n"); + for(addr=(unsigned char *)(RAM_BASE_ADDRESS+BOOT_CODE_SIZE); addr< (unsigned char *)(RAM_BASE_ADDRESS+MEMORY_SIZE); addr+=4) + { + if( addr< (unsigned char *)CFE_MEM_SPACE || addr > (unsigned char *)CFE_MEM_SPACE+CFE_MEM_SIZE ) + { + *(unsigned long *)addr = MAGIC_NUMBER; + } + } + + for(addr=(unsigned char *)(RAM_BASE_ADDRESS+BOOT_CODE_SIZE); addr< (unsigned char *)(RAM_BASE_ADDRESS+MEMORY_SIZE); addr+=4) + { + if( addr< (unsigned char *)CFE_MEM_SPACE || addr > (unsigned char *)CFE_MEM_SPACE+CFE_MEM_SIZE ) + { + if( *(unsigned long *)addr != MAGIC_NUMBER ) + pass=0; + } + } + if(pass) + printf("DRAM check OK!!!!\n"); + else + printf("DRAM check NG!!!!\n"); + +#if 0 + //printf("Verifying NAND flash access...\n"); + pass=1; + + for(i=0; i<NAND_SECTOR_SIZE/4; i++) + { + buf1[i]=MAGIC_NUMBER; + } + + /* The CFE ROM boot loader saved the rootfs partition index at the + * memory location before CFE RAM load address. + */ + extern unsigned char _ftext; + int rootfs = (int) *(&_ftext - 1); + NVRAM_DATA nvramData; + int offset = 0; + int blk_start; + + readNvramData(&nvramData); + + if(rootfs == NP_ROOTFS_1 && nvramData.ulNandPartSizeKb[NP_ROOTFS_2]>0) + offset = nvramData.ulNandPartOfsKb[NP_ROOTFS_2] * 1024; + else + offset = nvramData.ulNandPartOfsKb[NP_ROOTFS_1] * 1024; + + printf("Verifying NAND flash access from 0x%08x...\n", FLASH_BASE+offset); + + for(i=0; i<NAND_TEST_SIZE/NAND_SECTOR_SIZE; i++, offset+=NAND_SECTOR_SIZE) + { + kerSysBcmImageSet(FLASH_BASE+offset, (unsigned char *)buf1, NAND_SECTOR_SIZE, 1); + kerSysReadFromFlash( buf2, FLASH_BASE+offset, NAND_SECTOR_SIZE ); + blk_start = flash_get_blk(FLASH_BASE+offset); + flash_sector_erase_int(blk_start); // erase blk before flash + if( memcmp(buf1, buf2, NAND_SECTOR_SIZE)) + { + printf("Failed address is 0x%08x\n", FLASH_BASE+offset); + for(j=0; j<NAND_SECTOR_SIZE/4; j++) + { + printf("buf2[%d]=%x\n", j, buf2[j]); + } + pass=0; + break; + } + } + + if(pass) + printf("NAND flash check OK!!!!\n"); + else + printf("NAND flash check NG!!!!\n"); +#endif + + return( 0 ); +} + +extern int ui_init_netcmds(void); + +int ui_cmd_nmrp(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_cmd_nmrp(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + _start_nmrp(); + return 0; +} + + +int ui_cmd_flash_read(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_cmd_flash_read(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char str[10]; + + kerSysReadFromFlash(str, BOARD_DATA_ADDR, 7); + + printf("%s\n", str); + + return 0; +} + +int ui_cmd_write_boardid(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_cmd_write_boardid(ui_cmdline_t *cmd,int argc,char *argv[]) +{ +#if (INC_NAND_FLASH_DRIVER==1) + NVRAM_DATA nvramData; + int len; +#endif + + if ( argv[0] != NULL ) { +#if (INC_NAND_FLASH_DRIVER==1) + len = strlen(argv[0]); + readNvramData(&nvramData); + memcpy(nvramData.szFirmwareUpgradeBoardId, argv[0], len); + writeNvramData(&nvramData); +#else + kerSysBcmImageSet(BOARD_DATA_ADDR, (unsigned char *)argv[0], strlen(argv[0])+1 , 5); +#endif + } +#if (INC_NAND_FLASH_DRIVER==1) + else { + readNvramData(&nvramData); + } + printf("read board id: %s \n", nvramData.szFirmwareUpgradeBoardId); +#endif + return 0; +} + +/* Foxconn add start by Cliff Wang, 03/23/2010 */ +extern int ui_init_netcmds(void); +/* Foxconn add end by Cliff Wang, 03/23/2010 */ + +static int ui_init_bcm63xx_cmds(void) +{ + console_name = fakeConsole; // for cfe_rawfs strcmp + // Used to flash an image that does not contain a FILE_TAG record. + + /* Foxconn add start by Cliff Wang, 03/23/2010 */ + cmd_addcmd("flashimage", + ui_cmd_flash_router_image, + NULL, + "Flashes a compressed image after the bootloader.", + "eg. flashimage [hostip:]compressed_image_file_name", + ""); + /* Foxconn add end by Cliff Wang, 03/23/2010 */ + cmd_addcmd("bid", + ui_cmd_write_boardid, + NULL, + "write board id to nand flash.", + "eg. bi str ", + ""); + + cmd_addcmd("reset", + ui_cmd_reset, + NULL, + "Reset the board", + "", + ""); + + cmd_addcmd("b", + ui_cmd_set_board_param, + NULL, + "Change board parameters", + "", + ""); + + cmd_addcmd("a", + ui_cmd_set_afe_id, + NULL, + "Change board AFE ID", + "", + ""); + + cmd_addcmd("i", + ui_cmd_erase_psi, + NULL, + "Erase persistent storage data", + "", + ""); + + if( flash_get_flash_type() != FLASH_IFC_NAND ) + cmd_addcmd("f", + ui_cmd_flash_image, + NULL, + "Write image to the flash ", + "eg. f [[hostip:]filename]<cr> -- if no filename, tftped from host with file name in 'Default host flash file name'", + ""); + + cmd_addcmd("c", + ui_cmd_change_bootline, + NULL, + "Change booline parameters", + "", + ""); + + cmd_addcmd("p", + ui_cmd_print_system_info, + NULL, + "Print boot line and board parameter info", + "", + ""); + + cmd_addcmd("r", + ui_cmd_run_program, + NULL, + "Run program from flash image or from host depend on [f/h] flag", + "eg. r [[hostip:]filenaem]<cr> if no filename, use the file name in 'Default host run file name'", + ""); + +#if (INC_SPI_PROG_NAND==1) + cmd_addcmd("n", + ui_cmd_erase_nand, + NULL, + "Erase NAND flash", + "e [a]", + ""); +#else + if( flash_get_flash_type() == FLASH_IFC_NAND ) + cmd_addcmd("e", + ui_cmd_erase_nand, + NULL, + "Erase NAND flash", + "e [a]", + ""); + else +#endif + cmd_addcmd("e", + ui_cmd_erase, + NULL, + "Erase [n]vram or [a]ll flash except bootrom", + "e [n/a]", + ""); + + cmd_addcmd("w", + ui_cmd_write_whole_image, + NULL, + "Write the whole image start from beginning of the flash", + "eg. w [hostip:]whole_image_file_name", + ""); + + cmd_addcmd("chw", + ui_cmd_write_chk_image, + NULL, + "Write chkw image start from beginning of the flash", + "eg. chkw [hostip:]whole_image_file_name", + ""); + + cmd_addcmd("dm", + ui_cmd_dump_mem, + NULL, + "Dump memory or registers.", + "eg. dm address_in_hex length_in_decimal", + ""); + + cmd_addcmd("sm", + ui_cmd_set_mem, + NULL, + "Set memory or registers.", + "eg. sm address_in_hex value_in_hex size_4_2_or_1", + ""); + + cmd_addcmd("nmrp", + ui_cmd_nmrp, + NULL, + "start memory or registers.", + "eg. nmrp ", + ""); + + cmd_addcmd("fr", + ui_cmd_flash_read, + NULL, + "read data from flash.", + "eg. fr addr ", + ""); + + /* Foxconn add start by Cliff Wang, 03/23/2010 */ + cmd_addcmd("checkmem", + ui_cmd_check_mem, + NULL, + "Check memory.", + "Check memory.", + ""); + + ui_init_tftpdcmds(); + /* Foxconn add end by Cliff Wang, 03/23/2010 */ + + return 0; +} + + +static int runDelay(int delayCount) +{ + int goAuto = 0; + + if (delayCount == 0) + return goAuto; + + printf("*** Press any key to stop auto run (%d seconds) ***\n", delayCount); + printf("Auto run second count down: %d", delayCount); + + cfe_sleep(CFE_HZ/8); // about 1/4 second + + while (1) + { + printf("\b%d", delayCount); + cfe_sleep(CFE_HZ); // about 1 second + if (console_status()) + break; + if (--delayCount == 0) + { + goAuto = 1; + break; + } + } + printf("\b%d\n", delayCount); + + return goAuto; +} + + +int bcm63xx_run(int breakIntoCfe) +{ + int goAuto; + + ui_init_bcm63xx_cmds(); + printSysInfo(); + enet_init(); + + goAuto = runDelay(bootInfo.bootDelay); + if (!breakIntoCfe && runDelay(bootInfo.bootDelay)) + { + /* Foxconn add start by Cliff Wang, 03/23/2010 */ + if(_start_nmrp() != 0) + autoRun(NULL); // never returns + /* Foxconn add end by Cliff Wang, 03/23/2010 */ + } + return goAuto; +} + + |