summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c')
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c1878
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;
+}
+
+