summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/board
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/board')
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm63xx_util.h167
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_common.h32
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_cpu.h32
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_map.h32
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmmii.h164
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmtypes.h144
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/bsp_config.h94
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_eth.h127
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_flash.h38
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/include/jffs2.h251
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/Makefile55
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_board.c830
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_cmd.c1878
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_devs.c734
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_env_subr.c277
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_httpd.c1031
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_elf.c388
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c368
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_main.c611
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_net_icmp.c199
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ram_boot.S88
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_util.c1375
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_eth.c547
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_flash.c629
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_uart.c211
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ul.html48
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ulinfo.html60
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/ram_cfe.mk378
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c615
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/Makefile23
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_rom_boot.S548
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_sdramDqs.c439
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_impl1_rom_boot.S1818
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_main.c649
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c1031
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/rom_cfe.mk370
36 files changed, 16281 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm63xx_util.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm63xx_util.h
new file mode 100755
index 0000000..273b9c7
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm63xx_util.h
@@ -0,0 +1,167 @@
+/***************************************************************************
+ * Broadcom Corp. Confidential
+ * Copyright 2001, 2002 Broadcom Corp. All Rights Reserved.
+ *
+ * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED
+ * SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM.
+ * YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT
+ * SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
+ *
+ ***************************************************************************
+ * File Name : bcm63xx_util.h
+ *
+ * Created on : 04/18/2002 seanl
+ ***************************************************************************/
+
+#if !defined(_BCM63XX_UTIL_H_)
+#define _BCM63XX_UTIL_H_
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_console.h"
+#include "cfe_devfuncs.h"
+#include "cfe_timer.h"
+#include "cfe_ioctl.h"
+#include "cfe_error.h"
+#include "env_subr.h"
+#include "ui_command.h"
+#include "cfe.h"
+#include "net_ebuf.h"
+#include "net_ether.h"
+#include "net_api.h"
+#include "cfe_fileops.h"
+#include "bsp_config.h"
+#include "cfe_mem.h"
+#include "cfe_loader.h"
+#include "addrspace.h"
+
+#include "dev_bcm63xx_flash.h"
+#include "bcm_hwdefs.h"
+#include "bcmTag.h"
+#include "boardparms.h"
+#include "boardparms_voice.h"
+#include "bcm_map.h"
+
+extern unsigned long cfe_sdramsize;
+
+#define NAND_FLASH_BOOT_IMAGE_NAME "vmlinux.lz"
+
+#define BOARD_IMAGE_DOWNLOAD_ADDRESS \
+ ((cfe_sdramsize > 0x00800000) ? 0x80800000 : 0x80000000)
+#define BOARD_IMAGE_DOWNLOAD_SIZE \
+ ((cfe_sdramsize > 0x00800000) ? cfe_sdramsize - 0x00800000 : 0x00400000)
+
+#define MAX_PROMPT_LEN 50 // assume no one wants to type more than 50 chars
+#define MAX_MAC_STR_LEN 19 // mac address string 18+1 in regular format
+#define PROMPT_DEFINE_LEN 2
+#define MASK_LEN 8 // vxworks like ffffff00
+
+typedef struct
+{
+ char* promptName;
+ char* errorPrompt;
+ char promptDefine[PROMPT_DEFINE_LEN];
+ char parameter[MAX_PROMPT_LEN];
+ int maxValueLength;
+ int (*func)(char *);
+ int enabled;
+} PARAMETER_SETTING, *PPARAMETER_SETTING;
+
+#define IP_PROMPT "Invalid ip address. eg. 192.168.1.200[:ffffff00]"
+#define RUN_FROM_PROMPT "f = jump to flash; h = tftpd from host"
+#define HOST_FN_PROMPT "eg. vmlinux"
+#define FLASH_FN_PROMPT "eg. bcm963xx_fs_kernel"
+#define BOOT_DELAY_PROMPT "range 0-9, 0=forever prompt"
+#define BOOT_PARTITION_PROMPT "1 = latest image, 2 = previous image"
+#define AFE_PROMPT "Invalid AFE ID eg. 0x10608100"
+
+// error input prompts
+#define BOARDID_STR_PROMPT "Invalid board ID"
+#define MAC_CT_PROMPT "Invalid MAC addresses number: 1 - 32"
+#define MAC_ADDR_PROMPT "Invalid MAC address format: eg. 12:34:56:ab:cd:ef or 123456abcdef"
+#define PSI_SIZE_PROMPT "Invalid PSI size: (1-64) Kbytes"
+#define BACKUP_PSI_PROMPT "Enable Backup PSI (0 or 1)"
+#define SYSLOG_SIZE_PROMPT "Invalid System Log size: (0-256) Kbytes"
+#define CPU_TP_PROMPT "Invalid thread number: [0|1]"
+#define GPON_SN_PROMPT "Invalid GPON Serial Number"
+#define GPON_PW_PROMPT "Invalid GPON Password"
+#define WPS_DEVICE_PIN_PROMPT "Invalid WPS Device Pin"
+
+// bootline definition:
+// Space is the deliminator of the parameters. Currently supports following parameters:
+// t=xxx.xxx.xxx.xxx h=xxx.xxx.xxx.xxx g=xxx.xxx.xxx.xxx r=f/h (run from flash or host)
+// f=vmlinux (if r=h) i=bcm963xx_fs_kernel d=3 (default delay, range 0-9, 0=forever prompt)
+
+#define BOOT_IP_LEN 18 // "t=xxx.xxx.xxx.xxx"
+#define BOOT_FILENAME_LEN 50 // "f=vmlinux"
+
+typedef struct
+{
+ char boardIp[BOOT_IP_LEN];
+ char boardMask[BOOT_IP_LEN]; // set for the board only and ignore for the host/gw. fmt :ffffff00
+ char hostIp[BOOT_IP_LEN];
+ char gatewayIp[BOOT_IP_LEN];
+ char runFrom;
+ char hostFileName[BOOT_FILENAME_LEN];
+ char flashFileName[BOOT_FILENAME_LEN];
+ int bootDelay;
+ char bootPartition;
+} BOOT_INFO, *PBOOT_INFO;
+
+#define LED_OFF 0
+#define LED_ON 1
+
+extern void getBootLine(void);
+extern void setDefaultBootline(void);
+extern int printSysInfo(void);
+extern int changeBootLine(void);
+extern int changeAfeId(void);
+extern void dumpHex(unsigned char *start, int len);
+extern BOOT_INFO bootInfo;
+extern void enet_init(void);
+extern int verifyTag(PFILE_TAG pTag, int verbose);
+extern int flashImage(unsigned char *ptr);
+extern int writeWholeImage(unsigned char *ptr, int size);
+
+/* Foxconn add start by Cliff Wang, 03/23/2010 */
+extern int bcm63xx_run(int breakIntoCfe);
+/* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+extern int getPartitionFromTag( PFILE_TAG pTag );
+extern PFILE_TAG getTagFromPartition(int imageNumber);
+extern PFILE_TAG getBootImageTag(void);
+extern int parsexdigit(char str);
+extern int setDefaultBoardParam(void); /* Bob added to set default board parameters, 11/01/2010 */
+extern int setBoardParam(void);
+extern int setGponBoardParam(void);
+extern int setWpsDevicePinBoardParam(void);
+extern int setVoiceBoardParam(void);
+extern int getBoardParam(void);
+extern void displayBoardParam(void);
+extern int processPrompt(PPARAMETER_SETTING promptPtr, int promptCt);
+extern UINT32 getCrc32(unsigned char *pdata, UINT32 size, UINT32 crc);
+extern int yesno(void);
+extern int bcm63xx_cfe_rawload(cfe_loadargs_t *la);
+extern int bcm63xx_cfe_elfload(cfe_loadargs_t *la);
+extern void setGpio (unsigned short led_gpio, unsigned short led_state);
+extern void setLed ( unsigned short led, unsigned short led_state );
+extern void setAllLedsOff(void);
+extern void setPowerOnLedOn(void);
+extern void setBreakIntoCfeLed(void);
+extern void softReset(void);
+extern void validateNandPartTbl(PNVRAM_DATA pNvramData);
+extern void writeNvramData(PNVRAM_DATA pNvramData);
+extern int readNvramData(PNVRAM_DATA pNvramData);
+
+/* Foxconn add start by Jenny Zhao, 07/02/2008*/
+extern int nmrp_led_toggle(void);
+extern int power_led_toggle(int state);
+extern int verify_board_id(char *buf);
+/* Foxconn add end by Jenny Zhao, 07/02/2008*/
+#endif // _BCM63XX_UTIL_H_
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_common.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_common.h
new file mode 100755
index 0000000..136267a
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_common.h
@@ -0,0 +1,32 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2004 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+#ifndef __BCM_COMMON_H
+#define __BCM_COMMON_H
+
+#if defined (_BCM96328_)
+#include "6328_common.h"
+#endif
+#if defined (_BCM96362_)
+#include "6362_common.h"
+#endif
+#if defined (_BCM96368_)
+#include "6368_common.h"
+#endif
+#if defined (_BCM96816_)
+#include "6816_common.h"
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_cpu.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_cpu.h
new file mode 100755
index 0000000..e033936
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_cpu.h
@@ -0,0 +1,32 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2004 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+#ifndef __BCM_CPU_H
+#define __BCM_CPU_H
+
+#if defined (_BCM96328_)
+#include "6328_cpu.h"
+#endif
+#if defined (_BCM96362_)
+#include "6362_cpu.h"
+#endif
+#if defined (_BCM96368_)
+#include "6368_cpu.h"
+#endif
+#if defined (_BCM96816_)
+#include "6816_cpu.h"
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_map.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_map.h
new file mode 100755
index 0000000..0383431
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcm_map.h
@@ -0,0 +1,32 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2004 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+#ifndef __BCM_MAP_H
+#define __BCM_MAP_H
+
+#if defined (_BCM96328_)
+#include "6328_map.h"
+#endif
+#if defined (_BCM96362_)
+#include "6362_map.h"
+#endif
+#if defined (_BCM96368_)
+#include "6368_map.h"
+#endif
+#if defined (_BCM96816_)
+#include "6816_map.h"
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmmii.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmmii.h
new file mode 100755
index 0000000..a33de5c
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmmii.h
@@ -0,0 +1,164 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2004 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+#ifndef _BCMMII_H_
+#define _BCMMII_H_
+
+#include "dev_bcm63xx_eth.h"
+
+/*---------------------------------------------------------------------*/
+/* Broadcom PHY MII register address */
+/* use when PhyType is BP_ENET_INTERNAL_PHY */
+/*---------------------------------------------------------------------*/
+#define BCM_PHY_ID_M 0x1F
+#define IsExtPhyId(id) ((id & BCM_PHY_ID_M) >= 0x10)
+//#define BCM_WAN_PORT 0x40
+//#define IsWanPort(id) (((id) & BCM_WAN_PORT) && ((id) != 0xFF))
+
+#define MII_ASR 0x19
+#define MII_INTERRUPT 0x1A
+#define MII_RESERVED_1B 0x1B
+#define MII_BRCM_TEST 0x1F
+
+/* MII ASR register. */
+#define MII_ASR_DONE(r) ((r & 0x8000) != 0)
+#define MII_ASR_LINK(r) ((r & 0x0004) != 0)
+#define MII_ASR_FDX(r) (((r & 0x0700) == 0x0700) || ((r & 0x0700) == 0x0500) || ((r & 0x0700) == 0x0200))
+#define MII_ASR_1000(r) (((r & 0x0700) == 0x0700) || ((r & 0x0700) == 0x0600))
+#define MII_ASR_100(r) (((r & 0x0700) == 0x0500) || ((r & 0x0700) == 0x0300))
+#define MII_ASR_10(r) (((r & 0x0700) == 0x0200) || ((r & 0x0700) == 0x0100))
+
+/* Reserved 0x1B register */
+#define MII_RESERVED_1B_ACT_LED 0x0004
+
+/* Broadcom Test register. */
+#define MII_BRCM_TEST_SHADOW2_ENABLE 0x0004
+
+/* MII Interrupt register. */
+#define MII_INTR_ENABLE 0x4000
+
+#define BCM54610_PHYID2 0xBD63
+#define BCM_PHYID_M 0xFFF0
+
+#define MII_REGISTER_1C 0x1c
+ #define MII_1C_WRITE_ENABLE (1 << 15)
+ #define MII_1C_SHADOW_REG_SEL_S 10
+ #define MII_1C_SHADOW_REG_SEL_M 0x1F
+#define MII_1C_SHADOW_CLK_ALIGN_CTRL 0x3
+ #define GTXCLK_DELAY_BYPASS_DISABLE (1 << 9)
+#define MII_1C_SHADOW_LED_CONTROL 0x9
+ #define ACT_LINK_LED_ENABLE (1 << 4)
+#define MII_1C_EXTERNAL_CONTROL_1 0xB
+ #define LOM_LED_MODE (1 << 2)
+
+#define PAGE_CONTROL 0x00
+#define PAGE_SELECT 0xff
+#define PAGE_MANAGEMENT 0x02
+
+/* Control page registers */
+#define REG_MII_PORT_CONTROL 0x08
+#define REG_SWITCH_MODE 0x0b
+#define REG_CONTROL_MII1_PORT_STATE_OVERRIDE 0x0e
+#define REG_POWER_DOWN_MODE 0x0f
+
+/* MII Port Control Register, Page 0x00 Address 0x08 */
+#define REG_MII_PORT_CONTROL_RX_UCST_EN 0x10
+#define REG_MII_PORT_CONTROL_RX_MCST_EN 0x08
+#define REG_MII_PORT_CONTROL_RX_BCST_EN 0x04
+
+/* Switch mode register, Page 0x00 Address 0x0b */
+#define REG_SWITCH_MODE_FRAME_MANAGE_MODE 0x01
+#define REG_SWITCH_MODE_SW_FWDG_EN 0x02
+
+/* MII1 Port State Override Register Page 0x00 Address 0x0e */
+#define REG_CONTROL_MPSO_MII_SW_OVERRIDE 0x80
+#define REG_CONTROL_MPSO_REVERSE_MII 0x10
+#define REG_CONTROL_MPSO_LP_FLOW_CONTROL 0x08
+#define REG_CONTROL_MPSO_SPEED100 0x04
+#define REG_CONTROL_MPSO_SPEED1000 0x08
+#define REG_CONTROL_MPSO_FDX 0x02
+#define REG_CONTROL_MPSO_LINKPASS 0x01
+
+/* Power down mode register Page 0x00 Address 0x0f */
+#define REG_POWER_DOWN_MODE_PORT1_PHY_DISABLE 0x01
+#define REG_POWER_DOWN_MODE_PORT2_PHY_DISABLE 0x02
+#define REG_POWER_DOWN_MODE_PORT3_PHY_DISABLE 0x04
+#define REG_POWER_DOWN_MODE_PORT4_PHY_DISABLE 0x08
+#define REG_POWER_DOWN_MODE_PORT5_PHY_DISABLE 0x10
+
+/* Switch control register page 0x0 */
+#define REG_SWITCH_CONTROL 0x20
+#define REG_SWITCH_CONTROL_MII_DUMP_FWD_EN 0x1
+
+/* Device ID register page 0x02 */
+#define REG_DEVICE_ID 0x30
+#define REG_GLOBAL_CONFIG 0x00
+#define REG_BRCM_HDR_CTRL 0x03
+
+/* Global Configuration Regiater Page 0x02 Address 0x00 */
+#define ENABLE_MII_PORT 0x80
+
+/* Broadcom Header Control Register Page 0x02 Address 0x03*/
+#define REG_BRCM_HDR_ENABLE 0x01
+
+
+
+/*---------------------------------------------------------------------*/
+/* 5325 Switch SPI Interface */
+/* use when configuration type is BP_ENET_CONFIG_SPI_SSB_x */
+/*---------------------------------------------------------------------*/
+#define BCM5325_SPI_CMD_LEN 1
+#define BCM5325_SPI_ADDR_LEN 1
+#define BCM5325_SPI_PREPENDCNT (BCM5325_SPI_CMD_LEN+BCM5325_SPI_ADDR_LEN)
+
+/* 5325 SPI Status Register */
+#define BCM5325_SPI_STS 0xfe
+
+/* 5325 SPI Status Register definition */
+#define BCM5325_SPI_CMD_RACK 0x20
+
+/* 5325 Command Byte definition */
+#define BCM5325_SPI_CMD_READ 0x00 /* bit 0 - Read/Write */
+#define BCM5325_SPI_CMD_WRITE 0x01 /* bit 0 - Read/Write */
+#define BCM5325_SPI_CHIPID_MASK 0x7 /* bit 3:1 - Chip ID */
+#define BCM5325_SPI_CHIPID_SHIFT 1
+#define BCM5325_SPI_CMD_NORMAL 0x60 /* bit 7:4 - Mode */
+#define BCM5325_SPI_CMD_FAST 0x10 /* bit 4 - Mode */
+
+/*---------------------------------------------------------------------*/
+/* 5325 Switch Pseudo PHY MII Register */
+/* use when configuration type is BP_ENET_CONFIG_MDIO_PSEUDO_PHY */
+/*---------------------------------------------------------------------*/
+#define PSEUDO_PHY_ADDR 0x1e /* Pseduo PHY address */
+
+/* Pseudo PHY MII registers */
+#define REG_PSEUDO_PHY_MII_REG16 0x10 /* register 16 - Switch Register Set Access Control Register */
+#define REG_PSEUDO_PHY_MII_REG17 0x11 /* register 17 - Switch Register Set Read/Write Control Register */
+#define REG_PSEUDO_PHY_MII_REG24 0x18 /* register 24 - Switch Accesss Register bit 15:0 */
+#define REG_PSEUDO_PHY_MII_REG25 0x19 /* register 25 - Switch Accesss Register bit 31:16 */
+#define REG_PSEUDO_PHY_MII_REG26 0x20 /* register 26 - Switch Accesss Register bit 47:32 */
+#define REG_PSEUDO_PHY_MII_REG27 0x21 /* register 27 - Switch Accesss Register bit 63:48 */
+
+/*Pseudo PHY MII register 16 Switch Register Set Access Control Register */
+#define REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT 8 /* bit 8..15 - switch page number */
+#define REG_PPM_REG16_MDIO_ENABLE 0x01 /* bit 0 - set MDC/MDIO access enable */
+
+/*Pseudo PHY MII register 17 Switch Register Set Read/Write Control Register */
+#define REG_PPM_REG17_REG_NUMBER_SHIFT 8 /* bit 8..15 - switch register number */
+#define REG_PPM_REG17_OP_DONE 0x00 /* bit 0..1 - no operation */
+#define REG_PPM_REG17_OP_WRITE 0x01 /* bit 0..1 - write operation */
+#define REG_PPM_REG17_OP_READ 0x02 /* bit 0..1 - read operation */
+
+#endif /* _BCMMII_H_ */
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmtypes.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmtypes.h
new file mode 100755
index 0000000..9359663
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bcmtypes.h
@@ -0,0 +1,144 @@
+//
+// bcmtypes.h - misc useful typedefs
+//
+#ifndef BCMTYPES_H
+#define BCMTYPES_H
+
+// These are also defined in typedefs.h in the application area, so I need to
+// protect against re-definition.
+
+#ifndef _TYPEDEFS_H_
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned long uint32;
+typedef unsigned long long uint64;
+typedef signed char int8;
+typedef signed short int16;
+typedef signed long int32;
+typedef signed long long int64;
+#if !defined(__cplusplus)
+typedef int bool;
+#endif
+#endif
+
+typedef unsigned char byte;
+typedef unsigned long sem_t;
+
+typedef unsigned long HANDLE,*PULONG,DWORD,*PDWORD;
+typedef signed long LONG,*PLONG;
+
+typedef unsigned int *PUINT;
+typedef signed int INT;
+
+typedef unsigned short *PUSHORT;
+typedef signed short SHORT,*PSHORT,WORD,*PWORD;
+
+typedef unsigned char *PUCHAR;
+typedef signed char *PCHAR;
+
+typedef void *PVOID;
+
+typedef unsigned char BOOLEAN, *PBOOL, *PBOOLEAN;
+
+typedef unsigned char BYTE,*PBYTE;
+
+//#ifndef __GNUC__
+//The following has been defined in Vxworks internally: vxTypesOld.h
+//redefine under vxworks will cause error
+typedef signed int *PINT;
+
+typedef signed char INT8;
+typedef signed short INT16;
+typedef signed long INT32;
+
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned long UINT32;
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+
+typedef void VOID;
+typedef unsigned char BOOL;
+
+//#endif /* __GNUC__ */
+
+
+// These are also defined in typedefs.h in the application area, so I need to
+// protect against re-definition.
+#ifndef TYPEDEFS_H
+
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+
+// Useful for true/false return values. This uses the
+// Taligent notation (k for constant).
+typedef enum
+{
+ kFalse = 0,
+ kTrue = 1
+} Bool;
+
+#endif
+
+/* macros to protect against unaligned accesses */
+
+#if 0
+/* first arg is an address, second is a value */
+#define PUT16( a, d ) { \
+ *((byte *)a) = (byte)((d)>>8); \
+ *(((byte *)a)+1) = (byte)(d); \
+}
+
+#define PUT32( a, d ) { \
+ *((byte *)a) = (byte)((d)>>24); \
+ *(((byte *)a)+1) = (byte)((d)>>16); \
+ *(((byte *)a)+2) = (byte)((d)>>8); \
+ *(((byte *)a)+3) = (byte)(d); \
+}
+
+/* first arg is an address, returns a value */
+#define GET16( a ) ( \
+ (*((byte *)a) << 8) | \
+ (*(((byte *)a)+1)) \
+)
+
+#define GET32( a ) ( \
+ (*((byte *)a) << 24) | \
+ (*(((byte *)a)+1) << 16) | \
+ (*(((byte *)a)+2) << 8) | \
+ (*(((byte *)a)+3)) \
+)
+#endif
+
+#ifndef YES
+#define YES 1
+#endif
+
+#ifndef NO
+#define NO 0
+#endif
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define READ32(addr) (*(volatile UINT32 *)((ULONG)&addr))
+#define READ16(addr) (*(volatile UINT16 *)((ULONG)&addr))
+#define READ8(addr) (*(volatile UINT8 *)((ULONG)&addr))
+
+#endif
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bsp_config.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bsp_config.h
new file mode 100755
index 0000000..57e51bb
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/bsp_config.h
@@ -0,0 +1,94 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * BSP Configuration file File: bsp_config.h
+ *
+ * This module contains global parameters and conditional
+ * compilation settings for building CFE.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * 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.
+ ********************************************************************* */
+
+#define CFG_CMT 1
+
+#define CFG_INIT_L1 1 /* initialize the L1 cache */
+#define CFG_INIT_L2 0 /* there is no L2 cache */
+
+#define CFG_INIT_DRAM 1 /* initialize DRAM controller */
+#define CFG_DRAM_SIZE xxx /* size of DRAM if you don't initialize */
+ /* NOTE : Size is in kilobytes. */
+
+#define CFG_NETWORK 1 /* define to include network support */
+
+#define CFG_FATFS 0
+#define CFG_UI 1 /* Define to enable user interface */
+
+#define CFG_MULTI_CPUS 0 /* no multi-cpu support */
+
+#define CFG_HEAP_SIZE 1024 /* heap size in kilobytes */
+
+#define CFG_STACK_SIZE 8192 /* stack size (bytes, rounded up to K) */
+
+#define CFG_SERIAL_BAUD_RATE 115200 /* normal console speed */
+
+#define CFG_VENDOR_EXTENSIONS 0
+#define CFG_MINIMAL_SIZE 1
+
+/*
+ * These parameters control the flash driver's sector buffer.
+ * If you write environment variables or make small changes to
+ * flash sectors from user applications, you
+ * need to have the heap big enough to store a temporary sector
+ * for merging in small changes to flash sectors, so you
+ * should set CFG_FLASH_ALLOC_SECTOR_BUFFER in that case.
+ * Otherwise, you can provide an address in unallocated memory
+ * of where to place the sector buffer.
+ */
+
+#define CFG_FLASH_ALLOC_SECTOR_BUFFER 0 /* '1' to allocate sector buffer from the heap */
+#define CFG_FLASH_SECTOR_BUFFER_ADDR (1*1024*1024-128*1024) /* 1MB - 128K */
+#define CFG_FLASH_SECTOR_BUFFER_SIZE (128*1024)
+
+/*
+ * The flash staging buffer is where we store a flash image before we write
+ * it to the flash. It's too big for the heap.
+ */
+
+#define CFG_FLASH_STAGING_BUFFER_ADDR (1*1024*1024)
+#define CFG_FLASH_STAGING_BUFFER_SIZE (1*1024*1024)
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_eth.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_eth.h
new file mode 100755
index 0000000..7432231
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_eth.h
@@ -0,0 +1,127 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2002 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+#ifndef __BCM63XX_ETH_H
+#define __BCM63XX_ETH_H
+
+#include "bcm_hwdefs.h"
+#include "bcm_map.h"
+#include "boardparms.h"
+
+// from linux if_ether.h
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_HLEN 14 /* Total octets in header. */
+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+#define ETH_CRC_LEN 4 /* CRC length */
+// end if_ether.h
+
+/*---------------------------------------------------------------------*/
+/* specify number of BDs and buffers to use */
+/*---------------------------------------------------------------------*/
+#define NR_TX_BDS 20
+#define NR_RX_BDS 20
+#define ENET_MAX_MTU_SIZE 1522 /* Body(1500) + EH_SIZE(14) + FCS(4) + VLAN(4) */
+#define DMA_MAX_BURST_LENGTH 8 /* in 64 bit words */
+#define ENET_BUF_SIZE ((ENET_MAX_MTU_SIZE + 63) & ~63)
+#define DMA_FC_THRESH_LO 5
+#define DMA_FC_THRESH_HI 10
+#define EMAC_TX_WATERMARK 32
+
+#define MAKE4(x) ((x[3] & 0xFF) | ((x[2] & 0xFF) << 8) | ((x[1] & 0xFF) << 16) | ((x[0] & 0xFF) << 24))
+#define MAKE2(x) ((x[1] & 0xFF) | ((x[0] & 0xFF) << 8))
+
+
+#define ERROR(x) xsprintf x
+#ifndef ASSERT
+#define ASSERT(x) if (x); else ERROR(("assert: "__FILE__" line %d\n", __LINE__));
+#endif
+
+//#define DUMP_TRACE
+
+#if defined(DUMP_TRACE)
+#define TRACE (x) xprintf x
+#else
+#define TRACE(x)
+#endif
+
+typedef struct PM_Addr {
+ uint16 valid; /* 1 indicates the corresponding address is valid */
+ unsigned char dAddr[ETH_ALEN];/* perfect match register's destination address */
+ unsigned int ref; /* reference count */
+} PM_Addr;
+#define MAX_PMADDR 4 /* # of perfect match address */
+
+#define NUM_PORTS 1
+
+typedef struct gpio_reg_addrs_t {
+ volatile uint16 *gpio_direction_reg;/* GPIO direction register */
+ volatile uint16 *gpio_value_reg; /* GPIO value register */
+} gpio_reg_addrs_t;
+
+typedef struct ethsw_info_t {
+ gpio_reg_addrs_t sbh;
+ uint32 ssl, clk, mosi, miso; /* GPIO mapping */
+ int cid, page; /* Current chip ID and page */
+} ethsw_info_t;
+
+typedef struct bcmenet_softc {
+
+ volatile DmaRegs *dmaCtrl;
+
+ /* transmit variables */
+ volatile DmaChannelCfg *txDma; /* location of transmit DMA register set */
+ volatile DmaDesc *txBds; /* Memory location of tx Dma BD ring */
+ volatile DmaDesc *txFirstBdPtr; /* ptr to first allocated Tx BD */
+ volatile DmaDesc *txNextBdPtr; /* ptr to next Tx BD to transmit with */
+ volatile DmaDesc *txLastBdPtr; /* ptr to last allocated Tx BD */
+
+ /* receive variables */
+ volatile DmaChannelCfg *rxDma; /* location of receive DMA register set */
+ volatile DmaDesc *rxBds; /* Memory location of rx bd ring */
+ volatile DmaDesc *rxFirstBdPtr; /* ptr to first allocated rx bd */
+ volatile DmaDesc *rxBdReadPtr; /* ptr to next rx bd to be processed */
+ volatile DmaDesc *rxLastBdPtr; /* ptr to last allocated rx bd */
+
+ uint32_t rxBuffers;
+ uint32_t txBuffers;
+
+ uint16 chipId; /* chip's id */
+ uint16 chipRev; /* step */
+ uint8_t hwaddr[ETH_ALEN];
+ ethsw_info_t ethSwitch; /* external switch */
+ ETHERNET_MAC_INFO EnetInfo;
+ uint32_t dmaPort;
+ uint32_t linkCheck;
+} bcmenet_softc;
+
+
+
+#define IncRxBdPtr(x, s) if (x == ((bcmenet_softc *)s)->rxLastBdPtr) \
+ x = ((bcmenet_softc *)s)->rxBds; \
+ else x++
+#define InctxBdPtr(x, s) if (x == ((bcmenet_softc *)s)->txLastBdPtr) \
+ x = ((bcmenet_softc *)s)->txBds; \
+ else x++
+
+// extern and function prototype
+
+extern int32_t _getticks(void);
+
+#ifdef DUMP_DATA
+static void hexdump( unsigned char * src, int srclen, int rowlen, int rows );
+#endif
+
+#endif // __BCM63XX_ETH_H
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_flash.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_flash.h
new file mode 100755
index 0000000..d8e7f1d
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/dev_bcm63xx_flash.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Broadcom Corp. Confidential
+ * Copyright 2001 Broadcom Corp. All Rights Reserved.
+ *
+ * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED
+ * SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM.
+ * YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT
+ * SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
+ *
+ ***************************************************************************
+ * File Name : dev_bcm63xx_flash.h
+ *
+ * Created on : 04/18/2002 seanl
+ ***************************************************************************/
+
+#if !defined(_DEV_BCM63XX_FLASH_)
+#define _DEV_BCM63XX_FLASH_
+
+#include "bcmtypes.h"
+#include "bcm_hwdefs.h"
+
+// Used for images that do not contain a FILE_TAG record.
+#define FLASH_IMAGE_START_ADDR (FLASH_BASE + FLASH_LENGTH_BOOT_ROM)
+
+// FLASH_ADDR_INFO is now defined in flash_common.h
+#include "flash_common.h"
+
+extern void kerSysFlashInit(void);
+extern void kerSysFlashAddrInfoGet(PFLASH_ADDR_INFO pflash_addr_info);
+extern int kerSysNvRamSet(unsigned char *string,int strLen,int offset);
+extern int kerSysNvRamGet(unsigned char *string,int strLen,int offset);
+extern int kerSysBcmImageSet( int flash_start_addr, unsigned char *string, int size, int fWholeImage);
+extern int kerSysErasePsi(void);
+extern int kerSysEraseNvRam(void);
+extern unsigned long kerSysReadFromFlash(void *toaddr, unsigned long fromaddr, unsigned long len);
+
+#endif /* _DEV_BCM63XX_FLASH_ */
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/include/jffs2.h b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/jffs2.h
new file mode 100755
index 0000000..586fb55
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/include/jffs2.h
@@ -0,0 +1,251 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2001-2003 Red Hat, Inc.
+ *
+ * Created by David Woodhouse <dwmw2@infradead.org>
+ *
+ * For licensing information, see the file 'LICENCE' in the
+ * jffs2 directory.
+ *
+ * $Id: jffs2.h,v 1.38 2005/09/26 11:37:23 havasi Exp $
+ *
+ */
+
+#ifndef __LINUX_JFFS2_H__
+#define __LINUX_JFFS2_H__
+
+//include <linux/magic.h>
+
+/* You must include something which defines the C99 uintXX_t types.
+ We don't do it from here because this file is used in too many
+ different environments. */
+
+/* Values we may expect to find in the 'magic' field */
+#define JFFS2_OLD_MAGIC_BITMASK 0x1984
+#define JFFS2_MAGIC_BITMASK 0x1985
+#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */
+#define JFFS2_EMPTY_BITMASK 0xffff
+#define JFFS2_DIRTY_BITMASK 0x0000
+
+#if defined(CONFIG_MTD_BRCMNAND)
+/* JFFS2 eraseblock header compat/incompat/rocompat features set */
+#define JFFS2_EBH_COMPAT_FSET 0x00
+#define JFFS2_EBH_INCOMPAT_FSET 0x00
+#define JFFS2_EBH_ROCOMPAT_FSET 0x00
+#endif
+
+/* Summary node MAGIC marker */
+#define JFFS2_SUM_MAGIC 0x02851885
+
+/* We only allow a single char for length, and 0xFF is empty flash so
+ we don't want it confused with a real length. Hence max 254.
+*/
+#define JFFS2_MAX_NAME_LEN 254
+
+/* How small can we sensibly write nodes? */
+#define JFFS2_MIN_DATA_LEN 128
+
+#define JFFS2_COMPR_NONE 0x00
+#define JFFS2_COMPR_ZERO 0x01
+#define JFFS2_COMPR_RTIME 0x02
+#define JFFS2_COMPR_RUBINMIPS 0x03
+#define JFFS2_COMPR_COPY 0x04
+#define JFFS2_COMPR_DYNRUBIN 0x05
+#define JFFS2_COMPR_ZLIB 0x06
+/* Compatibility flags. */
+#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
+#define JFFS2_NODE_ACCURATE 0x2000
+/* INCOMPAT: Fail to mount the filesystem */
+#define JFFS2_FEATURE_INCOMPAT 0xc000
+/* ROCOMPAT: Mount read-only */
+#define JFFS2_FEATURE_ROCOMPAT 0x8000
+/* RWCOMPAT_COPY: Mount read/write, and copy the node when it's GC'd */
+#define JFFS2_FEATURE_RWCOMPAT_COPY 0x4000
+/* RWCOMPAT_DELETE: Mount read/write, and delete the node when it's GC'd */
+#define JFFS2_FEATURE_RWCOMPAT_DELETE 0x0000
+
+#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
+#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
+#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
+#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
+
+#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6)
+
+#define JFFS2_NODETYPE_XATTR (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 8)
+#define JFFS2_NODETYPE_XREF (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 9)
+
+#if defined(CONFIG_MTD_BRCMNAND)
+#define JFFS2_NODETYPE_ERASEBLOCK_HEADER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 5)
+#endif
+
+/* XATTR Related */
+#define JFFS2_XPREFIX_USER 1 /* for "user." */
+#define JFFS2_XPREFIX_SECURITY 2 /* for "security." */
+#define JFFS2_XPREFIX_ACL_ACCESS 3 /* for "system.posix_acl_access" */
+#define JFFS2_XPREFIX_ACL_DEFAULT 4 /* for "system.posix_acl_default" */
+#define JFFS2_XPREFIX_TRUSTED 5 /* for "trusted.*" */
+
+#define JFFS2_ACL_VERSION 0x0001
+
+// Maybe later...
+//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
+//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
+
+
+#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
+ mount time, don't wait for it to
+ happen later */
+#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
+ compression type */
+
+
+/* These can go once we've made sure we've caught all uses without
+ byteswapping */
+
+typedef struct {
+ uint32_t v32;
+} __attribute__((packed)) jint32_t;
+
+typedef struct {
+ uint32_t m;
+} __attribute__((packed)) jmode_t;
+
+typedef struct {
+ uint16_t v16;
+} __attribute__((packed)) jint16_t;
+
+struct jffs2_unknown_node
+{
+ /* All start like this */
+ jint16_t magic;
+ jint16_t nodetype;
+ jint32_t totlen; /* So we can skip over nodes we don't grok */
+ jint32_t hdr_crc;
+};
+
+struct jffs2_raw_dirent
+{
+ jint16_t magic;
+ jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint32_t pino;
+ jint32_t version;
+ jint32_t ino; /* == zero for unlink */
+ jint32_t mctime;
+ uint8_t nsize;
+ uint8_t type;
+ uint8_t unused[2];
+ jint32_t node_crc;
+ jint32_t name_crc;
+ uint8_t name[0];
+};
+
+/* The JFFS2 raw inode structure: Used for storage on physical media. */
+/* The uid, gid, atime, mtime and ctime members could be longer, but
+ are left like this for space efficiency. If and when people decide
+ they really need them extended, it's simple enough to add support for
+ a new type of raw node.
+*/
+struct jffs2_raw_inode
+{
+ jint16_t magic; /* A constant magic number. */
+ jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */
+ jint32_t totlen; /* Total length of this node (inc data, etc.) */
+ jint32_t hdr_crc;
+ jint32_t ino; /* Inode number. */
+ jint32_t version; /* Version number. */
+ jmode_t mode; /* The file's type or mode. */
+ jint16_t uid; /* The file's owner. */
+ jint16_t gid; /* The file's group. */
+ jint32_t isize; /* Total resultant size of this inode (used for truncations) */
+ jint32_t atime; /* Last access time. */
+ jint32_t mtime; /* Last modification time. */
+ jint32_t ctime; /* Change time. */
+ jint32_t offset; /* Where to begin to write. */
+ jint32_t csize; /* (Compressed) data size */
+ jint32_t dsize; /* Size of the node's data. (after decompression) */
+ uint8_t compr; /* Compression algorithm used */
+ uint8_t usercompr; /* Compression algorithm requested by the user */
+ jint16_t flags; /* See JFFS2_INO_FLAG_* */
+ jint32_t data_crc; /* CRC for the (compressed) data. */
+ jint32_t node_crc; /* CRC for the raw inode (excluding data) */
+ uint8_t data[0];
+};
+
+struct jffs2_raw_xattr {
+ jint16_t magic;
+ jint16_t nodetype; /* = JFFS2_NODETYPE_XATTR */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint32_t xid; /* XATTR identifier number */
+ jint32_t version;
+ uint8_t xprefix;
+ uint8_t name_len;
+ jint16_t value_len;
+ jint32_t data_crc;
+ jint32_t node_crc;
+ uint8_t data[0];
+} __attribute__((packed));
+
+struct jffs2_raw_xref
+{
+ jint16_t magic;
+ jint16_t nodetype; /* = JFFS2_NODETYPE_XREF */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint32_t ino; /* inode number */
+ jint32_t xid; /* XATTR identifier number */
+ jint32_t xseqno; /* xref sequencial number */
+ jint32_t node_crc;
+} __attribute__((packed));
+
+struct jffs2_raw_summary
+{
+ jint16_t magic;
+ jint16_t nodetype; /* = JFFS2_NODETYPE_SUMMARY */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint32_t sum_num; /* number of sum entries*/
+ jint32_t cln_mkr; /* clean marker size, 0 = no cleanmarker */
+ jint32_t padded; /* sum of the size of padding nodes */
+ jint32_t sum_crc; /* summary information crc */
+ jint32_t node_crc; /* node crc */
+ jint32_t sum[0]; /* inode summary info */
+};
+
+#if defined(CONFIG_MTD_BRCMNAND)
+struct jffs2_raw_ebh
+{
+ jint16_t magic;
+ jint16_t nodetype; /* == JFFS2_NODETYPE_ERASEBLOCK_HEADER */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint32_t node_crc;
+ uint8_t reserved; /* reserved for future use and alignment */
+ uint8_t compat_fset;
+ uint8_t incompat_fset;
+ uint8_t rocompat_fset;
+ jint32_t erase_count; /* the erase count of this erase block */
+ jint32_t data[0];
+} __attribute__((packed));
+#endif
+
+union jffs2_node_union
+{
+ struct jffs2_raw_inode i;
+ struct jffs2_raw_dirent d;
+ struct jffs2_raw_xattr x;
+ struct jffs2_raw_xref r;
+ struct jffs2_raw_summary s;
+ struct jffs2_unknown_node u;
+};
+
+/* Data payload for device nodes. */
+union jffs2_device_node {
+ jint16_t old;
+ jint32_t new;
+};
+
+#endif /* __LINUX_JFFS2_H__ */
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/Makefile b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/Makefile
new file mode 100755
index 0000000..7320c9d
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/Makefile
@@ -0,0 +1,55 @@
+BSPOBJS += \
+ dev_bcm63xx_eth.o \
+ dev_bcm63xx_uart.o \
+ dev_bcm63xx_flash.o \
+ flash_api.o \
+ flash_common.o \
+ bcm63xx_ram_boot.o \
+ bcm63xx_devs.o \
+ bcm63xx_board.o \
+ bcm63xx_cmd.o \
+ bcm63xx_util.o \
+ bcm63xx_ldr_raw.o \
+ bcm63xx_ldr_elf.o \
+ bcm63xx_main.o \
+ bcm63xx_env_subr.o \
+ bcm63xx_net_icmp.o \
+ bcm63xx_httpd.o \
+ bcmSpiRes.o \
+ bcmLegSpi.o \
+ boardparms.o \
+ boardparms_voice.o
+
+ifneq ($(strip $(BRCM_CHIP)),6368)
+BSPOBJS += \
+ bcmHsSpi.o
+endif
+
+BSPOBJS += \
+ robosw_reg.o
+
+ifeq ($(strip ${INC_CFI_FLASH_DRIVER}),1)
+BSPOBJS += \
+ cfiflash.o
+endif
+
+ifeq ($(strip ${INC_SPI_FLASH_DRIVER}),1)
+BSPOBJS += \
+ spiflash.o
+endif
+
+ifeq ($(strip ${INC_SPI_PROG_NAND}),1)
+BSPOBJS += \
+ nandflash.o
+endif
+
+ifeq ($(strip ${INC_NAND_FLASH_DRIVER}),1)
+BSPOBJS += \
+ nandflash.o
+endif
+
+ifeq ($(strip ${CFG_WEB_SERVER}),1)
+BSPOBJS += \
+ ul.o \
+ ulinfo.o
+endif
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_board.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_board.c
new file mode 100755
index 0000000..5baa66c
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_board.c
@@ -0,0 +1,830 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * bcm63xx_board.c utility functions for bcm63xx board
+ *
+ * Created on : 09/25/2002 seanl
+ *
+ *********************************************************************
+
+<:copyright-broadcom
+
+ Copyright (c) 2002 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+
+#include "bcm63xx_util.h"
+#include "foxconnCfg.h"
+
+#define MAX_BOARD_ID_NAMES 16
+#define MAX_VOICE_BOARD_ID_NAMES 20
+
+static char g_boardIdNames[BP_BOARD_ID_LEN * MAX_BOARD_ID_NAMES];
+static int g_numBoardIdNames = 0;
+
+static char g_voiceBoardIdNames[BP_BOARD_ID_LEN * MAX_VOICE_BOARD_ID_NAMES];
+static int g_numVoiceBoardIdNames = 0;
+
+static int parsehwaddr(char *, uint8_t *);
+static int parseBoardIdStr(char *);
+static int parseVoiceBoardIdStr(char *);
+static int parsePsiSize(char *);
+static int parseBackupPsi(char *tpStr);
+static int parseSyslogSize(char *tpStr);
+static int parseMainTp(char *);
+static int parseMacAddrCount(char *);
+static int parseMacAddr(char *);
+static int charIsHex(char ch);
+static int parseGponSN(char *snStr);
+static int parseGponPW(char *pwStr);
+static int macNumToStr(unsigned char *, char *);
+static void getGponBoardParam(void);
+static int gponParamsInitialized(NVRAM_DATA *pNvramData);
+
+static int parseWpsDevicePin(char *pinStr);
+static void getWpsDevicePinBoardParam(void);
+#define PARAM_IDX_BOARD_NAME 0
+#define PARAM_IDX_NUM_MAC_ADDR 1
+#define PARAM_IDX_BASE_MAC_ADDR 2
+#define PARAM_IDX_PSI_SIZE 3
+#define PARAM_IDX_ENABLE_BACKUP_PSI 4
+#define PARAM_IDX_SYSLOG_SIZE 5
+#define PARAM_IDX_MAIN_THREAD_NUM 6
+
+#define PARAM_IDX_GPON_SN 0
+#define PARAM_IDX_GPON_PW 1
+
+#define PARAM_IDX_WPS_DEVICE_PIN 0
+
+#define PARAM_IDX_VOICE_BOARD_NAME 0
+
+static PARAMETER_SETTING gBoardParam[] =
+{
+ // prompt name Error Prompt Define Param Validation function
+ {"Board Id (0-# :", BOARDID_STR_PROMPT, "", "", 2,
+ parseBoardIdStr, TRUE},
+ {"Number of MAC Addresses (1-32) :", MAC_CT_PROMPT, "", "", 2,
+ parseMacAddrCount, TRUE},
+ {"Base MAC Address :", MAC_ADDR_PROMPT, "", "", 17,
+ parseMacAddr, TRUE},
+ {"PSI Size (1-64) KBytes :", PSI_SIZE_PROMPT, "", "", 2,
+ parsePsiSize, TRUE},
+ {"Enable Backup PSI [0|1] :", BACKUP_PSI_PROMPT, "", "", 1,
+ parseBackupPsi, TRUE},
+ {"System Log Size (0-256) KBytes :", SYSLOG_SIZE_PROMPT, "", "", 3,
+ parseSyslogSize, TRUE},
+ {"Main Thread Number [0|1] :", CPU_TP_PROMPT, "", "", 1,
+ parseMainTp, TRUE},
+ {NULL}
+};
+
+static int gNumBoardParams = (sizeof(gBoardParam) / sizeof(PARAMETER_SETTING))-1;
+
+static PARAMETER_SETTING gGponBoardParam[] =
+{
+ // prompt name Error Prompt Define Param Validation function
+ {"GPON Serial Number :", GPON_SN_PROMPT, "", "", 12,
+ parseGponSN, TRUE},
+ {"GPON Password :", GPON_PW_PROMPT, "", "", 10,
+ parseGponPW, TRUE},
+ {NULL}
+};
+
+static int gNumGponBoardParams = (sizeof(gGponBoardParam) / sizeof(PARAMETER_SETTING))-1;
+static int gGponParamsInitialized = 0;
+
+
+static PARAMETER_SETTING gWpsDevicePinBoardParam[] =
+{
+ // prompt name Error Prompt Define Param Validation function
+ {"Device Pin :", WPS_DEVICE_PIN_PROMPT, "", "", 8,
+ parseWpsDevicePin, TRUE},
+ {NULL}
+};
+
+static int gNumWpsDevicePinBoardParams = (sizeof(gWpsDevicePinBoardParam) / sizeof(PARAMETER_SETTING))-1;
+static int gWpsDevicePinInitialized = 0;
+
+static PARAMETER_SETTING gVoiceBoardParam[] =
+{
+ // prompt name Error Prompt Define Param Validation function
+ {"Voice Board Configuration (0-# :", BOARDID_STR_PROMPT, "", "", 2,
+ parseVoiceBoardIdStr, FALSE},
+ {NULL}
+};
+
+static int gNumVoiceBoardParams = (sizeof(gVoiceBoardParam) / sizeof(PARAMETER_SETTING))-1;
+static int gVoiceParamsInitialized = 0;
+
+
+static int parsehwaddr(char *str,uint8_t *hwaddr)
+{
+ int digit1,digit2;
+ int idx = 6;
+
+ if (strlen(str) == (MAX_MAC_STR_LEN - 7)) { // no ':' mac input format ie. 021800100801
+ while (*str && (idx > 0)) {
+ digit1 = parsexdigit(*str);
+ if (digit1 < 0)
+ return -1;
+ str++;
+ if (!*str)
+ return -1;
+ digit2 = parsexdigit(*str);
+ if (digit2 < 0)
+ return -1;
+ *hwaddr++ = (digit1 << 4) | digit2;
+ idx--;
+ str++;
+ }
+ return 0;
+ }
+
+ if (strlen(str) != MAX_MAC_STR_LEN-2)
+ return -1;
+ if (*(str+2) != ':' || *(str+5) != ':' || *(str+8) != ':' || *(str+11) != ':' || *(str+14) != ':')
+ return -1;
+
+ while (*str && (idx > 0)) {
+ digit1 = parsexdigit(*str);
+ if (digit1 < 0)
+ return -1;
+ str++;
+ if (!*str)
+ return -1;
+
+ if (*str == ':') {
+ digit2 = digit1;
+ digit1 = 0;
+ }
+ else {
+ digit2 = parsexdigit(*str);
+ if (digit2 < 0)
+ return -1;
+ str++;
+ }
+
+ *hwaddr++ = (digit1 << 4) | digit2;
+ idx--;
+
+ if (*str == ':')
+ str++;
+ }
+ return 0;
+}
+
+
+static int parseMacAddr(char * macStr)
+{
+ unsigned char tmpBuf[MAX_PROMPT_LEN];
+
+ return (parsehwaddr(macStr, tmpBuf));
+}
+
+
+static int parseBoardIdStr(char *boardIdStr)
+{
+ int ret = 1;
+ int boardId;
+
+ if (strlen (boardIdStr) != 0) {
+ boardId = atoi(boardIdStr);
+ if (boardId >= 0 && boardId < g_numBoardIdNames)
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+static int parseVoiceBoardIdStr(char *boardIdStr)
+{
+ int ret = 1;
+ int boardId;
+
+ if (strlen (boardIdStr) != 0) {
+ boardId = atoi(boardIdStr);
+ if (boardId >= 0 && boardId < g_numVoiceBoardIdNames)
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+static int parseMacAddrCount(char *ctStr)
+{
+ int count = atoi(ctStr);
+
+ if (count >= 1 && count <= NVRAM_MAC_COUNT_MAX)
+ return 0;
+ else
+ return 1;
+}
+
+static int parsePsiSize(char *tpStr)
+{
+ int psiSize = atoi(tpStr);
+
+ if (psiSize >= 1 && psiSize <= NVRAM_MAX_PSI_SIZE)
+ return 0;
+ else
+ return 1;
+}
+
+static int parseBackupPsi(char *tpStr)
+{
+ int enable = atoi(tpStr);
+
+ if (enable == 0 || enable == 1)
+ return 0;
+ else
+ return 1;
+}
+
+static int parseSyslogSize(char *tpStr)
+{
+ int syslogSize = atoi(tpStr);
+
+ if (syslogSize >= 0 && syslogSize <= NVRAM_MAX_SYSLOG_SIZE)
+ return 0;
+ else
+ return 1;
+}
+
+
+static int parseMainTp(char *tpStr)
+{
+ int tpNum = atoi(tpStr);
+
+ if (tpNum == 0 || tpNum == 1)
+ return 0;
+ else
+ return 1;
+}
+
+static int charIsHex(char ch)
+{
+ if (((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'a') && (ch <= 'f')) ||
+ ((ch >= 'A') && (ch <= 'F')))
+ return 1;
+ else
+ return 0;
+}
+
+static int parseGponSN(char *snStr)
+{
+ int i;
+ int ret = 0;
+
+ if(strlen(snStr) == NVRAM_GPON_SERIAL_NUMBER_LEN-1) {
+ for(i=4; i<NVRAM_GPON_SERIAL_NUMBER_LEN-1; ++i) {
+ if(!charIsHex(snStr[i])) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ else {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static int parseGponPW(char *pwStr)
+{
+ if(strlen(pwStr) == NVRAM_GPON_PASSWORD_LEN-1)
+ return 0;
+ else
+ return 1;
+}
+
+static int parseWpsDevicePin(char *pinStr)
+{
+ unsigned char accum=0;
+ unsigned char factor[NVRAM_WPS_DEVICE_PIN_LEN]={3,1,3,1,3,1,3,1};
+ int i =0;
+
+ /*Check Length*/
+ if(strlen(pinStr) != NVRAM_WPS_DEVICE_PIN_LEN)
+ return 1;
+
+ /*valid checksum*/
+ for ( i=0; i< NVRAM_WPS_DEVICE_PIN_LEN; i++ )
+ accum += (pinStr[i]-'0')*factor[i];
+
+ if ( (accum%10) ==0 )
+ return 0;
+
+ return 1;
+}
+
+int macNumToStr(unsigned char *macAddr, char *str)
+{
+ if (macAddr == NULL || str == NULL)
+ return 0;
+
+ sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ macAddr[0], macAddr[1], macAddr[2],
+ macAddr[3], macAddr[4], macAddr[5]);
+ return 1;
+}
+
+static int gponParamsInitialized(NVRAM_DATA *pNvramData)
+{
+ int i;
+ int erased = 1;
+
+ for(i=0; i<NVRAM_GPON_SERIAL_NUMBER_LEN-1; ++i) {
+ if((pNvramData->gponSerialNumber[i] != (char)0xFF) &&
+ (pNvramData->gponSerialNumber[i] != '\0')) {
+ erased = 0;
+ break;
+ }
+ }
+
+ if(erased) {
+ for(i=0; i<NVRAM_GPON_PASSWORD_LEN-1; ++i) {
+ if((pNvramData->gponPassword[i] != (char)0xFF) &&
+ (pNvramData->gponPassword[i] != '\0')) {
+ erased = 0;
+ break;
+ }
+ }
+ }
+
+ return (erased) ? 0 : 1;
+}
+
+static void getGponBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ int erased;
+ int i;
+ int writeNvram = 0;
+
+ readNvramData(&nvramData);
+
+ erased = 1;
+ for(i=0; i<NVRAM_GPON_SERIAL_NUMBER_LEN-1; ++i) {
+ if((nvramData.gponSerialNumber[i] != (char)0xFF) &&
+ (nvramData.gponSerialNumber[i] != '\0')) {
+ erased = 0;
+ break;
+ }
+ }
+
+ if(erased) {
+ strcpy(nvramData.gponSerialNumber, DEFAULT_GPON_SN);
+ writeNvram = 1;
+ }
+
+ erased = 1;
+ for(i=0; i<NVRAM_GPON_PASSWORD_LEN-1; ++i) {
+ if((nvramData.gponPassword[i] != (char)0xFF) &&
+ (nvramData.gponPassword[i] != '\0')) {
+ erased = 0;
+ break;
+ }
+ }
+
+ if(erased) {
+ strcpy(nvramData.gponPassword, DEFAULT_GPON_PW);
+ writeNvram = 1;
+ }
+
+ if(writeNvram) {
+ writeNvramData(&nvramData);
+ }
+
+ strcpy(gGponBoardParam[PARAM_IDX_GPON_SN].parameter, nvramData.gponSerialNumber);
+ strcpy(gGponBoardParam[PARAM_IDX_GPON_PW].parameter, nvramData.gponPassword);
+}
+
+int setGponBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ int ret = 0;
+
+ getGponBoardParam();
+
+ readNvramData(&nvramData);
+
+ if (processPrompt(gGponBoardParam, gNumGponBoardParams)) {
+
+ // At least one field was changed
+ strcpy(nvramData.gponSerialNumber, gGponBoardParam[PARAM_IDX_GPON_SN].parameter);
+ strcpy(nvramData.gponPassword, gGponBoardParam[PARAM_IDX_GPON_PW].parameter);
+
+ // save the buf to nvram
+ writeNvramData(&nvramData);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+
+
+static int gWpsDevicePinParamsInitialized(NVRAM_DATA *pNvramData)
+{
+ int i;
+
+ for(i=0; i<NVRAM_WPS_DEVICE_PIN_LEN; ++i) {
+ if(( (unsigned char)(pNvramData->wpsDevicePin[i]) > 0x39) ||
+ ( (unsigned char)(pNvramData->wpsDevicePin[i]) < 0x30) ) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void getWpsDevicePinBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+
+ readNvramData(&nvramData);
+
+ if ( gWpsDevicePinParamsInitialized( &nvramData) ) {
+ memcpy(gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].parameter,
+ nvramData.wpsDevicePin, NVRAM_WPS_DEVICE_PIN_LEN);
+ (gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].parameter)[NVRAM_WPS_DEVICE_PIN_LEN] =
+ '\0';
+ }
+ else {
+ /*Set Default Device Pin*/
+ memcpy(nvramData.wpsDevicePin, DEFAULT_WPS_DEVICE_PIN, NVRAM_WPS_DEVICE_PIN_LEN);
+ writeNvramData(&nvramData);
+
+ memcpy(gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].parameter,
+ nvramData.wpsDevicePin,
+ NVRAM_WPS_DEVICE_PIN_LEN);
+ (gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].parameter)[NVRAM_WPS_DEVICE_PIN_LEN] =
+ '\0';
+ }
+
+}
+
+int setWpsDevicePinBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ int ret = 0;
+
+ getWpsDevicePinBoardParam();
+
+ readNvramData(&nvramData);
+
+ if (processPrompt(gWpsDevicePinBoardParam, gNumWpsDevicePinBoardParams)) {
+ memcpy(nvramData.wpsDevicePin,
+ gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].parameter,
+ NVRAM_WPS_DEVICE_PIN_LEN);
+ // save the buf to nvram
+ writeNvramData(&nvramData);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+
+static int voiceParamsInitialized(NVRAM_DATA *pNvramData)
+{
+ int rc = 0;
+ NVRAM_DATA nvramData;
+ readNvramData(&nvramData);
+
+ if ( BpSetBoardId(nvramData.szBoardId) == BP_SUCCESS ) {
+ if ( BpGetVoipDspConfig( 0 ) == NULL ) {
+ gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].enabled = FALSE;
+ }
+ else {
+ gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].enabled = TRUE;
+ rc = 1;
+ }
+ }
+
+ return rc;
+}
+
+static void getVoiceBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ char *ptr;
+ char tmp[10];
+
+ if (g_numVoiceBoardIdNames == 0)
+ g_numVoiceBoardIdNames = BpGetVoiceBoardIds(g_voiceBoardIdNames, MAX_VOICE_BOARD_ID_NAMES);
+
+ ptr = strchr(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].promptName, '#');
+ if (ptr != NULL) {
+ sprintf(tmp, "%d)", g_numVoiceBoardIdNames - 1);
+ memcpy(ptr, tmp, strlen(tmp));
+ }
+
+ readNvramData(&nvramData);
+
+ memcpy(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter, nvramData.szVoiceBoardId, NVRAM_BOARD_ID_STRING_LEN);
+ gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter[NVRAM_BOARD_ID_STRING_LEN] = '\0';
+}
+
+int setVoiceBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ char voiceBoardIdPrompt[1000];
+ int i;
+ char tmp[3];
+ char *voiceBoardIdPromptPtr, *savedVoiceBoardIdPromptPtr;
+ int ret = 0;
+
+ getVoiceBoardParam();
+
+ readNvramData(&nvramData);
+
+ // Create prompt string with voice board ID name selection
+ voiceBoardIdPromptPtr = voiceBoardIdPrompt;
+ for (i = 0; i < g_numVoiceBoardIdNames; i++) {
+ sprintf (tmp, "%d", i);
+ sprintf (voiceBoardIdPromptPtr, "%-17s-- %2s\n", &g_voiceBoardIdNames[i * BP_BOARD_ID_LEN], tmp);
+ voiceBoardIdPromptPtr += strlen(voiceBoardIdPromptPtr);
+ }
+ strcpy (voiceBoardIdPromptPtr, gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].promptName);
+
+ // Save existing prompt string
+ savedVoiceBoardIdPromptPtr = gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].promptName;
+ // Set newly created prompt string
+ gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].promptName = voiceBoardIdPrompt;
+
+ // Convert board ID string to numeric value
+ for (i = 0; i < g_numVoiceBoardIdNames; i++) {
+ if (!strcmp(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter, &g_voiceBoardIdNames[i * BP_BOARD_ID_LEN])) {
+ sprintf(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter, "%d", i);
+ }
+ }
+
+ if (processPrompt(gVoiceBoardParam, gNumVoiceBoardParams)) {
+ // At least one field was changed
+ i = atoi(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter);
+ strcpy(nvramData.szVoiceBoardId, &g_voiceBoardIdNames[i * BP_BOARD_ID_LEN]);
+
+ // save the buf to nvram
+ writeNvramData(&nvramData);
+ ret = 1;
+ }
+
+ // Convert numeric value of voice board ID to string
+ gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].promptName = savedVoiceBoardIdPromptPtr;
+ i = atoi(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter);
+ strcpy(gVoiceBoardParam[PARAM_IDX_VOICE_BOARD_NAME].parameter, &g_voiceBoardIdNames[i * BP_BOARD_ID_LEN]);
+
+ return ret;
+}
+
+
+//
+// getBoardParam: convert the board param data and put them in the gBoardParam struct
+//
+int getBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ char *ptr;
+ char tmp[10];
+ int ret = 0;
+
+ if (g_numBoardIdNames == 0)
+ g_numBoardIdNames = BpGetBoardIds(g_boardIdNames, MAX_BOARD_ID_NAMES);
+
+ ptr = strchr(gBoardParam[PARAM_IDX_BOARD_NAME].promptName, '#');
+ if (ptr != NULL) {
+ sprintf(tmp, "%d)", g_numBoardIdNames - 1);
+ memcpy(ptr, tmp, strlen(tmp));
+ }
+
+ readNvramData(&nvramData);
+
+ if(!gGponParamsInitialized) {
+ gGponParamsInitialized = gponParamsInitialized(&nvramData);
+ }
+
+ /*WPS Device Pin Initialized?*/
+ if(!gWpsDevicePinInitialized) {
+ gWpsDevicePinInitialized = gWpsDevicePinParamsInitialized(&nvramData);
+ }
+
+ if (nvramData.ulVersion == -1) {
+ // Set default values
+ nvramData.ulVersion = NVRAM_VERSION_NUMBER;
+ nvramData.szBoardId[0] = '\0';
+ nvramData.ulNumMacAddrs = DEFAULT_MAC_NUM;
+ parsehwaddr(DEFAULT_BOARD_MAC, nvramData.ucaBaseMacAddr);
+ nvramData.ulMainTpNum = DEFAULT_TP_NUM;
+ nvramData.szVoiceBoardId[0] = '\0';
+ nvramData.ulPsiSize = DEFAULT_PSI_SIZE;
+ nvramData.backupPsi = 0;
+ nvramData.ulSyslogSize = 0;
+ writeNvramData(&nvramData);
+ }
+ else if (nvramData.ulVersion != NVRAM_VERSION_NUMBER) {
+ // When upgrading from older bootloader initialize new fields
+ printf("*** Upgrading NVRAM (version %d to version %d) ***\n\n",
+ nvramData.ulVersion, NVRAM_VERSION_NUMBER);
+ nvramData.ulVersion = NVRAM_VERSION_NUMBER;
+ if (nvramData.ulMainTpNum == -1)
+ nvramData.ulMainTpNum = DEFAULT_TP_NUM;
+ if ((nvramData.ulPsiSize == -1) || (nvramData.ulPsiSize == 0))
+ nvramData.ulPsiSize = DEFAULT_PSI_SIZE;
+ nvramData.szVoiceBoardId[0] = '\0';
+ if (nvramData.backupPsi == -1)
+ nvramData.backupPsi = 0;
+ if (nvramData.ulSyslogSize == -1)
+ nvramData.ulSyslogSize = 0;
+ writeNvramData(&nvramData);
+ ret = 1;
+ }
+
+ gVoiceParamsInitialized = voiceParamsInitialized(&nvramData);
+
+ // When backupPsi and syslog were introduced, the NVRAM version number
+ // was not bumped up. So convert -1 (unitialized) to 0 so it looks better.
+ if (nvramData.backupPsi == -1)
+ nvramData.backupPsi = 0;
+ if (nvramData.ulSyslogSize == -1)
+ nvramData.ulSyslogSize = 0;
+
+ strcpy(gBoardParam[PARAM_IDX_BOARD_NAME].parameter, nvramData.szBoardId);
+ sprintf(gBoardParam[PARAM_IDX_NUM_MAC_ADDR].parameter, "%d", nvramData.ulNumMacAddrs);
+ macNumToStr(nvramData.ucaBaseMacAddr, gBoardParam[PARAM_IDX_BASE_MAC_ADDR].parameter);
+ sprintf(gBoardParam[PARAM_IDX_PSI_SIZE].parameter, "%d", nvramData.ulPsiSize);
+ sprintf(gBoardParam[PARAM_IDX_ENABLE_BACKUP_PSI].parameter, "%d", nvramData.backupPsi);
+ sprintf(gBoardParam[PARAM_IDX_SYSLOG_SIZE].parameter, "%d", nvramData.ulSyslogSize);
+ sprintf(gBoardParam[PARAM_IDX_MAIN_THREAD_NUM].parameter, "%d", nvramData.ulMainTpNum);
+
+ return ret;
+}
+
+/* Bob added start to set default board parameters, 11/01/2010 */
+int setDefaultBoardParam(void)
+{
+ NVRAM_DATA nvramData;
+ int ret = 0;
+
+ if (getBoardParam()) {
+ /* New NVRAM version */
+ return ret;
+ }
+
+ readNvramData(&nvramData);
+
+ {
+ // At least one field was changed
+ nvramData.ulVersion = NVRAM_VERSION_NUMBER;
+ strcpy(nvramData.szBoardId, "963281TAN");
+ strcpy(nvramData.szFirmwareUpgradeBoardId, FOXCONN_BOARD_ID);
+ nvramData.ulNumMacAddrs = 10;
+ parsehwaddr("00:00:00:00:00:01", nvramData.ucaBaseMacAddr);
+ nvramData.ulPsiSize = 24;
+ nvramData.backupPsi = 0;
+ nvramData.ulSyslogSize = 0;
+ nvramData.ulMainTpNum = 0;
+
+ // save the buf to nvram
+ writeNvramData(&nvramData);
+ ret = 1;
+ }
+
+ return ret;
+}
+/* Bob added end to set default board parameters, 11/01/2010 */
+
+//
+// setBoardParam: Set the board Id string, mac addresses, psi size, etc...
+//
+int setBoardParam(void)
+{
+ char boardIdPrompt[1000];
+ NVRAM_DATA nvramData;
+ int i;
+ char tmp[3];
+ char *boardIdPromptPtr, *savedBoardIdPromptPtr;
+ int ret = 0;
+
+ if (getBoardParam()) {
+ /* New NVRAM version */
+ return ret;
+ }
+
+ readNvramData(&nvramData);
+
+ // Create prompt string with board ID name selection
+ boardIdPromptPtr = boardIdPrompt;
+ for (i = 0; i < g_numBoardIdNames; i++) {
+ sprintf (tmp, "%d", i);
+ sprintf (boardIdPromptPtr, "%-17s------- %2s\n", &g_boardIdNames[i * BP_BOARD_ID_LEN], tmp);
+ boardIdPromptPtr += strlen(boardIdPromptPtr);
+ }
+ strcpy (boardIdPromptPtr, gBoardParam[PARAM_IDX_BOARD_NAME].promptName);
+
+ // Save existing prompt string
+ savedBoardIdPromptPtr = gBoardParam[PARAM_IDX_BOARD_NAME].promptName;
+ // Set newly created prompt string
+ gBoardParam[PARAM_IDX_BOARD_NAME].promptName = boardIdPrompt;
+
+ // Convert board ID string to numeric value
+ for (i = 0; i < g_numBoardIdNames; i++) {
+ if (!strcmp(gBoardParam[PARAM_IDX_BOARD_NAME].parameter, &g_boardIdNames[i * BP_BOARD_ID_LEN])) {
+ sprintf(gBoardParam[PARAM_IDX_BOARD_NAME].parameter, "%d", i);
+ }
+ }
+
+ if (processPrompt(gBoardParam, gNumBoardParams)) {
+ // At least one field was changed
+ nvramData.ulVersion = NVRAM_VERSION_NUMBER;
+
+ // Convert numeric value of board ID to string
+ i = atoi(gBoardParam[PARAM_IDX_BOARD_NAME].parameter);
+ strcpy(nvramData.szBoardId, &g_boardIdNames[i * BP_BOARD_ID_LEN]);
+
+ nvramData.ulNumMacAddrs = atoi(gBoardParam[PARAM_IDX_NUM_MAC_ADDR].parameter);
+ parsehwaddr(gBoardParam[PARAM_IDX_BASE_MAC_ADDR].parameter, nvramData.ucaBaseMacAddr);
+ nvramData.ulPsiSize = atoi(gBoardParam[PARAM_IDX_PSI_SIZE].parameter);
+ nvramData.backupPsi = atoi(gBoardParam[PARAM_IDX_ENABLE_BACKUP_PSI].parameter);
+ nvramData.ulSyslogSize = atoi(gBoardParam[PARAM_IDX_SYSLOG_SIZE].parameter);
+ nvramData.ulMainTpNum = atoi(gBoardParam[PARAM_IDX_MAIN_THREAD_NUM].parameter);
+
+ // save the buf to nvram
+ writeNvramData(&nvramData);
+ ret = 1;
+ }
+
+ // restore gBoardParam
+ // Convert numeric value of board ID to string
+ gBoardParam[PARAM_IDX_BOARD_NAME].promptName = savedBoardIdPromptPtr;
+ i = atoi(gBoardParam[PARAM_IDX_BOARD_NAME].parameter);
+ strcpy(gBoardParam[PARAM_IDX_BOARD_NAME].parameter, &g_boardIdNames[i * BP_BOARD_ID_LEN]);
+
+ if(gGponParamsInitialized) {
+ printf("\n");
+ ret += setGponBoardParam();
+ }
+
+ if(gWpsDevicePinInitialized) {
+ printf("\n");
+ ret += setWpsDevicePinBoardParam();
+ }
+
+ gVoiceParamsInitialized = voiceParamsInitialized(&nvramData);
+
+ if(gVoiceParamsInitialized) {
+ printf("\n");
+ ret += setVoiceBoardParam();
+ }
+
+ return ret;
+}
+
+void displayBoardParam(void)
+{
+ int i;
+
+ getBoardParam();
+
+ for (i = 0; i < gNumBoardParams; i++) {
+ if( gBoardParam[i].enabled )
+ printf("%s %s \n", gBoardParam[i].promptName, gBoardParam[i].parameter);
+ }
+
+ if(gGponParamsInitialized) {
+ getGponBoardParam();
+
+ for (i = 0; i < gNumGponBoardParams; i++)
+ if( gGponBoardParam[i].enabled )
+ printf("%s \"%s\" \n", gGponBoardParam[i].promptName, gGponBoardParam[i].parameter);
+ }
+
+ /*Show WPS Device PIN */
+ if(gWpsDevicePinInitialized) {
+ getWpsDevicePinBoardParam();
+ if ( gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].enabled)
+ printf("%s \"%s\" \n", gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].promptName, \
+ gWpsDevicePinBoardParam[PARAM_IDX_WPS_DEVICE_PIN].parameter);
+ }
+
+ if(gVoiceParamsInitialized) {
+ getVoiceBoardParam();
+
+ for (i = 0; i < gNumVoiceBoardParams; i++)
+ if( gVoiceBoardParam[i].enabled )
+ printf("%s %s \n", gVoiceBoardParam[i].promptName, gVoiceBoardParam[i].parameter);
+ }
+}
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;
+}
+
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_devs.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_devs.c
new file mode 100755
index 0000000..ac75083
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_devs.c
@@ -0,0 +1,734 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Board device initialization File: bcm94710_devs.c
+ *
+ * This is the "C" part of the board support package. The
+ * routines to create and initialize the console, wire up
+ * device drivers, and do other customization live here.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * XX Copyright 2000,2001
+ * Broadcom Corporation. All rights reserved.
+ *
+ * BROADCOM PROPRIETARY AND CONFIDENTIAL
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the license.
+ ********************************************************************* */
+
+#include "lib_types.h"
+#include "lib_printf.h"
+
+/* Foxconn add start by Cliff Wang, 03/23/2010 */
+#include "lib_string.h"
+/* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+#include "cfe_timer.h"
+#include "cfe.h"
+#include "bcm_map.h"
+#include "bcm_hwdefs.h"
+#include "bcmTag.h"
+#include "dev_bcm63xx_flash.h"
+#include "bcm63xx_util.h"
+#include "flash_api.h"
+
+/* Foxconn add start by Cliff Wang, 03/23/2010 */
+#include "tftpd.h"
+/* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+static int checkForResetToDefaultHold( unsigned short rstToDfltIrq );
+
+/* Foxconn added start , 1/29/2010 */
+#include "gpio_drv.h"
+#include "foxconnCfg.h"
+
+typedef enum
+{
+ kGpioInactive,
+ kGpioActive
+} GPIO_STATE_t;
+static int test_led_control(int on_off);
+int power_led_toggle(int state);
+int nmrp_led_toggle(void);
+int verify_board_id(char *buf);
+int verify_checksum(char *buf, unsigned long buf_len, unsigned long chksum);
+#define NR_LED 24
+/* Foxconn added end , 1/29/2010 */
+
+/* *********************************************************************
+ * Devices we're importing
+ ********************************************************************* */
+
+extern cfe_driver_t bcm63xx_uart;
+extern cfe_driver_t bcm63xx_enet;
+
+/* *********************************************************************
+ * board_console_init()
+ *
+ * Add the console device and set it to be the primary
+ * console.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void board_console_init(void)
+{
+ /* Add the serial port driver. */
+ cfe_add_device(&bcm63xx_uart,0,0,0);
+
+ cfe_set_console( "uart0" );
+}
+
+
+/* *********************************************************************
+ * board_device_init()
+ *
+ * Initialize and add other devices. Add everything you need
+ * for bootstrap here, like disk drives, flash memory, UARTs,
+ * network controllers, etc.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void board_device_init(void)
+{
+ unsigned short GPIOOverlays;
+
+ kerSysFlashInit();
+
+#if defined (_BCM96328_)
+ if( BpGetGPIOverlays(&GPIOOverlays) == BP_SUCCESS ) {
+ /* Start with all HW LEDs disabled */
+ LED->ledHWDis |= 0xFFFFFF;
+ if (GPIOOverlays & BP_OVERLAY_SERIAL_LEDS) {
+ GPIO->PinMuxSel |= PINMUX_SERIAL_LED_DATA;
+ GPIO->PinMuxSel |= PINMUX_SERIAL_LED_CLK;
+ LED->ledInit |= LED_SERIAL_LED_EN;
+ }
+ /* Enable LED controller to drive GPIO */
+ /* foxconn modified start to let hardware control only act LEDs, Bob, 08/04/2010 */
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_0) {
+ GPIO->PinMuxSel |= PINMUX_EPHY0_ACT_LED;
+ //GPIO->GPIOMode |= (1 << EPHY0_SPD_LED);
+ //LED->ledHWDis &= ~(1 << EPHY0_SPD_LED);
+ }
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_1) {
+ GPIO->PinMuxSel |= PINMUX_EPHY1_ACT_LED;
+ //GPIO->GPIOMode |= (1 << EPHY1_SPD_LED);
+ //LED->ledHWDis &= ~(1 << EPHY1_SPD_LED);
+ }
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_2) {
+ GPIO->PinMuxSel |= PINMUX_EPHY2_ACT_LED;
+ //GPIO->GPIOMode |= (1 << EPHY2_SPD_LED);
+ //LED->ledHWDis &= ~(1 << EPHY2_SPD_LED);
+ }
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_3) {
+ GPIO->PinMuxSel |= PINMUX_EPHY3_ACT_LED;
+ //GPIO->GPIOMode |= (1 << EPHY3_SPD_LED);
+ //LED->ledHWDis &= ~(1 << EPHY3_SPD_LED);
+ }
+ /* foxconn modified end, Bob, 08/04/2010 */
+ }
+#endif
+
+#if defined (_BCM96362_)
+ if( BpGetGPIOverlays(&GPIOOverlays) == BP_SUCCESS ) {
+ /* Start with all HW LEDs disabled */
+ LED->ledHWDis |= 0xFFFFFF;
+ if (GPIOOverlays & BP_OVERLAY_SERIAL_LEDS) {
+ GPIO->GPIOMode |= (GPIO_MODE_SERIAL_LED_CLK | GPIO_MODE_SERIAL_LED_DATA);
+ LED->ledInit |= LED_SERIAL_LED_EN;
+ }
+ /* Map HW LEDs to LED controller inputs and enable LED controller to drive GPIO */
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_0) {
+ LED->ledLinkActSelHigh |= ((1 << (LED_ENET0 - 4)) << LED_4_LINK_SHIFT);
+ GPIO->LEDCtrl |= (1 << LED_ENET0);
+ LED->ledHWDis &= ~(1 << LED_ENET0);
+ }
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_1) {
+ LED->ledLinkActSelHigh |= ((1 << (LED_ENET1 - 4)) << LED_5_LINK_SHIFT);
+ GPIO->LEDCtrl |= (1 << LED_ENET1);
+ LED->ledHWDis &= ~(1 << LED_ENET1);
+ }
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_2) {
+ LED->ledLinkActSelHigh |= ((1 << (LED_ENET2 - 4)) << LED_6_LINK_SHIFT);
+ GPIO->LEDCtrl |= (1 << LED_ENET2);
+ LED->ledHWDis &= ~(1 << LED_ENET2);
+ }
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_3) {
+ LED->ledLinkActSelHigh |= ((1 << (LED_ENET3 - 4)) << LED_7_LINK_SHIFT);
+ GPIO->LEDCtrl |= (1 << LED_ENET3);
+ LED->ledHWDis &= ~(1 << LED_ENET3);
+ }
+ }
+#endif
+
+#if defined (_BCM96368_)
+ TIMER->WDResetCount = 50000; // Assert reset for 1ms only. If reset asserted for too
+ // long chip reboots twice
+ if( BpGetGPIOverlays(&GPIOOverlays) == BP_SUCCESS ) {
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_0) {
+ GPIO->GPIOMode |= GPIO_MODE_EPHY0_LED;
+ GPIO->GPIODir |= GPIO_MODE_EPHY0_LED;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_1) {
+ GPIO->GPIOMode |= GPIO_MODE_EPHY1_LED;
+ GPIO->GPIODir |= GPIO_MODE_EPHY1_LED;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_2) {
+ GPIO->GPIOMode |= GPIO_MODE_EPHY2_LED;
+ GPIO->GPIODir |= GPIO_MODE_EPHY2_LED;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_EPHY_LED_3) {
+ GPIO->GPIOMode |= GPIO_MODE_EPHY3_LED;
+ GPIO->GPIODir |= GPIO_MODE_EPHY3_LED;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_SERIAL_LEDS) {
+ GPIO->GPIOMode |= (GPIO_MODE_SERIAL_LED_CLK | GPIO_MODE_SERIAL_LED_DATA);
+ GPIO->GPIODir |= (GPIO_MODE_SERIAL_LED_CLK | GPIO_MODE_SERIAL_LED_DATA);
+ GPIO->SerialLed = 0xffffffff;
+ }
+ }
+
+ /* These blocks will be enabled by the appropriate driver if they are
+ * compiled into a router image.
+ */
+ PERF->blkEnables &= ~(USBH_CLK_EN | PCM_CLK_EN | SAR_CLK_EN | USBD_CLK_EN);
+#endif
+
+#if defined (_BCM96816_)
+ TIMER->WDResetCount = 50000; // Assert reset for 1ms only. If reset asserted for too
+ // long chip reboots twice
+
+ if( BpGetGPIOverlays(&GPIOOverlays) == BP_SUCCESS ) {
+ if (GPIOOverlays & BP_OVERLAY_GPHY_LED_0) {
+ GPIO->GPIOMode |= GPIO_MODE_GPHY0_LED;
+ GPIO->GPIODir |= GPIO_MODE_GPHY0_LED;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_GPHY_LED_1) {
+ GPIO->GPIOMode |= GPIO_MODE_GPHY1_LED;
+ GPIO->GPIODir |= GPIO_MODE_GPHY1_LED;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_SERIAL_LEDS) {
+ GPIO->GPIOMode |= (GPIO_MODE_SERIAL_LED_CLK | GPIO_MODE_SERIAL_LED_DATA);
+ GPIO->GPIODir |= (GPIO_MODE_SERIAL_LED_CLK | GPIO_MODE_SERIAL_LED_DATA);
+ GPIO->SerialLed = 0xffffffff;
+ }
+
+ if (GPIOOverlays & BP_OVERLAY_MOCA_LED) {
+ GPIO->GPIOMode |= GPIO_MODE_MOCA_LED;
+ GPIO->GPIODir |= GPIO_MODE_MOCA_LED;
+ }
+ }
+
+ MISC->miscMoCARst &= ~(MISC_MOCA_RST_REF_DIV2RST | MISC_MOCA_RST_REF_FBDIVRST);
+ MISC->miscMoCARst &= ~MISC_MOCA_RST_REF_VCRST;
+ MISC->miscMoCARst &= ~(MISC_MOCA_RST_REF_OUTDIV_RESET_M_MASK | MISC_MOCA_RST_REF_MDIV2RST);
+ MISC->miscMoCACtl |= (7 << MISC_MOCA_CTL_REF_QP_ICTRL_SHIFT);
+ MISC->miscMoCARst &= ~MISC_MOCA_RST_REF_LD_RESET_STRT;
+ PERF->softResetB &= ~(SOFT_RST_MOCA_CPU | SOFT_RST_MOCA_SYS | SOFT_RST_MOCA);
+#endif
+
+#if defined (_BCM96328_) || defined (_BCM96362_)
+ LED->ledInit &= ~LED_FAST_INTV_MASK;
+ LED->ledInit |= (LED_INTERVAL_20MS * 4) << LED_FAST_INTV_SHIFT;
+#else
+ /* Set blink rate for hardware LEDs. */
+ GPIO->LEDCtrl &= ~LED_INTERVAL_SET_MASK;
+ GPIO->LEDCtrl |= LED_INTERVAL_SET_80MS;
+#endif
+
+ /* Add the ethernet driver. */
+ cfe_add_device( &bcm63xx_enet, 0, 0, 0);
+}
+
+
+void setGpio (unsigned short led_gpio, unsigned short led_state)
+{
+#if 0
+ unsigned short gpio_state;
+
+ if (((led_gpio & BP_ACTIVE_LOW) && (led_state == LED_ON)) ||
+ (!(led_gpio & BP_ACTIVE_LOW) && (led_state == LED_OFF)))
+ gpio_state = 0;
+ else
+ gpio_state = 1;
+#endif
+
+ GPIO->GPIODir |= GPIO_NUM_TO_MASK(led_gpio);
+ if( led_state )
+ GPIO->GPIOio |= GPIO_NUM_TO_MASK(led_gpio);
+ else
+ GPIO->GPIOio &= ~GPIO_NUM_TO_MASK(led_gpio);
+}
+
+
+/* *********************************************************************
+ * board_final_init()
+ *
+ * Do any final initialization, such as adding commands to the
+ * user interface.
+ *
+ * If you don't want a user interface, put the startup code here.
+ * This routine is called just before CFE starts its user interface.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void board_final_init(void)
+{
+ unsigned short rstToDfltIrq;
+ int breakIntoCfe = 0;
+
+ /* Foxconn add start by Cliff Wang, 03/23/2010 */
+ int goAuto;
+ /* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+ setAllLedsOff();
+ setPowerOnLedOn();
+ setGpio(GPIO_POWER_RED_LED, GPIO_POWER_RED_LED_ON);
+#if (INC_SPI_PROG_NAND==1)
+ rstToDfltIrq = 1 ;
+ breakIntoCfe = rstToDfltIrq;
+#else
+ if( (bootInfo.runFrom == 'f') && getBootImageTag() == NULL ) {
+ setBreakIntoCfeLed();
+ printf("** Flash image not found. **\n\n");
+ kerSysErasePsi();
+ breakIntoCfe = 1;
+ }
+
+ if( BpGetResetToDefaultExtIntr( &rstToDfltIrq ) == BP_SUCCESS ) {
+ if (checkForResetToDefaultHold( rstToDfltIrq )) {
+ kerSysErasePsi();
+ /* Reset the default bootline if the board IP address has changed. */
+ if (strcmp(bootInfo.boardIp, DEFAULT_BOARD_IP) != 0) {
+ setDefaultBootline();
+ }
+ /* Foxconn modified start pling 09/09/2008 */
+ /* just load default, don't break into console */
+ //breakIntoCfe = 1;
+ printf("\n** Load default! **\n\n");
+ /* Foxconn modified end pling 09/09/2008 */
+ }
+ }
+#endif
+ /* Foxconn add start by Cliff Wang, 03/23/2010 */
+ goAuto = bcm63xx_run(breakIntoCfe);
+ setBreakIntoCfeLed();
+ if(goAuto)
+ {
+ ui_docommand("tftpd");
+ }
+ /* Foxconn add end by Cliff Wang, 03/23/2010 */
+}
+
+/* *********************************************************************
+ * Miscellaneous Board Functions
+ ********************************************************************* */
+
+/* *********************************************************************
+ * checkForResetToDefaultHold()
+ *
+ * Determines if the user is holding the reset to default button.
+ *
+ * Input parameters:
+ * Reset to default irq#
+ *
+ * Return value:
+ * 1 - break into the CFE, 0 - continue boot sequence
+ ********************************************************************* */
+#if (INC_SPI_PROG_NAND==0)
+static int checkForResetToDefaultHold( unsigned short rstToDfltIrq )
+{
+ const int nBreakIntoCfeDelay = 5;
+ int ret = 0;
+ int i;
+ uint32 irqBit;
+ volatile uint32 *extIrqReg;
+
+ extIrqReg = &PERF->ExtIrqCfg;
+ irqBit = 1 << (rstToDfltIrq + EI_STATUS_SHFT);
+
+#if defined(_BCM96368_)
+ if (rstToDfltIrq >= BP_EXT_INTR_4 && rstToDfltIrq <= BP_EXT_INTR_5) {
+ extIrqReg = &PERF->ExtIrqCfg1;
+ irqBit = 1 << (rstToDfltIrq - BP_EXT_INTR_4 + EI_STATUS_SHFT);
+ }
+#endif
+
+ /* Loop while the reset to default button is depressed. */
+ for(i = 0; !(*extIrqReg & irqBit); i++) {
+ if (i == nBreakIntoCfeDelay) {
+ setBreakIntoCfeLed();
+ printf("\n*** Break into CFE console ***\n\n");
+ ret = 1;
+ break;
+ }
+ cfe_sleep(CFE_HZ);
+ }
+
+ return( ret );
+}
+#endif
+/* *********************************************************************
+ * setLed(led_gpio, led_state)
+ *
+ * Turns on an LED.
+ *
+ * Input parameters:
+ * LED purpose
+ * LED State
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void setLed (unsigned short led_gpio, unsigned short led_state)
+{
+ unsigned short gpio_state;
+
+ if (((led_gpio & BP_ACTIVE_LOW) && (led_state == LED_ON)) ||
+ (!(led_gpio & BP_ACTIVE_LOW) && (led_state == LED_OFF)))
+ gpio_state = 0;
+ else
+ gpio_state = 1;
+
+#if defined(_BCM96328_)
+ /* Enable LED controller to drive this GPIO */
+ if (!(led_gpio & BP_GPIO_SERIAL))
+ GPIO->GPIOMode |= GPIO_NUM_TO_MASK(led_gpio);
+#endif
+
+#if defined(_BCM96362_)
+ /* Enable LED controller to drive this GPIO */
+ if (!(led_gpio & BP_GPIO_SERIAL))
+ GPIO->LEDCtrl |= GPIO_NUM_TO_MASK(led_gpio);
+#endif
+
+#if defined(_BCM96328_) || defined(_BCM96362_)
+ LED->ledMode &= ~(LED_MODE_MASK << GPIO_NUM_TO_LED_MODE_SHIFT(led_gpio));
+ if( gpio_state )
+ LED->ledMode |= (LED_MODE_OFF << GPIO_NUM_TO_LED_MODE_SHIFT(led_gpio));
+ else
+ LED->ledMode |= (LED_MODE_ON << GPIO_NUM_TO_LED_MODE_SHIFT(led_gpio));
+
+#else
+ if (led_gpio & BP_GPIO_SERIAL) {
+ while (GPIO->SerialLedCtrl & SER_LED_BUSY);
+ if( gpio_state )
+ GPIO->SerialLed |= GPIO_NUM_TO_MASK(led_gpio);
+ else
+ GPIO->SerialLed &= ~GPIO_NUM_TO_MASK(led_gpio);
+ }
+ else {
+ GPIO->GPIODir |= GPIO_NUM_TO_MASK(led_gpio);
+ if( gpio_state )
+ GPIO->GPIOio |= GPIO_NUM_TO_MASK(led_gpio);
+ else
+ GPIO->GPIOio &= ~GPIO_NUM_TO_MASK(led_gpio);
+ }
+#endif
+}
+
+/* *********************************************************************
+ * setAllLedsOff()
+ *
+ * Turns off all board LEDs on init
+ *
+ * Input parameters:
+ * LED purpose
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void setAllLedsOff(void)
+{
+ unsigned short gpio;
+
+ if( BpGetAdslLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetAdslFailLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetSecAdslLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetSecAdslFailLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetWirelessSesLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetHpnaLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetWanDataLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetWanErrorLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetBootloaderPowerOnLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetBootloaderStopLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetVoipLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetVoip1LedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetVoip2LedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetPotsLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetGponLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetMoCALedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetGponFailLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetMoCAFailLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+}
+
+/* *********************************************************************
+ * setPowerOnLedOn()
+ *
+ * Turns on the Power LED.
+ *
+ * Input parameters:
+ * LED purpose
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void setPowerOnLedOn(void)
+{
+ unsigned short gpio;
+ if( BpGetBootloaderStopLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ if( BpGetBootloaderPowerOnLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_ON );
+}
+
+
+/* *********************************************************************
+ * setBreakIntoCfeLed()
+ *
+ * Turns on the alarm LED.
+ *
+ * Input parameters:
+ * LED purpose
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void setBreakIntoCfeLed(void)
+{
+ unsigned short gpio;
+ if( BpGetBootloaderStopLedGpio( &gpio ) == BP_SUCCESS ) {
+ setLed( gpio, LED_ON );
+ if( BpGetBootloaderPowerOnLedGpio( &gpio ) == BP_SUCCESS )
+ setLed( gpio, LED_OFF );
+ }
+}
+
+/* *********************************************************************
+ * softReset()
+ *
+ * Resets the board.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void softReset(void)
+{
+ printf( "\nResetting board...\n" );
+#if defined (_BCM96816_)
+ /* Work around reset issues */
+ HVG->reg_hvg_cha_misc |= HVG_SOFT_INIT_0;
+ HVG->reg_hvg_chb_misc |= HVG_SOFT_INIT_0;
+#endif
+
+#if defined(_BCM96328_)
+ TIMER->SoftRst |= SOFT_RESET;
+#else
+ PERF->pll_control |= SOFT_RESET; // soft reset mips
+#if defined(_BCM96368_) || defined(_BCM96816_)
+ PERF->pll_control = 0;
+#endif
+#endif
+ while (1);
+}
+
+/* Foxconn added start , 1/29/2010 */
+extern int nmrp_server_detected;
+
+int test_led_control(int on_off)
+{
+ // unsigned short gpio;
+ int tftpd_state = get_tftpd_state();
+
+ if (tftpd_state == TFTPD_STATE_OFF)
+ {
+ setGpio(GPIO_POWER_RED_LED, GPIO_POWER_RED_LED_ON); //turn red power led
+ }
+ else if ( (tftpd_state == TFTPD_STATE_WAIT_IMAGE) || (tftpd_state == TFTPD_STATE_WRITE_IMAGE) )
+ {
+ if (on_off==1)
+ {
+ setGpio(GPIO_POWER_RED_LED, GPIO_POWER_RED_LED_ON);
+ }
+ else
+ {
+ setGpio(GPIO_POWER_RED_LED, GPIO_POWER_RED_LED_OFF);
+ }
+ }
+
+ return 0;
+}
+
+int power_led_toggle(int state)
+{
+ test_led_control(state);
+ return 0;
+}
+
+int nmrp_led_toggle(void)
+{
+ static int led_state = 0;
+
+ /* Foxconn added end for U12H154 */
+
+ if (led_state == 0)
+ {
+ led_state = 1;
+ setGpio(18, 1);
+ }
+ else
+ {
+ led_state = 0;
+ setGpio(18, 0);
+ }
+
+ return 0;
+}
+
+
+static unsigned long calculate_checksum (int action, char *s, int size)
+{
+ static unsigned long c0, c1;
+ unsigned long checksum, b;
+ int i;
+ switch (action)
+ {
+ case 0:
+ c0 = c1 = 0;
+ break;
+
+ case 1:
+ for (i = 0; i < size; i++)
+ {
+ c0 += s[i] & 0xff;
+ c1 += c0;
+ /* check the lan/wan ports status, Foxconn added by EricHuang, 10/24/2006 */
+ if ((i % 90000) == 0)
+ {
+ printf(".");
+// bcm_robo_check_link_status();
+ }
+ }
+ break;
+
+ case 2:
+ b = (c0 & 65535) + ((c0 >> 16) & 65535);
+ c0 = ((b >> 16) + b) & 65535;
+
+ b = (c1 & 65535) + ((c1 >> 16) & 65535);
+ c1 = ((b >> 16) + b) & 65535;
+
+ checksum = ((c1 << 16) | c0);
+
+ return checksum;
+ }
+ return 0;
+}
+
+int verify_checksum(char *buf, unsigned long buf_len, unsigned long chksum)
+{
+ unsigned long cal_chksum = 0;
+
+ xprintf("Loading .");
+ calculate_checksum (0, NULL, 0);
+ calculate_checksum (1, buf, buf_len);
+ cal_chksum = calculate_checksum (2, NULL, 0);
+ printf("\n");
+
+
+ if (cal_chksum != chksum) {
+ xprintf("Image chksum: 0x%08X\n", chksum);
+ xprintf("Calc chksum: 0x%08X\n", cal_chksum);
+ return -1;
+ }
+
+#ifdef _DEBUG
+ //printf("verify_checksum calculate_checksum = 0x%08X\n", cal_chksum);
+ //printf("verify_checksum image_chksum = 0x%08X\n", chksum);
+#endif
+
+ return 0;
+}
+
+int verify_board_id(char *buf)
+{
+ /* char *board_id = ( char *)BOARD_DATA_ADDR; */
+ char board_id[PROJECT_ID_LEN];
+
+ kerSysReadFromFlash(board_id, BOARD_DATA_ADDR, PROJECT_ID_LEN);
+
+ if(nmrp_server_detected==1) // in NMRP mode
+ {
+ if (strncmp(buf, board_id, PROJECT_ID_LEN) != 0)
+ {
+ printf("verify_board_id failed: (%s)\n", buf);
+ return -1;
+ }
+ }
+ else
+ {
+ if (strcmp(buf, board_id) != 0)
+ {
+ /* Foxconn removed start pling 12/10/2008 */
+ /* Don't check board ID in 'tftpd' mode */
+ printf("verify_board_id failed: (%s)\n", buf);
+ //return -1;
+ /* Foxconn removed end pling 12/10/2008 */
+ }
+ }
+ return 0;
+}
+
+/* Foxconn added end , 1/29/2010 */
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_env_subr.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_env_subr.c
new file mode 100755
index 0000000..3ce3a28
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_env_subr.c
@@ -0,0 +1,277 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Environment variable subroutines File: env_subr.c
+ *
+ * This module contains routines to muck with environment variables
+ * (manage the list, read/write to nvram, etc.)
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * 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 "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "env_subr.h"
+///#include "nvram_subr.h"
+
+#include "cfe_error.h"
+#include "cfe.h"
+
+/* *********************************************************************
+ * Types
+ ********************************************************************* */
+
+typedef struct cfe_envvar_s {
+ queue_t qb;
+ int flags;
+ char *name;
+ char *value;
+ /* name and value go here */
+} cfe_envvar_t;
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+queue_t env_envvars = {&env_envvars,&env_envvars};
+extern unsigned int cfe_startflags;
+
+/* *********************************************************************
+ * env_findenv(name)
+ *
+ * Locate an environment variable in the in-memory list
+ *
+ * Input parameters:
+ * name - name of env var to find
+ *
+ * Return value:
+ * cfe_envvar_t pointer, or NULL if not found
+ ********************************************************************* */
+
+static cfe_envvar_t *env_findenv(const char *name)
+{
+ queue_t *qb;
+ cfe_envvar_t *env;
+
+ for (qb = env_envvars.q_next; qb != &env_envvars; qb = qb->q_next) {
+ env = (cfe_envvar_t *) qb;
+ if (strcmp(env->name,name) == 0) break;
+ }
+
+ if (qb == &env_envvars) return NULL;
+
+ return (cfe_envvar_t *) qb;
+
+}
+
+/* *********************************************************************
+ * env_enum(idx,name,namelen,val,vallen)
+ *
+ * Enumerate environment variables. This routine locates
+ * the nth environment variable and copies its name and value
+ * to user buffers.
+ *
+ * The namelen and vallen variables must be preinitialized to
+ * the maximum size of the output buffer.
+ *
+ * Input parameters:
+ * idx - variable index to find (starting with zero)
+ * name,namelen - name buffer and length
+ * val,vallen - value buffer and length
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+
+int env_enum(int idx,char *name,int *namelen,char *val,int *vallen)
+{
+ queue_t *qb;
+ cfe_envvar_t *env;
+
+ for (qb = env_envvars.q_next; qb != &env_envvars; qb = qb->q_next) {
+ if (idx == 0) break;
+ idx--;
+ }
+
+ if (qb == &env_envvars) return CFE_ERR_ENVNOTFOUND;
+ env = (cfe_envvar_t *) qb;
+
+ *namelen = xstrncpy(name,env->name,*namelen);
+ *vallen = xstrncpy(val,env->value,*vallen);
+
+ return 0;
+
+}
+
+/* *********************************************************************
+ * env_envtype(name)
+ *
+ * Return the type of the environment variable
+ *
+ * Input parameters:
+ * name - name of environment variable
+ *
+ * Return value:
+ * flags, or <0 if error occured
+ ********************************************************************* */
+int env_envtype(const char *name)
+{
+ cfe_envvar_t *env;
+
+ env = env_findenv(name);
+
+ if (env) {
+ return env->flags;
+ }
+
+ return CFE_ERR_ENVNOTFOUND;
+}
+
+
+
+/* *********************************************************************
+ * env_delenv(name)
+ *
+ * Delete an environment variable
+ *
+ * Input parameters:
+ * name - environment variable to delete
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+
+int env_delenv(const char *name)
+{
+ cfe_envvar_t *env;
+
+ env = env_findenv(name);
+
+ if (!env) return 0;
+
+ if (!(env->flags & ENV_FLG_READONLY)) {
+ q_dequeue((queue_t *) env);
+ KFREE(env);
+ return 0;
+ }
+
+ return CFE_ERR_ENVNOTFOUND;
+}
+
+/* *********************************************************************
+ * env_getenv(name)
+ *
+ * Retrieve the value of an environment variable
+ *
+ * Input parameters:
+ * name - name of environment variable to find
+ *
+ * Return value:
+ * value, or NULL if variable is not found
+ ********************************************************************* */
+
+char *env_getenv(const char *name)
+{
+ cfe_envvar_t *env;
+
+ env = env_findenv(name);
+
+ if (env) {
+ return env->value;
+ }
+
+ return NULL;
+}
+
+
+/* *********************************************************************
+ * env_setenv(name,value,flags)
+ *
+ * Set the value of an environment variable
+ *
+ * Input parameters:
+ * name - name of variable
+ * value - value of variable
+ * flags - flags for variable (ENV_FLG_xxx)
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+
+int env_setenv(const char *name,char *value,int flags)
+{
+ cfe_envvar_t *env;
+ int namelen;
+
+ env = env_findenv(name);
+ if (env) {
+ if (!(flags & ENV_FLG_ADMIN)) {
+ if (env->flags & ENV_FLG_READONLY) return CFE_ERR_ENVREADONLY;
+ }
+ q_dequeue((queue_t *) env);
+ KFREE(env);
+ }
+
+ namelen = strlen(name);
+
+ env = KMALLOC(sizeof(cfe_envvar_t) + namelen + 1 + strlen(value) + 1,0);
+ if (!env) return CFE_ERR_NOMEM;
+
+ env->name = (char *) (env+1);
+ env->value = env->name + namelen + 1;
+ env->flags = (flags & ENV_FLG_MASK);
+
+ strcpy(env->name,name);
+ strcpy(env->value,value);
+
+ q_enqueue(&env_envvars,(queue_t *) env);
+
+ return 0;
+}
+int env_save(void)
+{
+ return 0;
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_httpd.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_httpd.c
new file mode 100755
index 0000000..dcd5b0a
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_httpd.c
@@ -0,0 +1,1031 @@
+/* milli_httpd - pretty small HTTP server
+** A combination of
+** micro_httpd - really small HTTP server
+** and
+** mini_httpd - small HTTP server
+**
+** Copyright 1999,2000 by Jef Poskanzer <jef@acme.com>.
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+** 1. Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+** FOR ANY 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) ARISING IN ANY WAY
+** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+** SUCH DAMAGE.
+*/
+
+#if (CFG_WEB_SERVER==1)
+
+/** Includes. **/
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_timer.h"
+#include "cfe_error.h"
+#include "cfe.h"
+#include "cfe_iocb.h"
+#include "cfe_devfuncs.h"
+
+#include "bsp_config.h"
+
+#include "bcmTag.h"
+#include "bcm63xx_util.h"
+
+
+/** Externs. **/
+
+extern char ul_html[];
+extern char ulinfo_html[];
+extern int ul_html_size;
+extern int ulinfo_html_size;
+
+extern int g_console_abort;
+extern int g_processing_cmd;
+
+/** Defines. **/
+
+#define SERVER_NAME "micro_httpd"
+#define SERVER_URL "http://www.acme.com/software/micro_httpd/"
+#define SERVER_PORT 80
+#define PROTOCOL "HTTP/1.0"
+#define POST_DATA_START (unsigned char *) \
+ BOARD_IMAGE_DOWNLOAD_ADDRESS
+#define SOCKET_CLOSED -100
+#define NUM_SOCKETS 4
+
+/* Return codes from cfe_web_gets. */
+#define WEB_GETS_DONE 1
+#define WEB_GETS_PENDING 2
+#define WEB_GETS_ERROR 3
+
+/* HTTP states. */
+#define HTTP_INITIAL 0
+#define HTTP_READ_FIRST_HDR 1
+#define HTTP_READ_REMAINING_HDRS 2
+#define HTTP_READ_POST_DATA 3
+
+/* HTTP POST status */
+#define UPLOAD_OK '0'
+#define UPLOAD_FAIL_NO_MEM '1'
+#define UPLOAD_FAIL_NO_FILENAME '2'
+#define UPLOAD_FAIL_ILLEGAL_IMAGE '3'
+#define UPLOAD_FAIL_IMAGE_TOOBIG '4'
+#define UPLOAD_FAIL_CORRUPT_IMAGE '5'
+#define UPLOAD_FAIL_FLASH '6'
+#define UPLOAD_FATAL '7'
+#define UPLOAD_PENDING '8'
+#define UPLOAD_TCP_ERROR '9'
+
+/* HTTP upload image formats. */
+#define NO_IMAGE_FORMAT 0
+#define BROADCOM_IMAGE_FORMAT 1
+#define FLASH_IMAGE_FORMAT 2
+
+
+/** Structs. **/
+
+typedef struct
+{
+ int s;
+ int state;
+ int web_buf_idx;
+ int post_content_length;
+ char web_first_buf[128];
+ char web_buf[256];
+} SOCKET_INFO, *PSOCKET_INFO;
+
+typedef struct
+{
+ char *wp_name;
+ char *wp_content_buf;
+ int *wp_content_size;
+ char *wp_mime_type;
+} WEB_PAGE_MAP, *PWEB_PAGE_MAP;
+
+
+/** Globals. **/
+
+static int g_listen_idx = 0;
+static unsigned char *g_image_start = NULL;
+static int g_image_len = 0;
+static int g_image_format = NO_IMAGE_FORMAT;
+static int g_post_data_in_progress = 0;
+static int g_post_data_idx = 0;
+
+static SOCKET_INFO g_socket_info[NUM_SOCKETS];
+
+static WEB_PAGE_MAP g_web_page_map[] =
+ {
+ {"/", ul_html, &ul_html_size, "text/html"},
+ {"/upload.html", ul_html, &ul_html_size, "text/html"},
+ {"/uploadinfo.html", ulinfo_html, &ulinfo_html_size, "text/html"},
+ {NULL, NULL, 0, NULL}
+ };
+
+
+/** Prototypes. **/
+
+int cfe_web_check(void);
+void cfe_web_fg_process(void);
+void cfe_web_poll(void *x);
+static void cfe_web_listen( int *listen_idx_ptr );
+static void cfe_web_bg_process(PSOCKET_INFO si);
+static int cfe_web_gets( char *web_buf, int web_buf_size,
+ int *web_buf_idx_ptr, int s );
+static int read_first_hdr(int s, char *web_buf, int web_buf_size,
+ int *web_buf_idx_ptr, int *close_tcp_ptr);
+static int read_remaining_hdrs(int s, char *web_buf, int web_buf_size,
+ int *web_buf_idx_ptr, int *close_tcp_ptr, int *content_length_ptr);
+static char read_post_data( int s, unsigned char *post_data_start,
+ int content_length, int *post_data_idx_ptr );
+static char parse_post_data( int s, unsigned char *post_data_start,
+ int post_data_length, unsigned char **image_start_ptr, int *image_len_ptr,
+ int *image_format_ptr );
+static void send_error( int s, int status, char* title, char* extra_header,
+ char* text );
+static void send_error( int s, int status, char* title, char* extra_header,
+ char* text );
+static void send_headers( int s, int status, char* title, char* extra_header,
+ char* mime_type );
+static void send_page( int s, char *path, int send_headers_flag,
+ char **substs, int num_substs );
+static int cfe_web_tcp_send( int s, char *buf, int size );
+void * memmove(void * dest,const void *src,size_t count);
+
+
+/***************************************************************************
+ * Function Name: cfe_web_check
+ * Description : Checks if an image has been downloaded through an HTTP POST
+ * request and is ready to be written to flash memory.
+ * Returns : 1 - image is ready to be flashed, 0 - nothing to do
+ ***************************************************************************/
+int cfe_web_check(void)
+{
+ return( (g_image_format != NO_IMAGE_FORMAT) ? 1 : 0 );
+} /* cfe_web_check */
+
+
+/***************************************************************************
+ * Function Name: cfe_web_process
+ * Description : Calls the appropriate functions to write an image to
+ * flash memory.
+ * Returns : None.
+ ***************************************************************************/
+void cfe_web_fg_process(void)
+{
+ /* Wait so the uploadinfo web page can be displayed on the browser. */
+ cfe_sleep(CFE_HZ * 2);
+ if( g_image_format == BROADCOM_IMAGE_FORMAT )
+ flashImage( g_image_start );
+ else
+ if( g_image_format == FLASH_IMAGE_FORMAT )
+ writeWholeImage( g_image_start, g_image_len );
+
+ if( g_image_format != NO_IMAGE_FORMAT )
+ softReset();
+
+} /* cfe_web_process */
+
+
+/***************************************************************************
+ * Function Name: cfe_web_poll
+ * Description : The entry point function that is called in the background
+ * at polled intervals. It listens for and processes HTTP
+ * requests.
+ * Returns : None.
+ ***************************************************************************/
+void cfe_web_poll(void *x)
+{
+ static int first_time = 1;
+ static int in_cfe_web_poll = 0;
+
+ PSOCKET_INFO si;
+ int i;
+
+ if( in_cfe_web_poll == 0 )
+ {
+ in_cfe_web_poll = 1;
+
+ /* If this is the first time that this function was called, initialize
+ * the socket info data array.
+ */
+ if( first_time == 1 )
+ {
+ first_time = 0;
+ for( i = 0, si = g_socket_info; i < NUM_SOCKETS; i++, si++ )
+ {
+ si->s = SOCKET_CLOSED;
+ si->state = HTTP_READ_FIRST_HDR;
+ si->web_buf_idx = 0;
+ si->post_content_length = 0;
+ }
+ }
+
+ /* Check the connection state of each socket. */
+ for( i = 0, si = g_socket_info; i < NUM_SOCKETS; i++, si++ )
+ {
+ cfe_web_listen( &g_listen_idx );
+ if( si->s >= 0 )
+ {
+ unsigned int connflag;
+ tcp_status( si->s, &connflag, NULL, NULL );
+ if( connflag == TCPSTATUS_CONNECTED )
+ {
+ cfe_web_bg_process( si );
+ POLL();
+ }
+ else
+ if( connflag == TCPSTATUS_NOTCONN )
+ {
+ console_log("web warning: Unexpected TCP disconnect.");
+ tcp_close(si->s);
+ si->s = SOCKET_CLOSED;
+ si->state = HTTP_READ_FIRST_HDR;
+ si->web_buf_idx = 0;
+ }
+ }
+ }
+
+ in_cfe_web_poll = 0;
+ }
+} /* cfe_web_poll */
+
+
+/***************************************************************************
+ * Function Name: cfe_web_listen
+ * Description : This function checks to see if TCP listen can be issued
+ * on the HTTP port and issues the listen if it can.
+ * Returns : None.
+ ***************************************************************************/
+static void cfe_web_listen( int *listen_idx_ptr )
+{
+ static int port = SERVER_PORT;
+
+ int listen_idx = *listen_idx_ptr;
+ PSOCKET_INFO si = &g_socket_info[listen_idx];
+
+ /* If a TCP socket has been opened, check its connection status. */
+ if( si->s >= 0 )
+ {
+ unsigned int connflag;
+ tcp_status( si->s, &connflag, NULL, NULL );
+
+ /* If the socket is connection, set the next socket index to listen for
+ * a TCP connection.
+ */
+ if( connflag == TCPSTATUS_CONNECTED )
+ {
+ listen_idx = (listen_idx + 1) % NUM_SOCKETS;
+ si = &g_socket_info[listen_idx];
+ }
+ }
+
+ /* If the TCP socket has not been opened, open it and listen for a TCP
+ * connection.
+ */
+ if( si->s == SOCKET_CLOSED )
+ {
+ /* Open the socket in non-blocking mode. */
+ POLL();
+ if( (si->s = tcp_socket()) >= 0 )
+ {
+ console_log("web info: Waiting for connection on socket %d.", si->s);
+ if( tcp_listen(si->s, port) != 0 )
+ console_log("web error: listen error on %d.", si->s);
+ }
+ else
+ {
+ console_log("web error %d: Could not create TCP socket.", si->s);
+ si->s = SOCKET_CLOSED;
+ }
+ }
+
+ *listen_idx_ptr = listen_idx;
+} /* cfe_web_listen */
+
+
+/***************************************************************************
+ * Function Name: cfe_web_bg_process
+ * Description : This function processes an HTTP request on a socket.
+ * Returns : None.
+ ***************************************************************************/
+static void cfe_web_bg_process(PSOCKET_INFO si)
+{
+ char post_subst[] = {UPLOAD_FATAL, '\0'};
+ char *post_substs[] = {post_subst};
+ int close_tcp = 0;
+
+ switch( si->state )
+ {
+ case HTTP_READ_FIRST_HDR:
+ if( read_first_hdr( si->s, si->web_first_buf,
+ sizeof(si->web_first_buf), &si->web_buf_idx, &close_tcp ) == 0 )
+ {
+ /* Not all of the first header has been read yet. Try again later.*/
+ break;
+ }
+
+ /* The first header has been read. */
+ si->state = HTTP_READ_REMAINING_HDRS;
+
+ /* fall thru */
+
+ case HTTP_READ_REMAINING_HDRS:
+ if( read_remaining_hdrs( si->s, si->web_buf, sizeof(si->web_buf),
+ &si->web_buf_idx, &close_tcp, &si->post_content_length ) )
+ {
+ if( g_processing_cmd == 0 )
+ {
+ char *method = NULL;
+ char *path = NULL;
+ char *ptr = (char *) si->web_first_buf;
+
+ method = gettoken(&ptr);
+ if( method )
+ path = gettoken(&ptr);
+
+ /* Process the HTTP request. Only GET and POST are supported. */
+ if( method && path )
+ {
+ if( !strcmpi( method, "get" ) )
+ {
+ send_page( si->s, path, 1, NULL, 0 );
+ close_tcp = 1;
+ }
+ else
+ {
+ if( !strcmpi( method, "post" ) )
+ {
+ if( g_post_data_in_progress == 0 )
+ {
+ g_post_data_in_progress = 1;
+ si->state = HTTP_READ_POST_DATA;
+ }
+ else
+ {
+ send_error( si->s, 501, "Upload Busy",
+ (char*) 0,
+ "An image is already being uploaded." );
+ close_tcp = 1;
+ }
+ }
+ else
+ {
+ send_error( si->s, 501, "Not Implemented",
+ (char*) 0,
+ "That method is not implemented." );
+ close_tcp = 1;
+ }
+ }
+ }
+ else
+ {
+ send_error( si->s, 400, "Bad Request", (char *) 0,
+ "Can't parse request." );
+ close_tcp = 1;
+ }
+ }
+ else
+ {
+ /* A download and flash image command is being executed from
+ * the serial port console.
+ */
+ send_error( si->s, 400, "Bad Request", (char *) 0,
+ "Console command is in progress." );
+ close_tcp = 1;
+ }
+ }
+
+ if( si->state != HTTP_READ_POST_DATA )
+ break;
+
+ case HTTP_READ_POST_DATA:
+ /* Read the post data, which contains an image to flash, into low
+ * memory.
+ */
+ if( (post_subst[0] = read_post_data( si->s, POST_DATA_START,
+ si->post_content_length, &g_post_data_idx )) == UPLOAD_OK )
+ {
+ /* Verify that the post data is a valid image to flash. */
+ post_subst[0] = parse_post_data( si->s, POST_DATA_START,
+ g_post_data_idx, (unsigned char **) &g_image_start, &g_image_len,
+ &g_image_format );
+ }
+
+ switch( post_subst[0] )
+ {
+ case UPLOAD_PENDING:
+ break;
+
+ case UPLOAD_TCP_ERROR:
+ close_tcp = 1;
+ g_post_data_in_progress = 0;
+ g_post_data_idx = 0;
+ break;
+
+ case UPLOAD_OK:
+ /* Notify foreground to abort the console input so it can
+ * write the image to flash memory.
+ */
+ g_console_abort = 1;
+
+ send_page(si->s, "/uploadinfo.html", 0, post_substs, 1);
+ close_tcp = 1;
+ g_post_data_idx = 0;
+ break;
+
+ default:
+ /* The image was downloaded OK but there was a problem with it
+ * so it could not be written to flash memory.
+ */
+ send_page(si->s, "/uploadinfo.html", 0, post_substs, 1);
+ close_tcp = 1;
+ g_post_data_in_progress = 0;
+ g_post_data_idx = 0;
+ break;
+ }
+ break;
+ }
+
+ /* Close the socket if the HTTP transaction is done. */
+ if( close_tcp )
+ {
+ POLL();
+ tcp_close(si->s);
+ si->s = SOCKET_CLOSED;
+ si->state = HTTP_READ_FIRST_HDR;
+ si->web_buf_idx = 0;
+ si->post_content_length = 0;
+ }
+} /* cfe_web_poll */
+
+
+/***************************************************************************
+ * Function Name: cfe_web_gets
+ * Description : Reads from a socket up to a <CR><LF> or <LF>. The socket
+ * is non-blocking.
+ * Returns : WEB_GETS_DONE - Complete line was read.
+ * WEB_GETS_PENDING - Line partially read.
+ * WEB_GETS_ERROR - Socket error.
+ ***************************************************************************/
+static int cfe_web_gets( char *web_buf, int web_buf_size,
+ int *web_buf_idx_ptr, int s )
+{
+ int ret = WEB_GETS_PENDING;
+ unsigned char ch;
+ int web_buf_idx = *web_buf_idx_ptr;
+ char *p = web_buf + web_buf_idx;
+ int continue_reading = 1;
+
+ while( web_buf_idx < web_buf_size && continue_reading )
+ {
+ switch( tcp_recv( s, &ch, 1 ) )
+ {
+ case 0: /* no characters are available to receive */
+ continue_reading = 0;
+ break;
+
+ case 1: /* character was read */
+ if( ch == '\n' )
+ {
+ *p = '\0';
+ continue_reading = 0;
+ ret = WEB_GETS_DONE;
+ }
+ else
+ if( ch != '\r' )
+ {
+ *p++ = ch;
+ web_buf_idx++;
+ }
+ break;
+
+ default:
+ continue_reading = 0;
+ ret = WEB_GETS_ERROR;
+ break;
+ }
+ }
+
+ if( web_buf_idx == web_buf_size )
+ {
+ web_buf[web_buf_idx - 1] = '\0';
+ ret = WEB_GETS_DONE;
+ }
+
+ *web_buf_idx_ptr = web_buf_idx;
+
+ return( ret );
+} /* cfe_web_gets */
+
+
+/***************************************************************************
+ * Function Name: read_first_hdr
+ * Description : This function reads the first HTTP header which contains
+ * the method (GET, POST), path and protocol. For example,
+ * GET /upload.html HTTP/1.1
+ * Returns : 1 - First header was read, 0 - was not read.
+ ***************************************************************************/
+static int read_first_hdr(int s, char *web_buf, int web_buf_size,
+ int *web_buf_idx_ptr, int *close_tcp_ptr)
+{
+ int ret = 0;
+ int sts = cfe_web_gets( web_buf, web_buf_size, web_buf_idx_ptr, s );
+
+ switch( sts )
+ {
+ case WEB_GETS_DONE:
+ /* The first HTTP header has been read into web_buf. */
+ *web_buf_idx_ptr = 0;
+ ret = 1;
+ break;
+
+ case WEB_GETS_ERROR:
+ console_log("web error: TCP read error.");
+ *close_tcp_ptr = 1;
+ break;
+ }
+
+ return( ret );
+} /* read_first_hdr */
+
+
+/***************************************************************************
+ * Function Name: read_remaining_hdrs
+ * Description : This function reads the remaining HTTP headers.
+ * Returns : 1 - Remaining headers were read, 0 - were not read.
+ ***************************************************************************/
+static int read_remaining_hdrs(int s, char *web_buf, int web_buf_size,
+ int *web_buf_idx_ptr, int *close_tcp_ptr, int *content_length_ptr)
+{
+ int ret = 0;
+ int sts = WEB_GETS_DONE;
+
+ while( sts == WEB_GETS_DONE )
+ {
+ sts = cfe_web_gets( web_buf, web_buf_size, web_buf_idx_ptr, s );
+ switch( sts )
+ {
+ case WEB_GETS_DONE:
+ if( *web_buf_idx_ptr == 0 )
+ {
+ /* The remaining HTTP headers have been read. */
+ ret = 1;
+ sts = WEB_GETS_PENDING;
+ }
+ else
+ {
+ char *p2 = web_buf;
+ char *p1 = gettoken(&p2);
+ if( !strcmpi( p1, "Content-Length:" ) )
+ *content_length_ptr=atoi(p2);
+ *web_buf_idx_ptr = 0;
+ }
+ break;
+
+ case WEB_GETS_ERROR:
+ console_log("web error: TCP read error.");
+ *close_tcp_ptr = 1;
+ break;
+ }
+ }
+
+ return( ret );
+} /* read_remaining_hdrs */
+
+
+/***************************************************************************
+ * Function Name: read_post_data
+ * Description : This function reads HTTP POST data which is the contents of
+ * a new image to write to flash memory.
+ * Returns : UPLOAD_OK - all data read
+ * UPLOAD_PENDING - not all data read
+ * UPLOAD_TCP_ERROR - TCP error
+ ***************************************************************************/
+static char read_post_data( int s, unsigned char *post_data_start,
+ int content_length, int *post_data_idx_ptr )
+{
+ char ret = UPLOAD_PENDING;
+ int post_data_idx = *post_data_idx_ptr;
+ int len;
+
+ do
+ {
+ len = tcp_recv( s, (unsigned char*)(post_data_start + post_data_idx),
+ content_length - post_data_idx );
+ post_data_idx += len;
+ POLL();
+ cfe_web_listen( &g_listen_idx );
+ } while( len > 0 && post_data_idx < content_length );
+
+ *post_data_idx_ptr = post_data_idx;
+
+ if( len < 0 )
+ {
+ console_log("web error: TCP read error receiving post data.");
+ ret = UPLOAD_TCP_ERROR;
+ }
+ else
+ if( post_data_idx == content_length )
+ ret = UPLOAD_OK;
+
+ return( ret );
+} /* read_post_data */
+
+
+/***************************************************************************
+ * Function Name: parse_post_data
+ * Description : This function parses HTTP POST data which is the contents of
+ * a new image to write to flash memory.
+ * Returns : UPLOAD_OK or UPLOAD_xxx error
+ ***************************************************************************/
+static char parse_post_data( int s, unsigned char *post_data_start,
+ int post_data_length, unsigned char **image_start_ptr, int *image_len_ptr,
+ int *image_format_ptr )
+{
+ char ret = UPLOAD_OK;
+ unsigned char *p = post_data_start;
+ int boundary_size = 0;
+
+ /* Convert the start boundary field into a string. It will be compared
+ * against the end boundary field below.
+ */
+ while( *p != '\r' && *p != '\n' &&
+ ((int) p - (int) post_data_start) < post_data_length )
+ {
+ p++;
+ }
+
+ if( *p == '\r' || *p == '\n' )
+ {
+ *p++ = '\0';
+ boundary_size = strlen((char*)post_data_start);
+ }
+ else
+ {
+ console_log("web error: HTTP POST start bound field not found.");
+ ret = UPLOAD_FATAL;
+ }
+
+ /* Verify that a filename has been entered. */
+ if( ret == UPLOAD_OK )
+ {
+ unsigned char *fname = NULL;
+ while( memcmp( p, "\r\n\r\n", strlen("\r\n\r\n") ) )
+ {
+ if( *p == 'f' && !memcmp( p, "filename=", strlen("filename=" ) ) )
+ {
+ p += strlen("filename=");
+ fname = p + 1;
+ if( p[0] == '"' && p[1] != '"' )
+ {
+ p++;
+ while( *p != '"' && *p != '\r' && *p != '\n' )
+ p++;
+ *p = '\0';
+ }
+ else
+ {
+ console_log("web error: HTTP POST filename not specified.");
+ ret = UPLOAD_FAIL_NO_FILENAME;
+ }
+ break;
+ }
+
+ p++;
+ }
+
+ if( fname == NULL )
+ {
+ console_log("web error: HTTP POST filename field not found.");
+ ret = UPLOAD_FATAL;
+ }
+ }
+
+ /* Find the start of the image which starts after two consecutive
+ * carriage return, linefeed pairs.
+ */
+ if( ret == UPLOAD_OK )
+ {
+ while( memcmp( p, "\r\n\r\n", strlen("\r\n\r\n") ) )
+ p++;
+
+ p += strlen("\r\n\r\n");
+ if( p[0] != '\r' || p[1] != '\n' ||
+ memcmp(p + 2, post_data_start, boundary_size ) )
+ {
+ *image_start_ptr = p;
+ }
+ else
+ {
+ console_log("web error: HTTP POST no image data.");
+ ret = UPLOAD_FAIL_ILLEGAL_IMAGE;
+ }
+ }
+
+ /* Find the end of the image which contains the same boundary field as
+ * at the start of the buffer.
+ */
+ if( ret == UPLOAD_OK )
+ {
+ p = post_data_start + post_data_length - 1;
+ while( *p == '\r' || *p == '\n' || *p == '-' )
+ p--;
+ p[1] = '\0';
+ p -= boundary_size + 1;
+ if( !memcmp( p + strlen("\r\n"), post_data_start, boundary_size ) )
+ *image_len_ptr = (int) p - (int) *image_start_ptr;
+ else
+ {
+ console_log("web error: HTTP POST end bound field not found.");
+ ret = UPLOAD_FATAL;
+ }
+ }
+
+ /* Verify that the image is (or should be) a Broadcom flash format file or
+ * a flash image format.
+ */
+ if( ret == UPLOAD_OK )
+ {
+ /* Align the image on a 16 byte boundary */
+ if( ((unsigned long) *image_start_ptr & 0x0f) != 0 )
+ {
+ unsigned char *dest = (unsigned char *)
+ ((unsigned long) *image_start_ptr & ~0x0f);
+ unsigned char *src = *image_start_ptr;
+ memmove( dest, src, *image_len_ptr );
+ *image_start_ptr = dest;
+ }
+
+ /* Check if the first part of the image is the Broadcom defined TAG
+ * record.
+ */
+ if( verifyTag( (FILE_TAG *) *image_start_ptr, 0 ) == -1 )
+ {
+ /* It is not a Broadcom flash format file. Now check if it is a
+ * flash image format file. A flash image format file must have a
+ * CRC at the end of the image.
+ */
+ unsigned char *image_ptr = *image_start_ptr;
+ unsigned long image_len = (unsigned long) *image_len_ptr - TOKEN_LEN;
+ unsigned long crc = CRC32_INIT_VALUE;
+
+ crc = getCrc32(image_ptr, image_len, crc);
+ if (memcmp(&crc, image_ptr + image_len, CRC_LEN) == 0)
+ {
+ console_log("web info: Upload %lu bytes, flash image format.",
+ *image_len_ptr);
+ *image_format_ptr = FLASH_IMAGE_FORMAT;
+ }
+ else
+ {
+ console_log("web info: Upload %lu bytes, invalid image format.",
+ *image_len_ptr);
+ ret = UPLOAD_FAIL_ILLEGAL_IMAGE;
+ }
+ }
+ else
+ {
+ console_log("web info: Upload %lu bytes, Broadcom image format.",
+ *image_len_ptr);
+ *image_format_ptr = BROADCOM_IMAGE_FORMAT;
+ }
+ }
+
+ return( ret );
+} /* parse_post_data */
+
+
+/***************************************************************************
+ * Function Name: send_error
+ * Description : This function sends an HTTP error response to the browser.
+ * Returns : None.
+ ***************************************************************************/
+static void send_error( int s, int status, char* title, char* extra_header,
+ char* text )
+{
+ int tcpret = 0;
+ char buf[128];
+ send_headers( s, status, title, extra_header, "text/html" );
+ sprintf( (char *) buf, "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n"
+ "<BODY BGCOLOR=\"#cc9999\"><H4>%d %s</H4>\n", status, title, status,
+ title );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ sprintf( (char *) buf, "%s\n", text );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ sprintf( (char *) buf, "<HR>\n<ADDRESS><A HREF=\"%s\">%s</A></ADDRESS>\n"
+ "</BODY></HTML>\n", SERVER_URL, SERVER_NAME );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+
+ if( tcpret < 0 )
+ console_log("web error: TCP write error sending error response.");
+} /* send_error */
+
+
+/***************************************************************************
+ * Function Name: send_headers
+ * Description : This function sends an HTTP response to the browser.
+ * Returns : None.
+ ***************************************************************************/
+static void send_headers( int s, int status, char* title, char* extra_header,
+ char* mime_type )
+{
+ int tcpret = 0;
+ char buf[128];
+ unsigned long secs = (unsigned long) cfe_ticks / CFE_HZ;
+
+ sprintf( buf, "%s %d %s\r\n", PROTOCOL, status, title );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ sprintf( buf, "Server: %s\r\n", SERVER_NAME );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ sprintf( buf, "Date: Thu, 01 Jan 1970 %2.2d:%2.2d:%2.2d GMT\r\n",
+ secs / 3600, (secs % 3600) / 60, secs % 60 );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ if ( extra_header != (char*) 0 )
+ {
+ sprintf( buf, "%s\r\n", extra_header );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ }
+ if ( mime_type != (char*) 0 )
+ {
+ sprintf( buf, "Content-Type: %s\r\n", mime_type );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+ }
+ sprintf( buf, "Connection: close\r\n\r\n" );
+ tcpret = tcp_send( s, (unsigned char*)buf, strlen(buf) );
+
+ if( tcpret < 0 )
+ console_log("web error: TCP write error sending header.");
+} /* send_headers */
+
+
+/***************************************************************************
+ * Function Name: send_page
+ * Description : This function sends a web page to the browser.
+ * Returns : None.
+ ***************************************************************************/
+static void send_page( int s, char *path, int send_headers_flag,
+ char **substs, int num_substs )
+{
+ PWEB_PAGE_MAP map;
+
+ /* Find the specified web page. */
+ for( map = g_web_page_map; map->wp_name; map++ )
+ {
+ if( !strcmp( map->wp_name, path ) )
+ {
+ /* Found the web page. */
+ char *p2 = NULL;
+ char *p = (char *) map->wp_content_buf;
+ int size = *map->wp_content_size;
+ int i = 0;
+
+ if( send_headers_flag )
+ send_headers( s, 200, "Ok", (char *) 0, map->wp_mime_type );
+
+ /* Make substitutions. */
+ while( i < num_substs && (p2 = strnchr( p, '<', size )) != NULL )
+ {
+ if( p2[1] == '%' )
+ {
+ /* Found a substituion pattern. Send up to that point. */
+ if( cfe_web_tcp_send( s, p, (int) (p2 - p) ) < 0 )
+ break;
+
+ /* Send substitution value. */
+ if( cfe_web_tcp_send( s, substs[i], strlen(substs[i]) ) < 0 )
+ break;
+
+ i++;
+
+ /* Skip to end of substitution pattern. */
+ p = p2 + 2; /* skip '<%' */
+ while( p[0] != '%' || p[1] != '>' )
+ p++;
+ p += 2; /* skip '%.' */
+ }
+ else
+ {
+ /* Was not a substitution pattern. Send up that point. */
+ p2++;
+ if( cfe_web_tcp_send( s, p, (int) (p2 - p) ) < 0 )
+ break;
+
+ p = p2;
+ }
+
+ size = *map->wp_content_size - ((int)p-(int)map->wp_content_buf);
+ }
+
+ /* Send remaining part of web page after the last substitution. */
+ cfe_web_tcp_send( s, p, size );
+
+ break; /* for loop */
+ }
+ }
+
+ if( map->wp_name == NULL )
+ send_error( s, 404, "Not Found", (char*) 0, "File not found." );
+} /* send_page */
+
+
+/***************************************************************************
+ * Function Name: cfe_web_tcp_send
+ * Description : Sends data on a TCP non blocking connection and waits for
+ * it to finish.
+ * Returns : > 0 - bytes send, < 0 - TCP error
+ ***************************************************************************/
+static int cfe_web_tcp_send( int s, char *buf, int size )
+{
+ int i, len = 0;
+
+ for( i = 0; i < size; i += len )
+ {
+ POLL();
+ cfe_web_listen( &g_listen_idx );
+ len = tcp_send( s, (unsigned char*)(buf + i), size - i );
+ if( len < 0 )
+ {
+ console_log("web error: TCP write error sending a web page.");
+ break;
+ }
+ }
+
+ return( len );
+} /* cfe_web_tcp_send */
+
+
+/**
+ * memmove - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * Unlike memcpy(), memmove() copes with overlapping areas.
+ */
+void * memmove(void * dest,const void *src,size_t count)
+{
+ char *tmp, *s;
+
+ if (dest <= src) {
+ tmp = (char *) dest;
+ s = (char *) src;
+ while (count--)
+ *tmp++ = *s++;
+ }
+ else {
+ tmp = (char *) dest + count;
+ s = (char *) src + count;
+ while (count--)
+ *--tmp = *--s;
+ }
+
+ return dest;
+}
+
+#else
+
+/***************************************************************************
+ * Function Name: Functions stubs.
+ * Description : Used when the web server is not compiled into the CFE.
+ * Returns : None.
+ ***************************************************************************/
+
+int cfe_web_check(void);
+void cfe_web_fg_process(void);
+void cfe_web_poll(void *x);
+
+int cfe_web_check(void)
+{
+ return(0);
+}
+
+void cfe_web_fg_process(void)
+{
+}
+
+void cfe_web_poll(void *x)
+{
+}
+
+#endif
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_elf.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_elf.c
new file mode 100755
index 0000000..fb3f122
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_elf.c
@@ -0,0 +1,388 @@
+
+//********** for boot -elf thing from cfe_ldr_elf.c
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * ELF Program Loader File: cfe_ldr_elf.c
+ *
+ * This program parses ELF executables and loads them into memory.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * 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 "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_console.h"
+#include "cfe_error.h"
+#include "cfe_devfuncs.h"
+#include "cfe_timer.h"
+#include "cfe_mem.h"
+
+#include "cfe.h"
+#include "cfe_loader.h"
+#include "cfe_fileops.h"
+#include "elf.h"
+
+#include "cfe_boot.h"
+
+/* *********************************************************************
+ * Externs
+ ********************************************************************* */
+
+int bcm63xx_cfe_elfload(cfe_loadargs_t *la);
+
+const cfe_loader_t elfloader = {
+ "elf",
+ bcm63xx_cfe_elfload,
+ 0};
+
+/* *********************************************************************
+ * readprogsegment(fsctx,ref,addr,size)
+ *
+ * Read a program segment, generally corresponding to one
+ * section of the file.
+ *
+ * Input parameters:
+ * fsctx - file I/O dispatch
+ * ref - reference data for open file handle
+ * addr - target virtual address
+ * size - size of region to read
+ *
+ * Return value:
+ * Number of bytes copied or <0 if error occured
+ ********************************************************************* */
+
+static int readprogsegment(fileio_ctx_t *fsctx,void *ref,
+ void *addr,int size,int flags)
+{
+ int res;
+
+#ifdef __long64
+ if (flags & LOADFLG_NOISY) xprintf("0x%016llx/%d ",addr,size);
+#else
+ if (flags & LOADFLG_NOISY) xprintf("0x%x/%d ",addr,size);
+#endif
+
+ res = fs_read(fsctx,ref,addr,size);
+
+ if (res < 0) return CFE_ERR_IOERR;
+ if (res != size) return CFE_ERR_BADELFFMT;
+
+ return size;
+}
+
+
+/* *********************************************************************
+ * readclearbss(addr,size)
+ *
+ * Process a BSS section, zeroing memory corresponding to
+ * the BSS.
+ *
+ * Input parameters:
+ * addr - address to zero
+ * size - length of area to zero
+ *
+ * Return value:
+ * number of zeroed bytes or <0 if error occured
+ ********************************************************************* */
+
+static int readclearbss(void *addr,int size,int flags)
+{
+
+#ifdef __long64
+ if (flags & LOADFLG_NOISY) xprintf("0x%016llx/%d ",addr,size);
+#else
+ if (flags & LOADFLG_NOISY) xprintf("0x%x/%d ",addr,size);
+#endif
+
+ if (size > 0) memset(addr,0,size);
+ return size;
+}
+
+
+/* *********************************************************************
+ * elfgetshdr(ops,ref,ep)
+ *
+ * Get a section header from the ELF file
+ *
+ * Input parameters:
+ * ops - file I/O dispatch
+ * ref - reference data for open file
+ * ep - extended header info
+ *
+ * Return value:
+ * copy of section header (malloc'd) or NULL if no memory
+ ********************************************************************* */
+
+static Elf32_Shdr *elfgetshdr(fileio_ctx_t *fsctx,void *ref,Elf32_Ehdr *ep)
+{
+ Elf32_Shdr *shtab;
+ unsigned size = ep->e_shnum * sizeof(Elf32_Shdr);
+
+ shtab = (Elf32_Shdr *) KMALLOC(size,0);
+ if (!shtab) {
+ return NULL;
+ }
+
+ if (fs_seek(fsctx,ref,ep->e_shoff,FILE_SEEK_BEGINNING) != ep->e_shoff ||
+ fs_read(fsctx,ref,(uint8_t *)shtab,size) != size) {
+ KFREE(shtab);
+ return NULL;
+ }
+
+ return (shtab);
+}
+
+/* *********************************************************************
+ * elfload_internal(ops,ref,entrypt,flags)
+ *
+ * Read an ELF file (main routine)
+ *
+ * Input parameters:
+ * ops - file I/O dispatch
+ * ref - open file handle
+ * entrypt - filled in with entry vector
+ * flags - generic boot flags
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+
+static int elfload_internal(fileio_ctx_t *fsctx,void *ref,
+ long *entrypt,int flags)
+{
+ Elf32_Ehdr *ep;
+ Elf32_Phdr *phtab = 0;
+ Elf32_Shdr *shtab = 0;
+ unsigned int nbytes;
+ int i;
+ int res;
+ Elf32_Ehdr ehdr;
+
+ ep = &ehdr;
+ if (fs_read(fsctx,ref,(uint8_t *) ep,sizeof(*ep)) != sizeof(*ep)) {
+ return CFE_ERR_IOERR;
+ }
+
+ /* check header validity */
+ if (ep->e_ident[EI_MAG0] != ELFMAG0 ||
+ ep->e_ident[EI_MAG1] != ELFMAG1 ||
+ ep->e_ident[EI_MAG2] != ELFMAG2 ||
+ ep->e_ident[EI_MAG3] != ELFMAG3) {
+ return CFE_ERR_NOTELF;
+ }
+
+ if (ep->e_ident[EI_CLASS] != ELFCLASS32) return CFE_ERR_NOT32BIT;
+
+#ifdef __MIPSEB
+ if (ep->e_ident[EI_DATA] != ELFDATA2MSB) return CFE_ERR_WRONGENDIAN; /* big endian */
+#endif
+#ifdef __MIPSEL
+ if (ep->e_ident[EI_DATA] != ELFDATA2LSB) return CFE_ERR_WRONGENDIAN; /* little endian */
+#endif
+
+ if (ep->e_ident[EI_VERSION] != EV_CURRENT) return CFE_ERR_BADELFVERS;
+ if (ep->e_machine != EM_MIPS) return CFE_ERR_NOTMIPS;
+
+ /* Is there a program header? */
+ if (ep->e_phoff == 0 || ep->e_phnum == 0 ||
+ ep->e_phentsize != sizeof(Elf32_Phdr)) {
+ return CFE_ERR_BADELFFMT;
+ }
+
+ /* Load program header */
+ nbytes = ep->e_phnum * sizeof(Elf32_Phdr);
+ phtab = (Elf32_Phdr *) KMALLOC(nbytes,0);
+ if (!phtab) {
+ return CFE_ERR_NOMEM;
+ }
+
+ if (fs_seek(fsctx,ref,ep->e_phoff,FILE_SEEK_BEGINNING) != ep->e_phoff ||
+ fs_read(fsctx,ref,(uint8_t *)phtab,nbytes) != nbytes) {
+ KFREE(phtab);
+ return CFE_ERR_IOERR;
+ }
+
+ /*
+ * From now on we've got no guarantee about the file order,
+ * even where the section header is. Hopefully most linkers
+ * will put the section header after the program header, when
+ * they know that the executable is not demand paged. We assume
+ * that the symbol and string tables always follow the program
+ * segments.
+ */
+
+ /* read section table (if before first program segment) */
+ if (ep->e_shoff < phtab[0].p_offset) {
+ shtab = elfgetshdr(fsctx,ref,ep);
+ }
+
+ /* load program segments */
+ /* We cope with a badly sorted program header, as produced by
+ * older versions of the GNU linker, by loading the segments
+ * in file offset order, not in program header order. */
+
+ while (1) {
+ Elf32_Off lowest_offset = ~0;
+ Elf32_Phdr *ph = 0;
+
+ /* find nearest loadable segment */
+ for (i = 0; i < ep->e_phnum; i++)
+ if ((phtab[i].p_type == PT_LOAD) && (phtab[i].p_offset < lowest_offset)) {
+ ph = &phtab[i];
+ lowest_offset = ph->p_offset;
+ }
+ if (!ph) {
+ break; /* none found, finished */
+ }
+ /* load the segment */
+ if (ph->p_filesz) {
+ if (fs_seek(fsctx,ref,ph->p_offset,FILE_SEEK_BEGINNING) != ph->p_offset) {
+ if (shtab) KFREE(shtab);
+ KFREE(phtab);
+ return CFE_ERR_BADELFFMT;
+ }
+ res = readprogsegment(fsctx,ref,
+ (void *)(intptr_t)(signed)ph->p_vaddr,
+ ph->p_filesz,flags);
+ if (res != ph->p_filesz) {
+ if (shtab) KFREE(shtab);
+ KFREE(phtab);
+ return res;
+ }
+ }
+ if (ph->p_filesz < ph->p_memsz) {
+ res = readclearbss((void *)(intptr_t)(signed)ph->p_vaddr + ph->p_filesz,
+ ph->p_memsz - ph->p_filesz,flags);
+ if (res < 0) {
+ if (shtab) KFREE(shtab);
+ KFREE(phtab);
+ return res;
+ }
+ }
+
+ ph->p_type = PT_NULL; /* remove from consideration */
+ }
+
+ KFREE(phtab);
+
+ *entrypt = (intptr_t)ep->e_entry; /* return entry point */
+ return 0;
+}
+
+
+
+/* *********************************************************************
+ * cfe_elfload(ops,file,flags)
+ *
+ * Read an ELF file (main entry point)
+ *
+ * Input parameters:
+ * ops - fileio dispatch
+ * file - name of file to read
+ * ept - where to put entry point
+ * flags - load flags
+ *
+ * Return value:
+ * 0 if ok, else error code
+ ********************************************************************* */
+
+int bcm63xx_cfe_elfload(cfe_loadargs_t *la)
+{
+ fileio_ctx_t *fsctx;
+ void *ref;
+ int res;
+
+ /*
+ * Look up the file system type and get a context
+ */
+
+
+ res = fs_init(la->la_filesys,&fsctx,la->la_device);
+ if (res != 0) {
+ return res;
+ }
+
+ /*
+ * Turn on compression if we're doing that.
+ */
+
+ if (la->la_flags & LOADFLG_COMPRESSED) {
+ res = fs_hook(fsctx,"z");
+ if (res != 0) {
+ return res;
+ }
+ }
+
+ /*
+ * Open the remote file
+ */
+
+ res = fs_open(fsctx,&ref,la->la_filename,FILE_MODE_READ);
+ if (res != 0) {
+ fs_uninit(fsctx);
+ return CFE_ERR_FILENOTFOUND;
+ }
+
+ /*
+ * Load the image.
+ */
+
+ la->la_entrypt = 0;
+ res = elfload_internal(fsctx,ref,&(la->la_entrypt),la->la_flags);
+
+ /*
+ * All done, release resources
+ */
+
+ fs_close(fsctx,ref);
+ fs_uninit(fsctx);
+
+ return res;
+}
+
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c
new file mode 100755
index 0000000..eaabf14
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ldr_raw.c
@@ -0,0 +1,368 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * RAW Program Loader File: cfe_ldr_raw.c
+ *
+ * This program reads raw binaries into memory.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * 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 "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_error.h"
+#include "cfe_devfuncs.h"
+
+#include "cfe.h"
+#include "cfe_fileops.h"
+
+#include "cfe_boot.h"
+#include "cfe_bootblock.h"
+
+#include "cfe_loader.h"
+
+/* *********************************************************************
+ * Externs
+ ********************************************************************* */
+
+int bcm63xx_cfe_rawload(cfe_loadargs_t *la);
+
+const cfe_loader_t rawloader = {
+ "raw",
+ bcm63xx_cfe_rawload,
+ 0};
+
+/* *********************************************************************
+ * cfe_findbootblock(la,fsctx,ref)
+ *
+ * Find the boot block on the specified device.
+ *
+ * Input parameters:
+ * la - loader args (to be filled in)
+ * ops - file operations
+ * ref - reference for open file handle
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+static int cfe_findbootblock(cfe_loadargs_t *la,
+ fileio_ctx_t *fsctx,
+ void *ref,
+ struct boot_block *bootblock)
+{
+ uint32_t checksum = 0;
+ uint32_t calcsum = 0;
+ uint32_t secsize = 0;
+ uint64_t secoffset = 0;
+ int res;
+ int curblk;
+
+ /*
+ * Search for the boot block. Stop when we find
+ * something with a matching checksum and magic
+ * number.
+ */
+
+ fs_seek(fsctx,ref,0,FILE_SEEK_BEGINNING);
+
+ for (curblk = 0; curblk < BOOT_BLOCK_MAXLOC; curblk++) {
+
+
+ /* Read a block */
+
+ res = fs_read(fsctx,ref,
+ (unsigned char *) bootblock,
+ sizeof(struct boot_block));
+
+ if (res != sizeof(struct boot_block)) {
+ return CFE_ERR_IOERR;
+ }
+
+ /* Verify magic number */
+
+#if defined(CONFIG_MIPS_BRCM)
+ continue;
+#else
+ if (bootblock->bb_magic != BOOT_MAGIC_NUMBER) {
+ continue;
+ }
+#endif
+
+ /* Extract fields from block */
+
+ checksum = ((uint32_t) (bootblock->bb_hdrinfo & BOOT_HDR_CHECKSUM_MASK));
+ bootblock->bb_hdrinfo &= ~BOOT_HDR_CHECKSUM_MASK;
+ secsize = ((uint32_t) (bootblock->bb_secsize & BOOT_SECSIZE_MASK));
+ secoffset = bootblock->bb_secstart;
+
+ /* Verify block's checksum */
+
+ CHECKSUM_BOOT_DATA(&(bootblock->bb_magic),BOOT_BLOCK_SIZE,&calcsum);
+
+ if (checksum == calcsum) {
+ break;
+ }
+ }
+
+ /*
+ * Okay, determine if we were successful.
+ */
+
+#if !defined(CONFIG_MIPS_BRCM)
+ if (bootblock->bb_magic != BOOT_MAGIC_NUMBER) {
+ return CFE_ERR_INVBOOTBLOCK;
+ }
+#endif
+
+ if (checksum != calcsum) {
+ return CFE_ERR_BBCHECKSUM;
+ }
+
+ /*
+ * If we get here, we had a valid boot block.
+ */
+
+ return 0;
+}
+
+
+/* *********************************************************************
+ * cfe_rawload(la)
+ *
+ * Read a raw (unformatted) boot file
+ *
+ * Input parameters:
+ * la - loader args
+ *
+ * Return value:
+ * 0 if ok, else error code
+ ********************************************************************* */
+int bcm63xx_cfe_rawload(cfe_loadargs_t *la)
+{
+ int res;
+ fileio_ctx_t *fsctx;
+ const fileio_dispatch_t *ops;
+ void *ref;
+ int ttlcopy = 0;
+ int findbb;
+ int devinfo;
+ struct boot_block bootblock;
+ uint8_t *ptr;
+ uint8_t *bootcode;
+#if !defined(CONFIG_MIPS_BRCM)
+ uint32_t checksum,calcsum;
+#endif
+ uint64_t secoffset = 0;
+ int32_t maxsize;
+ int amtcopy;
+ int thisamt;
+ uint32_t loadflags;
+ int onedot;
+
+ loadflags = la->la_flags;
+
+ /*
+ * Set starting address and maximum size. You can either
+ * explicitly set this (with LOADFLG_SPECADDR) or
+ * let CFE decide. If CFE decides, the load address
+ * will be BOOT_START_ADDRESS in all cases.
+ * The size is dependant on the device type: block and flash
+ * devices will get this info from the boot block,
+ * and network devices will get the info by reaching EOF
+ * on reads, up to the maximum size of the boot area.
+ */
+
+ if (loadflags & LOADFLG_SPECADDR) {
+ bootcode = (uint8_t *) la->la_address;
+ maxsize = la->la_maxsize;
+ findbb = FALSE; /* don't find a boot block */
+ }
+ else {
+ bootcode = (uint8_t *) BOOT_START_ADDRESS;
+ maxsize = BOOT_AREA_SIZE;
+ findbb = FALSE;
+ devinfo = la->la_device ? cfe_getdevinfo(la->la_device) : 0;
+
+ /*
+ * If the device is either a disk or a flash device,
+ * we will expect to find a boot block.
+ * Serial and network devices do not have boot blocks.
+ */
+ if ((devinfo >= 0) &&
+ ( ((devinfo & CFE_DEV_MASK) == CFE_DEV_DISK) ||
+ ((devinfo & CFE_DEV_MASK) == CFE_DEV_FLASH) )) {
+ findbb = TRUE;
+ }
+ }
+
+
+ /*
+ * merge in any filesystem-specific flags
+ */
+
+ ops = cfe_findfilesys(la->la_filesys);
+ if (!ops) return CFE_ERR_FSNOTAVAIL;
+ loadflags |= ops->loadflags;
+
+ /*
+ * turn off the boot block if requested.
+ */
+
+ if (loadflags & LOADFLG_NOBB) findbb = FALSE;
+
+ /*
+ * Create a file system context
+ */
+
+ res = fs_init(la->la_filesys,&fsctx,la->la_device);
+ if (res != 0) {
+ return res;
+ }
+
+ /*
+ * Turn on compression if we're doing that.
+ */
+
+ if (!findbb && (la->la_flags & LOADFLG_COMPRESSED)) {
+ res = fs_hook(fsctx,"z");
+ if (res != 0) {
+ return res;
+ }
+ }
+
+ /*
+ * Open the boot device
+ */
+
+ res = fs_open(fsctx,&ref,la->la_filename,FILE_MODE_READ);
+ if (res != 0) {
+ fs_uninit(fsctx);
+ return res;
+ }
+
+ /*
+ * If we need to find a boot block, do it now.
+ */
+
+ if (findbb) {
+ res = cfe_findbootblock(la,fsctx,ref,&bootblock);
+
+ /*
+ * If we found the boot block, seek to the part of the
+ * disk where the boot code is.
+ * Otherwise, get out now, since the disk has no boot block.
+ */
+
+ if (res == 0) {
+ maxsize = (int) ((uint32_t) (bootblock.bb_secsize & BOOT_SECSIZE_MASK));
+ secoffset = bootblock.bb_secstart;
+ fs_seek(fsctx,ref,secoffset,FILE_SEEK_BEGINNING);
+ }
+ else {
+ fs_close(fsctx,ref);
+ fs_uninit(fsctx);
+ return res;
+ }
+
+ }
+
+ /*
+ * Okay, go load the boot file.
+ */
+
+ ptr = bootcode;
+ amtcopy = maxsize;
+ ttlcopy = 0;
+
+ onedot = amtcopy / 10; /* ten dots for entire load */
+ if (onedot < 4096) onedot = 4096; /* but minimum 4096 bytes per dot */
+ onedot = (onedot + 1) & ~4095; /* round to multiple of 4096 */
+
+ while (amtcopy > 0) {
+ thisamt = onedot;
+ if (thisamt > amtcopy) thisamt = amtcopy;
+
+ res = fs_read(fsctx,ref,ptr,thisamt);
+ if (la->la_flags & LOADFLG_NOISY) {
+ xprintf(".");
+ }
+ if (res <= 0) break;
+ ptr += res;
+ amtcopy -= res;
+ ttlcopy += res;
+ }
+
+ /*
+ * We're done with the file.
+ */
+
+ fs_close(fsctx,ref);
+ fs_uninit(fsctx);
+
+ /*
+ * Verify the boot loader checksum if we were reading
+ * the disk.
+ */
+
+#if !defined(CONFIG_MIPS_BRCM)
+ if (findbb) {
+ CHECKSUM_BOOT_DATA(bootcode,maxsize,&calcsum);
+ checksum = (uint32_t) ((bootblock.bb_secsize & BOOT_DATA_CHECKSUM_MASK)
+ >> BOOT_DATA_CHECKSUM_SHIFT);
+
+ if (checksum != calcsum) {
+ return CFE_ERR_BOOTPROGCHKSUM;
+ }
+ }
+#endif
+
+ la->la_entrypt = (uintptr_t) bootcode;
+
+ if (la->la_flags & LOADFLG_NOISY) xprintf(" %d bytes read\n",ttlcopy);
+
+ return (res < 0) ? res : ttlcopy;
+
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_main.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_main.c
new file mode 100755
index 0000000..2cf2546
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_main.c
@@ -0,0 +1,611 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Main Module File: cfe_main.c
+ *
+ * This module contains the main "C" routine for CFE and
+ * the main processing loop. There should not be any board-specific
+ * stuff in here.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * 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 "lib_types.h"
+#include "lib_string.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_console.h"
+#include "cfe_timer.h"
+
+#include "env_subr.h"
+#include "cfe_mem.h"
+#include "cfe.h"
+
+#include "exception.h"
+
+#include "bsp_config.h"
+#include "bcm_hwdefs.h"
+#include "boardparms.h"
+#include "bcm_map.h"
+#include "bcm_cpu.h"
+#include "bcm63xx_util.h"
+
+#include "segtable.h"
+#include "initdata.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#ifndef CFG_STACK_SIZE
+#define STACK_SIZE 8192
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+/* *********************************************************************
+ * Externs
+ ********************************************************************* */
+
+void cfe_main(int,int);
+void cfe_command_restart(uint64_t status);
+
+extern void cfe_device_poll(void *x);
+
+extern int cfe_web_check(void);
+extern void cfe_web_fg_process(void);
+extern void cfe_web_poll(void *x);
+
+extern const char *builddate;
+extern const char *builduser;
+
+/* Foxconn add start by Cliff Wang, 03/23/2010 */
+extern int ui_init_netcmds(void);
+/* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+const char *cfe_boardname = CFG_BOARDNAME;
+unsigned int cfe_startflags = 0;
+#if defined (_BCM96368_)
+static int cfe_bus_speed = 0;
+static int cfe_ref_speed = 0;
+#endif
+#if defined (_BCM96328_) || defined (_BCM96362_) || defined (_BCM96816_)
+static int cfe_bus_speed = 0;
+static int cfe_ddr_speed = 0;
+#endif
+unsigned long cfe_sdramsize = 8 * 1024 * 1024;
+
+static void calculateCpuSpeed(void);
+
+#if defined (_BCM96328_)
+const uint32 cpu_speed_table[0x20] = {
+ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320,
+ 0, 320, 160, 200, 160, 200, 400, 320, 320, 160, 384, 320, 192, 320, 320, 320
+};
+const uint32 ddr_speed_table[0x20] = {
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 0, 80, 100, 100, 160, 200, 400, 400, 80, 160, 160, 160, 192, 192, 240, 320
+};
+const uint32 bus_speed_table[0x20] = {
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 0, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160
+};
+#endif
+
+#if defined (_BCM96362_)
+const uint32 cpu_speed_table[0x20] = {
+ 320, 320, 320, 240, 160, 400, 440, 384, 320, 320, 320, 240, 160, 320, 400, 320,
+ 320, 320, 320, 240, 160, 200, 400, 384, 320, 320, 320, 240, 160, 200, 400, 400
+};
+const uint32 ddr_speed_table[0x20] = {
+ 320, 400, 192, 320, 200, 400, 367, 320, 320, 400, 192, 320, 200, 400, 400, 320,
+ 320, 400, 192, 320, 200, 267, 400, 320, 320, 320, 192, 320, 200, 200, 400, 333
+};
+const uint32 bus_speed_table[0x20] = {
+ 160, 200, 96, 160, 100, 160, 183, 160, 160, 200, 96, 160, 100, 160, 200, 160,
+ 160, 200, 96, 160, 100, 100, 200, 160, 160, 160, 96, 160, 100, 100, 200, 166
+};
+#endif
+
+#if defined (_BCM96816_)
+const uint32 cpu_speed_table[0x20] = {
+ 200, 400, 400, 320, 200, 400, 333, 333, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 400, 400, 200, 360, 400, 400, 300, 300, 320, 320, 400, 400
+};
+const uint32 ddr_speed_table[0x20] = {
+ 200, 333, 200, 200, 200, 333, 333, 333, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 400, 200, 200, 300, 300, 300, 300, 300, 400, 400, 400, 400
+};
+const uint32 bus_speed_table[0x20] = {
+ 200, 200, 200, 160, 100, 167, 200, 167, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 200, 200, 160, 180, 171, 200, 171, 200, 160, 200, 160, 200
+};
+#endif
+
+static unsigned long cfe_get_sdram_size(void);
+
+/* *********************************************************************
+ * cfe_setup_default_env()
+ *
+ * Initialize the default environment for CFE. These are all
+ * the temporary variables that do not get stored in the NVRAM
+ * but are available to other programs and command-line macros.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void cfe_setup_default_env(void)
+{
+ char buffer[80];
+
+ xsprintf(buffer,"%d.%d.%d",CFE_VER_MAJOR,CFE_VER_MINOR,CFE_VER_BUILD);
+ env_setenv("CFE_VERSION",buffer,ENV_FLG_BUILTIN | ENV_FLG_READONLY);
+
+ if (cfe_boardname) {
+ env_setenv("CFE_BOARDNAME",(char *) cfe_boardname,
+ ENV_FLG_BUILTIN | ENV_FLG_READONLY);
+ }
+}
+
+
+/* *********************************************************************
+ * cfe_ledstr(leds)
+ *
+ * Display a string on the board's LED display, if it has one.
+ * This routine depends on the board-support package to
+ * include a "driver" to write to the actual LED, if the board
+ * does not have one this routine will do nothing.
+ *
+ * The LEDs are written at various places in the initialization
+ * sequence, to debug board problems.
+ *
+ * Input parameters:
+ * leds - pointer to four-character ASCII string
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void cfe_ledstr(const char *leds)
+{
+#if 0
+ unsigned int val;
+
+ val = ((((unsigned int) leds[0]) << 24) |
+ (((unsigned int) leds[1]) << 16) |
+ (((unsigned int) leds[2]) << 8) |
+ ((unsigned int) leds[3]));
+
+ cfe_leds(val);
+#endif
+}
+
+
+/* *********************************************************************
+ * cfe_say_hello()
+ *
+ * Print out the CFE startup message and copyright notice
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void cfe_command_restart(uint64_t status)
+{
+}
+
+static void cfe_say_hello(void)
+{
+ xprintf("\n\n");
+ xprintf("CFE version 2.0.3"
+#ifdef CFE_VER_RELEASE
+ ".%d"
+#endif
+ " for DGN2200v2 (%s)\n",
+ //CFE_VER_MAJOR,CFE_VER_MINOR,CFE_VER_BUILD, BCM63XX_MAJOR, BCM63XX_MINOR,
+#ifdef CFE_VER_RELEASE
+ CFE_VER_RELEASE,
+#endif
+ //cfe_boardname,
+#ifdef __long64
+ "64bit,"
+#else
+ "32bit,"
+#endif
+#if CFG_MULTI_CPUS
+ "MP,"
+#else
+ "SP,"
+#endif
+#ifdef __MIPSEL
+ "LE"
+#endif
+#ifdef __MIPSEB
+ "BE"
+#endif
+#if CFG_VAPI
+ ",VAPI"
+#endif
+ );
+
+ xprintf("Build Date: %s (%s)\n",builddate,builduser);
+ xprintf("Copyright (C) 2000-2009 Broadcom Corporation.\n");
+ xprintf("\n");
+}
+
+
+/* *********************************************************************
+ * cfe_restart()
+ *
+ * Restart CFE from scratch, jumping back to the boot vector.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+void cfe_restart(void)
+{
+ _exc_restart();
+}
+
+
+/* *********************************************************************
+ * cfe_start(ept)
+ *
+ * Start a user program
+ *
+ * Input parameters:
+ * ept - entry point
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void cfe_start(unsigned long ept)
+{
+ cfe_launch(ept);
+}
+
+/* *********************************************************************
+ * cfe_startup_info()
+ *
+ * Display startup memory configuration messages
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void cfe_startup_info(void)
+{
+ xprintf("Chip ID: BCM%X%X, ", (PERF->RevID & 0xFFFF0000) >> 16, PERF->RevID & 0xFF);
+ xprintf("MIPS: %dMHz",cfe_cpu_speed/1000000);
+#if defined (_BCM96328_) || defined (_BCM96362_) || defined (_BCM96816_)
+ xprintf(", DDR: %dMHz, Bus: %dMHz\n", cfe_ddr_speed/1000000, cfe_bus_speed/1000000);
+#else
+ xprintf("\n");
+#endif
+ {
+ unsigned long tp;
+ __asm __volatile(
+ "mfc0 $9, $22, 3;"
+ "move %0, $9"
+ :"=r" (tp));
+ tp = ((tp & CP0_CMT_TPID) == CP0_CMT_TPID) ? 1 : 0;
+ xprintf("Main Thread: TP%d\n", tp);
+ }
+#if defined (_BCM96328_) || defined (_BCM96362_) || defined (_BCM96816_)
+ if (DDR->TEST_CFG1 & 0x2) { /* Memory Test is finished */
+ xprintf("Memory Test ");
+ if (DDR->TEST_CFG1 & 0x4) {
+ xprintf("Failed\n");
+ }
+ else {
+ xprintf("Passed\n");
+ }
+ }
+#endif
+ cfe_sdramsize = cfe_get_sdram_size();
+ xprintf("Total Memory: %lu bytes (%luMB)\n", cfe_sdramsize, cfe_sdramsize >> 20);
+ xprintf("Boot Address: 0x%x\n\n", FLASH_BASE);
+}
+
+#if defined (_BCM96816_)
+/* *********************************************************************
+ * apm_hvg_init()
+ *
+ * Work around 6816-specific reset logic
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+static void apm_hvg_init(void)
+{
+ HVG->reg_hvg_cha_misc ^= HVG_SOFT_INIT_0;
+ HVG->reg_hvg_chb_misc ^= HVG_SOFT_INIT_0;
+}
+#endif
+
+/* *********************************************************************
+ * cfe_main(a,b)
+ *
+ * It's gotta start somewhere.
+ *
+ * Input parameters:
+ * a,b - not used
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+void cfe_main(int a,int b)
+{
+ /*
+ * By the time this routine is called, the following things have
+ * already been done:
+ *
+ * 1. The processor(s) is(are) initialized.
+ * 2. The caches are initialized.
+ * 3. The memory controller is initialized.
+ * 4. BSS has been zeroed.
+ * 5. The data has been moved to R/W space.
+ * 6. The "C" Stack has been initialized.
+ */
+
+ cfe_bg_init(); /* init background processing */
+ cfe_attach_init();
+ calculateCpuSpeed();
+ cfe_timer_init(); /* Timer process */
+ cfe_bg_add(cfe_device_poll,NULL);
+
+ /*
+ * Initialize the memory allocator
+ */
+ KMEMINIT((unsigned char *) (uintptr_t) mem_heapstart,
+ ((CFG_HEAP_SIZE)*1024));
+
+ /*
+ * Initialize the console. It is done before the other devices
+ * get turned on.
+ */
+
+ board_console_init();
+ cfe_setup_exceptions();
+ cfe_say_hello();
+
+#if defined(CONFIG_BRCM_IKOS)
+ {
+ /*0x694b6f32 (iKo2) is replaced with actual addr during the build process*/
+ static unsigned long linuxStartAddr=0x694b6f32;
+ printf("IKOS Build: Jump to Linux start address 0x%8.8lx.\n\n",
+ linuxStartAddr);
+ cfe_launch(linuxStartAddr);
+ }
+#endif
+
+ cfe_arena_init();
+ board_device_init();
+ cfe_startup_info();
+ cfe_setup_default_env();
+ ui_init_cmddisp();
+ getBootLine();
+ getBoardParam();
+#if defined (_BCM96816_)
+ apm_hvg_init();
+#endif
+
+ /* Foxconn add start by Cliff Wang, 03/23/2010 */
+ ui_init_netcmds();
+ /* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+ board_final_init();
+ cfe_command_loop();
+
+
+}
+
+
+/* *********************************************************************
+ * cfe_command_loop()
+ *
+ * This routine reads and processes user commands
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+void cfe_command_loop()
+{
+ char buffer[300];
+ int status;
+ char *prompt;
+
+ /* Start Web interface. */
+ cfe_bg_add(cfe_web_poll,NULL);
+
+ for (;;) {
+ prompt = env_getenv("PROMPT");
+ if (!prompt) prompt = "CFE> ";
+ console_readline(prompt,buffer,sizeof(buffer));
+
+ if (cfe_web_check())
+ cfe_web_fg_process();
+ else {
+ status = ui_docommands(buffer);
+ if (status != CMD_ERR_BLANK) {
+ xprintf("*** command status = %d\n", status);
+ }
+ }
+ }
+}
+
+/* *********************************************************************
+ * cfe_errortext(err)
+ *
+ * Returns an error message with a number in it. The number can be
+ * looked up in cfe_error.h.
+ *
+ * Input parameters:
+ * err - error code
+ *
+ * Return value:
+ * string description of error
+ ********************************************************************* */
+
+const char *cfe_errortext(int err)
+{
+ static char err_buf[20];
+
+ sprintf(err_buf, "CFE error %d", err);
+ return (const char *) err_buf;
+}
+
+#if defined (_BCM96368_)
+/* *********************************************************************
+ * calculateCpuSpeed()
+ * Calculate BCM6368 CPU speed by reading the PLL Config register
+ * and applying the following formula:
+ * Fref_clk = (64 * (P2/P1) * (MIPSDDR_NDIV / REF_MDIV)
+ * Fbus_clk = (64 * (P2/P1) * (MIPSDDR_NDIV / DDR_MDIV)
+ * Fcpu_clk = (64 * (P2/P1) * (MIPSDDR_NDIV / CPU_MDIV)
+ * Input parameters:
+ * none
+ * Return value:
+ * none
+ ********************************************************************* */
+void static calculateCpuSpeed(void)
+{
+ UINT32 numerator;
+ UINT32 pllConfig = DDR->MIPSDDRPLLConfig;
+ UINT32 pllMDiv = DDR->MIPSDDRPLLMDiv;
+
+ numerator = 64000000 / ((pllConfig & MIPSDDR_P1_MASK) >> MIPSDDR_P1_SHFT) *
+ ((pllConfig & MIPSDDR_P2_MASK) >> MIPSDDR_P2_SHFT) *
+ ((pllConfig & MIPSDDR_NDIV_MASK) >> MIPSDDR_NDIV_SHFT);
+
+ cfe_cpu_speed = numerator / ((pllMDiv & MIPS_MDIV_MASK) >> MIPS_MDIV_SHFT);
+ cfe_bus_speed = numerator / ((pllMDiv & DDR_MDIV_MASK) >> DDR_MDIV_SHFT);
+ cfe_ref_speed = numerator / ((pllConfig & REF_MDIV_MASK) >> REF_MDIV_SHFT);
+}
+#endif
+
+#if defined (_BCM96328_) || defined (_BCM96362_) || (_BCM96816_)
+/* *********************************************************************
+ * calculateCpuSpeed()
+ * Calculate CPU speed by reading strap register
+ * Input parameters:
+ * none
+ * Return value:
+ * none
+ ********************************************************************* */
+void static calculateCpuSpeed(void)
+{
+ uint32 mips_pll_fvco;
+
+ mips_pll_fvco = MISC->miscStrapBus & MISC_STRAP_BUS_MIPS_PLL_FVCO_MASK;
+ mips_pll_fvco >>= MISC_STRAP_BUS_MIPS_PLL_FVCO_SHIFT;
+ cfe_cpu_speed = cpu_speed_table[mips_pll_fvco] * 1000000;
+ cfe_ddr_speed = ddr_speed_table[mips_pll_fvco] * 1000000;
+ cfe_bus_speed = bus_speed_table[mips_pll_fvco] * 1000000;
+}
+#endif
+
+/* *********************************************************************
+ * cfe_get_sdram_size(void)
+ *
+ * Return amount of SDRAM on the board.
+ *
+ * Input parameters:
+ * None.
+ *
+ * Return value:
+ * Amount of SDRAM on the board.
+ ********************************************************************* */
+static unsigned long cfe_get_sdram_size(void)
+{
+#if defined (_BCM96368_)
+ uint32 size;
+ uint32 memCfg;
+
+ size = 1;
+ memCfg = MEMC->Config;
+ /* Number of column bits */
+ size <<= (((memCfg & MEMC_COL_MASK) >> MEMC_COL_SHFT) + 8);
+ /* Plus number of row bits */
+ size <<= (((memCfg & MEMC_ROW_MASK) >> MEMC_ROW_SHFT) + 11);
+ /* Plus bus width */
+ if (((memCfg & MEMC_WIDTH_MASK) >> MEMC_WIDTH_SHFT) == MEMC_32BIT_BUS)
+ size <<= 2;
+ else
+ size <<= 1;
+
+ /* Plus number of banks */
+ size <<= 2;
+
+ return( size );
+#else
+ return (DDR->CSEND << 24);
+#endif
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_net_icmp.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_net_icmp.c
new file mode 100755
index 0000000..89802f8
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_net_icmp.c
@@ -0,0 +1,199 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * ICMP Protocol File: net_icmp.c
+ *
+ * This module implements portions of the ICMP protocol. Note
+ * that it is not a complete implementation, just enough to
+ * generate and respond to ICMP echo requests.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * 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 "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_timer.h"
+
+#include "net_ebuf.h"
+#include "net_ether.h"
+
+#include "net_ip.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define ICMP_CODE_ECHO 0
+#define ICMP_TYPE_ECHOREPLY 0
+#define ICMP_TYPE_ECHOREQ 8
+
+#define ICMPMSG(type,code) (((type)<<8)|(code))
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+struct icmp_info_s {
+ ip_info_t *icmp_ipinfo;
+ queue_t icmp_echoreplies;
+ int icmp_maxreplies;
+};
+
+/* *********************************************************************
+ * ICMP_RX_CALLBACK(ref,buf,dst,src)
+ *
+ * This routine is called by the IP layer when we receive
+ * ICMP protocol messages.
+ *
+ * Input parameters:
+ * ref - reference data (an icmp_info_t)
+ * buf - the ebuf containing the buffer
+ * dst - destination IP address (us, usually)
+ * src - source IP address
+ *
+ * Return value:
+ * ETH_KEEP to keep packet, ETH_DROP to cause packet to be freed
+ ********************************************************************* */
+
+static int icmp_rx_callback(void *ref,ebuf_t *buf,uint8_t *dst,uint8_t *src)
+{
+ icmp_info_t *icmp = (icmp_info_t *)ref;
+ ip_info_t *ipi = icmp->icmp_ipinfo;
+ uint16_t imsg;
+ uint16_t cksum;
+ ebuf_t *txbuf;
+ uint8_t *icmphdr;
+ int res;
+
+ imsg = ICMPMSG(buf->eb_ptr[0],buf->eb_ptr[1]);
+
+ res = ETH_DROP; /* assume we're dropping the pkt */
+
+ switch (imsg) {
+ case ICMPMSG(ICMP_TYPE_ECHOREQ,ICMP_CODE_ECHO):
+ txbuf = _ip_alloc(ipi);
+ if (txbuf) {
+ /* Construct reply from the original packet. */
+ icmphdr = txbuf->eb_ptr;
+ ebuf_append_bytes(txbuf,buf->eb_ptr,buf->eb_length);
+ icmphdr[0] = ICMP_TYPE_ECHOREPLY;
+ icmphdr[1] = ICMP_CODE_ECHO;
+ icmphdr[2] = 0; icmphdr[3] = 0;
+ cksum = ~ip_chksum(0,icmphdr,ebuf_length(txbuf));
+ icmphdr[2] = (cksum >> 8) & 0xFF;
+ icmphdr[3] = (cksum & 0xFF);
+ if (_ip_send(ipi,txbuf,src,IPPROTO_ICMP) < 0) {
+ _ip_free(ipi,txbuf);
+ }
+ }
+ break;
+
+ case ICMPMSG(ICMP_TYPE_ECHOREPLY,ICMP_CODE_ECHO):
+ if (q_count(&(icmp->icmp_echoreplies)) < icmp->icmp_maxreplies) {
+ /* We're keeping this packet, put it on the queue and don't
+ free it in the driver. */
+ q_enqueue(&(icmp->icmp_echoreplies),(queue_t *) buf);
+ res = ETH_KEEP;
+ }
+ break;
+
+ default:
+ res = ETH_DROP;
+ }
+
+ return res;
+}
+
+
+/* *********************************************************************
+ * _ICMP_INIT(ipi)
+ *
+ * Initialize the ICMP layer.
+ *
+ * Input parameters:
+ * ipi - ipinfo structure of IP layer to attach to
+ *
+ * Return value:
+ * icmp_info_t structure or NULL if error occurs
+ ********************************************************************* */
+
+icmp_info_t *_icmp_init(ip_info_t *ipi)
+{
+ icmp_info_t *icmp;
+
+ icmp = (icmp_info_t *) KMALLOC(sizeof(icmp_info_t),0);
+ if (!icmp) return NULL;
+
+ icmp->icmp_ipinfo = ipi;
+ q_init(&(icmp->icmp_echoreplies));
+ icmp->icmp_maxreplies = 0;
+
+ _ip_register(ipi,IPPROTO_ICMP,icmp_rx_callback,icmp);
+
+ return icmp;
+}
+
+/* *********************************************************************
+ * _ICMP_UNINIT(icmp)
+ *
+ * Un-initialize the ICMP layer.
+ *
+ * Input parameters:
+ * icmp - icmp_info_t structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void _icmp_uninit(icmp_info_t *icmp)
+{
+ _ip_deregister(icmp->icmp_ipinfo,IPPROTO_ICMP);
+
+ KFREE(icmp);
+}
+
+int _icmp_ping(icmp_info_t *icmp,uint8_t *dest,int seq,int len)
+{
+ return 0;
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ram_boot.S b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ram_boot.S
new file mode 100755
index 0000000..cf48de0
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_ram_boot.S
@@ -0,0 +1,88 @@
+#include "sbmips.h"
+
+/* *********************************************************************
+ * BOARD_EARLYINIT()
+ *
+ * Initialize board registers. This is the earliest
+ * time the BSP gets control. This routine cannot assume that
+ * memory is operational, and therefore all code in this routine
+ * must run from registers only. The $ra register must not
+ * be modified, as it contains the return address.
+ *
+ * This routine will be called from uncached space, before
+ * the caches are initialized. If you want to make
+ * subroutine calls from here, you must use the CALLKSEG1 macro.
+ *
+ * Among other things, this is where the GPIO registers get
+ * programmed to make on-board LEDs function, or other startup
+ * that has to be done before anything will work.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+LEAF(board_earlyinit)
+ j ra
+END(board_earlyinit)
+
+/* *********************************************************************
+ * BOARD_DRAMINFO
+ *
+ * Return the address of the DRAM information table
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - DRAM info table, return 0 to use default table
+ ********************************************************************* */
+LEAF(board_draminfo)
+ j ra
+END(board_draminfo)
+
+/* *********************************************************************
+ * BOARD_DRAMINIT
+ *
+ * This routine should activate memory.
+ *
+ * Input parameters:
+ * a0 - points to configuration table returned by board_draminfo
+ * or 0 to use an automatic table
+ *
+ * Return value:
+ * v0 - total memory installed
+ *
+ * Registers used:
+ * can use all registers.
+ ********************************************************************* */
+LEAF(board_draminit)
+ j ra
+END(board_draminit)
+
+/* *********************************************************************
+ * BOARD_SETLEDS(x)
+ *
+ * Set LEDs for boot-time progress indication. Not used if
+ * the board does not have progress LEDs. This routine
+ * must not call any other routines, since it may be invoked
+ * either from KSEG0 or KSEG1 and it may be invoked
+ * whether or not the icache is operational.
+ *
+ * Input parameters:
+ * a0 - LED value (8 bits per character, 4 characters)
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2,t3
+ ********************************************************************* */
+LEAF(board_setleds)
+ j ra
+END(board_setleds)
+
+LEAF(bcmcore_tp1_switch)
+ j ra
+END(bcmcore_tp1_switch)
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_util.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_util.c
new file mode 100755
index 0000000..91e1ad0
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/bcm63xx_util.c
@@ -0,0 +1,1375 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * bcm63xx utility functions
+ *
+ * Created on : 04/18/2002 seanl
+ *
+ *********************************************************************
+
+<:copyright-broadcom
+
+ Copyright (c) 2002 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+
+#define BCMTAG_EXE_USE
+#include "bcm63xx_util.h"
+#include "flash_api.h"
+#include "jffs2.h"
+
+#define je16_to_cpu(x) ((x).v16)
+#define je32_to_cpu(x) ((x).v32)
+
+static void convertBootInfo(void);
+static int checkChipId(int tagChipId, char *sig2);
+static void UpdateImageSequenceNumber( char *imageSequence );
+
+BOOT_INFO bootInfo;
+
+static int parseFilename(char *fn)
+{
+ if (strlen(fn) < BOOT_FILENAME_LEN)
+ return 0;
+ else
+ return 1;
+}
+
+static int parseChoiceFh(char *choice)
+{
+
+ if (*choice == 'f' || *choice == 'h')
+ return 0;
+ else
+ return 1;
+}
+
+
+static int parseBootPartition(char *choice)
+{
+ return( (*choice == BOOT_LATEST_IMAGE || *choice == BOOT_PREVIOUS_IMAGE)
+ ? 0 : 1 );
+}
+
+static int parseChoice09(char *choice)
+{
+ int bChoice = *choice - '0';
+
+ if (bChoice >= 0 && bChoice <= 9)
+ return 0;
+ else
+ return 1;
+}
+
+static int parseIpAddr(char *ipStr);
+static int parseGwIpAddr(char *ipStr);
+static int parseAfeId(char *afeIdStr);
+
+#define PARAM_IDX_BOARD_IPADDR 0
+#define PARAM_IDX_HOST_IPADDR 1
+#define PARAM_IDX_GW_IPADDR 2
+#define PARAM_IDX_RUN_FROM 3
+#define PARAM_IDX_RUN_FILENAME 4
+#define PARAM_IDX_FLASH_FILENAME 5
+#define PARAM_IDX_BOOT_DELAY 6
+#define PARAM_IDX_BOOT_IMAGE 7
+
+static PARAMETER_SETTING gBootParam[] =
+{
+ // prompt name Error Prompt Boot Define Boot Param Validation function
+ {"Board IP address :", IP_PROMPT , "e=",
+ "", 24, parseIpAddr, TRUE}, // index 0
+ {"Host IP address :", IP_PROMPT , "h=",
+ "", 15, parseIpAddr, TRUE}, // index 1
+ {"Gateway IP address :", IP_PROMPT , "g=",
+ "", 15, parseGwIpAddr, TRUE}, // index 2
+ {"Run from flash/host (f/h) :", RUN_FROM_PROMPT , "r=",
+ "", 1, parseChoiceFh, TRUE}, // index 3
+ {"Default host run file name :", HOST_FN_PROMPT , "f=",
+ "", MAX_PROMPT_LEN - 1, parseFilename, TRUE}, // index 4
+ {"Default host flash file name :", FLASH_FN_PROMPT , "i=",
+ "", MAX_PROMPT_LEN - 1, parseFilename, TRUE}, // index 5
+ {"Boot delay (0-9 seconds) :", BOOT_DELAY_PROMPT, "d=",
+ "", 1, parseChoice09, TRUE}, // index 6
+ {"Boot image (0=latest, 1=previous) :", BOOT_PARTITION_PROMPT, "p=",
+ "", 1, parseBootPartition, TRUE}, // index 7
+ {NULL},
+};
+
+static int gNumBootParams = (sizeof(gBootParam) / sizeof(PARAMETER_SETTING))-1;
+
+static PARAMETER_SETTING gAfeId[] =
+{
+ // prompt name Error Prompt Boot Define Boot Param Validation function
+ {"Primary AFE ID :", AFE_PROMPT, "", "", 12, parseAfeId, TRUE}, // index 0
+ {"Bonding AFE ID :", AFE_PROMPT, "", "", 12, parseAfeId, TRUE}, // index 1
+ {NULL},
+};
+static int gAfeIdParams = (sizeof(gAfeId) / sizeof(PARAMETER_SETTING))-1;
+
+// move from lib_misc.c
+int parseipaddr(const char *ipaddr,uint8_t *dest)
+{
+ int a,b,c,d;
+ char *x;
+
+ /* make sure it's all digits and dots. */
+ x = (char *) ipaddr;
+ while (*x) {
+ if ((*x == '.') || ((*x >= '0') && (*x <= '9'))) {
+ x++;
+ continue;
+ }
+ return -1;
+ }
+
+ x = (char *) ipaddr;
+ a = lib_atoi(ipaddr);
+ x = lib_strchr(x,'.');
+ if (!x) return -1;
+ b = lib_atoi(x+1);
+ x = lib_strchr(x+1,'.');
+ if (!x) return -1;
+ c = lib_atoi(x+1);
+ x = lib_strchr(x+1,'.');
+ if (!x) return -1;
+ d = lib_atoi(x+1);
+
+ if ((a < 0) || (a > 255)) return -1;
+ if ((b < 0) || (b > 255)) return -1;
+ if ((c < 0) || (c > 255)) return -1;
+ if ((d < 0) || (d > 255)) return -1;
+
+ dest[0] = (uint8_t) a;
+ dest[1] = (uint8_t) b;
+ dest[2] = (uint8_t) c;
+ dest[3] = (uint8_t) d;
+
+ return 0;
+}
+
+#if 0
+static const char hextable[16] = "0123456789ABCDEF";
+void dumpHex(unsigned char *start, int len)
+{
+ unsigned char *ptr = start,
+ *end = start + len;
+
+ while (ptr < end)
+ {
+ long offset = ptr - start;
+ unsigned char text[120],
+ *p = text;
+ while (ptr < end && p < &text[16 * 3])
+ {
+ *p++ = hextable[*ptr >> 4];
+ *p++ = hextable[*ptr++ & 0xF];
+ *p++ = ' ';
+ }
+ p[-1] = 0;
+ printf("%4lX %s\n", offset, text);
+ }
+}
+
+#endif
+
+int parsexdigit(char str)
+{
+ int digit;
+
+ if ((str >= '0') && (str <= '9'))
+ digit = str - '0';
+ else if ((str >= 'a') && (str <= 'f'))
+ digit = str - 'a' + 10;
+ else if ((str >= 'A') && (str <= 'F'))
+ digit = str - 'A' + 10;
+ else
+ return -1;
+
+ return digit;
+}
+
+
+// convert in = fffffff00 to out=255.255.255.0
+// return 0 = OK, 1 failed.
+static int convertMaskStr(char *in, char *out)
+{
+ int i;
+ char twoHex[4];
+ uint8_t dest[4];
+ char mask[BOOT_IP_LEN];
+
+ if (strlen(in) != MASK_LEN) // mask len has to 8
+ return 1;
+
+ memset(twoHex, 0, sizeof(twoHex));
+ for (i = 0; i < 4; i++)
+ {
+ twoHex[0] = (uint8_t)*in++;
+ twoHex[1] = (uint8_t)*in++;
+ if (parsexdigit(*twoHex) == -1)
+ return 1;
+ dest[i] = (uint8_t) xtoi(twoHex);
+ }
+ sprintf(mask, "%d.%d.%d.%d", dest[0], dest[1], dest[2], dest[3]);
+ strcpy(out, mask);
+ return 0;
+}
+
+// return 0 - OK, !0 - Bad ip
+static int parseIpAddr(char *ipStr)
+{
+ char *x;
+ uint8_t dest[4];
+ char mask[BOOT_IP_LEN];
+ char ipMaskStr[2*BOOT_IP_LEN];
+
+ strcpy(ipMaskStr, ipStr);
+
+ x = strchr(ipMaskStr,':');
+ if (!x) // no mask
+ return parseipaddr(ipMaskStr, dest);
+
+ *x = '\0';
+
+ if (parseipaddr(ipMaskStr, dest)) // ipStr is not ok
+ return 1;
+
+ x++;
+ return convertMaskStr(x, mask); // mask is not used here
+
+}
+
+// return 0 - OK, !0 - Bad ip
+static int parseGwIpAddr(char *ipStr)
+{
+ int ret = 0;
+ if( *ipStr )
+ ret = parseIpAddr(ipStr);
+ return(ret);
+}
+
+// return 0 - OK, !0 - Bad ip
+static int parseAfeId(char *afeIdStr)
+{
+ return 0;
+}
+
+// port from ifconfig command in ui_netcmds.c
+void enet_init(void)
+{
+ char devname[] = "eth0";
+ uint8_t addr[IP_ADDR_LEN];
+ int res;
+ NVRAM_DATA nvramData;
+
+ readNvramData(&nvramData);
+
+ if (net_getparam(NET_DEVNAME) == NULL) {
+ res = net_init(devname); /* turn interface on */
+ if (res < 0) {
+ ui_showerror(res, "Could not activate network interface '%s'", devname);
+ return;
+ }
+ }
+
+ net_setparam(NET_HWADDR, nvramData.ucaBaseMacAddr);
+
+ parseipaddr(bootInfo.boardIp, addr);
+ net_setparam(NET_IPADDR, addr);
+
+ if (strlen(bootInfo.boardMask) > 0) {
+ parseipaddr(bootInfo.boardMask, addr);
+ net_setparam(NET_NETMASK, addr);
+ }
+
+ if (strlen(bootInfo.gatewayIp) > 0) {
+ parseipaddr(bootInfo.gatewayIp, addr);
+ net_setparam(NET_GATEWAY, addr);
+ }
+
+ net_setnetvars();
+}
+
+/***************************************************************************
+// Function Name: getCrc32
+// Description : caculate the CRC 32 of the given data.
+// Parameters : pdata - array of data.
+// size - number of input data bytes.
+// crc - either CRC32_INIT_VALUE or previous return value.
+// Returns : crc.
+****************************************************************************/
+UINT32 getCrc32(byte *pdata, UINT32 size, UINT32 crc)
+{
+ while (size-- > 0)
+ crc = (crc >> 8) ^ Crc32_table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
+
+
+// return 0, ok. return -1 = wrong chip
+static int checkChipId(int tagChipId, char *sig2)
+{
+ unsigned int chipId = (PERF->RevID & 0xFFFE0000) >> 16;
+ int result = 0;
+
+ /* Force BCM681x variants to be be BCM6816) */
+ if( (chipId & 0xfff0) == 0x6810 )
+ chipId = 0x6816;
+
+ if (tagChipId == chipId)
+ result = 0;
+ else {
+ printf("Chip Id error. Image Chip Id = %04x, Board Chip Id = %04x.\n", tagChipId, chipId);
+ result = -1;
+ }
+
+ return result;
+}
+
+// return -1: fail.
+// 0: OK.
+int verifyTag( PFILE_TAG pTag, int verbose )
+{
+ UINT32 crc;
+ FLASH_ADDR_INFO info;
+ int tagVer, curVer;
+
+ kerSysFlashAddrInfoGet( &info );
+
+ tagVer = atoi(pTag->tagVersion);
+ curVer = atoi(BCM_TAG_VER);
+
+ if (tagVer != curVer)
+ {
+ if( verbose )
+ {
+ printf("Firmware tag version [%d] is not compatible with the current Tag version [%d].\n", \
+ tagVer, curVer);
+ }
+ return -1;
+ }
+
+ if (checkChipId(xtoi(pTag->chipId), pTag->signiture_2) != 0)
+ return -1;
+
+ // check tag validate token first
+ crc = CRC32_INIT_VALUE;
+ crc = getCrc32((byte *) pTag, (UINT32)TAG_LEN-TOKEN_LEN, crc);
+
+ if (crc != (UINT32)(*(UINT32*)(pTag->tagValidationToken)))
+ {
+ if( verbose )
+ printf("Illegal image ! Tag crc failed.\n");
+ return -1;
+ }
+ return 0;
+}
+
+#if (INC_NAND_FLASH_DRIVER==0)
+PFILE_TAG getTagFromPartition(int imageNumber)
+{
+ static unsigned char sectAddr1[sizeof(FILE_TAG)];
+ static unsigned char sectAddr2[sizeof(FILE_TAG)];
+ int blk = 0;
+ UINT32 crc;
+ PFILE_TAG pTag = NULL;
+ unsigned char *pBase = flash_get_memptr(0);
+ unsigned char *pSectAddr = NULL;
+
+ /* The image tag for the first image is always after the boot loader.
+ * The image tag for the second image, if it exists, is at one half
+ * of the flash size.
+ */
+ if( imageNumber == 1 )
+ {
+
+ FLASH_ADDR_INFO flash_info;
+
+ kerSysFlashAddrInfoGet(&flash_info);
+ blk = flash_get_blk((int)(pBase+flash_info.flash_rootfs_start_offset));
+ pSectAddr = sectAddr1;
+ }
+ else
+ if( imageNumber == 2 )
+ {
+ blk = flash_get_blk((int) (pBase + (flash_get_total_size() / 2)));
+ pSectAddr = sectAddr2;
+ }
+
+ if( blk )
+ {
+ memset(pSectAddr, 0x00, sizeof(FILE_TAG));
+ flash_read_buf((unsigned short) blk, 0, pSectAddr, sizeof(FILE_TAG));
+ crc = CRC32_INIT_VALUE;
+ crc = getCrc32(pSectAddr, (UINT32)TAG_LEN-TOKEN_LEN, crc);
+ pTag = (PFILE_TAG) pSectAddr;
+ if (crc != (UINT32)(*(UINT32*)(pTag->tagValidationToken)))
+ pTag = NULL;
+ }
+
+ return( pTag );
+}
+#else
+#define tag_not_searched 0
+#define tag_not_found 1
+#define tag_found 2
+PFILE_TAG getTagFromPartition(int imageNumber)
+{
+ extern unsigned char *mem_topofmem;
+ static FILE_TAG Tag1 = {{tag_not_searched}};
+ static FILE_TAG Tag2 = {{tag_not_searched}};
+ PFILE_TAG pTag = (imageNumber == 2) ? &Tag2 : &Tag1;
+ PFILE_TAG ret = NULL;
+
+ switch( pTag->tagVersion[0] )
+ {
+ case tag_not_searched:
+ {
+ int rootfs = (imageNumber == 2) ? NP_ROOTFS_2 : NP_ROOTFS_1;
+ char fname[] = NAND_CFE_RAM_NAME;
+ int fname_actual_len = strlen(fname);
+ int fname_cmp_len = strlen(fname) - 3; /* last three are digits */
+ unsigned char *buf = (unsigned char *) mem_topofmem + 1024;
+ unsigned char *p;
+ int len = flash_get_sector_size(0);
+ int num_blks = flash_get_numsectors();
+ int i, done, start_blk, end_blk;
+ struct jffs2_raw_dirent *pdir;
+ unsigned long version = 0;
+ NVRAM_DATA nvramData;
+
+ pTag->tagVersion[0] = tag_not_found;
+ readNvramData(&nvramData);
+ validateNandPartTbl(&nvramData);
+
+ if( nvramData.ulNandPartOfsKb[rootfs] > 0 &&
+ nvramData.ulNandPartOfsKb[rootfs] < ((num_blks * len) / 1024) &&
+ nvramData.ulNandPartSizeKb[rootfs] > 0 &&
+ nvramData.ulNandPartSizeKb[rootfs] < ((num_blks * len) / 1024) )
+ {
+ const int max_not_jffs2 = 10;
+ int not_jffs2 = 0;
+
+ start_blk = nvramData.ulNandPartOfsKb[rootfs] / (len / 1024);
+ end_blk =
+ start_blk + (nvramData.ulNandPartSizeKb[rootfs] / (len / 1024));
+
+ /* 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_actual_len == pdir->nsize &&
+ !memcmp(fname, pdir->name, fname_cmp_len) )
+ {
+ if( je32_to_cpu(pdir->version) > version )
+ {
+ if( je32_to_cpu(pdir->ino) != 0 )
+ {
+ unsigned char *seq =
+ pdir->name + fname_cmp_len;
+ pTag->imageSequence[0] = seq[0];
+ pTag->imageSequence[1] = seq[1];
+ pTag->imageSequence[2] = seq[2];
+ pTag->imageSequence[3] = '\0';
+ pTag->tagVersion[0] = tag_found;
+
+ version = je32_to_cpu(pdir->version);
+
+ /* Setting 'done = 1' assumes there is
+ * only one version of the directory
+ * entry.
+ */
+ done = 1;
+ ret = pTag;
+ break;
+ }
+ }
+ }
+
+ p += (je32_to_cpu(pdir->totlen) + 0x03) & ~0x03;
+ not_jffs2 = 0;
+ }
+ else
+ {
+ if( not_jffs2++ > max_not_jffs2 )
+ done = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case tag_found:
+ ret = pTag;
+ break;
+
+ case tag_not_found:
+ ret = NULL;
+ break;
+ }
+
+ return(ret);
+}
+#endif
+
+
+int getPartitionFromTag( PFILE_TAG pTag )
+{
+ int ret = 0;
+
+ if( pTag )
+ {
+ PFILE_TAG pTag1 = getTagFromPartition(1);
+ PFILE_TAG pTag2 = getTagFromPartition(2);
+ int sequence = atoi(pTag->imageSequence);
+ int sequence1 = (pTag1) ? atoi(pTag1->imageSequence) : -1;
+ int sequence2 = (pTag2) ? atoi(pTag2->imageSequence) : -1;
+
+ if( pTag1 && sequence == sequence1 )
+ ret = 1;
+ else
+ if( pTag2 && sequence == sequence2 )
+ ret = 2;
+ }
+
+ return( ret );
+}
+
+PFILE_TAG getBootImageTag(void)
+{
+ PFILE_TAG pTag = NULL;
+
+ if( flash_get_flash_type() != FLASH_IFC_NAND )
+ {
+ PFILE_TAG pTag1 = getTagFromPartition(1);
+
+ /* Foxconn modified end pling 10/13/2008 */
+ PFILE_TAG pTag2 = NULL;
+ // PFILE_TAG pTag2 = getTagFromPartition(2);
+ //* Foxconn modified end pling 10/13/2008 */
+
+ if( pTag1 && pTag2 )
+ {
+ /* Two images are flashed. */
+ int sequence1 = atoi(pTag1->imageSequence);
+ int sequence2 = atoi(pTag2->imageSequence);
+
+ if( bootInfo.bootPartition == BOOT_LATEST_IMAGE )
+ pTag = (sequence2 > sequence1) ? pTag2 : pTag1;
+ else /* Boot from the previous image. */
+ pTag = (sequence2 < sequence1) ? pTag2 : pTag1;
+ }
+ else
+ /* One image is flashed. */
+ pTag = (pTag2) ? pTag2 : pTag1;
+ }
+ else
+ {
+ /* TBD. Verify that linux is on the file system. */
+ /* pTag pointer is only compared to NULL for NAND flash boot. */
+ pTag = (PFILE_TAG) 1;
+ }
+
+ return( pTag );
+}
+
+static void UpdateImageSequenceNumber( char *imageSequence )
+{
+ int newImageSequence = 0;
+ PFILE_TAG pTag = getTagFromPartition(1);
+
+ if( pTag )
+ newImageSequence = atoi(pTag->imageSequence);
+
+ pTag = getTagFromPartition(2);
+ if( pTag && atoi(pTag->imageSequence) > newImageSequence )
+ newImageSequence = atoi(pTag->imageSequence);
+
+ newImageSequence++;
+ sprintf(imageSequence, "%d", newImageSequence);
+}
+
+// return -1: fail.
+// 0: OK.
+int flashImage(uint8_t *imagePtr)
+{
+ UINT32 crc;
+ FLASH_ADDR_INFO info;
+ int totalImageSize = 0;
+ int cfeSize;
+ int cfeAddr, rootfsAddr, kernelAddr;
+ int status = 0;
+ PFILE_TAG pTag = (PFILE_TAG) imagePtr;
+ NVRAM_DATA nvramData, tmpNvramData;
+
+ if( flash_get_flash_type() == FLASH_IFC_NAND )
+ {
+ printf("ERROR: Image is not a valid NAND flash image.\n");
+ return -1;
+ }
+
+ // save existing NVRAM data into a local structure
+ readNvramData(&nvramData);
+
+ if( verifyTag( pTag, 1 ) == -1 )
+ return -1;
+
+ kerSysFlashAddrInfoGet( &info );
+
+ // check imageCrc
+ totalImageSize = atoi(pTag->totalImageLen);
+ crc = CRC32_INIT_VALUE;
+ crc = getCrc32((imagePtr+TAG_LEN), (UINT32) totalImageSize, crc);
+
+ if (crc != (UINT32) (*(UINT32*)(pTag->imageValidationToken)))
+ {
+ printf(" Illegal image ! Image crc failed.\n");
+ return -1;
+ }
+
+ cfeSize = cfeAddr = rootfsAddr = kernelAddr = 0;
+
+ // check cfe's existence
+ cfeAddr = atoi(pTag->cfeAddress);
+ if (cfeAddr)
+ {
+ cfeSize = atoi(pTag->cfeLen);
+ if( (cfeSize <= 0) )
+ {
+ printf("Illegal cfe size [%d].\n", cfeSize );
+ return -1;
+ }
+
+ printf("\nFlashing CFE: ");
+ if ((status = kerSysBcmImageSet(cfeAddr+BOOT_OFFSET, imagePtr+TAG_LEN,
+ cfeSize, 0)) != 0)
+ {
+ printf("Failed to flash CFE. Error: %d\n", status);
+ return status;
+ }
+
+ // Check if the new image has valid NVRAM
+ if ((readNvramData(&tmpNvramData) != 0) || (BpSetBoardId(tmpNvramData.szBoardId) != BP_SUCCESS) || (BpSetVoiceBoardId(tmpNvramData.szBoardId) != BP_SUCCESS))
+ writeNvramData(&nvramData);
+ }
+
+ // check root filesystem and kernel existence
+ rootfsAddr = atoi(pTag->rootfsAddress);
+ kernelAddr = atoi(pTag->kernelAddress);
+
+ if( rootfsAddr && kernelAddr )
+ {
+ char *p;
+ unsigned char *tagFs = imagePtr;
+ unsigned int baseAddr = (unsigned int) flash_get_memptr(0);
+ unsigned int totalSize = (unsigned int) flash_get_total_size();
+ unsigned int reservedBytesAtEnd;
+ unsigned int availableSizeOneImg;
+ unsigned int reserveForTwoImages;
+ unsigned int availableSizeTwoImgs;
+ unsigned int newImgSize = atoi(pTag->rootfsLen)+atoi(pTag->kernelLen);
+ PFILE_TAG pCurTag = getBootImageTag();
+ UINT32 crc;
+ unsigned int curImgSize = 0;
+ unsigned int rootfsOffset = (unsigned int)rootfsAddr-IMAGE_BASE-TAG_LEN;
+ FLASH_ADDR_INFO flash_info;
+
+ kerSysFlashAddrInfoGet(&flash_info);
+ if( rootfsOffset < flash_info.flash_rootfs_start_offset )
+ {
+ // Increase rootfs and kernel addresses by the difference between
+ // rootfs offset and what it needs to be.
+ rootfsAddr += flash_info.flash_rootfs_start_offset - rootfsOffset;
+ kernelAddr += flash_info.flash_rootfs_start_offset - rootfsOffset;
+ sprintf(pTag->rootfsAddress,"%lu", (unsigned long) rootfsAddr);
+ sprintf(pTag->kernelAddress,"%lu", (unsigned long) kernelAddr);
+ crc = CRC32_INIT_VALUE;
+ crc = getCrc32((unsigned char *)pTag,(UINT32)TAG_LEN-TOKEN_LEN,crc);
+ *(unsigned long *) &pTag->tagValidationToken[0] = crc;
+ }
+
+ rootfsAddr += BOOT_OFFSET;
+ kernelAddr += BOOT_OFFSET;
+
+ reservedBytesAtEnd = flash_get_reserved_bytes_at_end(&flash_info);
+ availableSizeOneImg = totalSize - ((unsigned int)rootfsAddr-baseAddr) -
+ reservedBytesAtEnd;
+ reserveForTwoImages =
+ (flash_info.flash_rootfs_start_offset > reservedBytesAtEnd)
+ ? flash_info.flash_rootfs_start_offset : reservedBytesAtEnd;
+ availableSizeTwoImgs = (totalSize / 2) - reserveForTwoImages;
+
+// printf("availableSizeOneImage=%dKB availableSizeTwoImgs=%dKB reserve=%dKB\n",
+// availableSizeOneImg/1024, availableSizeTwoImgs/1024, reserveForTwoImages/1024);
+
+ if( pCurTag )
+ curImgSize = atoi(pCurTag->rootfsLen) + atoi(pCurTag->kernelLen);
+
+ if( newImgSize > availableSizeOneImg)
+ {
+ printf("Illegal image size %d. Image size must not be greater "
+ "than %d.\n", newImgSize, availableSizeOneImg);
+ return -1;
+ }
+
+ // tag is alway at the sector start of fs
+ if (cfeAddr)
+ {
+ // will trash cfe memory, but cfe is already flashed
+ tagFs = imagePtr + cfeSize;
+ memcpy(tagFs, imagePtr, TAG_LEN);
+ }
+
+ // If the current image fits in half the flash space and the new
+ // image to flash also fits in half the flash space, then flash it
+ // in the partition that is not currently being used to boot from.
+ if( curImgSize <= availableSizeTwoImgs &&
+ newImgSize <= availableSizeTwoImgs &&
+ getPartitionFromTag( pCurTag ) == 1 )
+ {
+ // Update rootfsAddr to point to the second boot partition.
+ int offset = (totalSize / 2) + TAG_LEN;
+
+ sprintf(((PFILE_TAG) tagFs)->kernelAddress, "%lu",
+ (unsigned long) IMAGE_BASE + offset + (kernelAddr-rootfsAddr));
+ kernelAddr = baseAddr + offset + (kernelAddr - rootfsAddr);
+
+ sprintf(((PFILE_TAG) tagFs)->rootfsAddress, "%lu",
+ (unsigned long) IMAGE_BASE + offset);
+ rootfsAddr = baseAddr + offset;
+ }
+
+ UpdateImageSequenceNumber( ((PFILE_TAG) tagFs)->imageSequence );
+ crc = CRC32_INIT_VALUE;
+ crc = getCrc32((unsigned char *)tagFs, (UINT32)TAG_LEN-TOKEN_LEN, crc);
+ *(unsigned long *) &((PFILE_TAG) tagFs)->tagValidationToken[0] = crc;
+
+ printf("\nFlashing root file system and kernel at 0x%8.8lx: ",
+ rootfsAddr - TAG_LEN);
+ if( (status = kerSysBcmImageSet((rootfsAddr-TAG_LEN), tagFs,
+ TAG_LEN + newImgSize, 0)) != 0 )
+ {
+ printf("Failed to flash root file system. Error: %d\n", status);
+ return status;
+ }
+
+ for( p = nvramData.szBootline; p[2] != '\0'; p++ )
+ {
+ if( p[0] == 'p' && p[1] == '=' && p[2] != BOOT_LATEST_IMAGE )
+ {
+ // Change boot partition to boot from new image.
+ p[2] = BOOT_LATEST_IMAGE;
+ writeNvramData(&nvramData);
+ break;
+ }
+ }
+ }
+
+ printf(".\n*** Image flash done *** !\n");
+
+ return status;
+}
+
+static int nandUpdateImageSequenceNumber( uint8_t *imagePtr, int imageSize )
+{
+ unsigned char *buf, *p;
+ char fname[] = NAND_CFE_RAM_NAME;
+ int fname_actual_len = strlen(fname);
+ int fname_cmp_len = strlen(fname) - 3; /* last three are digits */
+ int len = flash_get_sector_size(0);
+ struct jffs2_raw_dirent *pdir;
+ unsigned long version = 0;
+ PFILE_TAG pTag1 = getTagFromPartition(1);
+ PFILE_TAG pTag2 = getTagFromPartition(2);
+ int seq = (pTag1) ? atoi(pTag1->imageSequence) : -1;
+ int seq2 = (pTag2) ? atoi(pTag2->imageSequence) : -1;
+ int ret = 0;
+
+ if( seq2 > seq )
+ seq = seq2;
+
+ if( seq != -1 )
+ {
+ int done = 0;
+
+ /* Increment the new highest sequence number. Add it to the CFE RAM
+ * file name.
+ */
+ seq++;
+
+ for(buf = imagePtr; buf < imagePtr+imageSize && done == 0; buf += len)
+ {
+ 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_actual_len == pdir->nsize &&
+ !memcmp(fname, pdir->name, fname_cmp_len) &&
+ je32_to_cpu(pdir->version) > version &&
+ je32_to_cpu(pdir->ino) != 0 )
+ {
+ p = pdir->name + fname_cmp_len;
+ p[0] = (seq / 100) + '0';
+ p[1] = ((seq % 100) / 10) + '0';
+ p[2] = ((seq % 100) % 10) + '0';
+ p[3] = '\0';
+
+ je32_to_cpu(pdir->name_crc) = getCrc32(pdir->name,
+ (unsigned long) fname_actual_len, 0);
+
+ version = je32_to_cpu(pdir->version);
+
+ /* Setting 'done = 1' assumes there is only one version
+ * of the directory entry.
+ */
+ done = 1;
+ ret = (buf - imagePtr) / len; /* block number */
+ break;
+ }
+
+ p += (je32_to_cpu(pdir->totlen) + 0x03) & ~0x03;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ return(ret);
+}
+
+// return -1: fail.
+// 0: OK.
+int writeWholeImage(uint8_t *imagePtr, int wholeImageSize)
+{
+ UINT32 crc;
+ int status = 0;
+ int offset = 0;
+ int imageSize = wholeImageSize - TOKEN_LEN;
+ unsigned char crcBuf[CRC_LEN];
+ NVRAM_DATA nvramData, tmpNvramData;
+ WFI_TAG wfiTag;
+#if (INC_SPI_PROG_NAND==1)
+ if( flash_get_flash_type() != FLASH_IFC_NAND && wholeImageSize > FLASH_LENGTH_BOOT_ROM)
+ flash_change_flash_type(FLASH_IFC_NAND);
+#endif
+
+ // if whole image size (plus TOKEN_LEN of crc) is greater than total flash size, return error
+ if (wholeImageSize > (flash_get_total_size() + TOKEN_LEN))
+ {
+ printf("Image size too big\n");
+ return -1;
+ }
+
+ memcpy(&wfiTag, imagePtr + imageSize, sizeof(wfiTag));
+ if( (wfiTag.wfiVersion & WFI_ANY_VERS_MASK) == WFI_ANY_VERS &&
+ checkChipId(wfiTag.wfiChipId, NULL) != 0 )
+ return -1;
+
+ // check tag validate token first
+ crc = CRC32_INIT_VALUE;
+ crc = getCrc32(imagePtr, (UINT32)imageSize, crc);
+ memcpy(crcBuf, imagePtr+imageSize, CRC_LEN);
+ if (memcmp(&crc, crcBuf, CRC_LEN) != 0)
+ {
+ printf("Illegal whole flash image\n");
+ return -1;
+ }
+
+ // save existing NVRAM data into a local structure
+ readNvramData(&nvramData);
+
+ if( flash_get_flash_type() == FLASH_IFC_NAND )
+ {
+ /* The CFE ROM boot loader saved the rootfs partition index at the
+ * memory location before CFE RAM load address.
+ */
+ extern unsigned char _ftext;
+
+ /* Allow addition blocks to flash cfram block that has sequence number
+ * and is flashed last.
+ */
+ const int overhead_blocks = 8;
+
+ int rootfs = (int) *(&_ftext - 1);
+ int blksize = flash_get_sector_size(0) / 1024;
+ int sectsize = flash_get_sector_size(0);
+ int i, cferam_blk, after_cferam, cferam_overhead;
+
+ if( (wfiTag.wfiVersion & WFI_ANY_VERS_MASK) == WFI_ANY_VERS &&
+ ((blksize == 16 && wfiTag.wfiFlashType != WFI_NAND16_FLASH) ||
+ (blksize == 128 && wfiTag.wfiFlashType != WFI_NAND128_FLASH)) )
+ {
+ printf("\nERROR: NAND flash block size does not match image "
+ "block size\n\n");
+ return -1;
+ }
+
+ if( *(unsigned short *) imagePtr != JFFS2_MAGIC_BITMASK )
+ {
+ /* Flash block 0 (cferom). */
+ PNVRAM_DATA pnd = (PNVRAM_DATA) (imagePtr + NVRAM_DATA_OFFSET);
+ char *p;
+
+ /* Copy NVRAM data to block to be flashed so it is preserved. */
+ memcpy((unsigned char *) pnd, (unsigned char *) &nvramData,
+ sizeof(NVRAM_DATA));
+ for( p = pnd->szBootline; p[2] != '\0'; p++ )
+ {
+ if( p[0] == 'p' && p[1] == '=' && p[2] != BOOT_LATEST_IMAGE )
+ {
+ // Change boot partition to boot from new image.
+ p[2] = BOOT_LATEST_IMAGE;
+ break;
+ }
+ }
+
+ /* Recalculate the nvramData CRC. */
+ pnd->ulCheckSum = 0;
+ pnd->ulCheckSum = getCrc32((unsigned char *) pnd,
+ sizeof(NVRAM_DATA), CRC32_INIT_VALUE);
+
+ if((status = kerSysBcmImageSet(FLASH_BASE,imagePtr,sectsize,0)) != 0)
+ printf("Failed to flash block 0. Error: %d\n", status);
+ imagePtr += sectsize;
+ imageSize -= sectsize;
+ }
+
+ validateNandPartTbl(&nvramData);
+ cferam_blk = nandUpdateImageSequenceNumber(imagePtr, imageSize);
+
+ /* rootfs is the partition that the CFE RAM booted from. Write the
+ * image to the other rootfs partition.
+ */
+ 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;
+
+ after_cferam = (cferam_blk + 1) * sectsize;
+ cferam_overhead = overhead_blocks * sectsize;
+
+ /* Erase block with cferam JFFS2 directory entry so if flashing this
+ * image does not finish, the partition will not be valid.
+ */
+ for( i = 0; i < (cferam_blk + 1 + overhead_blocks); i++ )
+ flash_sector_erase_int((offset / sectsize) + i);
+
+ /* Flash image after cferam directory entry. */
+ printf("\nFlashing root file system at 0x%8.8lx: ", FLASH_BASE+offset);
+ if((status = kerSysBcmImageSet(FLASH_BASE + offset + after_cferam +
+ cferam_overhead, imagePtr + after_cferam, imageSize - after_cferam,
+ 1)) != 0)
+ {
+ printf("Failed to flash whole image. Error: %d\n", status);
+ return status;
+ }
+
+ /* Flash block(s) up to and including the block with cferam JFFS2
+ * directory entry.
+ */
+ if((status = kerSysBcmImageSet(FLASH_BASE + offset, imagePtr,
+ after_cferam, 0)) != 0)
+ {
+ printf("Failed to flash whole image. Error: %d\n", status);
+ return status;
+ }
+ }
+ else /* NOR FLASH */
+ {
+ printf("\nFlashing root file system and kernel at 0x%8.8lx\n",
+ FLASH_BASE+offset);
+
+ if( (wfiTag.wfiVersion & WFI_ANY_VERS_MASK) == WFI_ANY_VERS &&
+ wfiTag.wfiFlashType != WFI_NOR_FLASH )
+ {
+ printf("\nERROR: Image does not support a NOR flash device.\n\n");
+ return -1;
+ }
+
+ if((status = kerSysBcmImageSet(FLASH_BASE+offset, imagePtr, imageSize,
+ 1)) != 0)
+ {
+ printf("Failed to flash whole image. Error: %d\n", status);
+ return status;
+ }
+ }
+
+ // Check if the new image has valid NVRAM
+ // Also check if the new image still supports currently configured board ID
+ if( (readNvramData(&tmpNvramData) != 0) ||
+ (BpSetBoardId(tmpNvramData.szBoardId) != BP_SUCCESS) ||
+ (BpSetVoiceBoardId(tmpNvramData.szVoiceBoardId) != BP_SUCCESS) )
+ {
+ // Don't write NVRAM area if we are flashing tiny bridge image.
+ // unlike cfe.w, the tiny bridge .w image will not have NVRAM_DATA_ID set
+ if (*(unsigned long *) &tmpNvramData == NVRAM_DATA_ID)
+ writeNvramData(&nvramData);
+ }
+
+ return status;
+}
+
+int processPrompt(PPARAMETER_SETTING promptPtr, int promptCt)
+{
+ char tmpBuf[MAX_PROMPT_LEN];
+ int i = 0;
+ int bChange = FALSE;
+
+ printf("Press: <enter> to use current value\r\n");
+ printf(" '-' to go previous parameter\r\n");
+ printf(" '.' to clear the current value\r\n");
+ printf(" 'x' to exit this command\r\n");
+
+ memset(tmpBuf, 0, MAX_PROMPT_LEN);
+ while (i < promptCt)
+ {
+ if( (promptPtr+i)->enabled == FALSE )
+ {
+ if( tmpBuf[0] == '-' )
+ {
+ if( i > 0 )
+ {
+ i--;
+ continue;
+ }
+ }
+ else
+ {
+ i++;
+ continue;
+ }
+ }
+
+ if (strlen((promptPtr+i)->parameter) > 0)
+ printf("%s %s ", (promptPtr+i)->promptName, (promptPtr+i)->parameter);
+ else
+ printf("%s %s", (promptPtr+i)->promptName, (promptPtr+i)->parameter);
+
+ memset(tmpBuf, 0, MAX_PROMPT_LEN);
+ console_readline ("", tmpBuf, (promptPtr+i)->maxValueLength + 1);
+
+ switch (tmpBuf[0])
+ {
+ case '-': // go back one parameter
+ if (i > 0)
+ i--;
+ break;
+ case 'x': // get out the b command
+ if ((promptPtr+i)->func != 0) // validate function is supplied, do a check
+ {
+ if ((promptPtr+i)->func((promptPtr+i)->parameter))
+ {
+ printf("\n%s; Try again!\n", (promptPtr+i)->errorPrompt);
+ break;
+ }
+ }
+ i = promptCt;
+ break;
+ case '.': // clear the current parameter and advance
+ if ((promptPtr+i)->func != 0) // validate function is supplied, do a check
+ {
+ if ((promptPtr+i)->func(""))
+ {
+ printf("\n%s; Try again!\n", (promptPtr+i)->errorPrompt);
+ break;
+ }
+ }
+ memset((promptPtr+i)->parameter, 0, MAX_PROMPT_LEN);
+ i++;
+ bChange = TRUE;
+ break;
+ case 0: // no input; use default if it is OK
+ if ((promptPtr+i)->func != 0) // validate function is supplied, do a check
+ {
+ if ((promptPtr+i)->func((promptPtr+i)->parameter))
+ {
+ printf("\n%s; Try again!\n", (promptPtr+i)->errorPrompt);
+ break;
+ }
+ }
+ i++;
+ break;
+ default: // new parameter
+ if ((promptPtr+i)->func != 0) // validate function is supplied, do a check
+ {
+ if ((promptPtr+i)->func(tmpBuf))
+ {
+ printf("\n%s; Try again!\n", (promptPtr+i)->errorPrompt);
+ break;
+ }
+ }
+ memset((promptPtr+i)->parameter, 0, MAX_PROMPT_LEN);
+ memcpy((promptPtr+i)->parameter, tmpBuf, strlen(tmpBuf));
+ i++;
+ bChange = TRUE;
+ }
+ }
+
+ return bChange;
+
+} // processPrompt
+
+// write the nvramData struct to nvram after CRC is calculated
+void writeNvramData(PNVRAM_DATA pNvramData)
+{
+ UINT32 crc = CRC32_INIT_VALUE;
+
+ pNvramData->ulCheckSum = 0;
+ crc = getCrc32((unsigned char *)pNvramData, sizeof(NVRAM_DATA), crc);
+ pNvramData->ulCheckSum = crc;
+ kerSysNvRamSet((unsigned char *)pNvramData, sizeof(NVRAM_DATA), 0);
+}
+
+// read the nvramData struct from nvram
+// return -1: crc fail, 0 ok
+int readNvramData(PNVRAM_DATA pNvramData)
+{
+ UINT32 crc = CRC32_INIT_VALUE, savedCrc;
+
+ kerSysNvRamGet((unsigned char *)pNvramData, sizeof(NVRAM_DATA), 0);
+ savedCrc = pNvramData->ulCheckSum;
+ pNvramData->ulCheckSum = 0;
+ crc = getCrc32((unsigned char *)pNvramData, sizeof(NVRAM_DATA), crc);
+ if (savedCrc != crc)
+ return -1;
+
+ return 0;
+}
+
+static void convertBootInfo(void)
+{
+ char *x;
+
+ memset(&bootInfo, 0, sizeof(BOOT_INFO));
+ strcpy(bootInfo.boardIp, gBootParam[PARAM_IDX_BOARD_IPADDR].parameter);
+
+ if ((x = strchr(bootInfo.boardIp, ':'))) // has mask
+ {
+ *x = '\0';
+ convertMaskStr((x+1), bootInfo.boardMask);
+ }
+ strcpy(bootInfo.hostIp, gBootParam[PARAM_IDX_HOST_IPADDR].parameter);
+ if ((x = strchr(bootInfo.hostIp, ':'))) // ignore host mask
+ *x = '\0';
+ strcpy(bootInfo.gatewayIp, gBootParam[PARAM_IDX_GW_IPADDR].parameter);
+ if ((x = strchr(bootInfo.gatewayIp, ':'))) // ignore gw mask
+ *x = '\0';
+ bootInfo.runFrom = gBootParam[PARAM_IDX_RUN_FROM].parameter[0];
+ strcpy(bootInfo.hostFileName, gBootParam[PARAM_IDX_RUN_FILENAME].parameter);
+ strcpy(bootInfo.flashFileName, gBootParam[PARAM_IDX_FLASH_FILENAME].parameter);
+ bootInfo.bootDelay = (int)(gBootParam[PARAM_IDX_BOOT_DELAY].parameter[0] - '0');
+ bootInfo.bootPartition = gBootParam[PARAM_IDX_BOOT_IMAGE].parameter[0];
+}
+
+void getBootLine(void)
+{
+ int i;
+ char *curPtr;
+ char *dPtr;
+ NVRAM_DATA nvramData;
+
+ readNvramData(&nvramData);
+
+ if ((nvramData.szBootline[0] == (char)0xff) ||
+ (nvramData.szBootline[0] == (char)0))
+ {
+ setDefaultBootline();
+ return;
+ }
+
+ curPtr = nvramData.szBootline;
+ for (i = 0; (i < gNumBootParams) && (curPtr != 0); i++)
+ {
+ curPtr = strchr(curPtr, '=');
+ if (curPtr) // found '=' and get the param.
+ {
+ dPtr = strchr(curPtr, ' '); // find param. deliminator ' '
+ memset(gBootParam[i].parameter, 0, MAX_PROMPT_LEN);
+ memcpy(gBootParam[i].parameter, curPtr+1, dPtr-curPtr-1);
+ // move to next param.
+ curPtr = dPtr;
+ }
+ } // for loop
+
+ if (i < gNumBootParams) {
+ setDefaultBootline();
+ return;
+ }
+
+ convertBootInfo();
+}
+
+// print the bootline and board parameter info and fill in the struct for later use
+//
+int printSysInfo(void)
+{
+ int i;
+ ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS];
+
+ // display the bootline info
+
+ if( getTagFromPartition(1) == NULL || getTagFromPartition(2) == NULL )
+ gBootParam[PARAM_IDX_BOOT_IMAGE].enabled = FALSE;
+
+ for (i = 0; i < gNumBootParams; i++)
+ if( gBootParam[i].enabled )
+ printf("%s %s \n", gBootParam[i].promptName, gBootParam[i].parameter);
+
+ // display the board param
+ displayBoardParam();
+
+ if( BpGetEthernetMacInfo( EnetInfos, BP_MAX_ENET_MACS ) == BP_SUCCESS )
+ {
+ // Here we should print whether EMAC1 or EMAC2 is selected
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+
+//**************************************************************************
+// Function Name: changeBootLine
+// Description : Use vxWorks bootrom style parameter input method:
+// Press <enter> to use default, '-' to go to previous parameter
+// Note: Parameter is set to current value in the menu.
+// Returns : None.
+//**************************************************************************
+int changeBootLine(void)
+{
+ int i;
+ char boardIpSaved[BOOT_IP_LEN];
+ NVRAM_DATA nvramData;
+
+ readNvramData(&nvramData);
+
+ strcpy(boardIpSaved, bootInfo.boardIp);
+
+ if (processPrompt(gBootParam, gNumBootParams))
+ {
+ char *blPtr = nvramData.szBootline;
+ int paramLen;
+
+ memset(blPtr, 0, NVRAM_BOOTLINE_LEN);
+ for (i = 0; i < gNumBootParams; i++)
+ {
+ memcpy(blPtr, gBootParam[i].promptDefine, PROMPT_DEFINE_LEN);
+ blPtr += PROMPT_DEFINE_LEN;
+ paramLen = strlen(gBootParam[i].parameter);
+ memcpy(blPtr, gBootParam[i].parameter, paramLen);
+ blPtr += paramLen;
+ if (!(gBootParam[i].parameter[0] == ' '))
+ {
+ memcpy(blPtr, " ", 1);
+ blPtr += 1;
+ }
+ }
+ writeNvramData(&nvramData);
+ }
+
+ getBootLine();
+
+ // if board ip differs, do enet init
+ if (strcmp(boardIpSaved, bootInfo.boardIp) != 0)
+ enet_init();
+
+ return 0;
+
+}
+
+void setDefaultBootline(void)
+{
+ char boardIpSaved[BOOT_IP_LEN];
+ NVRAM_DATA nvramData;
+
+ readNvramData(&nvramData);
+ strcpy(boardIpSaved, bootInfo.boardIp);
+
+ memset(nvramData.szBootline, 0, NVRAM_BOOTLINE_LEN);
+ strncpy(nvramData.szBootline, DEFAULT_BOOTLINE, strlen(DEFAULT_BOOTLINE));
+ printf("Use default boot line parameters: %s\n", DEFAULT_BOOTLINE);
+ writeNvramData(&nvramData);
+
+ getBootLine();
+
+ // if board ip differs, do enet init
+ if (strcmp(boardIpSaved, bootInfo.boardIp) != 0)
+ enet_init();
+}
+
+//**************************************************************************
+// Function Name: changeAfeId
+// Description : Use vxWorks bootrom style parameter input method:
+// Press <enter> to use default, '-' to go to previous parameter
+// Note: Parameter is set to current value in the menu.
+// Returns : None.
+//**************************************************************************
+static void hex2Str(unsigned long num, char *str)
+{
+ static const char hextable[16] = "0123456789ABCDEF";
+ unsigned long i, n;
+ str[0] = '0';
+ str[1] = 'x';
+ if (0 == num) {
+ str[2] = '0';
+ str[3] = 0;
+ return;
+ }
+ str +=2;
+ n = num >> 28;
+ i = 0;
+ while (0 == n) {
+ num <<= 4;
+ n = num >> 28;
+ i++;
+ }
+ for (; i < 8; i++) {
+ *str++ = hextable[num >> 28];
+ num <<= 4;
+ }
+ *str = 0;
+}
+
+int changeAfeId(void)
+{
+ NVRAM_DATA nvramData;
+
+ readNvramData(&nvramData);
+ hex2Str(nvramData.afeId[0], gAfeId[0].parameter);
+ hex2Str(nvramData.afeId[1], gAfeId[1].parameter);
+ if (processPrompt(gAfeId, gAfeIdParams))
+ {
+ nvramData.afeId[0] = lib_atoi(gAfeId[0].parameter);
+ nvramData.afeId[1] = lib_atoi(gAfeId[1].parameter);
+ writeNvramData(&nvramData);
+ }
+ return 0;
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_eth.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_eth.c
new file mode 100755
index 0000000..c4ea465
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_eth.c
@@ -0,0 +1,547 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2002 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+
+/** Includes. **/
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+
+#include "cfe_iocb.h"
+#include "cfe_ioctl.h"
+#include "cfe_device.h"
+#include "cfe_devfuncs.h"
+#include "sbmips.h"
+#include "cfe_timer.h"
+#include "dev_bcm63xx_eth.h"
+#include "dev_bcm63xx_flash.h"
+#include "mii.h"
+#include "robosw_reg.h"
+
+#define DMA_RX_CHAN (softc->dmaPort * 2)
+#define DMA_TX_CHAN (softc->dmaPort * 2 + 1)
+
+#define CACHE_ALIGN 16
+extern void _cfe_flushcache(int, uint8_t *, uint8_t *);
+#define INVAL_RANGE(s,l) _cfe_flushcache(CFE_CACHE_INVAL_RANGE,((uint8_t *) (s)),((uint8_t *) (s))+(l))
+#define FLUSH_RANGE(s,l) _cfe_flushcache(CFE_CACHE_FLUSH_RANGE,((uint8_t *) (s)),((uint8_t *) (s))+(l))
+
+/** Externs. **/
+extern unsigned long sysGetEnetModeFlag(void);
+
+/** Prototypes. **/
+static void bcm63xx_ether_probe( cfe_driver_t * drv, unsigned long probe_a,
+ unsigned long probe_b, void * probe_ptr );
+static int bcm63xx_ether_open(cfe_devctx_t *ctx);
+static int bcm63xx_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int bcm63xx_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
+static int bcm63xx_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int bcm63xx_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int bcm63xx_ether_close(cfe_devctx_t *ctx);
+static int internal_open(bcmenet_softc * softc);
+
+/** Variables. **/
+const static cfe_devdisp_t bcm63xx_ether_dispatch = {
+ bcm63xx_ether_open,
+ bcm63xx_ether_read,
+ bcm63xx_ether_inpstat,
+ bcm63xx_ether_write,
+ bcm63xx_ether_ioctl,
+ bcm63xx_ether_close,
+ NULL,
+ NULL
+};
+
+const cfe_driver_t bcm63xx_enet = {
+ "BCM63xx Ethernet",
+ "eth",
+ CFE_DEV_NETWORK,
+ &bcm63xx_ether_dispatch,
+ bcm63xx_ether_probe
+};
+
+/** Functions. **/
+static void bcm63xx_ether_probe( cfe_driver_t * drv, unsigned long probe_a,
+ unsigned long probe_b, void * probe_ptr )
+{
+ bcmenet_softc * softc;
+ char descr[100];
+
+ softc = (bcmenet_softc *) KMALLOC( sizeof(bcmenet_softc), CACHE_ALIGN );
+ if( softc == NULL ) {
+ xprintf( "BCM63xx : Failed to allocate softc memory.\n" );
+ } else {
+ memset( softc, 0, sizeof(bcmenet_softc) );
+
+ if (internal_open( softc ) == -1)
+ xprintf("Failed initializing enet hardware\n");
+ else
+ {
+ cfe_attach( drv, softc, NULL, descr );
+ }
+ }
+}
+
+static int bcm63xx_ether_open(cfe_devctx_t *ctx)
+{
+ /* FIXME -- See if this can be returned to its normal place. */
+ return 0;
+}
+
+/*
+ * init_dma: Initialize DMA control register
+ */
+static void init_dma(bcmenet_softc *softc)
+{
+ uint32 *StateRam;
+ int i;
+
+ /*
+ * clear State RAM
+ */
+ StateRam = (UINT32 *)&softc->dmaCtrl->stram.s[0];
+ for (i = 0; i < sizeof(DmaStateRam) / sizeof(UINT32) * NUM_PORTS * 2; i++)
+ StateRam[i] = 0;
+
+ /*
+ * initialize IUDMA controller register
+ */
+ softc->dmaCtrl->controller_cfg = DMA_FLOWC_CH1_EN;
+ softc->dmaCtrl->flowctl_ch1_thresh_lo = DMA_FC_THRESH_LO;
+ softc->dmaCtrl->flowctl_ch1_thresh_hi = DMA_FC_THRESH_HI;
+ softc->dmaCtrl->flowctl_ch1_alloc = 0;
+
+ // transmit
+ softc->txDma->cfg = 0; /* initialize first (will enable later) */
+ softc->txDma->maxBurst = DMA_MAX_BURST_LENGTH;
+ softc->txDma->intMask = 0; /* mask all ints */
+ /* clr any pending interrupts on channel */
+ softc->txDma->intStat = DMA_DONE|DMA_NO_DESC|DMA_BUFF_DONE;
+ softc->txDma->intMask = DMA_DONE;
+ softc->dmaCtrl->stram.s[DMA_TX_CHAN].baseDescPtr = (uint32)K1_TO_PHYS((uint32_t)(softc->txFirstBdPtr));
+
+ // receive
+ softc->rxDma->cfg = 0; // initialize first (will enable later)
+ softc->rxDma->maxBurst = DMA_MAX_BURST_LENGTH;
+ softc->rxDma->intMask = 0; /* mask all ints */
+ /* clr any pending interrupts on channel */
+ softc->rxDma->intStat = DMA_DONE|DMA_NO_DESC|DMA_BUFF_DONE;
+ softc->rxDma->intMask = DMA_DONE;
+ softc->dmaCtrl->stram.s[DMA_RX_CHAN].baseDescPtr = (uint32)K1_TO_PHYS((uint32_t)(softc->rxFirstBdPtr));
+}
+
+
+static int internal_open(bcmenet_softc * softc)
+{
+ int i;
+ void *p;
+
+ robosw_init();
+ softc->dmaCtrl = (DmaRegs *)(SWITCH_DMA_BASE);
+
+ softc->rxDma = &softc->dmaCtrl->chcfg[DMA_RX_CHAN];
+ softc->txDma = &softc->dmaCtrl->chcfg[DMA_TX_CHAN];
+
+ // If doing SW reboot in EPI the controller can still be active
+ softc->rxDma->cfg = 0;
+ softc->txDma->cfg = 0;
+ softc->dmaCtrl->controller_cfg &= ~DMA_MASTER_EN;
+
+ p = KMALLOC( NR_TX_BDS * sizeof(DmaDesc), CACHE_ALIGN );
+ if( p == NULL ) {
+ xprintf( "BCM63xx : Failed to allocate txBds memory.\n" );
+ return -1;
+ }
+ INVAL_RANGE(p, NR_TX_BDS * sizeof(DmaDesc));
+ softc->txBds = (DmaDesc *)K0_TO_K1((uint32) p);
+
+ p = KMALLOC( NR_RX_BDS * sizeof(DmaDesc), CACHE_ALIGN );
+ if( p== NULL ) {
+ xprintf( "BCM63xx : Failed to allocate rxBds memory.\n" );
+ KFREE( (void *)(softc->txBds) );
+ softc->txBds = NULL;
+ return -1;
+ }
+ INVAL_RANGE(p, NR_RX_BDS * sizeof(DmaDesc));
+ softc->rxBds = (DmaDesc *)K0_TO_K1((uint32) p);
+
+ softc->rxBuffers = (uint32_t)KMALLOC( NR_RX_BDS * ENET_BUF_SIZE, CACHE_ALIGN );
+ if( softc->rxBuffers == NULL ) {
+ xprintf( "BCM63xx : Failed to allocate RxBuffer memory.\n" );
+ KFREE( (void *)(softc->txBds) );
+ softc->txBds = NULL;
+ KFREE( (void *)(softc->rxBds) );
+ softc->rxBds = NULL;
+ return -1;
+ }
+ INVAL_RANGE(softc->rxBuffers, NR_RX_BDS * ENET_BUF_SIZE);
+
+ softc->txBuffers = (uint32_t)KMALLOC( NR_TX_BDS * ENET_BUF_SIZE, CACHE_ALIGN );
+ if( softc->txBuffers == NULL ) {
+ xprintf( "BCM63xx : Failed to allocate txBuffer memory.\n" );
+ KFREE( (void *)(softc->rxBuffers) );
+ softc->rxBuffers = NULL;
+ KFREE( (void *)(softc->txBds) );
+ softc->txBds = NULL;
+ KFREE( (void *)(softc->rxBds) );
+ softc->rxBds = NULL;
+ return -1;
+ }
+ INVAL_RANGE(softc->txBuffers, NR_TX_BDS * ENET_BUF_SIZE);
+
+ /* Init the Receive Buffer Descriptor Ring. */
+ softc->rxFirstBdPtr = softc->rxBdReadPtr = softc->rxBds;
+ softc->rxLastBdPtr = softc->rxBds + NR_RX_BDS - 1;
+
+ for(i = 0; i < NR_RX_BDS; i++) {
+ (softc->rxBds + i)->status = DMA_OWN;
+ (softc->rxBds + i)->length = ENET_BUF_SIZE;
+ (softc->rxBds + i)->address = softc->rxBuffers + i * ENET_BUF_SIZE;
+ (softc->rxBds + i)->address = K1_TO_PHYS( (softc->rxBds + i)->address );
+ softc->dmaCtrl->flowctl_ch1_alloc = 1;
+ }
+ softc->rxLastBdPtr->status |= DMA_WRAP;
+
+ /* Init Transmit Buffer Descriptor Ring. */
+ softc->txFirstBdPtr = softc->txNextBdPtr = softc->txBds;
+ softc->txLastBdPtr = softc->txBds + NR_TX_BDS - 1;
+
+ for(i = 0; i < NR_TX_BDS; i++) {
+ (softc->txBds + i)->status = 0;
+ (softc->txBds + i)->length = 0;
+ (softc->txBds + i)->address = softc->txBuffers + i * ENET_BUF_SIZE;
+ (softc->txBds + i)->address = K1_TO_PHYS( (softc->txBds + i)->address );
+ }
+ softc->txLastBdPtr->status = DMA_WRAP;
+
+ /* init dma registers */
+ init_dma(softc);
+
+ robosw_configure_ports();
+
+ softc->dmaCtrl->controller_cfg |= DMA_MASTER_EN;
+
+ softc->rxDma->cfg |= DMA_ENABLE;
+
+ softc->linkCheck = 0;
+
+ return 0;
+}
+
+static int bcm63xx_ether_read( cfe_devctx_t * ctx, iocb_buffer_t * buffer )
+{
+ unsigned char * dstptr;
+ unsigned char * srcptr;
+ volatile DmaDesc * CurrentBdPtr;
+ bcmenet_softc * softc = (bcmenet_softc *) ctx->dev_softc;
+ uint16 dmaFlag;
+
+ if( ctx == NULL ) {
+ xprintf( "No context\n" );
+ return -1;
+ }
+
+ if( buffer == NULL ) {
+ xprintf( "No dst buffer\n" );
+ return -1;
+ }
+
+ if( softc == NULL ) {
+ xprintf( "softc has not been initialized.\n" );
+ return -1;
+ }
+
+ dmaFlag = (uint16) softc->rxBdReadPtr->status;
+ if (!(dmaFlag & DMA_EOP))
+ {
+ xprintf("dmaFlag (return -1)[%04x]\n", dmaFlag);
+ return -1;
+ }
+
+ dstptr = buffer->buf_ptr;
+ CurrentBdPtr = softc->rxBdReadPtr;
+
+ srcptr = (unsigned char *)( PHYS_TO_K1(CurrentBdPtr->address) );
+
+ buffer->buf_retlen = ((CurrentBdPtr->length < buffer->buf_length) ? CurrentBdPtr->length : buffer->buf_length);
+
+ memcpy( dstptr, srcptr, buffer->buf_retlen );
+
+ CurrentBdPtr->length = ENET_BUF_SIZE;
+ CurrentBdPtr->status &= DMA_WRAP;
+ CurrentBdPtr->status |= DMA_OWN;
+
+ IncRxBdPtr( CurrentBdPtr, softc );
+ softc->rxBdReadPtr = CurrentBdPtr;
+ softc->dmaCtrl->flowctl_ch1_alloc = 1;
+
+ // enable rx dma
+ softc->rxDma->cfg = DMA_ENABLE;
+ return 0;
+}
+
+
+static int bcm63xx_ether_inpstat( cfe_devctx_t * ctx, iocb_inpstat_t * inpstat )
+{
+ bcmenet_softc * softc;
+ volatile DmaDesc * CurrentBdPtr;
+
+ /* ============================= ASSERTIONS ============================= */
+
+ if( ctx == NULL ) {
+ xprintf( "No context\n" );
+ return -1;
+ }
+
+ if( inpstat == NULL ) {
+ xprintf( "No inpstat buffer\n" );
+ return -1;
+ }
+
+ softc = (bcmenet_softc *)ctx->dev_softc;
+ if( softc == NULL ) {
+ xprintf( "softc has not been initialized.\n" );
+ return -1;
+ }
+
+ /* ====================================================================== */
+
+
+ CurrentBdPtr = softc->rxBdReadPtr;
+
+ // inp_status == 1 -> data available
+ inpstat->inp_status = (CurrentBdPtr->status & DMA_OWN) ? 0 : 1;
+
+ if (!inpstat->inp_status || (++softc->linkCheck > 100)) {
+ // Don't check link state too often when receiving data
+ softc->linkCheck = 0;
+ robosw_check_ports();
+ }
+
+ return 0;
+}
+
+
+static int bcm63xx_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ uint32_t status;
+ unsigned char * dstptr;
+ bcmenet_softc * softc;
+ volatile DmaDesc * CurrentBdPtr;
+ volatile uint32 txEvents = 0;
+
+ /* ============================= ASSERTIONS ============================= */
+
+ if( ctx == NULL ) {
+ xprintf( "No context\n" );
+ return -1;
+ }
+
+ if( buffer == NULL ) {
+ xprintf( "No dst buffer\n" );
+ return -1;
+ }
+
+ if( buffer->buf_length > ENET_MAX_MTU_SIZE ) {
+ xprintf( "src buffer too large.\n" );
+ xprintf( "size is %d\n", buffer->buf_length );
+ return -1;
+ }
+
+ softc = (bcmenet_softc *) ctx->dev_softc;
+ if( softc == NULL ) {
+ xprintf( "softc has not been initialized.\n" );
+ return -1;
+ }
+
+ /* ====================================================================== */
+
+ CurrentBdPtr = softc->txNextBdPtr;
+
+ /* Find out if the next BD is available. */
+ if( CurrentBdPtr->status & DMA_OWN ) {
+ xprintf( "No tx BD available ?!\n" );
+ return -1;
+ }
+
+ dstptr = (unsigned char *)PHYS_TO_K1( CurrentBdPtr->address );
+ memcpy( dstptr, buffer->buf_ptr, buffer->buf_length );
+
+ /* Set status of DMA BD to be transmitted. */
+ status = DMA_SOP | DMA_EOP | DMA_APPEND_CRC | DMA_OWN;
+ if( CurrentBdPtr == softc->txLastBdPtr ) {
+ status |= DMA_WRAP;
+ }
+
+ CurrentBdPtr->length = ((buffer->buf_length < ETH_ZLEN) ? ETH_ZLEN : buffer->buf_length);
+ CurrentBdPtr->status = status;
+
+ // Enable DMA for this channel
+ softc->txDma->cfg |= DMA_ENABLE;
+
+ // poll the dma status until done
+ do
+ {
+ txEvents = CurrentBdPtr->status;
+ } while (txEvents & DMA_OWN);
+
+
+ //Advance BD pointer to next in the chain.
+ InctxBdPtr( CurrentBdPtr, softc );
+ softc->txNextBdPtr = CurrentBdPtr;
+
+ return 0;
+}
+
+static int bcm63xx_ether_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
+{
+ bcmenet_softc *softc = (bcmenet_softc *) ctx->dev_softc;
+
+ switch ((int)buffer->buf_ioctlcmd) {
+ case IOCTL_ETHER_GETHWADDR:
+ memcpy(buffer->buf_ptr, softc->hwaddr, sizeof(softc->hwaddr));
+ return 0;
+
+ case IOCTL_ETHER_SETHWADDR:
+ memcpy(softc->hwaddr, buffer->buf_ptr, sizeof(softc->hwaddr));
+ return 0;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * bcm63xx_ether_flush: Flushes packets from the DMA receive ring
+ */
+static int bcm63xx_ether_flush(bcmenet_softc * softc)
+{
+ volatile DmaDesc * CurrentBdPtr;
+ uint16 dmaFlag;
+ unsigned char * srcptr;
+ uint16 len;
+ uint32 rxBdsCount = 0;
+ int i;
+
+ if( softc == NULL ) {
+ xprintf( "softc has not been initialized.\n" );
+ return -1;
+ }
+
+ xprintf("Disabling Switch ports.\n");
+
+ /* disable forwarding */
+ SWITCH->SwitchMode &= ~SwitchMode_FwdgEn;
+
+ /* Bring the link down on all switch ports */
+ for(i=0; i<8; ++i) {
+ SWITCH->PortOverride[i] &= ~PortOverride_Linkup;
+ /* disable Rx and Tx */
+ SWITCH->PortCtrl[i] = PortCtrl_DisableTx | PortCtrl_DisableRx;
+ }
+
+ for(i=0; i<1000; ++i) {
+ cfe_usleep(1000);
+ }
+
+ xprintf("Flushing Receive Buffers...\n");
+
+ while(!((dmaFlag = (uint16) softc->rxBdReadPtr->status) & DMA_OWN)) {
+
+ if (!(dmaFlag & DMA_EOP))
+ {
+ xprintf("dmaFlag (return -1)[%04x]\n", dmaFlag);
+ return -1;
+ }
+
+ CurrentBdPtr = softc->rxBdReadPtr;
+
+ srcptr = (unsigned char *)( PHYS_TO_K1(CurrentBdPtr->address) );
+
+ len = CurrentBdPtr->length;
+
+ ++rxBdsCount;
+
+ CurrentBdPtr->length = ENET_BUF_SIZE;
+ CurrentBdPtr->status &= DMA_WRAP;
+ CurrentBdPtr->status |= DMA_OWN;
+
+ IncRxBdPtr( CurrentBdPtr, softc );
+ softc->rxBdReadPtr = CurrentBdPtr;
+ softc->dmaCtrl->flowctl_ch1_alloc = 1;
+
+ // enable rx dma
+ softc->rxDma->cfg = DMA_ENABLE;
+ }
+
+ xprintf("%d buffers found.\n", rxBdsCount);
+
+ return 0;
+}
+
+static int bcm63xx_ether_close(cfe_devctx_t *ctx)
+{
+ int i;
+ bcmenet_softc * softc = (bcmenet_softc *) ctx->dev_softc;
+ unsigned long sts;
+
+ /* flush Rx DMA Channel */
+ bcm63xx_ether_flush(softc);
+
+ xprintf("Closing DMA Channels.\n");
+
+ sts = softc->rxDma->intStat;
+ softc->rxDma->intStat = sts;
+ softc->rxDma->intMask = 0;
+ softc->rxDma->cfg = 0;
+ // wait the current packet to complete before turning off EMAC, otherwise memory corruption can occur.
+ for(i=0; softc->rxDma->cfg & DMA_ENABLE; i++) {
+ // put the line below inside - it seems the signal can be lost and DMA never stops
+ softc->rxDma->cfg = 0;
+ if (i >= 20) {
+ xprintf("Rx Timeout !!!\n");
+ break;
+ }
+ cfe_usleep(100);
+ }
+
+ sts = softc->txDma->intStat;
+ softc->txDma->intStat = sts;
+ softc->txDma->intMask = 0;
+ softc->txDma->cfg = 0;
+ for(i=0; softc->txDma->cfg & DMA_ENABLE; i++) {
+ // put the line below inside - it seems the signal can be lost and DMA never stops
+ softc->txDma->cfg = 0;
+ if (i >= 20) {
+ xprintf("Tx Timeout !!!\n");
+ break;
+ }
+ cfe_usleep(100);
+ }
+
+ /* return buffer allocation register internal count to 0 */
+ softc->dmaCtrl->flowctl_ch1_alloc = (DMA_BUF_ALLOC_FORCE | 0);
+
+ softc->dmaCtrl->controller_cfg &= ~DMA_MASTER_EN;
+
+ KFREE( (void *)(softc->txBuffers) );
+ KFREE( (void *)(softc->rxBuffers) );
+ KFREE( (void *)(softc->txBds) );
+ KFREE( (void *)(softc->rxBds) );
+ return 0;
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_flash.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_flash.c
new file mode 100755
index 0000000..cf38104
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_flash.c
@@ -0,0 +1,629 @@
+/***************************************************************************
+ * Broadcom Corp. Confidential
+ * Copyright 2001 Broadcom Corp. All Rights Reserved.
+ *
+ * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED
+ * SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM.
+ * YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT
+ * SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
+ *
+ ***************************************************************************
+ * File Name : bcm63xx_flash.c
+ *
+ * Description: This file contains the flash device driver for bcm63xx board. Very similar to
+ * board.c in linux development.
+ *
+ * Created on : 4/18/2002 seanl
+ *
+ ***************************************************************************/
+
+
+/* Includes. */
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+
+#include "bcm_map.h"
+#include "bcm_hwdefs.h"
+#include "dev_bcm63xx_flash.h"
+#include "flash_api.h"
+#include "boardparms.h"
+#include "boardparms_voice.h"
+#include "bcm63xx_util.h"
+
+//#define DEBUG_FLASH
+
+/* This driver determines the NVRAM and persistent storage flash address and
+ * length.
+ */
+/* Foxconn start jenny add for timeout */
+extern int NMRPKeepAlive(void);
+extern int NMRPTFTPWaiting(void);
+extern int g_nmrp_keepalive;
+extern int nmrp_server_detected;
+/* Foxconn end jenny add for timeout*/
+
+static FLASH_ADDR_INFO fInfo;
+
+//**************************************************************************************
+// Flash read/write and image downloading..
+//**************************************************************************************
+
+void kerSysFlashInit( void )
+{
+ NVRAM_DATA nvramData;
+
+ flash_init();
+
+ while ((readNvramData(&nvramData) != 0) || (BpSetBoardId(nvramData.szBoardId) != BP_SUCCESS))
+ {
+ printf("\n*** Board is not initialized properly ***\n\n");
+ //setBoardParam(); /* Bob removed to set default board parameters, 11/01/2010 */
+ setDefaultBoardParam(); /* Bob added to set default board parameters, 11/01/2010 */
+ }
+
+ fInfo.flash_rootfs_start_offset = flash_get_sector_size(0);
+ if( fInfo.flash_rootfs_start_offset < FLASH_LENGTH_BOOT_ROM )
+ fInfo.flash_rootfs_start_offset = FLASH_LENGTH_BOOT_ROM;
+
+ flash_init_info(&nvramData, &fInfo);
+
+#if (INC_NAND_FLASH_DRIVER==1)
+ validateNandPartTbl(&nvramData);
+
+ /* Check if spare area data contains non 0xff values after JFFS2 clean
+ * marker. Early version of this CFE driver filled bytes 8 - 11 with
+ * 0 which Linux does not like.
+ */
+ {
+ extern int read_spare_data(int blk, unsigned char *buf, int bufsize);
+
+ int blk_size = flash_get_sector_size(0) / 1024;
+ int blk_start = nvramData.ulNandPartOfsKb[NP_DATA] / blk_size;
+ unsigned char spare[64];
+
+ memset(spare, 0xff, sizeof(spare));
+ if( read_spare_data(blk_start, spare, sizeof(spare)) == FLASH_API_OK )
+ {
+ const int spare_len = 8; /* Linux JFFS2 spare area is 8 bytes */
+ int i;
+
+ for( i = spare_len; i < sizeof(spare); i++ )
+ {
+ if( spare[i] != 0xff )
+ {
+ printf("Data spare area is not correct, erasing psi\n");
+ printf("%8.8lx %8.8lx %8.8lx %8.8lx\n",
+ *(unsigned long *) &spare[0],*(unsigned long *)&spare[4],
+ *(unsigned long *) &spare[8],*(unsigned long *)&spare[12]);
+ kerSysErasePsi();
+ break;
+ }
+ }
+ }
+ }
+#endif
+}
+
+#if (INC_NAND_FLASH_DRIVER==1) || (INC_SPI_PROG_NAND==1)
+/***********************************************************************
+ * Function Name: validateNandPartTbl
+ * Description : Checks the NAND partition table fields in NVRAM data.
+ * If nay of the fields are not valid, new values are set.
+ * Returns : None.
+ ***********************************************************************/
+void validateNandPartTbl(PNVRAM_DATA pNvramData)
+{
+ unsigned long ulBlockSizeKb = (unsigned long)flash_get_sector_size(0)/1024;
+ unsigned long ulTotalSizeKb = (unsigned long)flash_get_total_size() / 1024;
+
+#if (INC_SPI_PROG_NAND==1)
+ if( flash_get_flash_type() != FLASH_IFC_NAND )
+ return;
+#endif
+ if( pNvramData->ulNandPartSizeKb[NP_BOOT] != ulBlockSizeKb ||
+ pNvramData->ulNandPartSizeKb[NP_DATA] != NAND_DATA_SIZE_KB ||
+ (pNvramData->ulNandPartSizeKb[NP_BBT] != NAND_BBT_SMALL_SIZE_KB &&
+ pNvramData->ulNandPartSizeKb[NP_BBT] != NAND_BBT_BIG_SIZE_KB) )
+ {
+ /* Initialize NAND flash partition table. */
+ unsigned long ulRootfsSizeKb;
+ unsigned long ulBbtSizeKb = (ulTotalSizeKb > NAND_BBT_THRESHOLD_KB)
+ ? NAND_BBT_BIG_SIZE_KB : NAND_BBT_SMALL_SIZE_KB;
+
+ /* The Boot partition is first and is one block in size. */
+ pNvramData->ulNandPartOfsKb[NP_BOOT] = 0;
+ pNvramData->ulNandPartSizeKb[NP_BOOT] = ulBlockSizeKb;
+
+ /* The Bad Block Table partition is last and is a constant size. */
+ pNvramData->ulNandPartOfsKb[NP_BBT] = ulTotalSizeKb - ulBbtSizeKb;
+ pNvramData->ulNandPartSizeKb[NP_BBT] = ulBbtSizeKb;
+
+ /* The Data partition is before the BBT and is a constant size. */
+ pNvramData->ulNandPartOfsKb[NP_DATA] =
+ pNvramData->ulNandPartOfsKb[NP_BBT] - NAND_DATA_SIZE_KB;
+ pNvramData->ulNandPartSizeKb[NP_DATA] = NAND_DATA_SIZE_KB;
+
+ /* The first rootfs partition starts at the second sector. */
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_1] = ulBlockSizeKb;
+
+ /* The size of the two root file system partitions is whatever is left
+ * after the Boot, Data and BBT paritions divided by 2 and evenly
+ * divisible by the NAND flash block size.
+ */
+ ulRootfsSizeKb = ((pNvramData->ulNandPartOfsKb[NP_DATA] -
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_1]) / 2);
+ ulRootfsSizeKb = (ulRootfsSizeKb / ulBlockSizeKb) * ulBlockSizeKb;
+
+#if 1 /* support two file system partitions */
+ pNvramData->ulNandPartSizeKb[NP_ROOTFS_1] = ulRootfsSizeKb;
+
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_2] =
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_1] + ulRootfsSizeKb;
+ pNvramData->ulNandPartSizeKb[NP_ROOTFS_2] = ulRootfsSizeKb;
+#else /* support one file system partition */
+ pNvramData->ulNandPartSizeKb[NP_ROOTFS_1] = ulRootfsSizeKb * 2;
+
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_2] = ulTotalSizeKb;
+ pNvramData->ulNandPartSizeKb[NP_ROOTFS_2] = 0;
+#endif
+
+ writeNvramData(pNvramData);
+
+#if defined(DEBUG_FLASH)
+ printf("boot offset=0x%8.8lx, size=0x%8.8lx\n",
+ pNvramData->ulNandPartOfsKb[NP_BOOT],
+ pNvramData->ulNandPartSizeKb[NP_BOOT]);
+ printf("rootfs1 offset=0x%8.8lx, size=0x%8.8lx\n",
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_1],
+ pNvramData->ulNandPartSizeKb[NP_ROOTFS_1]);
+ printf("rootfs2 offset=0x%8.8lx, size=0x%8.8lx\n",
+ pNvramData->ulNandPartOfsKb[NP_ROOTFS_2],
+ pNvramData->ulNandPartSizeKb[NP_ROOTFS_2]);
+ printf("data offset=0x%8.8lx, size=0x%8.8lx\n",
+ pNvramData->ulNandPartOfsKb[NP_DATA],
+ pNvramData->ulNandPartSizeKb[NP_DATA]);
+ printf("bbt offset=0x%8.8lx, size=0x%8.8lx\n",
+ pNvramData->ulNandPartOfsKb[NP_BBT],
+ pNvramData->ulNandPartSizeKb[NP_BBT]);
+#endif
+ }
+}
+#else
+void validateNandPartTbl(PNVRAM_DATA pNvramData)
+{
+}
+#endif
+
+
+/***********************************************************************
+ * Function Name: kerSysFlashAddrInfoGet
+ * Description : Fills in a structure with information about the NVRAM
+ * and persistent storage sections of flash memory.
+ * Returns : None.
+ ***********************************************************************/
+void kerSysFlashAddrInfoGet(PFLASH_ADDR_INFO pflash_addr_info)
+{
+ memcpy(pflash_addr_info, &fInfo, sizeof(FLASH_ADDR_INFO));
+}
+
+// get shared blks into *** pTempBuf *** which has to be released bye the caller!
+// return: if pTempBuf != NULL, poits to the data with the dataSize of the buffer
+// !NULL -- ok
+// NULL -- fail
+static unsigned char *getSharedBlks(int start_blk, int num_blks)
+{
+ int i = 0;
+ int usedBlkSize = 0;
+ int sect_size = 0;
+ unsigned char *pTempBuf = NULL;
+ unsigned char *pBuf = NULL;
+
+ for (i = start_blk; i < (start_blk + num_blks); i++)
+ usedBlkSize += flash_get_sector_size((unsigned short) i);
+
+ if ((pTempBuf = (unsigned char *) KMALLOC(usedBlkSize, sizeof(long))) == NULL)
+ {
+ printf("failed to allocate memory with size: %d\n", usedBlkSize);
+ return pTempBuf;
+ }
+
+ pBuf = pTempBuf;
+ for (i = start_blk; i < (start_blk + num_blks); i++)
+ {
+ sect_size = flash_get_sector_size((unsigned short) i);
+#if defined(DEBUG_FLASH)
+ printf("getShareBlks: blk=%d, sect_size=%d\n", i, sect_size);
+#endif
+ flash_read_buf((unsigned short)i, 0, pBuf, sect_size);
+ pBuf += sect_size;
+ }
+
+ return pTempBuf;
+}
+
+
+
+// Set the pTempBuf to flash from start_blk for num_blks
+// return:
+// 0 -- ok
+// -1 -- fail
+static int setSharedBlks(int start_blk, int num_blks, unsigned char *pTempBuf)
+{
+ int i = 0;
+ int sect_size = 0;
+ int sts = 0;
+ unsigned char *pBuf = pTempBuf;
+
+ for (i = start_blk; i < (start_blk + num_blks); i++)
+ {
+ sect_size = flash_get_sector_size((unsigned short) i);
+ flash_sector_erase_int(i);
+ if (flash_write_buf(i, 0, pBuf, sect_size) != sect_size)
+ {
+ printf("Error writing flash sector %d.", i);
+ sts = -1;
+ break;
+ }
+
+#if defined(DEBUG_FLASH)
+ printf("setShareBlks: blk=%d, sect_size=%d\n", i, sect_size);
+#endif
+
+ pBuf += sect_size;
+ }
+
+ return sts;
+}
+
+
+
+/*******************************************************************************
+ * NVRAM functions
+ *******************************************************************************/
+
+// get nvram data
+// return:
+// 0 - ok
+// -1 - fail
+int kerSysNvRamGet(unsigned char *string, int strLen, int offset)
+{
+ unsigned char *pBuf = NULL;
+
+ if ((pBuf = getSharedBlks(NVRAM_SECTOR, 1)) == NULL)
+ return -1;
+
+ // get string off the memory buffer
+ memcpy(string, (pBuf + NVRAM_DATA_OFFSET + offset), strLen);
+
+ KFREE(pBuf);
+
+ return 0;
+}
+
+
+// set nvram
+// return:
+// 0 - ok
+// -1 - fail
+int kerSysNvRamSet(unsigned char *string, int strLen, int offset)
+{
+ int sts = 0;
+ unsigned char *pBuf = NULL;
+
+ if ((pBuf = getSharedBlks(NVRAM_SECTOR, 1)) == NULL)
+ return -1;
+
+ // set string to the memory buffer
+ memcpy((pBuf + NVRAM_DATA_OFFSET + offset), string, strLen);
+
+ if (setSharedBlks(NVRAM_SECTOR, 1, pBuf) != 0)
+ sts = -1;
+
+ KFREE(pBuf);
+
+ return sts;
+}
+
+/***********************************************************************
+ * Function Name: kerSysEraseNvRam
+ * Description : Erase the NVRAM storage section of flash memory.
+ * Returns : 1 -- ok, 0 -- fail
+ ***********************************************************************/
+int kerSysEraseNvRam(void)
+{
+ int sts = 1;
+ unsigned char *tempStorage = KMALLOC(NVRAM_LENGTH, sizeof(long));
+
+ // just write the whole buf with '0xff' to the flash
+ if (!tempStorage)
+ sts = 0;
+ else
+ {
+ memset(tempStorage, 0xff, NVRAM_LENGTH);
+ if (kerSysNvRamSet(tempStorage, NVRAM_LENGTH, 0) != 0)
+ sts = 0;
+ KFREE(tempStorage);
+ }
+
+ return sts;
+}
+
+
+/*******************************************************************************
+ * PSI functions
+ *******************************************************************************/
+
+#if (INC_NAND_FLASH_DRIVER!=1)
+/** set psi while preserving any other data that might be sharing sectors with
+ * the psi, e.g. scratch pad.
+ *
+ * @param string (IN) buffer that holds the data to be written.
+ * @param strLen (IN) length of buffer.
+ *
+ * @return 0 if OK, -1 on failure.
+ */
+static int kerSysPsiSet(const unsigned char *string, int strLen)
+{
+ int sts = 0;
+ unsigned char *pBuf = NULL;
+
+ if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
+ fInfo.flash_persistent_number_blk)) == NULL)
+ return -1;
+
+ // set string to the memory buffer
+ memcpy((pBuf + fInfo.flash_persistent_blk_offset), string, strLen);
+
+ if (setSharedBlks(fInfo.flash_persistent_start_blk,
+ fInfo.flash_persistent_number_blk, pBuf) != 0)
+ sts = -1;
+
+ KFREE(pBuf);
+
+ return sts;
+}
+
+/** set backup psi
+ *
+ * Backup PSI does not share its sectors with anything else, so this
+ * function does not need to read first and write. Just write.
+ * This function expects the length of the buffer to be exactly the
+ * length of the entire PSI.
+ *
+ * @param string (IN) buffer that holds the data to be written.
+ *
+ * @return 0 if OK, -1 on failure.
+ */
+static int kerSysBackupPsiSet(const unsigned char *string)
+{
+ int sts = 0;
+
+ if (setSharedBlks(fInfo.flash_backup_psi_start_blk,
+ fInfo.flash_backup_psi_number_blk,
+ (unsigned char *) string) != 0)
+ sts = -1;
+
+ return sts;
+}
+
+/***********************************************************************
+ * Function Name: kerSysErasePsi
+ * Description : Erase the Psi storage section of flash memory.
+ * Returns : 1 -- ok, 0 -- fail
+ ***********************************************************************/
+int kerSysErasePsi(void)
+{
+ int sts = 1;
+ unsigned char *tempStorage;
+
+ if (fInfo.flash_persistent_start_blk == 0) {
+ sts = 0;
+ }
+ else {
+ tempStorage = KMALLOC(fInfo.flash_persistent_length, sizeof(long));
+ // just write the whole buf with '0xff' to the flash
+ if (!tempStorage)
+ sts = 0;
+ else
+ {
+ memset(tempStorage, 0xff, fInfo.flash_persistent_length);
+ if (kerSysPsiSet(tempStorage, fInfo.flash_persistent_length) != 0)
+ sts = 0;
+
+ // Also erase backup psi if it is there
+ if (fInfo.flash_backup_psi_number_blk > 0)
+ {
+ if (kerSysBackupPsiSet(tempStorage) != 0)
+ sts = 0;
+ }
+
+ KFREE(tempStorage);
+ }
+ }
+ return sts;
+}
+#else
+int kerSysErasePsi(void)
+{
+ int sts = 1;
+ NVRAM_DATA nvramData;
+
+ if( readNvramData(&nvramData) == 0 )
+ {
+ int blk_size = flash_get_sector_size(0) / 1024;
+ int blk_start = nvramData.ulNandPartOfsKb[NP_DATA] / blk_size;
+ int total_blks =
+ blk_start + (nvramData.ulNandPartSizeKb[NP_DATA]) / blk_size;
+
+ while( blk_start < total_blks )
+ {
+ flash_sector_erase_int(blk_start);
+ blk_start++;
+ }
+ sts = 0;
+ }
+
+ return(sts);
+}
+#endif
+
+// flash bcm image
+// return:
+// 0 - ok
+// !0 - the sector number fail to be flashed (should not be 0)
+int kerSysBcmImageSet( int flash_start_addr, unsigned char *string, int size, int fWholeImage)
+{
+ int sts;
+ int sect_size;
+ int blk_start;
+ // int savedSize = size;
+ int total_blks = flash_get_numsectors();
+
+ /* Foxconn add by Cliff Wang, 03/23/2010 */
+ unsigned char *pTempBuf = NULL;
+ int savedBlkStart;
+ /* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+ if( flash_get_flash_type() == FLASH_IFC_NAND )
+ {
+ if( flash_start_addr == FLASH_BASE )
+ total_blks = 1;
+ else
+ {
+ NVRAM_DATA nvramData;
+
+ if( readNvramData(&nvramData) == 0 )
+ {
+ sect_size = flash_get_sector_size(0);
+ int rootfs =
+ ((flash_start_addr - FLASH_BASE) / 1024 ==
+ nvramData.ulNandPartOfsKb[NP_ROOTFS_2])
+ ? NP_ROOTFS_2 : NP_ROOTFS_1;
+
+ total_blks = (nvramData.ulNandPartOfsKb[rootfs] +
+ nvramData.ulNandPartSizeKb[rootfs]) / (sect_size/ 1024);
+ }
+ }
+ }
+
+#if defined(DEBUG_FLASH)
+ printf("kerSysBcmImageSet: flash_start_addr=0x%x string=%p len=%d wholeImage=%d\n",
+ flash_start_addr, string, size, fWholeImage);
+#endif
+
+ blk_start = flash_get_blk(flash_start_addr);
+ /* Foxconn add start by Cliff Wang, 03/23/2010 */
+ savedBlkStart = blk_start;
+ if( blk_start < 0 )
+ return( -1 );
+ /* Foxconn add end by Cliff Wang, 03/23/2010 */
+
+ /* write image to flash memory */
+ do
+ {
+ g_nmrp_keepalive = 1; /* Foxconn add by Cliff Wang, 03/23/2010 */
+
+ sect_size = flash_get_sector_size(blk_start);
+
+#if defined(DEBUG_FLASH)
+ printf("Image flashing on block: %d\n", blk_start);
+#endif
+
+ // share the blk with psi only when fWholeImage == 0
+ // Foxconn modified by Silver Shih for burn board Id
+ if ((!fWholeImage && blk_start == fInfo.flash_persistent_start_blk) || (fWholeImage == 5))
+ {
+
+#if 0
+ if (size > (sect_size - fInfo.flash_persistent_length))
+ {
+ printf("Image is too big\n");
+ break; // image is too big. Can not overwrite to psi
+ }
+#endif
+
+ if ((pTempBuf = (unsigned char *) KMALLOC(sect_size, sizeof(long))) == NULL)
+ {
+ printf("Failed to allocate memory with size: %d\n", sect_size);
+ break;
+ }
+ flash_read_buf((unsigned short)blk_start, 0, pTempBuf, sect_size);
+ memcpy(pTempBuf, string, size);
+ flash_sector_erase_int(blk_start); // erase blk before flash
+
+
+ if (flash_write_buf(blk_start, 0, pTempBuf, sect_size) == sect_size)
+ size = 0; // break out and say all is ok
+ break;
+ }
+
+ flash_sector_erase_int(blk_start); // erase blk before flash
+
+ if (sect_size > size)
+ {
+ if (size & 1)
+ size++;
+ sect_size = size;
+ }
+ if (flash_write_buf(blk_start, 0, string, sect_size) != sect_size) {
+ if( flash_get_flash_type() != FLASH_IFC_NAND )
+ break;
+ blk_start++;
+ }
+ else {
+ printf(".");
+ blk_start++;
+ string += sect_size;
+ size -= sect_size;
+
+ /* Foxconn added start by jenny @NMRP */
+ if(nmrp_server_detected==1) // in NMRP mode
+ {
+ if(blk_start - savedBlkStart == 30)
+ {
+ savedBlkStart = blk_start;
+ printf("\n");
+ NMRPKeepAlive();
+ }
+ }
+ /* Foxconn added end by jenny @NMRP */
+ }
+ } while (size > 0);
+ g_nmrp_keepalive = 0; /* Foxconn added by jenny add for timeout */
+
+#if 0 /* Foxconn removed by EricHuang */
+ if (size == 0 && fWholeImage && savedSize > FLASH_LENGTH_BOOT_ROM)
+ {
+ // If flashing a whole image, erase to end of flash.
+ while( blk_start < total_blks )
+ {
+ flash_sector_erase_int(blk_start);
+ printf(".");
+ blk_start++;
+ }
+ }
+#endif
+
+ printf("\n\n");
+
+ if( size == 0 )
+ sts = 0; // ok
+ else
+ sts = blk_start; // failed to flash this sector
+
+ g_nmrp_keepalive = 0; /* Foxconn jenny add for timeout */
+ return sts;
+}
+
+unsigned long kerSysReadFromFlash( void *toaddr, unsigned long fromaddr,
+ unsigned long len )
+{
+ int sect = flash_get_blk((int) fromaddr);
+ unsigned char *start = flash_get_memptr(sect);
+ flash_read_buf( sect, (int) fromaddr - (int) start, toaddr, len );
+
+ return(len);
+}
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_uart.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_uart.c
new file mode 100755
index 0000000..3b2ce63
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/dev_bcm63xx_uart.c
@@ -0,0 +1,211 @@
+#include "cfe.h"
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_ioctl.h"
+
+#include "sbmips.h"
+#include "bsp_config.h"
+
+#include "bcm_hwdefs.h"
+#include "bcm_map.h"
+
+static void bcm63xx_uart_probe(cfe_driver_t *drv,
+ unsigned long probe_a, unsigned long probe_b,
+ void *probe_ptr);
+
+static int bcm63xx_uart_open(cfe_devctx_t *ctx);
+static int bcm63xx_uart_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int bcm63xx_uart_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
+static int bcm63xx_uart_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int bcm63xx_uart_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int bcm63xx_uart_close(cfe_devctx_t *ctx);
+
+const static cfe_devdisp_t bcm63xx_uart_dispatch = {
+ bcm63xx_uart_open,
+ bcm63xx_uart_read,
+ bcm63xx_uart_inpstat,
+ bcm63xx_uart_write,
+ bcm63xx_uart_ioctl,
+ bcm63xx_uart_close,
+ NULL,
+ NULL
+};
+
+
+const cfe_driver_t bcm63xx_uart = {
+ "BCM63xx DUART",
+ "uart",
+ CFE_DEV_SERIAL,
+ &bcm63xx_uart_dispatch,
+ bcm63xx_uart_probe
+};
+
+
+typedef struct bcm63xx_uart_s {
+ int baudrate;
+} bcm63xx_uart_t;
+
+
+static void bcm63xx_set_baudrate( bcm63xx_uart_t * softc )
+{
+ uint32_t baudwd;
+
+ baudwd = (FPERIPH / softc->baudrate) / 16;
+ if( baudwd & 0x1 ) {
+ baudwd = baudwd / 2;
+ } else {
+ baudwd = baudwd / 2 - 1;
+ }
+ UART->baudword = baudwd;
+}
+
+
+static void bcm63xx_uart_probe(cfe_driver_t *drv,
+ unsigned long probe_a, unsigned long probe_b,
+ void *probe_ptr)
+{
+ bcm63xx_uart_t * softc;
+ char descr[80];
+
+ /* enable the transmitter interrupt? */
+
+ /*
+ * probe_a is the DUART base address.
+ * probe_b is the channel-number-within-duart (0 or 1)
+ * probe_ptr is unused.
+ */
+ softc = (bcm63xx_uart_t *) KMALLOC(sizeof(bcm63xx_uart_t),0);
+ if (softc) {
+ xsprintf( descr, "%s channel %d", drv->drv_description, probe_b );
+ cfe_attach( drv, softc, NULL, descr );
+ }
+}
+
+static int bcm63xx_uart_open(cfe_devctx_t *ctx)
+{
+ bcm63xx_uart_t * softc = ctx->dev_softc;
+
+ /* Enable the UART clock */
+ softc->baudrate = CFG_SERIAL_BAUD_RATE;
+ bcm63xx_set_baudrate( softc );
+
+ UART->control = BRGEN | TXEN | RXEN;
+ UART->config = BITS8SYM | ONESTOP;
+ UART->fifoctl = RSTTXFIFOS | RSTRXFIFOS;
+ UART->intMask = 0;
+
+ return 0;
+}
+
+
+static int bcm63xx_uart_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ unsigned char * bptr;
+ int blen;
+ uint32_t status;
+ char inval;
+
+ bptr = buffer->buf_ptr;
+ blen = buffer->buf_length;
+
+ while (blen > 0) {
+ status = UART->intStatus;
+ if(status & (RXOVFERR | RXPARERR | RXFRAMERR | RXBRK)) {
+ /* RX over flow */
+ if(status & RXOVFERR) {
+ /* reset RX FIFO to clr interrupt */
+ UART->fifoctl |= RSTRXFIFOS;
+ }
+
+ /* other errors just read the bad character to clear the bit */
+ inval = UART->Data;
+ }
+ else if(status & RXFIFONE) {
+ *bptr++ = UART->Data;
+ blen--;
+ }
+ else
+ break;
+ }
+
+ buffer->buf_retlen = buffer->buf_length - blen;
+ return 0;
+}
+
+
+static int bcm63xx_uart_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat)
+{
+ inpstat->inp_status = UART->intStatus & RXFIFONE;
+ return 0;
+}
+
+
+static int bcm63xx_uart_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ unsigned char * bptr;
+ int blen;
+ uint32_t status;
+
+ bptr = buffer->buf_ptr;
+ blen = buffer->buf_length;
+
+ status = 0;
+ while( (blen > 0) && !status ) {
+ /* Wait for the buffer to empty before we write the next character */
+ /* FIXME - The serial port should be able to accept more than one */
+ /* character at a time. Why doesn't it work though? */
+ do {
+ status = UART->intStatus & TXFIFOEMT;
+ } while( !status );
+ UART->Data = *bptr;
+ bptr++;
+ blen--;
+
+ status = UART->intStatus & (TXOVFERR|TXUNDERR);
+ }
+
+ if( status ) {
+ /* Reset TX FIFO */
+ UART->fifoctl |= RSTTXFIFOS;
+ blen++;
+ }
+
+ buffer->buf_retlen = buffer->buf_length - blen;
+ return 0;
+}
+
+
+static int bcm63xx_uart_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ bcm63xx_uart_t * softc = ctx->dev_softc;
+ unsigned int * info = (unsigned int *) buffer->buf_ptr;
+
+ switch ((int)buffer->buf_ioctlcmd) {
+ case IOCTL_SERIAL_GETSPEED:
+ *info = softc->baudrate;
+ break;
+ case IOCTL_SERIAL_SETSPEED:
+ softc->baudrate = *info;
+ bcm63xx_set_baudrate( softc );
+ break;
+ case IOCTL_SERIAL_GETFLOW:
+ *info = SERIAL_FLOW_NONE;
+ break;
+ case IOCTL_SERIAL_SETFLOW:
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int bcm63xx_uart_close(cfe_devctx_t *ctx)
+{
+ /* Turn off the UART clock. */
+ return 0;
+}
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ul.html b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ul.html
new file mode 100755
index 0000000..a663a35
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ul.html
@@ -0,0 +1,48 @@
+<html>
+ <head>
+ <meta HTTP-EQUIV='Pragma' CONTENT='no-cache'>
+ <script language="javascript">
+<!-- hide
+
+var progress = 0;
+
+function isInProgress() {
+ if ( progress == 0 ) {
+ progress = 1;
+ return true;
+ }
+ alert('Upload software is in progress. Please wait for a minute.');
+ return false;
+}
+
+// done hiding -->
+</script>
+ </head>
+ <body>
+ <blockquote>
+ <form method='post' ENCTYPE='multipart/form-data' action='upload.cgi' onSubmit='return isInProgress();'>
+ <b>Update Software</b><br>
+ <br>
+ <b>Step 1:</b> Obtain an updated software image file from your ISP.<br>
+ <br>
+ <b>Step 2:</b> Enter the path to the image file location in the box below or
+ click the &quot;Browse&quot; button to locate the image file.<br>
+ <br>
+ <b>Step 3:</b> Click the "Update Software" button once to upload the new image
+ file.<br>
+ <br>
+ NOTE: The update process takes about 2 minutes to complete, and your DSL Router
+ will reboot.<br>
+ <br>
+ <table border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>Software File Name:&nbsp;
+ </td>
+ <td><input type='file' name='filename' size='15'></td>
+ </tr>
+ </table>
+ <p align="center"><input type='submit' value='Update Software'></p>
+ </form>
+ </blockquote>
+ </body>
+</html>
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ulinfo.html b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ulinfo.html
new file mode 100755
index 0000000..1edb2ae
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/html/ulinfo.html
@@ -0,0 +1,60 @@
+<html>
+ <head>
+ <meta HTTP-EQUIV='Pragma' CONTENT='no-cache'>
+ <script language="javascript">
+<!-- hide
+var msg = new Array();
+msg[0] = 'New software is being programmed to the flash memory. The DSL Router will reboot upon completion. This process will take about 2 minutes.';
+msg[1] = 'Image uploading failed. The system is out of memory. The DSL Router is rebooting.';
+msg[2] = 'Image uploading failed. No image file was selected.';
+msg[3] = 'Image uploading failed. The selected file contains an illegal image.';
+msg[4] = 'Image uploading failed. The selected file contains an illegal image.';
+msg[5] = 'Image uploading failed. The selected file contains an illegal image.';
+msg[6] = ' ';
+msg[7] = 'Image uploading failed. The selected file contains an illegal image.';
+
+var idxStr = '<%%>';
+
+function getMsgIndex() {
+ var idxNum = parseInt(idxStr);
+ if ( isNaN(idxNum) || idxNum < 0 || idxNum > 7 )
+ idxNum = 7;
+
+ return idxNum;
+}
+
+function reboot() {
+ var loc = 'upload.html';
+
+ var code = 'location.assign("' + loc + '")';
+ eval(code);
+}
+
+function frmLoad() {
+ setTimeout('reboot()', 40000);
+}
+
+function btnBack() {
+ var code = 'location.assign("' + 'upload.html' + '")';
+ eval(code);
+}
+
+// done hiding -->
+</script>
+ </head>
+ <body onLoad='frmLoad()'>
+ <blockquote> <b>DSL Router Software Upgrade</b><br>
+ <br>
+ <script language="javascript">
+<!-- hide
+document.write(msg[getMsgIndex()]);
+// done hiding -->
+</script>
+ <br>
+ <br>
+ <center>
+ <input type='button' onClick='btnBack()' value='Back'>
+ </center>
+ </blockquote>
+ </body>
+</html>
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/ram_cfe.mk b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/ram_cfe.mk
new file mode 100755
index 0000000..a540170
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/ram_cfe.mk
@@ -0,0 +1,378 @@
+
+#
+# CFE's version number
+#
+
+include ${TOP}/main/cfe_version.mk
+
+#
+# Default values for certain parameters
+#
+
+CFG_MLONG64 ?= 0
+CFG_LITTLE ?= 0
+CFG_RELOC ?= 0
+CFG_UNCACHED ?= 0
+CFG_NEWRELOC ?= 0
+CFG_BOOTRAM ?= 0
+CFG_VGACONSOLE ?= 0
+CFG_PCI ?= 1
+CFG_LDT_REV_017 ?= 0
+CFG_ZLIB ?= 0
+CFG_BIENDIAN ?= 0
+CFG_DOWNLOAD ?= 0
+CFG_RAMAPP ?= 0
+CFG_USB ?= 0
+
+#
+# Paths to other parts of the firmware. Everything's relative to ${TOP}
+# so that you can actually do a build anywhere you want.
+#
+
+ARCH_TOP = ${TOP}/arch/${ARCH}
+ARCH_SRC = ${ARCH_TOP}/common/src
+ARCH_INC = ${ARCH_TOP}/common/include
+CPU_SRC = ${ARCH_TOP}/cpu/${CPU}/src
+CPU_INC = ${ARCH_TOP}/cpu/${CPU}/include
+
+#
+# It's actually optional to have a 'board'
+# directory. If you don't specify BOARD,
+# don't include the files.
+#
+
+ifneq ("$(strip ${BOARD})","")
+BOARD_SRC = ${ARCH_TOP}/board/${BOARD}/src
+BOARD_INC = ${ARCH_TOP}/board/${BOARD}/include
+endif
+
+#
+# Preprocessor defines for CFE's version number
+#
+
+VDEF = -DCFE_VER_MAJ=${CFE_VER_MAJ} -DCFE_VER_MIN=${CFE_VER_MIN} -DCFE_VER_ECO=${CFE_VER_ECO}
+
+#
+# Construct the list of paths that will eventually become the include
+# paths and VPATH
+#
+
+SRCDIRS = ${ARCH_SRC} ${CPU_SRC} ${LZMZ_SRC} ${BOARD_SRC} ${TOP}/main ${TOP}/vendor ${TOP}/include ${TOP}/net ${TOP}/dev ${TOP}/pci ${TOP}/ui ${TOP}/lib ${TOP}/common ${TOP}/verif ${TOP}/lzma
+
+CFE_INC = ${TOP}/include ${TOP}/pci ${TOP}/net
+
+ifeq ($(strip ${CFG_VGACONSOLE}),1)
+SRCDIRS += ${TOP}/x86emu ${TOP}/pccons
+CFE_INC += ${TOP}/x86emu ${TOP}/pccons
+endif
+
+ifeq ($(strip ${CFG_VAPI}),1)
+SRCDIRS += ${TOP}/verif
+CFE_INC += ${TOP}/verif
+endif
+
+ifeq ($(strip ${CFG_ZLIB}),1)
+SRCDIRS += ${TOP}/zlib
+CFE_INC += ${TOP}/zlib
+endif
+
+
+INCDIRS = $(patsubst %,-I%,$(subst :, ,$(ARCH_INC) $(CPU_INC) $(BOARD_INC) $(CFE_INC)))
+
+VPATH = $(SRCDIRS)
+
+#
+# Bi-endian support: If we're building the little-endian
+# version, use a different linker script so we can locate the
+# ROM at a higher address. You'd think we could do this with
+# normal linker command line switches, but there appears to be no
+# command-line way to override the 'AT' qualifier in the linker script.
+#
+
+CFG_TEXTAT1MB=0
+ifeq ($(strip ${CFG_BIENDIAN}),1)
+ ifeq ($(strip ${CFG_LITTLE}),1)
+ CFG_TEXTAT1MB=1
+ endif
+endif
+
+
+#
+# Configure tools and basic tools flags. This include sets up
+# macros for calling the C compiler, basic flags,
+# and linker scripts.
+#
+
+include ${ARCH_SRC}/tools.mk
+
+#
+# Add some common flags that are used on any architecture.
+#
+
+CFLAGS += -I. $(INCDIRS)
+CFLAGS += -D_CFE_ ${VDEF} -DCFG_BOARDNAME=\"${CFG_BOARDNAME}\" -DCONFIG_MIPS_BRCM
+
+#
+# Add flash driver support.
+#
+# INC_xxx_FLASH_DRIVER is exported from rom_cfe.mk
+
+CFLAGS += -DINC_CFI_FLASH_DRIVER=$(INC_CFI_FLASH_DRIVER)
+CFLAGS += -DINC_SPI_FLASH_DRIVER=$(INC_SPI_FLASH_DRIVER)
+CFLAGS += -DINC_NAND_FLASH_DRIVER=$(INC_NAND_FLASH_DRIVER)
+CFLAGS += -DINC_SPI_PROG_NAND=$(INC_SPI_PROG_NAND)
+
+#
+# Set CFG_TCP=0 to not include the TCP protocol.
+#
+
+CFG_TCP=1
+ifeq ($(strip ${CFG_TCP}),1)
+CFLAGS += -DCFG_TCP
+endif
+
+#
+# Set CFG_WEB_SERVER=0 to not include the web server.
+#
+
+CFG_WEB_SERVER=1
+CFLAGS += -DCFG_WEB_SERVER=${CFG_WEB_SERVER}
+
+#
+# Gross - allow more options to be supplied from command line
+#
+
+ifdef CFG_OPTIONS
+OPTFLAGS = $(patsubst %,-D%,$(subst :, ,$(CFG_OPTIONS)))
+CFLAGS += ${OPTFLAGS}
+endif
+
+
+#
+# IKOS Build
+#
+
+ifeq ($(strip $(BRCM_IKOS)),y)
+CFLAGS += -DCONFIG_BRCM_IKOS
+endif
+
+#
+# This is the makefile's main target. Note that we actually
+# do most of the work in 'ALL' not 'all', since we include
+# other makefiles after this point.
+#
+
+all : build_date.c ALL
+
+#
+# Macros that expand to the list of arch-independent files
+#
+
+LZMAOBJS = LzmaDecode.o dcapi.o
+DEVOBJS =
+## dev_newflash.o dev_null.o dev_promice.o dev_ide_common.o dev_ns16550.o dev_ds17887clock.o dev_flash.o
+LIBOBJS = lib_malloc.o lib_printf.o lib_queue.o lib_string.o lib_string2.o \
+ lib_setjmp.o lib_arena.o
+##lib_hssubr.o lib_physio.o lib_misc.o lib_qsort.o
+
+## Foxconn add start by Cliff Wang, 03/23/2010 ##
+#NETOBJS = net_ether.o net_tftp.o net_ip.o net_udp.o net_dns.o net_arp.o \
+ net_api.o net_tcp.o net_tcpbuf.o
+NETOBJS = net_ether.o net_tftp.o net_ip.o net_udp.o net_dns.o net_arp.o \
+ net_api.o net_tcp.o net_tcpbuf.o net_nmrp.o
+## Foxconn add end by Cliff Wang, 03/23/2010
+
+## dev_tcpconsole.o net_dhcp.o net_icmp.o
+CFEOBJS = cfe_attach.o cfe_iocb_dispatch.o cfe_devfuncs.o \
+ cfe_console.o cfe_mem.o cfe_timer.o \
+ cfe_background.o build_date.o \
+ cfe_xreq.o cfe_filesys.o
+## cfe_error.o cfe_rawfs.o cfe_fatfs.o cfe_httpfs.o cfe_ldr_srec.o cfe_autoboot.o cfe_boot.o cfe_ldr_elf.o cfe_ldr_raw.o cfe_loader.o
+## cfe_main.o nvram_subr.o url.o cfe_savedata.o env_subr.o cfe_zlibfs.o
+
+#UIOBJS = ui_command.o ui_cmddisp.o
+# Foxconn add start by Cliff Wang, 03/23/2010
+UIOBJS = ui_command.o ui_cmddisp.o ui_tftpd.o ui_netcmds.o
+
+## ui_pcicmds.o \ui_tcpcmds.o ui_memcmds.o ui_loadcmds.o ui_flash.o ui_envcmds.o ui_devcmds.o ui_netcmds.o
+## ui_examcmds.o ui_misccmds.o \
+## ui_test_disk.o ui_test_ether.o ui_test_flash.o ui_test_uart.o
+
+#
+# Add more object files if we're supporting PCI
+#
+
+ifeq ($(strip ${CFG_PCI}),1)
+PCIOBJS = pciconf.o ldtinit.o pci_subr.o
+PCIOBJS += pci_devs.o
+DEVOBJS += dev_sp1011.o dev_ht7520.o
+DEVOBJS += dev_ide_pci.o dev_ns16550_pci.o
+DEVOBJS += dev_tulip.o dev_dp83815.o
+CFLAGS += -DCFG_PCI=1
+ifeq ($(strip ${CFG_LDT_REV_017}),1)
+CFLAGS += -DCFG_LDT_REV_017=1
+endif
+ifeq ($(strip ${CFG_DOWNLOAD}),1)
+DEVOBJS += dev_bcm1250.o download.data
+CFLAGS += -DCFG_DOWNLOAD=1
+endif
+endif
+
+#
+# If doing bi-endian, add the compiler switch to change
+# the way the vectors are generated. These switches are
+# only added to the big-endian portion of the ROM,
+# which is located at the real boot vector.
+#
+
+ifeq ($(strip ${CFG_BIENDIAN}),1)
+ ifeq ($(strip ${CFG_LITTLE}),0)
+ CFLAGS += -DCFG_BIENDIAN=1
+ endif
+endif
+
+#
+# Include the makefiles for the architecture-common, cpu-specific,
+# and board-specific directories. Each of these will supply
+# some files to "ALLOBJS". The BOARD directory is optional
+# as some ports are so simple they don't need boad-specific stuff.
+#
+
+include ${ARCH_SRC}/Makefile
+include ${CPU_SRC}/Makefile
+
+ifneq ("$(strip ${BOARD})","")
+include ${BOARD_SRC}/Makefile
+endif
+
+#
+# Add the common object files here.
+#
+
+ALLOBJS += $(LIBOBJS) $(DEVOBJS) $(CFEOBJS) $(VENOBJS) $(UIOBJS) $(NETOBJS) $(LZMAOBJS)
+#$(PCIOBJS)
+
+#
+# VAPI continues to be a special case.
+#
+
+ifeq ($(strip ${CFG_VAPI}),1)
+include ${TOP}/verif/Makefile
+endif
+
+#
+# USB support
+#
+
+ifeq ($(strip ${CFG_USB}),1)
+SRCDIRS += ${TOP}/usb
+CFE_INC += ${TOP}/usb
+include ${TOP}/usb/Makefile
+endif
+
+#
+# If we're doing the VGA console thing, pull in the x86 emulator
+# and the pcconsole subsystem
+#
+
+ifeq ($(strip ${CFG_VGACONSOLE}),1)
+include ${TOP}/x86emu/Makefile
+include ${TOP}/pccons/Makefile
+endif
+
+#
+# If we're including ZLIB, then add its makefile.
+#
+
+ifeq ($(strip ${CFG_ZLIB}),1)
+include ${TOP}/zlib/Makefile
+CFLAGS += -DCFG_ZLIB=1 -DMY_ZCALLOC -DNO_MEMCPY
+endif
+
+#
+# Vendor extensions come next - they live in their own directory.
+#
+
+include ${TOP}/vendor/Makefile
+
+.PHONY : all
+.PHONY : ALL
+.PHONY : build_date.c
+
+#
+# Build the local tools that we use to construct other source files
+#
+
+mkpcidb : ${TOP}/hosttools/mkpcidb.c
+ gcc -o mkpcidb ${TOP}/hosttools/mkpcidb.c
+
+memconfig : ${TOP}/hosttools/memconfig.c
+ gcc -o memconfig -D_MCSTANDALONE_ -D_MCSTANDALONE_NOISY_ -I${TOP}/arch/mips/cpu/sb1250/include ${TOP}/hosttools/memconfig.c ${TOP}/arch/${ARCH}/cpu/${CPU}/src/sb1250_draminit.c
+
+pcidevs_data2.h : mkpcidb ${TOP}/pci/pcidevs_data.h
+ ./mkpcidb > pcidevs_data2.h
+
+mkflashimage : ${TOP}/hosttools/mkflashimage.c
+ gcc -o mkflashimage -I${TOP}/include ${TOP}/hosttools/mkflashimage.c
+
+pci_subr.o : ${TOP}/pci/pci_subr.c pcidevs_data2.h
+
+build_date.c :
+ echo "const char *builddate = \"`date`\";" > build_date.c
+ echo "const char *builduser = \"`whoami`@`hostname`\";" >> build_date.c
+
+#
+# Make a define for the board name
+#
+
+CFLAGS += -D_$(patsubst "%",%,${CFG_BOARDNAME})_
+
+LIBCFE = libcfe.a
+
+%.o : %.c
+ $(GCC) $(CFLAGS) -o $@ $<
+
+%.o : %.S
+ $(GCC) $(CFLAGS) -o $@ $<
+
+%.o : %.html
+ echo unsigned char $*_html[] = { > $*.c
+ hexdump -v -e '" " 12/1 "0x%2.2x, " "\n"' $< | sed -e "s/ 0x .*$\//" -e "\$$s/, *$$//" >> $*.c
+ echo ' };' >> $*.c
+ echo 'int $*_html_size = sizeof($*_html);' >> $*.c
+ echo >> $*.c
+ $(GCC) $(CFLAGS) -o $@ $*.c
+ rm -f $*.c
+
+%.o : %.css
+ echo unsigned char $*_css[] = { > $*.c
+ hexdump -v -e '" " 12/1 "0x%2.2x, " "\n"' $< | sed -e "s/ 0x .*$\//" -e "\$$s/, *$$//" >> $*.c
+ echo ' };' >> $*.c
+ echo 'int $*_css_size = sizeof($*_css);' >> $*.c
+ echo >> $*.c
+ $(GCC) $(CFLAGS) -o $@ $*.c
+ rm -f $*.c
+
+%.o : %.gif
+ echo unsigned char $*_gif[] = { > $*.c
+ hexdump -v -e '" " 12/1 "0x%2.2x, " "\n"' $< | sed -e "s/ 0x .*$\//" -e "\$$s/, *$$//" >> $*.c
+ echo ' };' >> $*.c
+ echo 'int $*_gif_size = sizeof($*_gif);' >> $*.c
+ echo >> $*.c
+ $(GCC) $(CFLAGS) -o $@ $*.c
+ rm -f $*.c
+
+#
+# This rule constructs "libcfe.a" which contains most of the object
+# files.
+#
+
+$(LIBCFE) : $(ALLOBJS)
+ rm -f $(LIBCFE)
+ $(AR) cr $(LIBCFE) $(ALLOBJS)
+ $(RANLIB) $(LIBCFE)
+
+
+
+
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c
new file mode 100755
index 0000000..15dad53
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_ram/src/robosw_reg.c
@@ -0,0 +1,615 @@
+/*
+<:copyright-broadcom
+
+ Copyright (c) 2007 Broadcom Corporation
+ All Rights Reserved
+ No portions of this material may be reproduced in any form without the
+ written permission of:
+ Broadcom Corporation
+ 16215 Alton Parkway
+ Irvine, California 92619
+ All information contained in this document is Broadcom Corporation
+ company private, proprietary, and trade secret.
+
+:>
+*/
+
+#include "bcm_map.h"
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+#include "mii.h"
+#include "bcmmii.h"
+#include "sbmips.h"
+#include "cfe_iocb.h"
+#include "cfe_timer.h"
+#include "robosw_reg.h"
+#include "dev_bcm63xx_eth.h"
+#include "bcmSpiRes.h"
+
+static uint32 mii_read(uint32 uPhyAddr, uint32 uRegAddr);
+static void mii_write(uint32 uPhyAddr, uint32 uRegAddr, uint32 data);
+
+static int ext_switch_init(void);
+static int ethsw_spi_ss_id(void);
+static void ethsw_spi_select(int page);
+static void ethsw_spi_rreg(int page, int reg, uint8 *data, int len);
+static void ethsw_spi_wreg(int page, int reg, uint8 *data, int len);
+
+void ethsw_rreg_ext(int access_type, int page, int reg, uint8 *data, int len);
+void ethsw_wreg_ext(int access_type, int page, int reg, uint8 *data, int len);
+
+
+static ETHERNET_MAC_INFO EnetInfo[BP_MAX_ENET_MACS];
+static uint16 PortLinkState[BP_MAX_SWITCH_PORTS];
+
+#define MDIO_BUS 0
+#define SPI_BUS 1
+#define TX_BDS 3
+#define RX_BDS 16
+#define CACHE_ALIGN 16
+#define BUF_LENGTH 160
+extern void _cfe_flushcache(int, uint8_t *, uint8_t *);
+#define INVAL_RANGE(s,l) _cfe_flushcache(CFE_CACHE_INVAL_RANGE,((uint8_t *) (s)),((uint8_t *) (s))+(l))
+
+/* read a value from the MII */
+static uint32 mii_read(uint32 uPhyAddr, uint32 uRegAddr)
+{
+ SWITCH->MdioCtrl = 0x0;
+ SWITCH->MdioCtrl = MdioCtrl_Read | (IsExtPhyId(uPhyAddr) ? MdioCtrl_Ext : 0) |
+ ((uPhyAddr << MdioCtrl_ID_Shift) & MdioCtrl_ID_Mask) |
+ (uRegAddr << MdioCtrl_Addr_Shift);
+ cfe_usleep(100);
+ return SWITCH->MdioData;
+}
+
+/* write a value to the MII */
+static void mii_write(uint32 uPhyAddr, uint32 uRegAddr, uint32 data)
+{
+ SWITCH->MdioCtrl = 0x0;
+ SWITCH->MdioCtrl = MdioCtrl_Write | (IsExtPhyId(uPhyAddr) ? MdioCtrl_Ext : 0) |
+ ((uPhyAddr << MdioCtrl_ID_Shift) & MdioCtrl_ID_Mask) |
+ (uRegAddr << MdioCtrl_Addr_Shift) | data;
+ cfe_usleep(100);
+}
+
+static int clkHz = 781000;
+#if !defined(_BCM96328_)
+static int clk781k = 2;
+#endif
+static int ethsw_spi_ss_id()
+{
+ int slave_select;
+
+ switch(EnetInfo[1].usConfigType) {
+ case BP_ENET_CONFIG_SPI_SSB_0:
+ slave_select = 0;
+ break;
+ case BP_ENET_CONFIG_SPI_SSB_1:
+ slave_select = 1;
+ break;
+ case BP_ENET_CONFIG_SPI_SSB_2:
+ slave_select = 2;
+ break;
+ case BP_ENET_CONFIG_SPI_SSB_3:
+ slave_select = 3;
+ break;
+ default:
+ slave_select = 1;
+ xprintf("Invalid SPI_SS in usConfigType, Assuming 1\n");
+ break;
+ }
+ return slave_select;
+}
+
+static void ethsw_spi_select(int page)
+{
+ unsigned char buf[3];
+ int spi_ss, cid = 0;
+
+ spi_ss = ethsw_spi_ss_id();
+ /* Select new chip */
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_WRITE |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+
+ /* Select new page */
+ buf[1] = PAGE_SELECT;
+ buf[2] = (char)page;
+#if defined(_BCM96328_)
+ BcmSpi_Write(buf, sizeof(buf), HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ BcmSpi_Write(buf, sizeof(buf), LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+
+}
+
+static void ethsw_spi_rreg(int page, int reg, uint8 *data, int len)
+{
+ unsigned char buf[64];
+ int rc;
+ int i;
+ int max_check_spi_sts;
+ int prependCnt = BCM5325_SPI_PREPENDCNT, spi_ss, cid = 0;
+
+ spi_ss = ethsw_spi_ss_id();
+
+ ethsw_spi_select(page);
+
+ /* write command byte and register address */
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_READ |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+ buf[1] = (unsigned char)reg;
+#if defined(_BCM96328_)
+ rc = BcmSpi_Read(buf, prependCnt, 1, HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ rc = BcmSpi_Read(buf, prependCnt, 1, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+
+ if (rc == SPI_STATUS_OK) {
+ max_check_spi_sts = 0;
+ do {
+ /* write command byte and read spi_sts address */
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_READ |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+ buf[1] = (unsigned char)BCM5325_SPI_STS;
+#if defined(_BCM96328_)
+ rc = BcmSpi_Read(buf, prependCnt, 1, HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ rc = BcmSpi_Read(buf, prependCnt, 1, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+ if (rc == SPI_STATUS_OK) {
+ /* check the bit 0 RACK bit is set */
+ if (buf[0] & BCM5325_SPI_CMD_RACK) {
+ break;
+ }
+ cfe_usleep(10000);
+ } else {
+ break;
+ }
+ } while (max_check_spi_sts++ < 10);
+
+ if (rc == SPI_STATUS_OK) {
+ for (i = 0; i < len; i++) {
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_READ |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+ buf[1] = (unsigned char)0xf0;
+#if defined(_BCM96328_)
+ rc = BcmSpi_Read(buf, prependCnt, 1, HS_SPI_BUS_NUM, spi_ss, clkHz);
+#else
+ rc = BcmSpi_Read(buf, prependCnt, 1, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+#endif
+ if (rc == SPI_STATUS_OK) {
+ *(data + (len - i - 1)) = buf[0];
+ }
+ }
+ }
+ }
+}
+
+static void ethsw_spi_wreg(int page, int reg, uint8 *data, int len)
+{
+ unsigned char buf[64];
+ int i;
+ int spi_ss, cid = 0;
+
+ ethsw_spi_select(page);
+
+ spi_ss = ethsw_spi_ss_id();
+ buf[0] = BCM5325_SPI_CMD_NORMAL | BCM5325_SPI_CMD_WRITE |
+ ((cid & BCM5325_SPI_CHIPID_MASK) << BCM5325_SPI_CHIPID_SHIFT);
+
+ buf[1] = (char)reg;
+ for (i = 0; i < len; i++) {
+ /* Write the data out in LE format to the switch */
+ buf[BCM5325_SPI_PREPENDCNT+i] = *(data + (len - i - 1));
+ }
+ BcmSpi_Write(buf, len+BCM5325_SPI_PREPENDCNT, LEG_SPI_BUS_NUM, spi_ss, clkHz);
+}
+
+/* External switch register access through MDC/MDIO */
+static void ethsw_mdio_rreg(int page, int reg, uint8 *data, int len)
+{
+ uint32 cmd, res, ret;
+ int max_retry = 0;
+
+ cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd);
+
+ cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_READ;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd);
+
+ do {
+ res = mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17);
+ cfe_usleep(10);
+ } while (((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE) &&
+ (max_retry++ < 5));
+
+ ret = 0;
+ ret |= mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24) << 0;
+ ret |= mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25) << 16;
+ switch (len) {
+ case 1:
+ *data = (uint8)ret;
+ break;
+ case 2:
+ *(uint16 *)data = (uint16)ret;
+ break;
+ case 4:
+ *(uint32 *)data = ret;
+ break;
+ }
+}
+
+static void ethsw_mdio_wreg(int page, int reg, uint8 *data, int len)
+{
+ uint32 cmd, res;
+ uint32 val = 0;
+ int max_retry = 0;
+
+ switch (len) {
+ case 1:
+ val = *data;
+ break;
+ case 2:
+ val = *(uint16 *)data;
+ break;
+ case 4:
+ val = *(uint32 *)data;
+ break;
+ }
+ cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd);
+
+ cmd = val>>0 & 0xffff;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24, cmd);
+ cmd = val>>16 & 0xffff;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25, cmd);
+ cmd = 0;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG26, cmd);
+ cmd = 0;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG27, cmd);
+
+ cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_WRITE;
+ mii_write(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd);
+
+ do {
+ res = mii_read(PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17);
+ cfe_usleep(10);
+ } while (((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE) &&
+ (max_retry++ < 5));
+}
+
+void ethsw_rreg_ext(int access_type, int page, int reg, uint8 *data, int len)
+{
+ if (access_type == MDIO_BUS) {
+ ethsw_mdio_rreg(page, reg, data, len);
+
+ } else {
+ ethsw_spi_rreg(page, reg, data, len);
+ }
+}
+
+void ethsw_wreg_ext(int access_type, int page, int reg, uint8 *data, int len)
+{
+ if (access_type == MDIO_BUS) {
+ ethsw_mdio_wreg(page, reg, data, len);
+ } else {
+ ethsw_spi_wreg(page, reg, data, len);
+ }
+}
+
+int ext_switch_init(void)
+{
+ uint8 data8;
+ uint32 data32, access_type;
+#if !defined(_BCM96328_)
+ uint32 clkSave;
+#endif
+
+ switch (EnetInfo[1].usConfigType) {
+ case BP_ENET_CONFIG_SPI_SSB_0:
+ case BP_ENET_CONFIG_SPI_SSB_1:
+ case BP_ENET_CONFIG_SPI_SSB_2:
+ case BP_ENET_CONFIG_SPI_SSB_3:
+ access_type = SPI_BUS;
+#if !defined(_BCM96328_)
+ clkSave = SPI->spiClkCfg & SPI_CLK_MASK;
+ xprintf("spiClkCfg = %x; clkSave = %d \n", SPI->spiClkCfg, clkSave);
+ SPI->spiClkCfg = (SPI->spiClkCfg & ~SPI_CLK_MASK) | clk781k;
+#endif
+ break;
+
+ case BP_ENET_CONFIG_MDIO_PSEUDO_PHY:
+ access_type = MDIO_BUS;
+ break;
+
+ default:
+ xprintf("Unknown PHY configuration type\n");
+ return -1;
+ }
+
+ ethsw_rreg_ext(access_type, PAGE_MANAGEMENT, REG_DEVICE_ID, (uint8 *)&data32, sizeof(data32));
+ xprintf("External switch id = %x \n", data32);
+
+ if (data32 == 0x53115)
+ {
+ /* setup Switch MII1 port state override */
+ data8 = (REG_CONTROL_MPSO_MII_SW_OVERRIDE |
+ REG_CONTROL_MPSO_SPEED1000 |
+ REG_CONTROL_MPSO_FDX |
+ REG_CONTROL_MPSO_LINKPASS);
+ ethsw_wreg_ext(access_type, PAGE_CONTROL,
+ REG_CONTROL_MII1_PORT_STATE_OVERRIDE, &data8, sizeof(data8));
+ /* management mode, enable forwarding */
+ data8 = REG_SWITCH_MODE_FRAME_MANAGE_MODE | REG_SWITCH_MODE_SW_FWDG_EN;
+ ethsw_wreg_ext(access_type, PAGE_CONTROL,
+ REG_SWITCH_MODE, &data8, sizeof(data8));
+ /* Enable IMP Port */
+ data8 = ENABLE_MII_PORT;
+ ethsw_wreg_ext(access_type, PAGE_MANAGEMENT,
+ REG_GLOBAL_CONFIG, &data8, sizeof(data8));
+ /* Disable BRCM Tag for IMP */
+ data8 = ~REG_BRCM_HDR_ENABLE;
+ ethsw_wreg_ext(access_type, PAGE_MANAGEMENT,
+ REG_BRCM_HDR_CTRL, &data8, sizeof(data8));
+ /* enable rx bcast, ucast and mcast of imp port */
+ data8 = (REG_MII_PORT_CONTROL_RX_UCST_EN |
+ REG_MII_PORT_CONTROL_RX_MCST_EN |
+ REG_MII_PORT_CONTROL_RX_BCST_EN);
+ ethsw_wreg_ext(access_type, PAGE_CONTROL, REG_MII_PORT_CONTROL, &data8, sizeof(data8));
+ }
+
+#if !defined(_BCM96328_)
+ if (access_type == SPI_BUS)
+ SPI->spiClkCfg = (SPI->spiClkCfg & ~SPI_CLK_MASK) | clkSave;
+#endif
+ return 0;
+}
+
+
+void robosw_init(void)
+{
+ int port;
+
+ BpGetEthernetMacInfo(EnetInfo, BP_MAX_ENET_MACS);
+
+ // Power up and reset EPHYs
+ GPIO->RoboswEphyCtrl = 0;
+ cfe_usleep(1000);
+
+ // Take EPHYs out of reset
+ GPIO->RoboswEphyCtrl =
+ EPHY_RST_4 |
+ EPHY_RST_3 |
+ EPHY_RST_2 |
+ EPHY_RST_1;
+ cfe_usleep(1000);
+
+#if defined(_BCM96328_) || defined(_BCM96362_)
+ GPIO->RoboswSwitchCtrl |= (RSW_MII_DUMB_FWDG_EN | RSW_HW_FWDG_EN);
+#endif
+#if defined(_BCM96368_) || defined(_BCM96816_)
+ GPIO->RoboswEphyCtrl |= (RSW_MII_DUMB_FWDG_EN | RSW_HW_FWDG_EN);
+#endif
+
+ // Enable Switch clock
+ PERF->blkEnables |= ROBOSW_CLK_EN;
+#if defined(_BCM96368_)
+ PERF->blkEnables |= SWPKT_SAR_CLK_EN | SWPKT_USB_CLK_EN;
+#endif
+#if defined(_BCM96816_)
+ PERF->blkEnables |= SWPKT_GPON_CLK_EN | SWPKT_USB_CLK_EN;
+#endif
+
+ cfe_usleep(1000);
+
+ PERF->softResetB &= ~SOFT_RST_SWITCH;
+ cfe_usleep(1000);
+ PERF->softResetB |= SOFT_RST_SWITCH;
+ cfe_usleep(1000);
+
+ /* Disable Rx and Tx on all Ethernet Ports */
+ for (port = 0; port < EPHY_PORTS; port++) {
+ SWITCH->PortCtrl[port] = 0x03;
+ }
+
+ if (EnetInfo[1].ucPhyType == BP_ENET_EXTERNAL_SWITCH) {
+ ext_switch_init();
+ }
+
+}
+
+void robosw_configure_ports()
+{
+ uint16 data;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ if ((EnetInfo[0].sw.port_map & (1 << i)) != 0) {
+ if (EnetInfo[0].sw.phy_id[i] == 0xff) {
+#if defined(_BCM96368_)
+ if (i == 4)
+ GPIO->GPIOBaseMode |= (EN_GMII1);
+ if (i == 5)
+ GPIO->GPIOBaseMode |= (EN_GMII2);
+#endif
+ continue;
+ }
+ if (IsWanPort(EnetInfo[0].sw.phy_id[i])) {
+ *(SWITCH_PBVLAN + i) = PBMAP_MIPS;
+ SWITCH->DisableLearn |= (1 << i);
+ }
+ // Reset
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BMCR, BMCR_RESET);
+ PortLinkState[i] = 0;
+ if (!IsExtPhyId(EnetInfo[0].sw.phy_id[i])) {
+ // Configure PHY link/act LED
+#if defined(_BCM96368_)
+ // Enable status change notification */
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_INTERRUPT, MII_INTR_ENABLE);
+ // Configure LEDs
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_RESERVED_1B);
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_RESERVED_1B, data | MII_RESERVED_1B_ACT_LED);
+#elif defined(_BCM96816_)
+ // Configure LEDs
+ mii_write(EnetInfo[0].sw.phy_id[i], 0x1c, 0xa410);
+#elif defined(_BCM96328_) || defined(_BCM96362_)
+ // Configure LEDs
+ // Enable Shadow register 2
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_BRCM_TEST);
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BRCM_TEST, (data | MII_BRCM_TEST_SHADOW2_ENABLE));
+ // Set LED0 to speed. Set LED1 to blinky link
+ mii_write(EnetInfo[0].sw.phy_id[i], 0x15, 0x71);
+ // Disable Shadow register 2
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BRCM_TEST, (data & ~MII_BRCM_TEST_SHADOW2_ENABLE));
+#endif
+ } else {
+#if defined(_BCM96368_)
+ if (i == 4)
+ GPIO->GPIOBaseMode |= (EN_GMII1);
+ if (i == 5)
+ GPIO->GPIOBaseMode |= (EN_GMII2);
+#endif
+#if defined(_BCM96816_)
+ if (i == 2)
+ GPIO->GPIOBaseMode |= (EN_GMII1);
+ if (i == 3)
+ GPIO->GPIOBaseMode |= (EN_GMII2);
+#endif
+#if defined(_BCM96362_)
+ if (i == 4)
+ GPIO->RoboswSwitchCtrl |= (RSW_MII_SEL_2P5V << RSW_MII_SEL_SHIFT);
+ if (i == 5)
+ GPIO->RoboswSwitchCtrl |= (RSW_MII_2_IFC_EN | (RSW_MII_SEL_2P5V << RSW_MII_2_SEL_SHIFT));
+#endif
+#if defined(_BCM96328_)
+ if (i == 4)
+ MISC->miscPadCtrlHigh |= (MISC_MII_SEL_2P5V << MISC_MII_SEL_SHIFT);
+#endif
+ // Reset
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BMCR, BMCR_RESET);
+ // Enable auto-negotiation
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_ANAR, ANAR_TXFD | ANAR_TXHD | ANAR_10FD | ANAR_10HD | PSB_802_3);
+
+ // Configure LED for link/activity
+ data = MII_1C_SHADOW_LED_CONTROL << MII_1C_SHADOW_REG_SEL_S;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C);
+ data |= ACT_LINK_LED_ENABLE;
+ data |= MII_1C_WRITE_ENABLE;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_PHYIDR2);
+ if ((data & BCM_PHYID_M) == (BCM54610_PHYID2 & BCM_PHYID_M)) {
+ // Configure RGMII timing for 54610 GPHY
+ data = MII_1C_SHADOW_CLK_ALIGN_CTRL << MII_1C_SHADOW_REG_SEL_S;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C);
+ data &= (~GTXCLK_DELAY_BYPASS_DISABLE);
+ data |= MII_1C_WRITE_ENABLE;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+
+ // Configure LOM LED Mode
+ data = MII_1C_EXTERNAL_CONTROL_1 << MII_1C_SHADOW_REG_SEL_S;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C);
+ data |= LOM_LED_MODE;
+ data |= MII_1C_WRITE_ENABLE;
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_REGISTER_1C, data);
+ }
+ }
+ // Restart auto-negotiation
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_BMCR);
+ mii_write(EnetInfo[0].sw.phy_id[i], MII_BMCR, data | BMCR_RESTARTAN);
+ }
+ }
+
+#if defined(_BCM96816_)
+ // Disable SERDES, MoCA, USB and GPON port
+ SWITCH->PortOverride[SERDES_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[MOCA_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[USB_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[GPON_PORT_ID] = PortOverride_Enable;
+#endif
+
+#if defined(_BCM96328_) || defined(_BCM96362_)
+ // Ports 6 and 7 are not used on 6328 and 6362
+ SWITCH->PortOverride[PORT_6_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[PORT_7_PORT_ID] = PortOverride_Enable;
+#endif
+
+#if defined(_BCM96368_)
+ // Disable SAR and USB port
+ SWITCH->PortOverride[USB_PORT_ID] = PortOverride_Enable;
+ SWITCH->PortOverride[SAR_PORT_ID] = PortOverride_Enable;
+#endif
+
+ // Enable the GMII clocks.
+ SWITCH->ImpRgmiiCtrlP4 |= ImpRgmiiCtrl_GMII_En;
+ /* RGMII Delay Programming. Enable ID mode */
+ SWITCH->ImpRgmiiCtrlP4 |= ImpRgmiiCtrl_Timing_Sel;
+
+#if !defined(_BCM96328_)
+ SWITCH->ImpRgmiiCtrlP5 |= ImpRgmiiCtrl_GMII_En;
+ SWITCH->ImpRgmiiCtrlP5 |= ImpRgmiiCtrl_Timing_Sel;
+#endif
+
+ // Reset MIB counters
+ SWITCH->GlbMgmt = GlbMgmt_ResetMib;
+ cfe_usleep(100);
+ SWITCH->GlbMgmt = 0;
+
+ SWITCH->ImpOverride |= ImpOverride_Force | ImpOverride_Linkup;
+
+}
+
+void robosw_check_ports()
+{
+ uint16 data;
+ uint8 PortOverride;
+ int i;
+
+ for (i = 0; i < EPHY_PORTS; i++) {
+ if ((EnetInfo[0].sw.port_map & (1 << i)) != 0) {
+ if (EnetInfo[0].sw.phy_id[i] == 0xff) {
+ PortOverride = PortOverride_Enable | PortOverride_1000Mbs |
+ PortOverride_Fdx | PortOverride_Linkup;
+ if ((SWITCH->PortOverride[i] & PortOverride) != PortOverride) {
+ SWITCH->PortOverride[i] = PortOverride;
+ SWITCH->PortCtrl[i] = 0;
+ PortLinkState[i] = 1;
+ }
+ continue;
+ }
+ PortOverride = PortOverride_Enable;
+ data = mii_read(EnetInfo[0].sw.phy_id[i], MII_ASR);
+ if (PortLinkState[i] != MII_ASR_LINK(data)) {
+
+ if (MII_ASR_LINK(data))
+ PortOverride |= PortOverride_Linkup;
+
+ if (MII_ASR_DONE(data)) {
+ if (MII_ASR_FDX(data))
+ PortOverride |= PortOverride_Fdx;
+ if (MII_ASR_1000(data))
+ PortOverride |= PortOverride_1000Mbs;
+ else if (MII_ASR_100(data))
+ PortOverride |= PortOverride_100Mbs;
+ else
+ PortOverride |= PortOverride_10Mbs;
+ }
+
+ SWITCH->PortOverride[i] = PortOverride;
+
+ if(PortOverride & PortOverride_Linkup) {
+ /* Enable Rx and Tx */
+ SWITCH->PortCtrl[i] = 0;
+ }
+
+ PortLinkState[i] = MII_ASR_LINK(data);
+ }
+ }
+ }
+}
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/Makefile b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/Makefile
new file mode 100755
index 0000000..808ddc2
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/Makefile
@@ -0,0 +1,23 @@
+ifeq ($(strip ${CFG_BOARDNAME}),"BCM96328")
+BSPOBJS += \
+ bcm63xx_impl1_rom_boot.o
+endif
+ifeq ($(strip ${CFG_BOARDNAME}),"BCM96362")
+BSPOBJS += \
+ bcm63xx_impl1_rom_boot.o
+endif
+ifeq ($(strip ${CFG_BOARDNAME}),"BCM96368")
+BSPOBJS += \
+ bcm6368_rom_boot.o \
+ bcm6368_sdramDqs.o
+endif
+ifeq ($(strip ${CFG_BOARDNAME}),"BCM96816")
+BSPOBJS += \
+ bcm63xx_impl1_rom_boot.o
+endif
+ifeq ($(strip ${INC_NAND_FLASH_DRIVER}),1)
+BSPOBJS += \
+ nandflash.o
+endif
+BSPOBJS += \
+ bcm63xx_main.o
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_rom_boot.S b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_rom_boot.S
new file mode 100755
index 0000000..f1cba19
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_rom_boot.S
@@ -0,0 +1,548 @@
+#include "sbmips.h"
+#include "bsp_config.h"
+
+#include "6368_cpu.h"
+#include "6368_common.h"
+#include "bcm_hwdefs.h"
+#include "boardparms.h"
+#include "mipsmacros.h"
+
+#define SETLEDS1(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ bal board_setleds
+
+/* *********************************************************************
+ * BOARD_EARLYINIT()
+ *
+ * Initialize board registers. This is the earliest
+ * time the BSP gets control. This routine cannot assume that
+ * memory is operational, and therefore all code in this routine
+ * must run from registers only. The $ra register must not
+ * be modified, as it contains the return address.
+ *
+ * This routine will be called from uncached space, before
+ * the caches are initialized. If you want to make
+ * subroutine calls from here, you must use the CALLKSEG1 macro.
+ *
+ * Among other things, this is where the GPIO registers get
+ * programmed to make on-board LEDs function, or other startup
+ * that has to be done before anything will work.
+ *
+ * Input parameters:
+ * a0 - Flash base address (address of MIPS reset)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(board_earlyinit)
+
+ .set noreorder
+
+ mfc0 t1, C0_BCM_CONFIG, 3
+ li t2, CP0_CMT_TPID
+ and t1, t2
+ bnez t1, 2f # if we are running on thread 1, skip init
+ nop
+
+#if 0
+ /* wait for a while to allow catch by jtag debugger */
+ li t8, -(200000000*3) /* we will count up to 0 to delay a couple of seconds */
+ /* and give the emulator a chance to catch us */
+ mtc0 t8, C0_COUNT
+catchloop:
+ bltz t8, catchloop
+ mfc0 t8, C0_COUNT
+#endif
+
+ /**--------------------------------------------------------------**/
+ /** platform specific code **/
+ /**--------------------------------------------------------------**/
+ /**----- Enable I Cache -----------------------------------------**/
+ mfc0 t1, C0_BCM_CONFIG
+ or t1, (CP0_BCM_CFG_ICSHEN | CP0_BCM_CFG_DCSHEN)
+ mtc0 t1, C0_BCM_CONFIG # Enable I Cache
+
+ // In the begining MIPS core registers are mapped to 0xbfax_xxxx
+ li t1, 0x1FA0000C # Set up CBR to 1FAx_xxxx
+ mtc0 t1, C0_BCM_CONFIG, 6
+
+ li t1, MIPS_BASE_BOOT
+ lw t2, MIPS_LMB_CR(t1)
+ or t2, 0xC0000000 # enable ffxx_xxxx space
+ sw t2, MIPS_LMB_CR(t1)
+ li t2, 0xFFF80001 # SBR FFF8_xxxx and enable
+ sw t2, MIPS_SBR(t1)
+
+ // Now map MIPS core registers to 0xFF4x_xxxx space
+ li t1, 0xFF40000C # CBR FF4x_xxxx (and reserved bits 0xc).
+ mtc0 t1, C0_BCM_CONFIG, 6
+
+ /**----- Initialize EBI -----------------------------------------**/
+ li t1, MPI_BASE
+ li t2, EBI_SIZE_32M
+ or t2, a0
+ sw t2, CS0BASE(t1) # CS[0] Base
+ li t2, THREEWT|EBI_WORD_WIDE|EBI_ENABLE
+ sw t2, CS0CNTL(t1) # CS[0] Control
+
+ /**----- Initialize Serial --------------------------------------**/
+ li t3, ((FPERIPH / 115200) / 16)
+ /*
+ # Baudword = (FPeriph)/Baud/32-1. We have to perform rounding
+ # and subtraction. Above we divided by 16 (instead of 32). If
+ # bit0 is set, we round up. However, we then subtract 1, so final
+ # result should be t3/2. If bit0 is 0, then we truncate and subtract
+ # 1, t3=t3/2-1.
+ */
+ andi t0, t3, 0x1
+ bne t0,zero,1f # do shift only (in delay slot)
+ # and jump to apply
+ srl t3,1 # do divide by 2
+ addiu t3, -1 # subtract 1
+1:
+
+ # t3 contains the UART BAUDWORD
+ li t0, UART_BASE
+ sw t3, UART0BAUD(t0) # Store BaudRate
+ li t1, BITS8SYM|ONESTOP
+ sb t1, UART0CONFIG(t0) # 8 Bits/1 Stop
+ li t1, TXEN|RXEN|BRGEN
+ sb t1, UART0CONTROL(t0) # Enable, No Parity
+ move t1, zero
+ sh t1, UART0INTMASK(t0)
+
+ .set reorder
+2:
+ j ra
+END(board_earlyinit)
+
+/* *********************************************************************
+ * BOARD_DRAMINFO
+ *
+ * Return the address of the DRAM information table
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - DRAM info table, return 0 to use default table
+ ********************************************************************* */
+LEAF(board_draminfo)
+ j ra
+END(board_draminfo)
+
+/* *********************************************************************
+ * BOARD_DRAMINIT
+ *
+ * This routine should activate memory.
+ *
+ * Input parameters:
+ * None
+ *
+ * Return value:
+ * None
+ *
+ * Registers used:
+ * can use all registers.
+ ********************************************************************* */
+LEAF(board_draminit)
+ .set noreorder
+
+ li t0, MEMC_BASE
+ li t1, DDR_BASE
+
+ li t4, (7 << 28) | (7 << 24) | (1 << 20) | (7 << 16) # UBUS_CNTR_CYCLES = 7, LLMB_CNTR_CYCLES = 7, PH_CNTR_EN = 1, PH_CNTR_CYCLES = 7
+ sw t4, DDR_MIPS_PHASE_CNTL(t1)
+
+ # Calculate a value for a 90 degree phase shift.
+
+ lw t2, DDR_MIPSDDR_PLL_MDIV(t1)
+ srl t2, 8 # Shift and mask off DDR_MDIV
+ and t2, 0xff
+ sll t2, 2 # PI_steps = (90deg * 16 * MBUS(t2) + 2)/360 ~= MBUS * 4
+ or t2, (1 << 14) # set the count direction
+
+ lw t3, DDR_DDR3_4_PHASE_CNTL(t1) # Get current DDR3/4 value.
+ ori t3, 0x7fff # Clear low 15 bits (DDR3 value).
+ xori t3, 0x7fff
+ or t3, t2 # Set new DDR3 value, preserving existing DDR4 value.
+ sw t3, DDR_DDR3_4_PHASE_CNTL(t1)
+
+ li t4, (1 << 28) | (7 << 24) | (1 << 23) | (1 << 20) | (7 << 16) # UBUS_CNTR_CYCLES = 1, LLMB_CNTR_CYCLES = 7, UBUS_CNTR_EN = 1, PH_CNTR_EN = 1, PH_CNTR_CYCLES = 7
+ sw t4, DDR_MIPS_PHASE_CNTL(t1)
+
+ li t4, 0x103e
+ sw t4, DDR_UBUS_PI_DSK1(t1)
+ li t4, 0x40000000
+ sw t4, DDR_UBUS_PI_DSK0(t1)
+
+ ## Set PI mask, and frequnecy of updates
+ # bit[5:0] 1 to 31, controls how often feedback is send back to PI
+ # bit[7] update register in sampling logic to take the new value in bit[5:0]
+ # bit[14:8] masking bits for the sampling result
+
+ li t2, 0x00000010 # 0x8 for 8 DDR cycles, 0x10 for 16 DDR cycles, 0x4 for 4 DDR cycles, can take values from 1 to 31
+ sw t2, DDR_UBUS_PI_DSK0(t1) # set PI update to 16 ddr cycles
+ li t2, 0x00000090 # update value
+ sw t2, DDR_UBUS_PI_DSK0(t1)
+ li t2, 0x00000c90 # set mask to 0001100; 0x1890 will set mask to 0011000
+ sw t2, DDR_UBUS_PI_DSK0(t1)
+
+ ###### Check to see if we found the edge...
+ ###### Ideally we want to loop here until we find an edge....
+
+ li t3, 0
+ li t2, 10000
+
+1:
+ # Looking for a rising edge.
+ lw t4, DDR_UBUS_PI_DSK0(t1) # Read a sample value.
+ srl t4, 16 # The sample is in the upper 16 bits.
+ andi t4, 0x41 # Look at the 2 outermost bits; if the LSB is 0 and the MSB is 1,
+ beq t4, 0x40, 2f # then there is an edge somewhere in the sample.
+
+ addi t3, 1
+ bne t2, t3, 1b
+ nop
+
+2:
+
+ /**----- Configure DDR controller ------------------------------------**/
+ li v0, 16
+ li t2, ((MEMC_12BIT_ROW << MEMC_ROW_SHFT) | (MEMC_9BIT_COL << MEMC_COL_SHFT))
+ or t2, (MEMC_16BIT_BUS << MEMC_WIDTH_SHFT)
+ or t2, (MEMC_SEL_PRIORITY)
+ or t2, (2 << MEMC_EARLY_HDR_CNT_SHFT)
+ or t2, (MEMC_USE_HDR_CNT)
+// or t2, (MEMC_EN_FAST_REPLY)
+ or t2, (MEMC_RR_ARB)
+ or t2, (MEMC_DQS_GATE_EN | MEMC_MEMTYPE_DDR)
+ sw t2, MEMC_CONFIG(t0) # Enable DDR Mem & SEQ EN, 16MB
+
+ li t2, 0x7 # Reduce drive strength for command pins (per John Lorek)
+ sw t2, DDR_CMD_PAD_CNTL(t1)
+
+ li t2, 0x00A778DD
+ sw t2, MEMC_DRAM_TIM(t0) # DDR Timing Set Latency 2.5 Latency,tRAS period =7,tRFC period=12, tWR=3
+ li t2, 0x00000003
+ sw t2, MEMC_CONTROL(t0) # Turn on CKE
+ li t2, 0x0000000B
+ sw t2, MEMC_CONTROL(t0) # PreCharge
+ li t2, 0x00004002
+ sw t2, MEMC_M_EM_BUF(t0) # Value for Extended Mode Register, DDR Reduced Drive Strength On
+ li t2, 0x00000013
+ sw t2, MEMC_CONTROL(t0) # MRS command
+ li t2, 0x00000163
+ sw t2, MEMC_M_EM_BUF(t0) # Reset DLL, Burst Length = 8, Burst Type Sequential 2.5 Latency
+ li t2, 0x00000013
+ sw t2, MEMC_CONTROL(t0) # MRS command
+ nop # Delay 200 DDR clock cycles (~1.5 uS)
+ nop
+ nop
+ li t2, 0x0000000B
+ sw t2, MEMC_CONTROL(t0) # Precharge
+ li t2, 0x0000840f
+ sw t2, MEMC_REF_PD_CONTROL(t0) # Enable auto refresh
+ li t2, 0x00000007
+ sw t2, MEMC_CONTROL(t0) # Set Auto Refresh Mode
+ li t2, 0x00000007
+ sw t2, MEMC_CONTROL(t0) # Set Auto Refresh Mode
+ li t2, 0x00000063
+ sw t2, MEMC_M_EM_BUF(t0) # Reset DLL, Burst Length = 8, Burst Type Sequential 2.5 Latency
+ li t2, 0x00000013
+ sw t2, MEMC_CONTROL(t0) # MRS
+
+ .set reorder
+
+ li sp, 0x80001000
+ sub sp, 8
+ sw ra, 0(sp)
+ sw v0, 4(sp)
+ bal sdramDqsPhaseSet
+ lw v0, 4(sp)
+ lw ra, 0(sp)
+ add sp, 8
+
+ /**----- switch to sync -----------------------------------------**/
+ li t0, 0xff410000
+ li t1, DDR_BASE
+ li t2, 4048
+ li t3, 1
+
+1:
+ lw t4, 0x40(t0) # Read a sample value.
+ srl t4, 16 # The sample is in the upper 16 bits.
+
+ andi t4, t4, 0x41 # Look at the 2 outermost bits; if the LSB is 0 and the MSB is 1,
+ beq t4, 0x40, 2f # then there is an edge somewhere in the sample.
+
+ lw t5, DDR_MIPS_PHASE_CNTL(t1)
+ and t5, 0xffff0000
+ or t5, t3
+ or t5, (1<<14)
+ sw t5, DDR_MIPS_PHASE_CNTL(t1)
+
+ lw t5, 0x40(t0) # Delay before reading another sample.
+ add t3, 1
+ bne t2, t3, 1b
+ b 3f
+
+2:
+ # Success
+ lw t2, DDR_MIPS_PHASE_CNTL(t1) # Turn on auto-PI mode.
+ and t2, 0xf0ffffff
+ or t2, (1 << 24) | (1 << 21) # LLMB_CNTR_CYCLES_CNTL = 1, LLMB_CNTR_EN = 1
+ sw t2, DDR_MIPS_PHASE_CNTL(t1)
+
+ li t2, 0x0010 # Set PI mask to 0000110, and check new value every 16 MIPS cycles.
+ sw t2, 0x40(t0) # set PI update to 16 ddr cycles
+ li t2, 0x80000090 # Enable MIPS auto-PI | Enable update period | Set 16 clock update
+ sw t2, 0x40(t0)
+ li t2, 0x80000c90 # Enable MIPS auto-PI | Enable comparator | Enable update period | Set 16 clock update
+ sw t2, 0x40(t0)
+
+ lw t2, 0x40(t0) # Do a few reads to wait till the edge is stable...
+ lw t2, 0x40(t0)
+ lw t2, 0x40(t0)
+ lw t2, 0x40(t0)
+ lw t2, 0x40(t0)
+
+ mfc0 t1, C0_BCM_CONFIG, 5
+ and t1, ~(0x1 << 28)
+ mtc0 t1, C0_BCM_CONFIG, 5
+
+ /**----- Enable RAC and LMB -------------------------------------**/
+ li t1, MIPS_BASE
+ lw t2, MIPS_LMB_CR(t1)
+ or t2, LMB_EN # Enable LMB
+ sw t2, MIPS_LMB_CR(t1)
+
+ li t2, 0xFFF << RAC_UPB_SHFT # Enable prefetch for RAM address range up to 256MB
+ sw t2, MIPS_RAC_ARR(t1)
+
+ lw t2, MIPS_RAC_CR0(t1)
+ or t2, (RAC_C_INV | RAC_I | RAC_PF_I)
+ sw t2, MIPS_RAC_CR0(t1)
+
+ lw t2, MIPS_RAC_CR1(t1)
+ or t2, (RAC_C_INV | RAC_I | RAC_PF_I)
+ sw t2, MIPS_RAC_CR1(t1)
+
+3:
+ /**----- Enable branch prediction and non-blocking data cache ---**/
+ mfc0 t1, C0_BCM_CONFIG
+ and t1, ~CP0_BCM_CFG_BTHD
+ or t1, CP0_BCM_CFG_NBK
+ or t1, CP0_BCM_CFG_CLF
+ mtc0 t1, C0_BCM_CONFIG
+
+ /* Test whether memory is 16 or 32 bit wide */
+ li t0, MEMC_BASE
+ lw t2, MEMC_CONFIG(t0)
+ and t2, ~MEMC_WIDTH_MASK
+ or t2, (MEMC_32BIT_BUS << MEMC_WIDTH_SHFT)
+ sw t2, MEMC_CONFIG(t0)
+
+ li t3, DRAM_BASE_NOCACHE
+ li t4, 0x12345678
+ sw t4, 0(t3)
+ li t4, 0x87654321
+ sw t4, 4(t3)
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ li t4, 0x12345678
+ lw t5, 0(t3)
+ beq t4, t5, 4f
+
+ /* 16 bit wide memory */
+ lw t2, MEMC_CONFIG(t0)
+ and t2, ~MEMC_WIDTH_MASK
+ or t2, (MEMC_16BIT_BUS << MEMC_WIDTH_SHFT)
+ sw t2, MEMC_CONFIG(t0)
+4:
+ j ra
+
+END(board_draminit)
+
+/* *********************************************************************
+ * BOARD_SETLEDS(x)
+ *
+ * Set LEDs for boot-time progress indication. Not used if
+ * the board does not have progress LEDs. This routine
+ * must not call any other routines, since it may be invoked
+ * either from KSEG0 or KSEG1 and it may be invoked
+ * whether or not the icache is operational.
+ *
+ * Input parameters:
+ * a0 - LED value (8 bits per character, 4 characters)
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2,t3
+ ********************************************************************* */
+LEAF(board_setleds)
+#if 0
+ li t0, UART_BASE
+ li t2, TXFIFOEMT
+
+1: lh t1, UART0INTSTAT(t0)
+ and t1, t2
+ bne t1, t2, 1b
+
+ srl t3, a0, 24
+ sb t3, UART0DATA(t0)
+ srl t3, a0, 16
+ sb t3, UART0DATA(t0)
+ srl t3, a0, 8
+ sb t3, UART0DATA(t0)
+ sb a0, UART0DATA(t0)
+ li a0, '\r'
+ sb a0, UART0DATA(t0)
+ li a0, '\n'
+ sb a0, UART0DATA(t0)
+#endif
+ j ra
+END(board_setleds)
+
+/* *********************************************************************
+ * BCMCORE_TP1_SWITCH()
+ *
+ * Check if the thread switch is required. If we are already
+ * running on thread 1 this function will do nothing and just return
+ * If we are running on thread 0 this function will take thread 1
+ * out of reset and put thread 0 to sleep waiting for singnal from
+ * thread 1.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+LEAF(bcmcore_tp1_switch)
+
+ mfc0 t1, C0_BCM_CONFIG, 3
+ li t2, CP0_CMT_TPID
+ and t1, t2
+ bnez t1, tp1 # Already running on thread 1
+
+# Start TP1
+# Set boot address for TP1
+ li t1, MIPS_BASE
+ li t2, 0x98000000 | ENABLE_ALT_BV
+ sw t2, MIPS_TP1_ALT_BV(t1)
+
+# Set a flag so we can wait for TP1 to catch up
+ li t1, 0x0
+ mtc0 t1, $31 # CO_DESAVE
+
+# Take TP1 out of reset
+ mfc0 t1, C0_BCM_CONFIG, 2
+ or t1, CP0_CMT_RSTSE
+ mtc0 t1, C0_BCM_CONFIG, 2
+
+ /* wait until second thread catches up with the first */
+waittp1:
+ mfc0 t0, $31 # CO_DESAVE
+ beqz t0, waittp1
+
+ li t0, THREAD_NUM_ADDRESS
+ FIXUP(t0)
+ lw t0, 0(t0)
+ li t1, 1
+ bne t0, t1, return # Linux will run on TP0, continue running bootloader
+
+# Voice will run on TP0. Set it up and put it to sleep
+
+ # enable interrupts and enable SW IRQ 0
+ li t0, M_SR_IE | M_SR_IBIT1
+ mtc0 t0, C0_SR
+
+ # Set up to use alternate exception vector 0x80000200
+ li t0, M_CAUSE_IV
+ mtc0 t0, C0_CAUSE
+
+ mfc0 t1, C0_BCM_CONFIG, 1
+ # set all ints except IRQ1 to TP1 and cross over SW IRQ 0
+ or t1, (CP0_CMT_XIR_4 | CP0_CMT_XIR_3 | CP0_CMT_XIR_2 | CP0_CMT_XIR_0 | CP0_CMT_SIR_0 | CP0_CMT_NMIR_TP1)
+ mtc0 t1, C0_BCM_CONFIG, 1
+
+ mfc0 t1, C0_BCM_CONFIG, 2
+ # Set debug on TP1, give priority to TP0, and
+ # set TLB exception serialization to ignore SCNT value in CP0 reg22 sel 4
+ and t1, ~CP0_CMT_TPS_MASK;
+ or t1, (CP0_CMT_DSU_TP1 | CP0_CMT_PRIO_TP0 | (1 << CP0_CMT_TPS_SHFT))
+ mtc0 t1, C0_BCM_CONFIG, 2
+
+ # Enable Data RAC on TP0
+ li t1, MIPS_BASE
+ lw t2, MIPS_RAC_CR0(t1)
+ or t2, (RAC_D | RAC_PF_D)
+ sw t2, MIPS_RAC_CR0(t1)
+
+2:
+ li t8, 0
+ b wait_for_wake
+
+tp1:
+# Running on TP1....
+# First signal to TP0 that TP1 is up
+ li t1, 0x1
+ mtc0 t1, $31 # CO_DESAVE
+
+ li t0, THREAD_NUM_ADDRESS
+ FIXUP(t0)
+ lw t0, 0(t0)
+ li t1, 1
+ beq t0, t1, return # Linux will run on TP1, continue running bootloader
+
+# Voice will run on TP1. Set it up and put it to sleep
+
+ # enable interrupts and enable SW IRQ 0
+ li t0, M_SR_IE | M_SR_IBIT1
+ mtc0 t0, C0_SR
+
+ # Set up to use alternate exception vector 0x80000200
+ li t0, M_CAUSE_IV
+ mtc0 t0, C0_CAUSE
+
+ mfc0 t1, C0_BCM_CONFIG, 1
+ # set IRQ1 to TP1 and cross over SW IRQ 0
+ or t1, (CP0_CMT_XIR_1 | CP0_CMT_SIR_0 | CP0_CMT_NMIR_TP0)
+ mtc0 t1, C0_BCM_CONFIG, 1
+
+ mfc0 t1, C0_BCM_CONFIG, 2
+ # Set debug on TP0, give priority to TP1, and
+ # set TLB exception serialization to ignore SCNT value in CP0 reg22 sel 4
+ and t1, ~CP0_CMT_TPS_MASK;
+ or t1, (CP0_CMT_PRIO_TP1 | (1 << CP0_CMT_TPS_SHFT))
+ mtc0 t1, C0_BCM_CONFIG, 2
+
+ # Enable Data RAC on TP1
+ li t1, MIPS_BASE
+ lw t2, MIPS_RAC_CR1(t1)
+ or t2, (RAC_D | RAC_PF_D)
+ sw t2, MIPS_RAC_CR1(t1)
+ b 2b
+
+return:
+ j ra
+
+END(bcmcore_tp1_switch)
+
+# align this code to cache line. NAND flash is not memory mapped after system boots
+# so when we are signaling to the second TP to wake we need
+# jal instruction to be in cache
+ .align 4
+LEAF(wait_for_wake)
+ sync
+ wait # wait for interrupt
+ jal t8 # jump to entry point
+END(wait_for_wake)
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_sdramDqs.c b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_sdramDqs.c
new file mode 100755
index 0000000..96d5000
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm6368_sdramDqs.c
@@ -0,0 +1,439 @@
+/***************************************************************************
+*
+* Copyright (c) 2004 Broadcom Corporation, All Rights Reserved.
+* Contains proprietary and confidential information.
+*
+* No portions of this material may be reproduced in any form without the
+* written permission of:
+*
+* Broadcom Corporation
+* 16215 Alton Parkway
+* P.O. Box 57013
+* Irvine, California 92619-7013
+*
+* All information contained in this document is Broadcom Corporation
+* company private, proprietary, and trade secret.
+*
+****************************************************************************/
+#include "lib_types.h"
+#include "bcm_map.h"
+
+// Uncomment out the below line to use MemoryTestSuite()
+// #define EXTENDED_MEMORY_TESTS
+
+/* ---- Private Constants and Types -------------------------------------- */
+#define VCDL_PHASE_DEFAULT 16
+#define VCDL_PHASE_MAX 47 /* 154.69 degree */
+#define VCDL_PHASE_MIN 0 /* 22.5 degree */
+
+typedef unsigned long u;
+
+#define N 32*1024 // Size of the copy operation
+ // Must be at least equal to the L2 cache size
+#define S (1*sizeof(u))
+
+/* ---- Private Function Prototypes -------------------------------------- */
+inline static int MemoryTest(void) __attribute__((always_inline));
+inline static void PI_upper_set(volatile uint32 *, int bitOffset, int shift) __attribute__((always_inline));
+inline static void PI_shmoo(volatile uint32 *PI_reg, int bitOffset, int minValue, int maxValue, int increment) __attribute__((always_inline));
+inline static void shmooVcdl(int minValue, int maxValue, int increment) __attribute__((always_inline));
+
+// #define DEBUG_SHMOO 1
+#if DEBUG_SHMOO
+inline static void dumpChar(uint8 c) __attribute__((always_inline));
+inline static void dumpChar(uint8 c)
+{
+ //wait till tx fifo below threshold
+ while (UART->txf_levl > 14);
+ UART->Data = c;
+}
+
+#else
+#define dumpChar(c)
+#endif
+
+#if defined(EXTENDED_MEMORY_TESTS)
+#include "memtest.c"/* Suite memory tests SCAN, MARCH, SLIDING, SHIFT ADDRESS */
+inline static int MemoryTestSuite(void) __attribute__((always_inline));
+#endif
+
+/* ==== Public Functions ================================================= */
+void sdramDqsPhaseSet(void);
+void vcdlCalibration(void);
+
+/*******************************************************************************/
+void sdramDqsPhaseSet(void)
+{
+ int dqOutPhaseMax;
+ int delay;
+ int ubusPhase, mipsPhase;
+ int equalCount = 0;
+
+ // Reset VCDL
+ DDR->Spare1 |= 0x1;
+ delay = 1000;
+ while(delay--);
+ DDR->Spare1 &= ~0x1;
+
+ // Calculate max phase offset from PLL config register.
+ dqOutPhaseMax = ((DDR->MIPSDDRPLLMDiv & DDR_MDIV_MASK) >> DDR_MDIV_SHFT) * 8;
+
+ dumpChar('\n');
+ dumpChar('\r');
+
+ // Start by setting VCDL to the default. This almost always works.
+ // Enable squelch
+ DDR->WSliceCntl |= (0x1<<20) | (0x1<<4);
+ DDR->VCDLPhaseCntl0 = (VCDL_PHASE_DEFAULT << 22) | (VCDL_PHASE_DEFAULT << 16) | (VCDL_PHASE_DEFAULT << 6) | VCDL_PHASE_DEFAULT;
+ DDR->VCDLPhaseCntl1 = (VCDL_PHASE_DEFAULT << 22) | (VCDL_PHASE_DEFAULT << 16) | (VCDL_PHASE_DEFAULT << 6) | VCDL_PHASE_DEFAULT;
+ DDR->WSliceCntl &= ~((0x1<<20) | (0x1<<4));
+
+ // Now shmoo over DQ phase to find an optimum value.
+ dumpChar('D');dumpChar('D');dumpChar('R');dumpChar('2');
+ dumpChar('\n');
+ dumpChar('\r');
+ PI_shmoo(&DDR->DDR1_2PhaseCntl0, 16, -dqOutPhaseMax, dqOutPhaseMax, 1);
+
+ dumpChar('V');dumpChar('C');dumpChar('D');dumpChar('L');
+ dumpChar('\n');
+ dumpChar('\r');
+ shmooVcdl(VCDL_PHASE_MIN, VCDL_PHASE_MAX, 1);
+
+ // Now setup the UBUS clock
+ dumpChar('U');dumpChar('B');dumpChar('U');dumpChar('S');
+ dumpChar('\n');
+ dumpChar('\r');
+
+ MEMC->RefreshPdControl &= ~MEMC_REFRESH_ENABLE; // Turn off refresh while messing with UBus clock
+
+ DDR->MIPSPhaseCntl &= ~(0x1<<23); // turn off ubus PI auto mode
+
+ mipsPhase = DDR->MIPSPhaseCntl;
+ do {
+ if (DDR->MIPSPhaseCntl == mipsPhase)
+ equalCount++;
+ else {
+ equalCount = 0;
+ mipsPhase = DDR->MIPSPhaseCntl;
+ }
+ } while (equalCount < 3);
+
+ ubusPhase = ((DDR->UBUSPhaseCntl) & 0x3ffe); // make it even and decrease count
+ DDR->UBUSPhaseCntl = ubusPhase;
+
+ // Wait until we match several times in a row, to be sure we wait long enough
+ do {
+ if (DDR->UBUSPhaseCntl == ubusPhase)
+ equalCount++;
+ else
+ equalCount = 0;
+ } while (equalCount < 3);
+
+ MEMC->RefreshPdControl |= MEMC_REFRESH_ENABLE;
+}
+
+
+/* ==== Private Functions ================================================ */
+
+inline static void PI_upper_set(volatile uint32 *PI_reg, int bitOffset, int shift)
+{
+ uint32 oldVal;
+ uint32 newVal;
+ int32 oldPhase;
+ int32 newPhase;
+ int equalCount = 0;
+
+ oldVal = *PI_reg; // get the phase config (may have other controls in other 16 bits)
+
+ oldPhase = ( oldVal >> bitOffset ) & 0x3fff;
+ if ( oldPhase & (0x1<<13) ) {
+ oldPhase |= ~0x3fff; // sign extend
+ }
+
+ newPhase = shift & 0x3fff; // set up phase shift value[13:0]
+ if (shift > oldPhase) { // set up up/down [14], shift is signed value
+ newPhase |= 0x1<<14;
+ }
+
+ newPhase = newPhase << bitOffset;
+ oldVal = oldVal & (0xffff << (16-bitOffset)); // Keep the other control bits
+ newVal = newPhase | oldVal;
+ *PI_reg = newVal;
+
+ // Wait until we match several times in a row, to be sure we wait long enough
+ do {
+ if (*PI_reg == newVal)
+ equalCount++;
+ else
+ equalCount = 0;
+ } while (equalCount < 3);
+}
+
+
+inline static void PI_shmoo(volatile uint32 *PI_reg, int bitOffset, int minValue, int maxValue, int increment)
+{
+ int piPhase, piPhaseCnt, passStatus;
+ int pass1Start, pass1Fail, pass2Start, pass2Fail;
+ int pass1Cnt, pass2Cnt;
+
+ PI_upper_set(PI_reg, bitOffset, minValue);
+
+ passStatus = 0;
+ pass1Start = maxValue;
+ pass1Fail = minValue;
+ pass2Start = minValue;
+ pass2Fail = minValue;
+
+ for (piPhase = minValue; piPhase <= maxValue; piPhase += increment) {
+
+ // if (MemoryTestSuite())
+ if (MemoryTest())
+ {
+ if (passStatus == 0x0) { // first_pass start
+ passStatus = 0x1;
+ pass1Start = piPhase;
+ }
+ else if (passStatus == 0x2) { // second_pass start
+ passStatus = 0x3;
+ pass2Start = piPhase;
+ }
+ dumpChar('p');
+ }
+ else {
+ if (passStatus == 0x1) { // fisrt_pass end
+ passStatus = 0x2;
+ pass1Fail = piPhase;
+ }
+ else if (passStatus == 0x3) { // second_pass end
+ passStatus = 0x4;
+ pass2Fail = piPhase;
+ }
+ dumpChar('.');
+ }
+
+ piPhaseCnt = ( piPhase + 0x01) & 0x3fff;
+ if (increment) {
+ piPhaseCnt |= (0x01<<14);
+ }
+
+ *PI_reg = (*PI_reg & (0xffff << (16-bitOffset))) | (piPhaseCnt<<bitOffset);
+
+ }
+
+ // Figure out the middle point of the pass window
+ // valid window 1 -- .......PPPPPPPPPPPPPP.......
+ // valid window 2 -- PPPPPPP........PPPPPPPPPPPPP
+
+ if ((pass1Start != maxValue) && (pass2Start == minValue)) { // valid window 1
+ if (pass1Fail == minValue) {
+ piPhaseCnt = (pass1Start + maxValue) >> 1; // mid-point of the pass window
+ } else {
+ piPhaseCnt = (pass1Start + pass1Fail - 0x1) >> 1; // mid-point of the pass window
+ }
+ }
+ else if ((pass1Start == minValue) && (pass2Start != minValue) && (pass2Fail == minValue)) { // valid window 2
+ pass1Cnt = pass1Fail - minValue;
+ pass2Cnt = maxValue - pass2Start + 1;
+ passStatus= (pass1Cnt + pass2Cnt) >> 1;
+ if (passStatus < pass1Cnt) { // mid-point of the overall pass window is in sub-window 1
+ piPhaseCnt = minValue + ( pass1Cnt - passStatus );
+ }
+ else {
+ piPhaseCnt = pass2Start - 0x1 + passStatus;
+ }
+ }
+ else {
+ piPhaseCnt = 0x0; // shmoo failed.
+ }
+
+ piPhaseCnt &= ~0x01; // make it even number
+
+ PI_upper_set(PI_reg, bitOffset, piPhaseCnt); // set the final phase value
+
+ dumpChar('\n');
+ dumpChar('\r');
+}
+
+
+inline static void shmooVcdl(int minValue, int maxValue, int increment)
+{
+ UINT32 dqsInPhase;
+ UINT32 dqsInSum = 0;
+ UINT32 passCnt = 0;
+ volatile int delay;
+
+ for (dqsInPhase = minValue; dqsInPhase <= maxValue; dqsInPhase += increment) {
+ delay = 1000;
+ while(delay--);
+ // Enable squelch
+ DDR->WSliceCntl |= (0x1<<20) | (0x1<<4);
+ DDR->VCDLPhaseCntl0 = (dqsInPhase << 22) | (dqsInPhase << 16) | (dqsInPhase << 6) | dqsInPhase;
+ DDR->VCDLPhaseCntl1 = (dqsInPhase << 22) | (dqsInPhase << 16) | (dqsInPhase << 6) | dqsInPhase;
+ DDR->WSliceCntl &= ~((0x1<<20) | (0x1<<4));
+
+ delay = 1000;
+ while(delay--);
+
+#if defined(EXTENDED_MEMORY_TESTS)
+ if (MemoryTestSuite() == MEMTEST_SUCCESS )
+#else
+ if (MemoryTest())
+#endif
+ {
+ dqsInSum += dqsInPhase;
+ passCnt++;
+ dumpChar('p');
+ }
+ else {
+ dumpChar('.');
+ }
+ }
+ delay = 1000;
+ while(delay--);
+ // Enable squelch
+ DDR->WSliceCntl |= (0x1<<20) | (0x1<<4);
+ if (passCnt > 0) {
+ dqsInPhase = dqsInSum / passCnt;
+ DDR->VCDLPhaseCntl0 = (dqsInPhase << 22) | (dqsInPhase << 16) | (dqsInPhase << 6) | dqsInPhase;
+ DDR->VCDLPhaseCntl1 = (dqsInPhase << 22) | (dqsInPhase << 16) | (dqsInPhase << 6) | dqsInPhase;
+ }
+ else {
+ DDR->VCDLPhaseCntl0 = (VCDL_PHASE_DEFAULT << 22) | (VCDL_PHASE_DEFAULT << 16) | (VCDL_PHASE_DEFAULT << 6) | VCDL_PHASE_DEFAULT;
+ DDR->VCDLPhaseCntl1 = (VCDL_PHASE_DEFAULT << 22) | (VCDL_PHASE_DEFAULT << 16) | (VCDL_PHASE_DEFAULT << 6) | VCDL_PHASE_DEFAULT;
+ }
+ DDR->WSliceCntl &= ~((0x1<<20) | (0x1<<4));
+ dumpChar('\n');
+ dumpChar('\r');
+}
+
+#if defined(EXTENDED_MEMORY_TESTS)
+
+// Define the memory size for use by the memory test suite
+#define MEMORY_SIZE (2 * 1024)
+
+int MemoryTestSuite(void)
+{
+ int test = 1;
+ uint32_t * memory = (uint32_t*) (0xa0000000);
+ Pattern_t pat32, patIx;
+
+ for (patIx = PATTERN_0x00000000; patIx < PATTERN_MAX; patIx++ )
+ {
+ pat32 = pattern[ patIx ];
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( scanWordValue( memory, MEMORY_SIZE, pat32 ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( scanBulkValue( memory, MEMORY_SIZE, pat32 ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( scanBulkAltInv( memory, MEMORY_SIZE, pat32 ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( slidingAltInv( memory, MEMORY_SIZE, pat32 ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( slidingDiag( memory, MEMORY_SIZE, pat32 ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+ }
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( scanWordSelf( memory, MEMORY_SIZE ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+
+ fill_memory( memory, MEMORY_SIZE, 0x0 );
+ if ( scanBulkSelf( memory, MEMORY_SIZE ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ test++;
+
+ fill_alt_memory( memory, MEMORY_SIZE, 0XAAAAAAAA, 0x55555555 );
+ if ( memoryBulkCopy( memory, (memory + ((MEMORY_SIZE/2)/sizeof(uint32_t))),
+ MEMORY_SIZE/2 ) == MEMTEST_FAILURE )
+ goto exit_tests;
+
+ // return tests;
+ return MEMTEST_SUCCESS;
+
+exit_tests:
+ return MEMTEST_FAILURE;
+
+}
+#endif /* defined(EXTENDED_MEMORY_TESTS) */
+
+//
+// Returns: 0=FAILURE, 1=SUCCESS
+inline static int MemoryTest(void)
+{
+ // Test 32-bit write/read
+ volatile uint32 *memAddr;
+ uint32 memBase;
+ uint32 testValue;
+ int i;
+ int j;
+ int k;
+
+ memBase = 0xa0000000;
+ for (i = 2; i < 24; i++) {
+ memAddr = (void *) (memBase + (1 << i));
+ for (k = 0; k < 2; k++) {
+ /* walking one */
+ testValue = 1;
+ for (j = 0; j < 32; j++) {
+ *memAddr = testValue;
+ if (*memAddr != testValue)
+ return 0;
+
+ testValue <<= 1;
+ }
+ /* walking zero */
+ testValue = ~1;
+ for (j = 0; j < 32; j++) {
+ *memAddr = testValue;
+ if (*memAddr != testValue)
+ return 0;
+
+ testValue = (testValue << 1) | 1;
+ }
+ /* shift in zeroes */
+ testValue = -1;
+ for (j = 0; j < 32; j++) {
+ *memAddr = testValue;
+ *(uint32*)memBase = 0;
+ if (*memAddr != testValue)
+ return 0;
+
+ testValue <<= 1;
+ }
+ /* shift in ones */
+ testValue = 1;
+ for (j = 0; j < 32; j++) {
+ *memAddr = testValue;
+ *(uint32*)memBase = 0;
+ if (*memAddr != testValue)
+ return 0;
+
+ testValue = (testValue << 1) | 1;
+ }
+ }
+ }
+ return 1;
+}
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_impl1_rom_boot.S b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_impl1_rom_boot.S
new file mode 100755
index 0000000..b3986ed
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_impl1_rom_boot.S
@@ -0,0 +1,1818 @@
+#include "sbmips.h"
+#include "bsp_config.h"
+
+#include "bcm_cpu.h"
+#include "bcm_common.h"
+
+#include "bcm_hwdefs.h"
+#include "boardparms.h"
+#include "mipsmacros.h"
+
+#define DDR_TEST 1
+#define UBUS_SYNC_ENABLE 1
+#define LMB_SYNC_ENABLE 1
+#define MIPS_SYNC_ENABLE 1
+#define LMB_ENABLE 1
+
+/* Memory mapping table for different size DRAMs (256Mb, 512Mb, 1Gb, 2Gb) */
+ .globl dram_map_table_x8
+dram_map_table_x8:
+ // 128Mb 64B Interleaving (x8 Mode) 32MB
+ // This is just a place holder. This memory does not exist
+ _LONG_ 0x0F0E0D0C, 0x13121110, 0x17161514, 0x00000018 // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0A090805, 0x0000000B, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00080706, 0x00000002, 0x00000055 // Bank CS_End Dramsize
+
+ // 256Mb 64B Interleaving (x8 Mode) 64MB
+ _LONG_ 0x100F0E0D, 0x14131211, 0x18171615, 0x00000019 // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0A090805, 0x00000C0B, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00000706, 0x00000004, 0x00000066 // Bank CS_End Dramsize
+
+ // 512Mb 64B Interleaving (x8 Mode) 128MB
+ _LONG_ 0x100F0E0D, 0x14131211, 0x18171615, 0x00001A19 // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0A090805, 0x00000C0B, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00000706, 0x00000008, 0x00000077 // Bank CS_End Dramsize
+
+ // 1Gb 64B Interleaving (x8 Mode) 256MB
+ _LONG_ 0x11100F0E, 0x15141312, 0x19181716, 0x00001B1A // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0B0A0905, 0x00000D0C, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00080706, 0x00000010, 0x00000088 // Bank CS_End Dramsize
+
+ .globl dram_map_table_x16
+dram_map_table_x16:
+ // 256Mb 64B Interleaving (x16 Mode) 32MB
+ _LONG_ 0x0F0E0D0C, 0x13121110, 0x17161514, 0x00000018 // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0A090805, 0x0000000B, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00000706, 0x00000002, 0x00000055 // Bank CS_End Dramsize
+
+ // 512Mb 64B Interleaving (x16 Mode) 64MB
+ _LONG_ 0x100F0E0D, 0x14131211, 0x18171615, 0x00000019 // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0A090805, 0x00000C0B, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00000706, 0x00000004, 0x00000066 // Bank CS_End Dramsize
+
+ // 1Gb 64B Interleaving (x16 Mode) 128MB
+ _LONG_ 0x11100F0E, 0x15141312, 0x19181716, 0x0000001A // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0B0A0905, 0x00000D0C, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00080706, 0x00000008, 0x00000077 // Bank CS_End Dramsize
+
+ // 2Gb 64B Interleaving (x16 Mode) 256MB
+ _LONG_ 0x11100F0E, 0x15141312, 0x19181716, 0x00001B1A // Row00_0 Row00_1 Row01_0 Row01_1
+ _LONG_ 0x04000000, 0x0B0A0905, 0x00000D0C, 0x00000000 // Col00_0 Col00_1 Col01_0 Col01_1
+ _LONG_ 0x00080706, 0x00000010, 0x00000088 // Bank CS_End Dramsize
+
+ .globl dram_tRefi_table
+dram_tRefi_table: /* Refresh Interval table for different Speed DRAMs (100-200, 300-333, 400) */
+ _LONG_ 0x16, 0x49, 0x5D // 100-200 300-333 400 (MHz)
+
+ .globl dram_tRFC_table
+dram_tRFC_table: /* tRFC table for different size & Speed DRAMs (256Mb, 512Mb, 1Gb)/(200, 333, 400) */
+// 200 333 400 (MHz)
+ _LONG_ 0xF, 0x19, 0x1E // 256Mb
+ _LONG_ 0x15, 0x23, 0x2A // 512Mb
+ _LONG_ 0x1A, 0x2B, 0x33 // 1Gb
+ _LONG_ 0x28, 0x42, 0x4F // 2Gb
+
+ .globl dram_timing_table
+dram_timing_table: /* */
+// tRCD tCL tWR tWL tRP tRRD tRC tFAW tW2R tR2W tR2R tAL tRTP tW2W
+// ---------------------------------------------------------------------
+ .byte 0x03,0x04,0x03,0x03,0x03,0x02,0x11,0x00,0x01,0x01,0x00,0x02,0x02,0x00,0x00,0x00 // 200MHz
+ .byte 0x05,0x05,0x05,0x04,0x05,0x04,0x13,0x00,0x02,0x01,0x00,0x04,0x03,0x00,0x00,0x00 // 300MHz
+ .byte 0x05,0x05,0x06,0x04,0x06,0x05,0x18,0x00,0x02,0x01,0x00,0x04,0x03,0x00,0x00,0x00 // 400MHz
+
+ .globl dram_sync_table
+dram_sync_table: /* Bit vector table for Ubus sync modes and Lmb sync modes */
+#if defined(_BCM96328_)
+ _LONG_ 0x8E10FFFF, 0x8A10FFFF, 0xEDC2FFFF // UBUS Sync , LMB Sync, Mips Sync
+#elif defined(_BCM96362_)
+ _LONG_ 0xFFBFBFBF, 0x6341C101, 0xE7E5E5E5 // UBUS Sync , LMB Sync, Mips Sync
+#elif defined(_BCM96816_)
+ _LONG_ 0xC03033B5, 0x80303095, 0xFF90FFFF // UBUS Sync , LMB Sync, Mips Sync
+#endif
+ .globl dram_speed_table
+dram_speed_table: /* Memory Speed Table for different clock strap values */
+ /* 0=200Mhz 1=333MHz 2=400MHz */
+#if defined(_BCM96328_)
+ .byte 0 // 0x0
+ .byte 0 // 0x1
+ .byte 0 // 0x2
+ .byte 0 // 0x3
+ .byte 0 // 0x4
+ .byte 0 // 0x5
+ .byte 0 // 0x6
+ .byte 0 // 0x7
+ .byte 0 // 0x8
+ .byte 0 // 0x9
+ .byte 0 // 0xa
+ .byte 0 // 0xb
+ .byte 0 // 0xc
+ .byte 0 // 0xd
+ .byte 0 // 0xe
+ .byte 0 // 0xf
+ .byte 0 // 0x10
+ .byte 0 // 0x11
+ .byte 0 // 0x12
+ .byte 0 // 0x13
+ .byte 0 // 0x14
+ .byte 0 // 0x15
+ .byte 2 // 0x16
+ .byte 2 // 0x17
+ .byte 0 // 0x18
+ .byte 0 // 0x19
+ .byte 0 // 0x1a
+ .byte 0 // 0x1b
+ .byte 0 // 0x1c
+ .byte 0 // 0x1d
+ .byte 0 // 0x1e
+ .byte 1 // 0x1f
+#elif defined(_BCM96362_)
+ .byte 1 // 0x0
+ .byte 2 // 0x1
+ .byte 0 // 0x2
+ .byte 1 // 0x3
+ .byte 0 // 0x4
+ .byte 2 // 0x5
+ .byte 2 // 0x6
+ .byte 1 // 0x7
+ .byte 1 // 0x8
+ .byte 2 // 0x9
+ .byte 0 // 0xa
+ .byte 1 // 0xb
+ .byte 0 // 0xc
+ .byte 2 // 0xd
+ .byte 2 // 0xe
+ .byte 1 // 0xf
+ .byte 1 // 0x10
+ .byte 2 // 0x11
+ .byte 0 // 0x12
+ .byte 1 // 0x13
+ .byte 0 // 0x14
+ .byte 1 // 0x15 // 267MHz. Need to change tREFI if this is used.
+ .byte 2 // 0x16
+ .byte 1 // 0x17
+ .byte 1 // 0x18
+ .byte 1 // 0x19
+ .byte 0 // 0x1a
+ .byte 1 // 0x1b
+ .byte 0 // 0x1c
+ .byte 0 // 0x1d
+ .byte 2 // 0x1e
+ .byte 1 // 0x1f
+#elif defined(_BCM96816_)
+ .byte 0 // 0x0
+ .byte 1 // 0x1
+ .byte 0 // 0x2
+ .byte 0 // 0x3
+ .byte 0 // 0x4
+ .byte 1 // 0x5
+ .byte 1 // 0x6
+ .byte 1 // 0x7
+ .byte 1 // 0x8
+ .byte 1 // 0x9
+ .byte 1 // 0xa
+ .byte 2 // 0xb
+ .byte 2 // 0xc
+ .byte 2 // 0xd
+ .byte 2 // 0xe
+ .byte 2 // 0xf
+ .byte 2 // 0x10
+ .byte 2 // 0x11
+ .byte 2 // 0x12
+ .byte 2 // 0x13
+ .byte 2 // 0x14
+ .byte 0 // 0x15
+ .byte 0 // 0x16
+ .byte 1 // 0x17
+ .byte 1 // 0x18
+ .byte 1 // 0x19
+ .byte 1 // 0x1a
+ .byte 1 // 0x1b
+ .byte 2 // 0x1c
+ .byte 2 // 0x1d
+ .byte 2 // 0x1e
+ .byte 2 // 0x1f
+#endif
+
+ .globl memc_ubus_ratio_table
+memc_ubus_ratio_table: /* Memory Speed Table for different clock strap values */
+#if defined(_BCM96328_)
+// 6328 Clock Speed Table
+ .byte 3 // 0x0
+ .byte 3 // 0x1
+ .byte 3 // 0x2
+ .byte 3 // 0x3
+ .byte 3 // 0x4
+ .byte 3 // 0x5
+ .byte 3 // 0x6
+ .byte 3 // 0x7
+ .byte 3 // 0x8
+ .byte 3 // 0x9
+ .byte 3 // 0xa
+ .byte 3 // 0xb
+ .byte 3 // 0xc
+ .byte 3 // 0xd
+ .byte 3 // 0xe
+ .byte 3 // 0xf
+ .byte 3 // 0x10
+ .byte 3 // 0x11
+ .byte 0xf // 0x12
+ .byte 0xf // 0x13
+ .byte 3 // 0x14
+ .byte 9 // 0x15
+ .byte 9 // 0x16
+ .byte 9 // 0x17
+ .byte 3 // 0x18
+ .byte 3 // 0x19
+ .byte 3 // 0x1a
+ .byte 3 // 0x1b
+ .byte 0xb // 0x1c
+ .byte 0xb // 0x1d
+ .byte 0xb // 0x1e
+ .byte 3 // 0x1f
+#elif defined(_BCM96362_)
+// 6362 Clock Speed Table
+ .byte 3 // 0x0
+ .byte 3 // 0x1
+ .byte 3 // 0x2
+ .byte 3 // 0x3
+ .byte 3 // 0x4
+ .byte 3 // 0x5
+ .byte 3 // 0x6
+ .byte 3 // 0x7
+ .byte 3 // 0x8
+ .byte 3 // 0x9
+ .byte 3 // 0xa
+ .byte 3 // 0xb
+ .byte 3 // 0xc
+ .byte 3 // 0xd
+ .byte 3 // 0xe
+ .byte 3 // 0xf
+ .byte 3 // 0x10
+ .byte 3 // 0x11
+ .byte 3 // 0x12
+ .byte 3 // 0x13
+ .byte 4 // 0x14
+ .byte 4 // 0x15
+ .byte 15 // 0x16
+ .byte 3 // 0x17
+ .byte 3 // 0x18
+ .byte 3 // 0x19
+ .byte 3 // 0x1a
+ .byte 3 // 0x1b
+ .byte 3 // 0x1c
+ .byte 3 // 0x1d
+ .byte 3 // 0x1e
+ .byte 3 // 0x1f
+#elif defined(_BCM96816_)
+// 6816 Clock Speed Table
+ .byte 3 // 0x0
+ .byte 9 // 0x1
+ .byte 3 // 0x2
+ .byte 4 // 0x3
+ .byte 3 // 0x4
+ .byte 3 // 0x5
+ .byte 9 // 0x6
+ .byte 3 // 0x7
+ .byte 3 // 0x8
+ .byte 3 // 0x9
+ .byte 2 // 0xa
+ .byte 4 // 0xb
+ .byte 2 // 0xc
+ .byte 3 // 0xd
+ .byte 4 // 0xe
+ .byte 9 // 0xf
+ .byte 1 // 0x10
+ .byte 1 // 0x11
+ .byte 1 // 0x12
+ .byte 1 // 0x13
+ .byte 3 // 0x14
+ .byte 3 // 0x15
+ .byte 4 // 0x16
+ .byte 9 // 0x17
+ .byte 6 // 0x18
+ .byte 2 // 0x19
+ .byte 6 // 0x1a
+ .byte 2 // 0x1b
+ .byte 4 // 0x1c
+ .byte 3 // 0x1d
+ .byte 4 // 0x1e
+ .byte 3 // 0x1f
+#endif
+
+#if defined(_BCM96816_)
+ .globl periph_fix_table
+periph_fix_table: // Periph Clock fix vector for different clock strap values
+ _LONG_ 0xAA30A047
+#endif
+
+#define SETLEDS1(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ bal board_setleds; \
+ nop
+
+/* *********************************************************************
+ * BOARD_EARLYINIT()
+ *
+ * Initialize board registers. This is the earliest
+ * time the BSP gets control. This routine cannot assume that
+ * memory is operational, and therefore all code in this routine
+ * must run from registers only. The $ra register must not
+ * be modified, as it contains the return address.
+ *
+ * This routine will be called from uncached space, before
+ * the caches are initialized. If you want to make
+ * subroutine calls from here, you must use the CALLKSEG1 macro.
+ *
+ * Among other things, this is where the GPIO registers get
+ * programmed to make on-board LEDs function, or other startup
+ * that has to be done before anything will work.
+ *
+ * Input parameters:
+ * a0 - Flash base address (address of MIPS reset)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(board_earlyinit)
+
+ .set noreorder
+
+ mfc0 t1, C0_BCM_CONFIG, 3
+ li t2, CP0_CMT_TPID
+ and t1, t2
+ bnez t1, 3f # if we are running on thread 1, skip init
+ nop
+
+ /**-------------------------------------------------------------**/
+ /** platform specific code **/
+ /**-------------------------------------------------------------**/
+
+#if defined(_BCM96816_)
+ /**----- Offset UBUS Clock 180 degrees -------------------------**/
+ li t2, MISC_BASE
+ lw t1, MISC_STRAP_BUS(t2)
+
+ srl t1, MISC_STRAP_BUS_MIPS_PLL_FVCO_SHIFT
+ andi t1, 0x1f // Mask out strap bits
+
+ move s0,ra
+ LOADREL(t2, periph_fix_table)
+ lw t2, 0(t2)
+ srl t2, t1
+ andi t2, 1
+ move ra,s0
+
+ beq t2, zero, 2f
+ nop
+
+ li t0, DDR_BASE
+ li t1, 0x00070000 // send new phase value to PLL every 8 cycles
+ sw t1, DDR_CTL_PI_UBUS_CTL(t0)
+ ori t1, 0x4080 // shift 128 steps in the positive direction to be 180 degree's offset VCO 1.6GHz
+ sw t1, DDR_CTL_PI_UBUS_CTL(t0)
+ li t1, 0x00000001
+ sw t1, DDR_CTL_PI_GCF(t0)
+
+ li t1, 0x10000 // delay
+1:
+ bnez t1, 1b
+ addi t1, -1
+
+2:
+ /**----- Set 1.2V and 2.5V Voltage regulators ------------------**/
+ li t1, GPIO_BASE
+ lw t2, GPIO_SWREG_CONFIG(t1)
+ and t2, ~GPIO_SW_VREG_SEL_MASK
+ or t2, (0x0 << GPIO_SW_VREG_SEL_SHIFT)
+ and t2, ~GPIO_LIN_VREG_ADJ_MASK
+ or t2, (0x0 << GPIO_LIN_VREG_ADJ_SHIFT)
+ sw t2, GPIO_SWREG_CONFIG(t1)
+
+ li t1, 0x10000
+1:
+ bnez t1, 1b
+ addi t1, -1
+#endif
+
+#if defined (_BCM96328_) || defined (_BCM96362_)
+ /* slow down mips clk (div 4) to unlock memory */
+ mfc0 t1, C0_BCM_CONFIG, 5
+ or t2, t1, 0x40000000
+ mtc0 t2, C0_BCM_CONFIG, 5
+ nop
+
+ mtc0 t1, C0_BCM_CONFIG, 5
+ nop
+#endif
+
+#if defined (_BCM96362_)
+ /* Adjust VREG frequency up by 50% to improve DSL performance */
+ li t2, MISC_BASE
+
+ /* First set ramp control */
+ lw t1, MISC_VREG_CONTROL0(t2)
+ or t1, (0x2 << MISC_VREG_CONTROL0_VREG_RAMP1P8_SHIFT) | (0x2 << MISC_VREG_CONTROL0_VREG_RAMP1P2_SHIFT)
+ sw t1, MISC_VREG_CONTROL0(t2)
+
+ /* wait 10ms for the setting to take effect */
+ li t8, -2000000
+ mtc0 t8, C0_COUNT
+1:
+ bltz t8, 1b
+ mfc0 t8, C0_COUNT
+
+ and t1, ~((0x7 << MISC_VREG_CONTROL0_VREG_RAMP1P8_SHIFT) | (0x7 << MISC_VREG_CONTROL0_VREG_RAMP1P2_SHIFT))
+ or t1, (0x3 << MISC_VREG_CONTROL0_VREG_ADJ_SHIFT)
+ sw t1, MISC_VREG_CONTROL0(t2)
+
+ /* Increase 2.5V regulator to provide increased range for 1.8V */
+ lw t1, MISC_VREG_CONTROL1(t2)
+ and t1, ~MISC_VREG_CONTROL1_VREG_ISEL2P5_MASK
+ or t1, (MISC_VREG_LDO_2P61 << MISC_VREG_CONTROL1_VREG_ISEL2P5_SHIFT)
+ sw t1, MISC_VREG_CONTROL1(t2)
+#endif
+
+#if 0
+ /* wait for a while to allow catch by jtag debugger */
+ li t8, -(200000000*3) /* we will count up to 0 to delay a couple of seconds */
+ /* and give the emulator a chance to catch us */
+ mtc0 t8, C0_COUNT
+catchloop:
+ bltz t8, catchloop
+ mfc0 t8, C0_COUNT
+#endif
+
+ /**----- Enable I Cache -----------------------------------------**/
+ mfc0 t1, C0_BCM_CONFIG
+ or t1, (CP0_BCM_CFG_ICSHEN | CP0_BCM_CFG_DCSHEN)
+ mtc0 t1, C0_BCM_CONFIG # Enable I Cache
+
+ // In the begining MIPS core registers are mapped to 0xbfax_xxxx
+ li t1, 0x1FA0000C # Set up CBR to 1FAx_xxxx
+ mtc0 t1, C0_BCM_CONFIG, 6
+
+ li t1, MIPS_BASE_BOOT
+ lw t2, MIPS_LMB_CR(t1)
+ or t2, 0xC0000000 # enable ffxx_xxxx space
+ sw t2, MIPS_LMB_CR(t1)
+ li t2, 0xFFF80001 # SBR FFF8_xxxx and enable
+ sw t2, MIPS_SBR(t1)
+
+ // Now map MIPS core registers to 0xFF4x_xxxx space
+ li t1, 0xFF40000C # CBR FF4x_xxxx (and reserved bits 0xc).
+ mtc0 t1, C0_BCM_CONFIG, 6
+
+#if defined(_BCM96816_)
+ /**----- Initialize EBI -----------------------------------------**/
+ li t1, MPI_BASE
+ li t2, EBI_SIZE_32M
+ or t2, a0
+ sw t2, CS0BASE(t1) # CS[0] Base
+ li t2, THREEWT|EBI_WORD_WIDE|EBI_ENABLE
+ sw t2, CS0CNTL(t1) # CS[0] Control
+#endif
+
+ /**----- Initialize Serial --------------------------------------**/
+ li t3, ((FPERIPH / 115200) / 16)
+ /*
+ # Baudword = (FPeriph)/Baud/32-1. We have to perform rounding
+ # and subtraction. Above we divided by 16 (instead of 32). If
+ # bit0 is set, we round up. However, we then subtract 1, so final
+ # result should be t3/2. If bit0 is 0, then we truncate and subtract
+ # 1, t3=t3/2-1.
+ */
+ andi t0, t3, 0x1
+ bne t0,zero,1f # do shift only (in delay slot)
+ # and jump to apply
+ srl t3,1 # do divide by 2
+ addiu t3, -1 # subtract 1
+1:
+
+ // t3 contains the UART BAUDWORD
+ li t0, UART_BASE
+ sw t3, UART0BAUD(t0) # Store BaudRate
+ li t1, BITS8SYM|ONESTOP
+ sb t1, UART0CONFIG(t0) # 8 Bits/1 Stop
+ li t1, TXEN|RXEN|BRGEN
+ sb t1, UART0CONTROL(t0) # Enable, No Parity
+ move t1, zero
+ sh t1, UART0INTMASK(t0)
+
+ .set reorder
+3:
+ j ra
+END(board_earlyinit)
+
+/* *********************************************************************
+ * BOARD_DRAMINFO
+ *
+ * Return the address of the DRAM information table
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - DRAM info table, return 0 to use default table
+ ********************************************************************* */
+LEAF(board_draminfo)
+ j ra
+END(board_draminfo)
+
+/* *********************************************************************
+ * BOARD_DRAMINIT
+ *
+ * This routine should activate memory.
+ *
+ * Input parameters:
+ * None
+ *
+ * Return value:
+ * None
+ *
+ * Registers used:
+ * can use all registers.
+ ********************************************************************* */
+LEAF(board_draminit)
+ .set noreorder
+
+ move s0,ra
+
+/***** Load DDR Base *************************************/
+ li t0, DDR_BASE
+
+/***** Disable Auto refresh ******************************/
+ li t1, 0x10000
+ sw t1, DDR_CTL_CLKS(t0)
+ SETLEDS1('-','-','-', '-')
+ SETLEDS1('P','H','Y','S')
+
+ li t1, 0x10 // Loop count value
+ li t3, 1
+
+zq_loop:
+ sub t1, t3 // Decrement count by 1
+ beq t1, zero, zq_error
+ nop
+
+ sw zero, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Reset the calibration engine
+ li t4, (1 << 26)
+ sw t4, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Start the calibration
+
+ li t2, 0x100 // Timeout value
+
+wait_zq1:
+ beq t2, zero, zq_timeout
+ nop
+
+ lw t4, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Read the calibration result
+ move t5, t4 // Save calibration result1
+ and t4, (1 << 28)
+ beq t4, zero, wait_zq1
+ sub t2, t3
+
+ sw zero, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Reset the calibration engine
+ li t4, (1 << 26)
+ sw t4, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Start the calibration
+
+ li t2, 0x100 // Timeout value
+
+wait_zq2:
+ beq t2, zero, zq_timeout
+ nop
+
+ lw t4, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Read the calibration result
+ move t6, t4 // Save calibration result1
+ and t4, (1 << 28)
+ beq t4, zero, wait_zq2
+ sub t2, t3
+
+ sw zero, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Reset the calibration engine
+ li t4, (1 << 26)
+ sw t4, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Start the calibration
+
+ li t2, 0x100 // Timeout value
+
+wait_zq3:
+ beq t2, zero, zq_timeout
+ nop
+
+ lw t4, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Read the calibration result
+ move t7, t4 // Save calibration result1
+ and t4, (1 << 28)
+ beq t4, zero, wait_zq3
+ sub t2, t3
+
+ bne t5, t6, zq_loop
+ nop
+ bne t5, t7, zq_loop
+ nop
+ bne t6, t7, zq_loop
+ nop
+
+ b zq_done;
+ nop
+
+zq_error:
+ SETLEDS1('Z','Q','E','R')
+ b zq_done
+ nop
+
+zq_timeout:
+ SETLEDS1('Z','Q','T','O')
+ nop
+zq_done:
+ sw zero, PHY_CONTROL_REGS_ZQ_PVT_COMP_CTL(t0) // Reset the calibration engine
+
+ SETLEDS1('Z','Q','D','N')
+ nop
+
+/****** Set control pad strength to half ********/
+ lw t2, PHY_CONTROL_REGS_DRIVE_PAD_CTL(t0)
+ or t2, 0x4
+ sw t2, PHY_CONTROL_REGS_DRIVE_PAD_CTL(t0)
+
+#if defined(_BCM96816_)
+/****** Disable byte lanes 2 and 3 ********/
+ li t1, 0x800fffff
+ sw t1, PHY_BYTE_LANE_2_IDLE_PAD_CONTROL(t0)
+ sw t1, PHY_BYTE_LANE_3_IDLE_PAD_CONTROL(t0)
+#endif
+
+/****** Disable byte lane 1 clock ********/
+ li t1, 1
+ sw t1, PHY_BYTE_LANE_1_CLOCK_PAD_DISABLE(t0)
+
+ddr_x8:
+
+/****** Change the slew and receiver power to full strength in the byte lanes ********/
+ li t1, 0xFFFFFFFC
+ lw t2, PHY_BYTE_LANE_0_DRIVE_PAD_CTL(t0)
+ and t2, t2, t1
+ sw t2, PHY_BYTE_LANE_0_DRIVE_PAD_CTL(t0)
+ lw t2, PHY_BYTE_LANE_1_DRIVE_PAD_CTL(t0)
+ and t2, t2, t1
+ sw t2, PHY_BYTE_LANE_1_DRIVE_PAD_CTL(t0)
+
+/****** Hardware calibrate VDL *******/
+ li t1, 3
+ sw t1, PHY_BYTE_LANE_0_VDL_CALIBRATE(t0)
+ sw t1, PHY_BYTE_LANE_1_VDL_CALIBRATE(t0)
+
+ li t1, 0x1000
+1:
+ bnez t1, 1b
+ addi t1, -1
+
+/****** Check strap value to figure out 400MHz or 200Mhz DDR ******/
+ li t2, MISC_BASE
+ lw t1, MISC_STRAP_BUS(t2)
+
+ srl t1, MISC_STRAP_BUS_MIPS_PLL_FVCO_SHIFT
+ andi t1, 0x1f // Mask out strap bits
+
+ LOADREL(t2, dram_speed_table)
+
+ add t2, t1
+ lb t1, 0x00(t2)
+ beq t1, zero, ddr_clk_200
+ li t2, 1
+ beq t1, t2, ddr_clk_300
+ nop
+
+/****** Software override rd_en VDL and ADDRESS VDL ********/
+ddr_clk_450:
+ddr_clk_400:
+ li a1, 2 // Set speed to 400MHz (2)
+ b 1f
+ nop
+ddr_clk_300:
+ li a1, 1 // Set speed to 300MHz (1)
+
+/* At higher frequencies set Read_en VDL value to calibrated VDL value + 10 */
+1: li t2, 0x10000
+ lw t1, PHY_BYTE_LANE_0_VDL_STATUS(t0)
+ srl t1, 8
+ addi t1, 0xA
+ or t1, t1, t2
+ sw t1, PHY_BYTE_LANE_0_VDL_OVERRIDE_2(t0)
+ lw t1, PHY_BYTE_LANE_1_VDL_STATUS(t0)
+ srl t1, 8
+ addi t1, 0xA
+ or t1, t1, t2
+ sw t1, PHY_BYTE_LANE_1_VDL_OVERRIDE_2(t0)
+ b vdl_override_cont
+ nop
+
+ddr_clk_200:
+ li a1, 0 // Set speed to 200MHz (0)
+ li t3, 0x1f // Set maximum VDL step size for 200MHz
+ b 1f
+ nop
+
+vdl_override_cont:
+ lw t2, PHY_BYTE_LANE_0_VDL_STATUS(t0)
+ andi t3, t2, 0x1f00
+ srl t3, 8
+ addi t3, t3, 0x4 // Add Stepsize 4
+
+1: li t1, 0x110000 // Enable & Force Override
+ or t1, t3 // Fine rise and fine fall are set to 0
+
+ sw t1, PHY_CONTROL_REGS_STATIC_VDL_OVERRIDE(t0)
+ li t1, 0x0c
+ sw t1, DDR_CTL_DCMD(t0) // Set VDL
+
+ SETLEDS1('P','H','Y','E')
+
+/* Program MC Timing Registers
+
+ Read each timing parameter based on the speed and then create the
+ timing registers and program them.
+*/
+ LOADREL(t2, dram_timing_table)
+
+ li t1, 0x10 // size of dram_timing_table element
+ mult t1, a1
+ mflo t1 // dram_timing_table offset
+ add t2, t1
+
+ move t3, zero
+ lb t1, 0x00(t2) // tRCD
+ andi t1, 0xf
+ move t3, t1
+ lb t1, 0x01(t2) // tCL
+ andi t1, 0xf
+
+ move t4, t1
+ and t4, 0x7 // Make sure that only 3 bits are written to DRAM's tCL field
+ sll t4, 20
+ sw t4, DDR_CTL_DMODE_0 (t0) // Write tCL to the MRS register holder
+
+ sll t1, 4
+ or t3, t1
+ lb t1, 0x02(t2) // tWR
+ andi t1, 0xf
+
+ // Here we create the MRS register values
+ move t4, t1
+ li t5, 1
+ subu t4, t5 // tWR written to DRAM is 1 less than real tWR value
+ andi t4, 0x7
+ sll t4, 25
+ li t5, 0x01030000 // Sequential burst mode, burst of 8, reset DLL
+ or t4, t5
+ lw t5, DDR_CTL_DMODE_0 (t0)
+ or t5, t4
+ sw t5, DDR_CTL_DMODE_0 (t0) // Add tWR to the MRS register holder
+
+ sll t1, 9
+ or t3, t1
+ lb t1, 0x03(t2) // tWL
+ andi t1, 0xf
+ sll t1, 12
+ or t3, t1
+ lb t1, 0x04(t2) // tRP
+ andi t1, 0xf
+ sll t1, 16
+ or t3, t1
+ lb t1, 0x05(t2) // tRRD
+ andi t1, 0xf
+ sll t1, 20
+ or t3, t1
+ lb t1, 0x06(t2) // tRC
+ andi t1, 0x1f
+ sll t1, 24 // tRCw
+ or t3, t1
+ sw t3, DDR_CTL_TIM1_0(t0) // Program TIM1_0 register
+
+ move t3, zero
+ lb t1, 0x06(t2) // tRC
+ andi t1, 0x1f
+ or t3, t1 // tRCr
+ lb t1, 0x07(t2) // tFAW
+ andi t1, 0x3f
+ sll t1, 8
+ or t3, t1
+ li t1, 0xff // tRFC = 0xff (Set to max value first.
+ sll t1, 16 // We'll fix it after we determine dram size)
+ or t3, t1
+
+ // We skip tFIFO since it needs to be 0
+
+ lb t1, 0x08(t2) // tW2R
+ andi t1, 0x3
+ sll t1, 26
+ or t3, t1
+ lb t1, 0x09(t2) // tR2W
+ andi t1, 0x3
+ sll t1, 28
+ or t3, t1
+ lb t1, 0x0a(t2) // tR2R
+ andi t1, 0x1
+ sll t1, 30
+ or t3, t1
+ sw t3, DDR_CTL_TIM1_1(t0) // Program TIM1_1 register
+
+ move t3, zero
+ lb t1, 0x0b(t2) // tAL
+ andi t1, 0xf
+
+ // Here we create the EMRS register values
+ move t4, t1
+ andi t4, 0x7
+ sll t4, 3
+ li t5, 0x384 // RTT=75ohm, OCD Enter
+ or t4, t5
+ lw t5, DDR_CTL_DMODE_0 (t0)
+ or t5, t4
+ sw t5, DDR_CTL_DMODE_0 (t0) // Store required values in EMRS holding register
+
+ or t3, t1
+ lb t1, 0x0c(t2) // tRTP
+ andi t1, 0x7
+ sll t1, 4
+ or t3, t1
+ lb t1, 0x0d(t2) // tW2W
+ andi t1, 0x3
+ sll t1, 8
+ or t3, t1
+ sw t3, DDR_CTL_TIM2(t0) // Program TIM2 register
+
+/*
+// (tRRD is incremented by 1 due to tFAW bug for >=1Gb devices)
+ li t1, 0x18564c55 // tRCD=5,tWR=6,tCL=5,tWL=4,tRP=6,tRRD=5,tRCw=0x18
+// li t1, 0x13554a55 // tRCD=5,tWR=5,tCL=5,tWL=4,tRP=5,tRRD=5,tRCw=0x13
+ sw t1, DDR_CTL_TIM1_0(t0)
+ li t1, 0x18330018 // tR2W=1,tR2R=0,tW2R=2,tFIFO=0,tRFC=0x33,tFAW=0,tRCr=0x18
+// li t1, 0x182b0013 // tR2W=1,tR2R=0,tW2R=2,tFIFO=0,tRFC=0x2b,tFAW=0,tRCr=0x13
+ sw t1, DDR_CTL_TIM1_1(t0)
+ li t1, 0x00000034 // tAL=4 (tRCD-1), tRTP=3, tW2W=0
+ sw t1, DDR_CTL_TIM2(t0)
+*/
+
+// Set x16 mode and Page policy
+ li t1, 0x100
+ sw t1, DDR_CTL_DMODE_1(t0)
+
+// Enable ODT for writes
+ li t1, 0x104
+ sw t1, DDR_CTL_ODT(t0)
+
+/***** Turn on CKE ***************/
+ li t1, 0x35
+ sw t1, DDR_CTL_DCMD(t0)
+
+ li t1, 0x200
+2:
+ bnez t1, 2b
+ addi t1, -1
+
+/***** Set arbitor for Burst Round Robin Mode ***/
+ lw t1, DDR_CTL_ARB(t0)
+ or t1, 4 << 16
+ sw t1, DDR_CTL_ARB(t0)
+
+/***** Issue Precharge All Banks Command ***/
+ li t1, 0x32
+ sw t1, DDR_CTL_DCMD(t0)
+
+/***** Issue EMRS2 Command ***/
+ li t1, 0x0
+ lw t2, DDR_CTL_DMODE_0 (t0) // Load previous value to t2 to preserve it
+ nop
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x38
+ sw t1, DDR_CTL_DCMD(t0)
+
+/***** Issue EMRS3 Command***/
+ li t1, 0x0
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x39
+ sw t1, DDR_CTL_DCMD(t0)
+
+// Enable DLL by issuing EMRS Command
+// li t1, 0x0
+// sw t1, DDR_CTL_DMODE_0 (t0)
+ sw t2, DDR_CTL_DMODE_0 (t0) // Use the saved value back to DMODE_0 register
+ li t1, 0x30
+ sw t1, DDR_CTL_DCMD(t0)
+
+/*
+// Issue MRS Command tCL=5 tWL=4
+ li t1, 0x0b530000
+// li t1, 0x07530000 // tCL=5 tWR=5, Reset DLL, Sequential Mode, Burst Length = 8
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x31
+ sw t1, DDR_CTL_DCMD(t0)
+*/
+// Issue MRS Command. Set Reset DLL bit
+ li t1, 0x31
+ sw t1, DDR_CTL_DCMD(t0)
+
+// Issue Precharge All Banks Command
+ li t1, 0x32
+ sw t1, DDR_CTL_DCMD(t0)
+
+// Issue Autorefresh Command
+ li t1, 0x33
+ sw t1, DDR_CTL_DCMD(t0)
+ li t1, 0x33
+ sw t1, DDR_CTL_DCMD(t0)
+
+ li t1, 0x200
+3:
+ bnez t1, 3b
+ addi t1, -1
+
+/*
+// Clear DLL Reset by Issuing MRS Command, tCL=5 tWL=4
+ li t1, 0x0a530000
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x31
+ sw t1, DDR_CTL_DCMD(t0)
+*/
+
+// Issue MRS Command w/ DLL Reset bit set to 0
+ lw t1, DDR_CTL_DMODE_0 (t0)
+ li t2, 0xFEFFFFFF // Reset DLL reset bit
+ and t1, t2
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x31
+ sw t1, DDR_CTL_DCMD(t0)
+
+/*
+// Issue EMRS Command (Enter OCD Calibration)
+ li t1, 0x380
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x30
+ sw t1, DDR_CTL_DCMD(t0)
+*/
+
+// Issue EMRS Command (Enter OCD Calibration) 75 Ohm, Full strength Drive, tAL=tRCD-1
+ li t1, 0x30
+ sw t1, DDR_CTL_DCMD(t0)
+
+// Issue EMRS Command (Exit OCD Calibration)
+ lw t1, DDR_CTL_DMODE_0 (t0)
+ li t2, 0xFC7F // Reset OCD field for exit mode
+ and t1, t2
+ sw t1, DDR_CTL_DMODE_0 (t0)
+ li t1, 0x30
+ sw t1, DDR_CTL_DCMD(t0)
+
+// Check x8 or x16 DDR
+ li t1, 0x12345678
+ li t3, 0xA0000000
+ sw zero, 0(t3)
+ sw t1, 0(t3)
+ lw t2, 0(t3)
+ bne t1, t2, 3f // Failed
+ nop
+// Do the test twice. Just in case random values match...
+ li t1, 0x87654321
+ sw t1, 0(t3)
+ lw t2, 0(t3)
+ beq t1, t2, 1f // Clock lines are enabled as needed
+ nop
+
+3:
+// Memory test failed. Need to re-enable byte lane 1 clock
+ sw zero, PHY_BYTE_LANE_1_CLOCK_PAD_DISABLE(t0)
+ li t1, 0x200
+2:
+ bnez t1, 2b // Delay after enabling clocks
+ addi t1, -1
+ b ddr_x8
+ nop
+
+1:
+// Find memory size. a3 keeps the size: 0=256Mb, 1=512Mb, 2=1Gb, 3=2Gb
+// Start from 2Gb device
+ LOADREL(t7, dram_map_table_x8)
+ lw t1, PHY_BYTE_LANE_1_CLOCK_PAD_DISABLE(t0)
+ beqz t1, 1f
+ nop
+ LOADREL(t7, dram_map_table_x16)
+
+1:
+ li a3, 4
+ddr_size:
+ addi a3, -1
+
+ li t1, 0x2c // size of dram_map_table element
+ mult t1, a3
+ mflo t2 // dram_map_table offset
+ add t2, t7
+
+ lw t1, 0x00(t2) // Row00_0
+ sw t1, DDR_CTL_ROW00_0(t0)
+
+ lw t1, 0x04(t2) // Row00_1
+ sw t1, DDR_CTL_ROW00_1(t0)
+
+ lw t1, 0x08(t2) // Row01_0
+ sw t1, DDR_CTL_ROW01_0(t0)
+
+ lw t1, 0x0C(t2) // Row01_1
+ sw t1, DDR_CTL_ROW01_1(t0)
+
+ lw t1, 0x10(t2) // Col00_0
+ sw t1, DDR_CTL_COL00_0(t0)
+
+ lw t1, 0x14(t2) // Col00_1
+ sw t1, DDR_CTL_COL00_1(t0)
+
+ lw t1, 0x18(t2) // Col01_0
+ sw t1, DDR_CTL_COL01_0(t0)
+
+ lw t1, 0x1C(t2) // Col01_1
+ sw t1, DDR_CTL_COL01_1(t0)
+
+ lw t1, 0x20(t2) // Bank
+ sw t1, DDR_CTL_BNK10(t0)
+
+ li t1, 0x0 // CS_Start
+ sw t1, DDR_CTL_CSST(t0)
+
+ lw t1, 0x24(t2) // CS_End
+ sw t1, DDR_CTL_CSEND(t0)
+
+ li t1, 0x0 // CS Interleaving CFG
+ sw t1, DDR_CTL_CNFG(t0)
+
+ lw t3, 0x28(t2) // Dram Size
+ lw t1, DDR_CTL_GCFG(t0) // GCFG
+ li t2, 0xFFFFFF00
+ and t1, t1, t2 // Mask out Dram Size Fields
+ or t1, t3, t1 // insert new DRAM Size value
+ sw t1, DDR_CTL_GCFG(t0)
+ beqz a3, ddr_speed
+ nop
+
+// Check for memory aliasing
+// This assumes that the bank interleaving is below address bits 8.
+ li t1, 8
+ li t2, 24
+ add t2, a3 // Scan up to maximum memory size
+ li t3, 0xA0000000
+
+check_alias:
+ li t4, 1
+ sll t4, t1
+ add t4, t3
+
+ sw zero, 0(t3)
+ li t5, -1
+ sw t5, 0(t4)
+ lw t6, 0(t3)
+
+ beq t5, t6, ddr_size
+ nop
+
+ bne t1, t2, check_alias
+ addi t1, 1
+
+ddr_speed:
+ li t1, 3
+ lw t2, PHY_BYTE_LANE_1_CLOCK_PAD_DISABLE(t0)
+ beqz t2, 1f
+ nop
+ li t1, 2
+1:
+ blt a3, t1, tRefi_update // If smaller than 1Gb device, keep tRRD same
+ nop
+
+ lw t1, DDR_CTL_TIM1_0(t0) // Load DDR_CTL_TIM1_0 register
+ move t2, t1
+ srl t2, 20
+ andi t2, 0xf
+ addi t2, 1 // Increment ttRRD by one (software work around for a bug)
+ sll t2, 20
+ li t3, 0xFF0FFFFF
+ and t1, t3 // Clear tRRD field
+ or t1, t2 // Insert the new tRRD value
+ sw t1, DDR_CTL_TIM1_0(t0) // Store DDR_CTL_TIM1_0 register
+ nop
+
+tRefi_update:
+ LOADREL(t2, dram_tRefi_table)
+
+ li t1, 0x4 // size of dram_tRefi_table entry
+ mult t1, a1
+ mflo t1 // dram_tRefi_table offset
+ add t2, t1
+
+ lw t1, 0x0(t2) // tRefi
+ sll t1, 8
+ sw t1, DDR_CTL_CLKS(t0)
+
+ LOADREL(t2, dram_tRFC_table)
+
+ li t1, 0x4 // size of dram_tRFC_table entry
+ mult t1, a1
+ mflo t1 // dram_tRefi_table offset
+ add t2, t1 // Calculate address in the row
+
+ li t1, 0xc // size of dram_tRFC_table row
+ mult t1, a3
+ mflo t1 // dram_tRefi_table offset
+ add t2, t1 // Calculate address in the column
+
+ lw t3, 0x0(t2) // Load tRFC value
+ andi t3, 0xFF // Mask tRFC to 8-bits
+ sll t3, 16 // Move it to bit location [23:16]
+
+ lw t1, DDR_CTL_TIM1_1(t0) // Load DDR_CTL_TIM1_1 register
+ li t2, 0xFF00FFFF
+ and t1, t1, t2 // Mask out tRFC Field
+ or t1, t3, t1 // insert new tRFC value
+ sw t1, DDR_CTL_TIM1_1(t0) // Write to TIM1_1 register
+
+ SETLEDS1('D','I','N','T')
+
+/***** UBUS align to MEMC *****/
+align_memc:
+
+/*** check MEMC clk ratio to set sampling freq *****/
+ li t2, MISC_BASE
+ lw t1, MISC_STRAP_BUS(t2)
+
+ srl t1, MISC_STRAP_BUS_MIPS_PLL_FVCO_SHIFT
+ andi t1, 0x1f // Mask out strap bits
+
+#if defined(_BCM96816_)
+ LOADREL(t2, periph_fix_table)
+ lw t2, 0(t2)
+ srl t2, t1
+ andi t2, 1
+ bne t2, zero, 2f
+#endif
+
+ LOADREL(t2, memc_ubus_ratio_table)
+
+ add t2, t1
+ lb t1, 0x00(t2)
+ sll t4,t1,28 // Update Sampling Period Field
+
+pi_ubus:
+ li t2, 4048
+ li t3, 1
+
+ sw zero, DDR_CTL_PI_GCF(t0)
+ li t1, 0x00001c0b // send feedback command every 11 cycles
+ or t1, t1, t4
+ sw t1, DDR_CTL_PI_UBUS_SMPL(t0)
+ ori t1, 0x80 // trigger stoke signal to latch in new counter value
+ sw t1, DDR_CTL_PI_UBUS_SMPL(t0)
+ li t1, 0x00040000 // send new phase value to PLL every 5 cycles
+ sw t1, DDR_CTL_PI_UBUS_CTL(t0)
+ li t1, 0x00000001 // enable enable counter that change PLL phase
+ sw t1, DDR_CTL_PI_GCF(t0)
+ nop
+
+#if defined (_BCM96328_) || defined(_BCM96362_)
+// Enable PHY MIPS PI
+ li t1, 0x00130000
+ sw t1, DDR_CTL_PI_DSL_MIPS_CTL(t0)
+ nop
+#endif
+
+1:
+ lw t4, DDR_CTL_PI_UBUS_SMPL(t0) // Read a sample value.
+ srl t4, 16 // The sample is in the upper 16 bits.
+
+ andi t4, t4, 0x22 // Look at the 2 outermost bits; if the LSB is 0 and the MSB is 1,
+ beq t4, 0x20, 2f // then there is an edge somewhere in the sample.
+ nop
+ lw t5, DDR_CTL_PI_UBUS_CTL(t0)
+ and t5, 0xffff0000
+ or t5, t3
+ or t5, (1<<14) // move phase in positive direction
+ sw t5, DDR_CTL_PI_UBUS_CTL(t0)
+ nop
+ lw t5, DDR_CTL_PI_UBUS_CTL(t0) // Delay before reading another sample.
+ add t3, 1
+ bne t2, t3, 1b
+ nop
+
+ SETLEDS1('U','A','S','Y')
+ SETLEDS1('L','A','S','Y')
+ SETLEDS1('M','A','S','Y')
+ b run_async // failed to set sync mode
+ nop
+
+2:
+/*** check MIPS clk ratio *****/
+ li t4, 0xff410010
+ li t2, MISC_BASE
+ lw t1, MISC_STRAP_BUS(t2)
+
+ srl t1, MISC_STRAP_BUS_MIPS_PLL_FVCO_SHIFT
+ andi t1, 0x1f // Mask out strap bits
+
+ b _mips_align_2_ubus // none of the above means it is either 1/1 or 2/1
+ nop
+
+
+_mips_align_2_ubus:
+
+/***** MIPS align to UBUS *****/
+ li t1, 0xff410000
+
+ li t2, 0x00040000 // update PLL phase value every 5 MC cycles
+ sw t2, DDR_CTL_PI_MIPS_CTL(t0)
+
+ li t2, 0xc0001c03 // force update on mclk_period
+ sw t2, 0x40(t1)
+ li t2, 0x80001c83
+ sw t2, 0x40(t1)
+
+ lw t2, DDR_CTL_PI_MIPS_CTL(t0) // add delay
+ li t3, 1
+
+1: lw t4, 0x40(t1) // Read a sample value.
+ srl t4, 16 // The sample is in the upper 16 bits.
+
+ andi t4, t4, 0x22 // Look at the 2 outermost bits, if the LSB is 0 and the MSB is 1,
+ beq t4, 0x20, 2f // then there is an edge somewhere in the sample.
+ nop
+ lw t5, DDR_CTL_PI_MIPS_CTL(t0)
+ and t5, 0xffff0000
+ or t5, t3
+ or t5, (1<<14) // move phase in positive direction
+ sw t5, DDR_CTL_PI_MIPS_CTL(t0)
+ nop
+ lw t5, DDR_CTL_PI_MIPS_CTL(t0) // Delay before reading another sample.
+ add t3, 1
+ bne t2, t3, 1b
+ nop
+
+ SETLEDS1('U','A','S','Y')
+ SETLEDS1('L','A','S','Y')
+ SETLEDS1('M','A','S','Y')
+ b run_async // failed to set sync mode
+ nop
+2:
+ // Success
+ lw t2, DDR_CTL_PI_MIPS_CTL(t0) // Turn on auto-PI mode.
+ or t2, (1 << 20) // PI_UBUS_CTL_Hw_Cntr_En = 1
+ sw t2, DDR_CTL_PI_MIPS_CTL(t0)
+
+ /**----- Enable DDR/UBUS and DDR/LMB sync mode ------------------**/
+ /*** only MIPS in sync mode for these strap options */
+
+ li t2, MISC_BASE
+ lw t1, MISC_STRAP_BUS(t2)
+
+ srl t1, MISC_STRAP_BUS_MIPS_PLL_FVCO_SHIFT
+ andi t1, 0x1f // Mask out strap bits
+
+ li t3, 0 // Used to keep MC/MIPS and MC/UBUS sync/async mode
+
+ LOADREL(t2, dram_sync_table)
+
+ lw t4, 0x0(t2) // Ubus Sync vector
+ lw t5, 0x4(t2) // Lmb Sync vector
+
+#if defined (_96816_)
+ move t4, t6
+#endif
+ lw t6, 0x8(t2) // Mips Sync vector
+
+ srl t4, t1 // Get the ubus sync flag
+ srl t5, t1 // Get the lmb sync flag
+ srl t6, t1 // Get the mips sync flag
+ andi t4, 1 // Mask out other bits
+ andi t5, 1 // Mask out other bits
+ andi t6, 1 // Mask out other bits
+
+ li t2, 1
+ bne t4, t2, ubus_async // 1f below. If ubus is not sync, lmb can't be in sync
+ nop // Go to ubus_async (1f)
+
+ // Ubus Sync Mode. Turn on Ubus Clock tracking
+ lw t2, DDR_CTL_PI_UBUS_CTL(t0) // Turn on auto-PI mode.
+ or t2, (1 << 20) // PI_UBUS_CTL_Hw_Cntr_En = 1
+ sw t2, DDR_CTL_PI_UBUS_CTL(t0)
+
+ // Is LMB Sync as well?
+ li t2, 1
+ beq t5, t2, memc_all_sync // If both ubus and lmb are sync, go to memc_all_sync
+ nop
+
+memc_ubus_sync:
+#if UBUS_SYNC_ENABLE
+// set MC/UBUS to SYNC
+ li t3, 0x4
+ SETLEDS1('L','A','S','Y')
+ SETLEDS1('U','S','Y','N')
+#else
+// set MC/UBUS to ASYNC
+ li t3, 0xc
+ SETLEDS1('L','A','S','Y')
+ SETLEDS1('U','A','S','Y')
+#endif
+
+ b update_sync_mode
+ nop
+
+memc_all_sync:
+#if LMB_SYNC_ENABLE
+// set MC/MIPS to SYNC
+ nop
+ SETLEDS1('L','S','Y','N')
+#else
+// set MC/MIPS to ASYNC
+ li t1, 0x4
+ or t3, t1
+ SETLEDS1('L','A','S','Y')
+#endif
+#if UBUS_SYNC_ENABLE
+// set MC/UBUS to SYNC
+ nop
+ SETLEDS1('U','S','Y','N')
+#else
+// set MC/UBUS to ASYNC
+ li t1, 0x8
+ or t3, t1
+ SETLEDS1('U','A','S','Y')
+#endif
+
+update_sync_mode:
+ li t1, MISC_BASE
+ sw t3, MISC_MEMC_CONTROL(t1)
+ b 2f
+ nop
+1:
+ubus_async:
+ SETLEDS1('L','A','S','Y')
+ SETLEDS1('U','A','S','Y')
+
+2:
+ // Can Mips run in sync mode? If not, skip all below
+ beq t6, zero, run_async
+ nop
+
+#if MIPS_SYNC_ENABLE
+ /**----- Clear MIPS Async mode bit ------------------------------**/
+ mfc0 t1, C0_BCM_CONFIG, 5
+ and t1, ~(0x1 << 28)
+ mtc0 t1, C0_BCM_CONFIG, 5
+
+ SETLEDS1('M','S','Y','N')
+#else
+ SETLEDS1('M','A','S','Y')
+#endif
+
+3:
+ /**----- Enable RAC and LMB -------------------------------------**/
+ li t0, MIPS_BASE
+ lw t2, MIPS_LMB_CR(t0)
+#if LMB_ENABLE
+ or t2, LMB_EN // Enable LMB
+ SETLEDS1('L','M','B','E')
+#else
+ SETLEDS1('L','M','B','D')
+#endif
+ sw t2, MIPS_LMB_CR(t0)
+
+ li t2, 0xFFF << RAC_UPB_SHFT // Enable prefetch for RAM address range up to 256MB
+ sw t2, MIPS_RAC_ARR(t0)
+
+ lw t2, MIPS_RAC_CR0(t0)
+ or t2, (RAC_C_INV | RAC_I | RAC_PF_I)
+ sw t2, MIPS_RAC_CR0(t0)
+
+ lw t2, MIPS_RAC_CR1(t0)
+ or t2, (RAC_C_INV | RAC_I | RAC_PF_I)
+ sw t2, MIPS_RAC_CR1(t0)
+
+run_async:
+ /**----- Enable branch prediction and non-blocking data cache ---**/
+ mfc0 t1, C0_BCM_CONFIG
+ and t1, ~CP0_BCM_CFG_BTHD
+ or t1, CP0_BCM_CFG_NBK
+ or t1, CP0_BCM_CFG_CLF
+ mtc0 t1, C0_BCM_CONFIG
+
+#if DDR_TEST
+#######################################
+# Run test on DRAM using Test Engine #
+#######################################
+#define BACKGND_MODE_DATA 0x0
+#define BACKGND_MODE_LFSR 0x400
+#define BACKGND_MODE_PRBS 0x800
+#define BACKGND_MODE_NOT_PRBS 0xc00
+#define BACKGND_MODE_PAT 0x1000
+#define BACKGND_MODE_NOT_PAT 0x1400
+
+#define VICT_MODE_PRBS 0
+#define VICT_MODE_NOT_PRBS 0x100
+#define VICT_MODE_PAT 0x200
+#define VICT_MODE_NOT_PAT 0x300
+
+#define VICT_ENABLE 0x8000
+#define VICT_SWEEP_ENABLE 0x10000
+#define VICT_COUNT 0x0
+
+#define PRBS_ORDER(x) ((x & 0x3) << 13)
+
+#define TEST_COUNT 0x1000
+#define TEST_ADDR 0x0
+#define TEST_ADDR_UPDT 0x1
+#define TEST_PATTERN0 0x5555
+#define TEST_PATTERN1 0xaaaa
+#define TEST_PATTERN (TEST_PATTERN1 << 16 | TEST_PATTERN0)
+
+#define TEST_ENABLE 0x1
+#define TEST_DONE 0x2
+#define TEST_ERROR 0x4
+#define TEST_WRITE 0x10
+#define TEST_READ 0x0
+
+#define BACKGND_DATA0 0xa5a5a5a5
+#define BACKGND_DATA1 0x5a5a5a5a
+#define BACKGND_DATA2 0xa5a5a5a5
+#define BACKGND_DATA3 0x5a5a5a5a
+
+#define TEST_DATA0 0x02468ace
+#define TEST_DATA1 0x13579bdf
+#define TEST_DATA2 0x33cccc33
+#define TEST_DATA3 0x55aaaa55
+
+/***** Load DDR Base *************************************/
+ li t0, DDR_BASE
+ li t1, BACKGND_DATA0
+ sw t1, DDR_CTL_TEST_DATA0(t0)
+ li t1, BACKGND_DATA1
+ sw t1, DDR_CTL_TEST_DATA1(t0)
+ li t1, BACKGND_DATA2
+ sw t1, DDR_CTL_TEST_DATA2(t0)
+ li t1, BACKGND_DATA3
+ sw t1, DDR_CTL_TEST_DATA3(t0)
+ li t1, TEST_COUNT
+ li t2, VICT_COUNT
+ or t1, t2 # add victim count value
+ sw t1, DDR_CTL_TEST_COUNT(t0)
+ li t1, TEST_ADDR
+ sw t1, DDR_CTL_TEST_ADDR(t0)
+ li t1, TEST_ADDR_UPDT
+ sw t1, DDR_CTL_TEST_ADDR_UPDT(t0)
+ li t1, TEST_PATTERN
+ sw t1, DDR_CTL_TEST_PAT(t0)
+
+# Write a background pattern first
+ li t1, BACKGND_MODE_DATA
+ li t2, TEST_WRITE
+ or t1, t2
+ li t2, TEST_ENABLE
+ or t1, t2
+ sw t1, DDR_CTL_TEST_CFG1(t0)
+
+ li t2, 0x2
+ li t3, MISC_BASE
+
+ li t5, 0x10000
+2: li t1, 0x100
+1: addiu t1, -1
+ bnez t1, 1b
+ nop
+
+ lw t4, MISC_MEMC_CONTROL(t3)
+ and t4, 0x2
+ beq t4, t2, backgnd_write_done
+ nop
+ addiu t5, -1
+ bnez t5, 2b
+ nop
+
+# Background write operation is finished
+
+backgnd_write_done:
+ li t1, TEST_DATA0
+ sw t1, DDR_CTL_TEST_DATA0(t0)
+ li t1, TEST_DATA1
+ sw t1, DDR_CTL_TEST_DATA1(t0)
+ li t1, TEST_DATA2
+ sw t1, DDR_CTL_TEST_DATA2(t0)
+ li t1, TEST_DATA3
+ sw t1, DDR_CTL_TEST_DATA3(t0)
+ li t1, TEST_COUNT
+ li t2, VICT_COUNT
+ or t1, t2 # add victim count value
+ sw t1, DDR_CTL_TEST_COUNT(t0)
+ li t1, TEST_ADDR
+ sw t1, DDR_CTL_TEST_ADDR(t0)
+ li t1, TEST_ADDR_UPDT
+ sw t1, DDR_CTL_TEST_ADDR_UPDT(t0)
+ li t1, TEST_PATTERN
+ sw t1, DDR_CTL_TEST_PAT(t0)
+
+# li t1, BACKGND_MODE_DATA
+# li t1, BACKGND_MODE_PAT
+# li t2, VICT_MODE_NOT_PAT
+ li t1, BACKGND_MODE_PRBS
+ li t2, VICT_MODE_NOT_PRBS
+
+ or t1, t2
+ li t2, VICT_ENABLE
+ or t1, t2
+ li t2, VICT_SWEEP_ENABLE
+ or t1, t2
+ li t2, PRBS_ORDER(0)
+ or t1, t2
+ li t2, TEST_WRITE
+ or t1, t2
+ li t2, TEST_ENABLE
+ or t1, t2
+ sw t1, DDR_CTL_TEST_CFG1(t0)
+
+ li t2, 0x2
+ li t3, MISC_BASE
+
+ li t5, 0x10000
+2: li t1, 0x100
+1: addiu t1, -1
+ bnez t1, 1b
+ nop
+
+ lw t4, MISC_MEMC_CONTROL(t3)
+ and t4, 0x2
+ beq t4, t2, test_write_done
+ nop
+ addiu t5, -1
+ bnez t5, 2b
+ nop
+
+# Test write operation is finished
+
+test_write_done:
+ li t1, TEST_DATA0
+ sw t1, DDR_CTL_TEST_DATA0(t0)
+ li t1, TEST_DATA1
+ sw t1, DDR_CTL_TEST_DATA1(t0)
+ li t1, TEST_DATA2
+ sw t1, DDR_CTL_TEST_DATA2(t0)
+ li t1, TEST_DATA3
+ sw t1, DDR_CTL_TEST_DATA3(t0)
+ li t1, TEST_COUNT
+ li t2, VICT_COUNT
+ or t1, t2 # add victim count value
+ sw t1, DDR_CTL_TEST_COUNT(t0)
+ li t1, TEST_ADDR
+ sw t1, DDR_CTL_TEST_ADDR(t0)
+ li t1, TEST_ADDR_UPDT
+ sw t1, DDR_CTL_TEST_ADDR_UPDT(t0)
+ li t1, TEST_PATTERN
+ sw t1, DDR_CTL_TEST_PAT(t0)
+
+# li t1, BACKGND_MODE_DATA
+# li t1, BACKGND_MODE_PAT
+# li t2, VICT_MODE_NOT_PAT
+ li t1, BACKGND_MODE_PRBS
+ li t2, VICT_MODE_NOT_PRBS
+
+ or t1, t2
+ li t2, VICT_ENABLE
+ or t1, t2
+ li t2, VICT_SWEEP_ENABLE
+ or t1, t2
+ li t2, PRBS_ORDER(0)
+ or t1, t2
+ li t2, TEST_READ
+ or t1, t2
+ li t2, TEST_ENABLE
+ or t1, t2
+ sw t1, DDR_CTL_TEST_CFG1(t0)
+
+ li t3, MISC_BASE
+ li t2, 0x2
+
+ li t5, 0x10000
+2: li t1, 0x100
+1: addiu t1, -1
+ bnez t1, 1b
+ nop
+
+ lw t4, MISC_MEMC_CONTROL(t3)
+ and t4, 0x2
+ beq t4, t2, test_read_done
+ nop
+ addiu t5, -1
+ bnez t5, 2b
+ nop
+
+# Test read operation is finished
+
+test_read_done:
+ lw t1, DDR_CTL_TEST_CFG1(t0)
+ srl t1, 2
+ and t1, 1
+ beq t1, zero, test_passed
+ nop
+
+test_failed:
+ SETLEDS1('F','A','I','L')
+ b 1f
+ nop
+test_passed:
+ SETLEDS1('P','A','S','S')
+1:
+ SETLEDS1('-','-','-', '-')
+#endif
+
+ move ra,s0
+ j ra
+ nop
+
+ .set reorder
+
+END(board_draminit)
+
+/* *********************************************************************
+ * BOARD_SETLEDS(x)
+ *
+ * Set LEDs for boot-time progress indication. Not used if
+ * the board does not have progress LEDs. This routine
+ * must not call any other routines, since it may be invoked
+ * either from KSEG0 or KSEG1 and it may be invoked
+ * whether or not the icache is operational.
+ *
+ * Input parameters:
+ * a0 - LED value (8 bits per character, 4 characters)
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t7,t8,t9
+ ********************************************************************* */
+LEAF(board_setleds)
+#if 1
+ li t7, UART_BASE
+ li t8, TXFIFOEMT
+
+1: lh t9, UART0INTSTAT(t7)
+ and t9, t8
+ bne t9, t8, 1b
+
+ srl t8, a0, 24
+ sb t8, UART0DATA(t7)
+ srl t8, a0, 16
+ sb t8, UART0DATA(t7)
+ srl t8, a0, 8
+ sb t8, UART0DATA(t7)
+ sb a0, UART0DATA(t7)
+ li a0, '\r'
+ sb a0, UART0DATA(t7)
+ li a0, '\n'
+ sb a0, UART0DATA(t7)
+#endif
+ j ra
+END(board_setleds)
+
+/* *********************************************************************
+ * BCMCORE_TP1_SWITCH()
+ *
+ * Check if the thread switch is required. If we are already
+ * running on thread 1 this function will do nothing and just return
+ * If we are running on thread 0 this function will take thread 1
+ * out of reset and put thread 0 to sleep waiting for singnal from
+ * thread 1.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+LEAF(bcmcore_tp1_switch)
+
+#if defined(_BCM96328_)
+ li t1, OTP_BASE
+ addi t1, OTP_USER_BITS
+ addi t1, 0xc - ((OTP_TP1_DISABLE_BIT / 8) & ~3)
+ lw t0, 0(t1)
+ andi t0, 1 << (OTP_TP1_DISABLE_BIT % 32)
+ beqz t0, 1f
+ j ra
+1:
+#endif
+ mfc0 t1, C0_BCM_CONFIG, 3
+ li t2, CP0_CMT_TPID
+ and t1, t2
+ bnez t1, tp1 # Already running on thread 1
+
+# Start TP1
+# Set boot address for TP1
+ li t1, MIPS_BASE
+ li t2, 0x98000000 | ENABLE_ALT_BV
+ sw t2, MIPS_TP1_ALT_BV(t1)
+
+# Set a flag so we can wait for TP1 to catch up
+ li t1, 0x0
+ mtc0 t1, $31 # CO_DESAVE
+
+# Take TP1 out of reset
+ mfc0 t1, C0_BCM_CONFIG, 2
+ or t1, CP0_CMT_RSTSE
+ mtc0 t1, C0_BCM_CONFIG, 2
+
+ /* wait until second thread catches up with the first */
+waittp1:
+ mfc0 t0, $31 # CO_DESAVE
+ beqz t0, waittp1
+
+ li t0, THREAD_NUM_ADDRESS
+ FIXUP(t0)
+ lw t0, 0(t0)
+ li t1, 1
+ bne t0, t1, return # Linux will run on TP0, continue running bootloader
+
+# Voice will run on TP0. Set it up and put it to sleep
+
+ # enable interrupts and enable SW IRQ 0
+ li t0, M_SR_IE | M_SR_IBIT1
+ mtc0 t0, C0_SR
+
+ # Set up to use alternate exception vector 0x80000200
+ li t0, M_CAUSE_IV
+ mtc0 t0, C0_CAUSE
+
+ mfc0 t1, C0_BCM_CONFIG, 1
+ # set all ints except IRQ1 to TP1 and cross over SW IRQ 0
+ or t1, (CP0_CMT_XIR_4 | CP0_CMT_XIR_3 | CP0_CMT_XIR_2 | CP0_CMT_XIR_0 | CP0_CMT_SIR_0 | CP0_CMT_NMIR_TP1)
+ mtc0 t1, C0_BCM_CONFIG, 1
+
+ mfc0 t1, C0_BCM_CONFIG, 2
+ # Set debug on TP1, give priority to TP0, and
+ # set TLB exception serialization to ignore SCNT value in CP0 reg22 sel 4
+ and t1, ~CP0_CMT_TPS_MASK;
+ or t1, (CP0_CMT_DSU_TP1 | CP0_CMT_PRIO_TP0 | (1 << CP0_CMT_TPS_SHFT))
+ mtc0 t1, C0_BCM_CONFIG, 2
+
+ # Enable Data RAC on TP0
+ li t1, MIPS_BASE
+ lw t2, MIPS_RAC_CR0(t1)
+ or t2, (RAC_D | RAC_PF_D)
+ sw t2, MIPS_RAC_CR0(t1)
+
+2:
+ b wait_for_wake
+
+tp1:
+# Running on TP1....
+# First signal to TP0 that TP1 is up
+ li t1, 0x1
+ mtc0 t1, $31 # CO_DESAVE
+
+ li t0, THREAD_NUM_ADDRESS
+ FIXUP(t0)
+ lw t0, 0(t0)
+ li t1, 1
+ beq t0, t1, return # Linux will run on TP1, continue running bootloader
+
+# Voice will run on TP1. Set it up and put it to sleep
+
+ # enable interrupts and enable SW IRQ 0
+ li t0, M_SR_IE | M_SR_IBIT1
+ mtc0 t0, C0_SR
+
+ # Set up to use alternate exception vector 0x80000200
+ li t0, M_CAUSE_IV
+ mtc0 t0, C0_CAUSE
+
+ mfc0 t1, C0_BCM_CONFIG, 1
+ # set IRQ1 to TP1 and cross over SW IRQ 0
+ or t1, (CP0_CMT_XIR_1 | CP0_CMT_SIR_0 | CP0_CMT_NMIR_TP0)
+ mtc0 t1, C0_BCM_CONFIG, 1
+
+ mfc0 t1, C0_BCM_CONFIG, 2
+ # Set debug on TP0, give priority to TP1, and
+ # set TLB exception serialization to ignore SCNT value in CP0 reg22 sel 4
+ and t1, ~CP0_CMT_TPS_MASK;
+ or t1, (CP0_CMT_PRIO_TP1 | (1 << CP0_CMT_TPS_SHFT))
+ mtc0 t1, C0_BCM_CONFIG, 2
+
+ # Enable Data RAC on TP1
+ li t1, MIPS_BASE
+ lw t2, MIPS_RAC_CR1(t1)
+ or t2, (RAC_D | RAC_PF_D)
+ sw t2, MIPS_RAC_CR1(t1)
+ b 2b
+
+return:
+ j ra
+
+END(bcmcore_tp1_switch)
+
+# align this code to cache line. NAND flash is not memory mapped after system boots
+# so when we are signaling to the second TP to wake we need
+# jal instruction to be in cache
+ .align 4
+LEAF(wait_for_wake)
+ sync
+ wait # wait for interrupt
+ jal t8 # jump to entry point
+END(wait_for_wake)
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_main.c b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_main.c
new file mode 100755
index 0000000..201d6d8
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/bcm63xx_main.c
@@ -0,0 +1,649 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Main Module File: bcm63xxBoot_main.c
+ *
+ * This module contains the main "C" routine for CFE bootstrap loader
+ * and decompressor to decompress the real CFE to ram and jump over.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ * Revised: seanl
+ *
+ *********************************************************************
+ *
+ * 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 "lib_types.h"
+#include "lib_string.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_console.h"
+#include "cfe_timer.h"
+
+#include "env_subr.h"
+#include "ui_command.h"
+#include "cfe_mem.h"
+#include "cfe.h"
+
+#include "bsp_config.h"
+#include "bcm_hwdefs.h"
+#include "bcm_map.h"
+
+#include "exception.h"
+
+#include "segtable.h"
+
+#include "initdata.h"
+
+#if defined(_BCM96368_) || defined(_BCM96362_) || defined(_BCM96328_) || defined(_BCM96816_)
+#include "flash_api.h"
+#include "jffs2.h"
+#endif
+
+#if CFG_PCI
+#include "pcivar.h"
+#endif
+
+
+
+int cfe_size_ram(void);
+inline static int is_aliased(int max_bits) __attribute__((always_inline));
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#ifndef CFG_STACK_SIZE
+#define STACK_SIZE 8192
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+inline static int is_aliased(int max_bits)
+{
+ volatile uint32 *mem_base;
+ volatile uint32 *test_ptr;
+ uint32 tmp;
+ int bit;
+ int res = 0;
+
+ mem_base = (uint32*)DRAM_BASE_NOCACHE;
+
+ *mem_base = 0;
+
+ for (bit = 8; bit < max_bits; bit++) {
+ test_ptr = (uint32*)((uint32)mem_base | 1 << bit);
+ /* ram may contain useful data, save location before modifying */
+ tmp = *test_ptr;
+ *test_ptr = -1;
+ if (*mem_base == *test_ptr) {
+ *test_ptr = tmp;
+ res = 1;
+ break;
+ }
+ *test_ptr = tmp;
+ }
+ return res;
+}
+
+#define MEMC_MAX_ROWS 14
+
+int cfe_size_ram(void)
+{
+#if !(defined(_BCM96328_) || defined (_BCM96362_) || defined(_BCM96816_))
+ uint32 col_bits, row_bits, bus_bits, bank_bits;
+ uint32 size;
+
+ /* Bus width is configured during early boot */
+ if (((MEMC->Config & MEMC_WIDTH_MASK) >> MEMC_WIDTH_SHFT) == MEMC_32BIT_BUS)
+ bus_bits = 2;
+ else
+ bus_bits = 1;
+
+ bank_bits = 2;
+ /* Start from setting to the lowest possible configuration */
+ col_bits = 8;
+ row_bits = 11;
+
+ MEMC->Config &= ~MEMC_COL_MASK;
+ MEMC->Config |= ((col_bits - 8) << MEMC_COL_SHFT);
+
+ MEMC->Config &= ~MEMC_ROW_MASK;
+ MEMC->Config |= ((row_bits - 11) << MEMC_ROW_SHFT);
+
+ /* Determine number of rows */
+ for (row_bits = 12; row_bits <= MEMC_MAX_ROWS; row_bits++) {
+ MEMC->Config &= ~MEMC_ROW_MASK;
+ MEMC->Config |= ((row_bits - 11) << MEMC_ROW_SHFT);
+ /* check if this address bit is valid */
+ if (is_aliased (col_bits + row_bits + bus_bits + bank_bits))
+ break;
+ }
+ row_bits -= 1;
+ MEMC->Config &= ~MEMC_ROW_MASK;
+ MEMC->Config |= ((row_bits - 11) << MEMC_ROW_SHFT);
+
+ /* Determine number of columns */
+ for (col_bits = 9; col_bits <= 11; col_bits++) {
+ MEMC->Config &= ~MEMC_COL_MASK;
+ MEMC->Config |= ((col_bits - 8) << MEMC_COL_SHFT);
+ /* check if this address bit is valid */
+ if (is_aliased (col_bits + row_bits + bus_bits + bank_bits))
+ break;
+ }
+ col_bits -= 1;
+ MEMC->Config &= ~MEMC_COL_MASK;
+ MEMC->Config |= ((col_bits - 8) << MEMC_COL_SHFT);
+
+ /* Compute memory size in MB */
+ size = 1 << (bus_bits + col_bits + row_bits + bank_bits - 20);
+
+ return size;
+#else
+ return (DDR->CSEND << 24);
+#endif
+}
+
+// fake functions for not to modifying init_mips.S
+void _exc_entry(void);
+void cfe_command_restart(void);
+void cfe_doxreq(void);
+
+void _exc_entry(void)
+{
+}
+
+void cfe_command_restart(void)
+{
+}
+void cfe_doxreq(void)
+{
+}
+
+/* *********************************************************************
+ * Externs
+ ********************************************************************* */
+
+void cfe_main(int,int);
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+void cfe_ledstr(const char *leds)
+{
+}
+
+#if !defined(CONFIG_BRCM_IKOS)
+extern void _binArrayStart(void);
+extern void _binArrayEnd(void);
+extern int decompressLZMA(unsigned char *in, unsigned insize, unsigned char *out, unsigned outsize);
+
+#if (INC_NAND_FLASH_DRIVER==1) || (INC_SPI_PROG_NAND==1)
+#define je16_to_cpu(x) ((x).v16)
+#define je32_to_cpu(x) ((x).v32)
+extern void rom_nand_flash_init(void);
+extern int nand_flash_get_sector_size(unsigned short sector);
+extern int nand_flash_get_numsectors(void);
+extern int nand_flash_read_buf(unsigned short blk, int offset,
+ unsigned char *buffer, int len);
+extern void board_setleds(unsigned long);
+
+void *lib_memcpy(void *dest,const void *src,size_t cnt)
+{
+ unsigned char *d;
+ const unsigned char *s;
+
+ d = (unsigned char *) dest;
+ s = (const unsigned char *) src;
+
+ while (cnt) {
+ *d++ = *s++;
+ cnt--;
+ }
+
+ return dest;
+}
+
+int lib_memcmp(const void *dest,const void *src,size_t cnt)
+{
+ const unsigned char *d;
+ const unsigned char *s;
+
+ d = (const unsigned char *) dest;
+ s = (const unsigned char *) src;
+
+ while (cnt) {
+ if (*d < *s) return -1;
+ if (*d > *s) return 1;
+ d++; s++; cnt--;
+ }
+
+ return 0;
+}
+
+#if (INC_NAND_FLASH_DRIVER==1)
+/* Find uncompressed file cferam.bin on the JFFS2 file system, load it into
+ * memory and jump to its entry point function.
+ */
+char g_fname[] = NAND_CFE_RAM_NAME;
+int g_fname_actual_len = sizeof(g_fname) - 1;
+int g_fname_cmp_len = sizeof(g_fname) - 4; /* last three are digits */
+static void bootImageFromNand(void)
+{
+ const unsigned long bv_invalid = 0xfffffff;
+ const int max_not_jffs2 = 10;
+
+ struct rootfs_info
+ {
+ int rootfs;
+ int start_blk;
+ int end_blk;
+ unsigned long boot_val;
+ unsigned long ino;
+ } rfs_info[2], *prfs_info[2], *rfsi;
+
+ unsigned char *buf = (unsigned char *) mem_heapstart;
+ unsigned long version = 0;
+ struct jffs2_raw_dirent *pdir;
+ struct jffs2_raw_inode *pino;
+ unsigned char *p;
+ int i, j, k, done, not_jffs2;
+ int num_blks;
+ int len;
+ int boot_prev;
+ PNVRAM_DATA nd;
+ static int err0=0, err1=1;
+
+ rom_nand_flash_init();
+ num_blks = nand_flash_get_numsectors();
+ len = nand_flash_get_sector_size(0);
+ nd = (PNVRAM_DATA) (buf + len);
+
+ NAND->NandNandBootConfig = NBC_AUTO_DEV_ID_CFG | 0x101;
+ NAND->NandCsNandXor = 1;
+
+ memcpy((unsigned char *) nd, (unsigned char *)
+ FLASH_BASE + NVRAM_DATA_OFFSET, sizeof(NVRAM_DATA));
+
+ NAND->NandNandBootConfig = NBC_AUTO_DEV_ID_CFG | 0x2;
+ NAND->NandCsNandXor = 0;
+
+ /* Look at config to determine whether to boot current or previous image.*/
+ for( i = 0, p = (unsigned char *) nd->szBootline, boot_prev = 0;
+ i < NVRAM_BOOTLINE_LEN; i++, p++ )
+ {
+ if( p[0] == ' ' && p[1] == 'p' && p[2] == '=' )
+ {
+ boot_prev = p[3] - '0';
+ if( boot_prev != 0 && boot_prev != 1 )
+ boot_prev = '0';
+ break;
+ }
+ }
+
+ /* Find the CFE ram inode entry point for both root file systems. */
+ board_setleds((boot_prev == 0) ? 0x4e414e30 : 0x4e414e31);
+ for( k = 0, rfsi = rfs_info; k < 2; k++, rfsi++ )
+ {
+ version = 0;
+ not_jffs2 = 0;
+ rfsi->rootfs = k + NP_ROOTFS_1;
+ rfsi->boot_val = bv_invalid;
+ if( nd->ulNandPartOfsKb[rfsi->rootfs] > 0 &&
+ nd->ulNandPartOfsKb[rfsi->rootfs] < ((num_blks * len) / 1024))
+ {
+ rfsi->start_blk = nd->ulNandPartOfsKb[rfsi->rootfs] / (len/1024);
+ rfsi->end_blk = rfsi->start_blk +
+ (nd->ulNandPartSizeKb[rfsi->rootfs] / (len / 1024));
+ }
+ else
+ rfsi->start_blk = rfsi->end_blk = 0;
+
+ if( rfsi->start_blk == 0 || rfsi->start_blk >= rfsi->end_blk ||
+ rfsi->start_blk >= num_blks || rfsi->end_blk >= num_blks )
+ {
+ /* NVRAM_DATA fields for this rootfs are not valid. */
+ if( k == 0 )
+ {
+ /* Skip this rootfs. */
+ board_setleds(0x4e414e36);
+ continue;
+ }
+
+ if( rfs_info[0].boot_val == bv_invalid )
+ {
+ /* File system info cannot be found for either rootfs.
+ * NVRAM_DATA may not be set. Use default values.
+ */
+ board_setleds(0x4e414e37);
+ rfsi = rfs_info;
+ rfsi->start_blk = 1;
+ rfsi->end_blk = num_blks;
+ }
+ }
+
+ /* Find the directory entry. */
+ for( i = rfsi->start_blk, done = 0; i < rfsi->end_blk && done == 0; i++ )
+ {
+ /* This loop sequentially reads a NAND flash block into memory and
+ * processes it.
+ */
+ if( nand_flash_read_buf(i, 0, buf, len) > 0 )
+ {
+ /* This loop reads inodes in a block. */
+ 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 &&
+ g_fname_actual_len == pdir->nsize &&
+ !memcmp(g_fname, pdir->name, g_fname_cmp_len) )
+ {
+ /* The desired directory was found. */
+ if( je32_to_cpu(pdir->version) > version )
+ {
+ if( (rfsi->ino = je32_to_cpu(pdir->ino)) != 0 )
+ {
+ unsigned char *fname =
+ pdir->name + g_fname_cmp_len;
+ rfsi->boot_val =
+ ((fname[0] - '0') * 100) +
+ ((fname[1] - '0') * 10) +
+ ((fname[2] - '0') * 1);
+ version = je32_to_cpu(pdir->version);
+
+ board_setleds(0x42540000 +
+ ((unsigned long) fname[1] << 8) +
+ (unsigned long) fname[2]);
+
+ /* 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;
+ not_jffs2 = 0;
+ }
+ else
+ {
+ if( not_jffs2++ > max_not_jffs2 )
+ {
+ /* No JFFS2 magic bitmask for consecutive blocks.
+ * Assume this partion does not have a file system
+ * on it.
+ */
+ board_setleds(0x53544F50);
+ done = 1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ if(!err0)
+ {
+ err0=1;
+ board_setleds(0x45525230);
+ }
+ }
+ }
+ board_setleds(0x4e414e39);
+ }
+
+ /* Set the rfs_info to the index to boot from. */
+ if( (boot_prev == 0 && rfs_info[0].boot_val > rfs_info[1].boot_val) ||
+ (boot_prev == 1 && rfs_info[0].boot_val < rfs_info[1].boot_val) ||
+ rfs_info[1].boot_val == bv_invalid )
+ {
+ /* Boot from the most recent image. */
+ prfs_info[0] = &rfs_info[0];
+ prfs_info[1] = &rfs_info[1];
+ }
+ else
+ {
+ /* Boot from the previous image. */
+ prfs_info[0] = &rfs_info[1];
+ prfs_info[1] = &rfs_info[0];
+ }
+
+ /* If the directory entry for the desired file, which is the CFE RAM image,
+ * is found, read it into memory and jump to its entry point function.
+ * This loop checks for CFE RAM image in two possible rootfs file sytems.
+ */
+ for( k = 0; k < 2; k++ )
+ {
+ unsigned char *pucDest = NULL;
+ unsigned char *pucEntry = NULL;
+ long isize = 0;
+
+ board_setleds(0x4e414e33);
+ rfsi = prfs_info[k];
+ if( rfsi->boot_val == bv_invalid )
+ continue;
+
+ /* When j == 0, get the first inode to find the entry point address.
+ * When j == 1, read the file contents into memory.
+ */
+ for( j = 0; j < 2; j++ )
+ {
+ /* This loop sequentially reads a NAND flash block into memory and
+ * processes it.
+ */
+ for(i = rfsi->start_blk, done = 0; i<rfsi->end_blk && done==0; i++)
+ {
+ if( nand_flash_read_buf(i, 0, buf, len) > 0 )
+ {
+ /* This loop reads inodes in a block. */
+ p = buf;
+ while( p < buf + len )
+ {
+ /* Verify the first short word is the JFFS2 magic
+ * number.
+ */
+ 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) == rfsi->ino )
+ {
+ unsigned long size = je32_to_cpu(pino->dsize);
+ unsigned long ofs = je32_to_cpu(pino->offset);
+
+ if( size )
+ {
+ /* A node of the CFE RAM file was found
+ * with data. */
+ if( pucDest == NULL )
+ {
+ /* The entry point and copy destination
+ * addresses have not been obtained.
+ * If this is the first node of the CFE
+ * RAM file, obtain this information.
+ */
+ if( ofs == 0 )
+ {
+ /* The first 12 bytes contain a
+ * header. The first word is the
+ * entry point address.
+ */
+ pucEntry = (unsigned char *)
+ *(unsigned long *) pino->data;
+ pucDest = pucEntry - 12;
+ isize = je32_to_cpu(pino->isize);
+ done = 1;
+ board_setleds(0x52465330 |
+ rfsi->rootfs);
+ break;
+ }
+ }
+ else
+ {
+ /* Copy the image to memory. Stop when
+ * the entire image has been copied.
+ */
+ memcpy(pucDest+ofs, pino->data, size);
+ if( (isize -= size) <= 0 )
+ {
+ done = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Skip to the next inode entry. */
+ p += (je32_to_cpu(pino->totlen) + 0x03) & ~0x03;
+ }
+ else
+ break;
+ }
+ }
+ else
+ {
+ if(!err1)
+ {
+ err1=1;
+ board_setleds(0x45525231);
+ }
+ }
+ }
+ }
+
+ if( pucEntry && isize <= 0 )
+ {
+ board_setleds(0x4e414e35);
+
+ /* Save the rootfs partition that the CFE RAM image boots from
+ * at the memory location before the CFE RAM load address. The
+ * CFE RAM image uses this value to determine the partition to
+ * flash a new rootfs to.
+ */
+ *(pucEntry - 1) = (unsigned char) rfsi->rootfs;
+
+ cfe_launch((unsigned long) pucEntry); // never return...
+ }
+ board_setleds(0x4e414e38);
+ }
+
+ /* Error occurred. */
+ board_setleds(0x44494530);
+ while(1);
+}
+#endif
+#endif
+
+/* *********************************************************************
+ * cfe_main(a,b)
+ *
+ * It's gotta start somewhere.
+ * Input parameters:
+ * a,b - not used
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+void cfe_main(int a,int b)
+{
+ unsigned char *pucSrc;
+ unsigned char *pucDst;
+ unsigned int *entryPoint;
+ unsigned int binArrayStart = (unsigned int) _binArrayStart;
+ unsigned int binArrayEnd = (unsigned int) _binArrayEnd;
+ unsigned int dataLen = binArrayEnd - binArrayStart - 4;
+ int ret;
+
+ KMEMINIT((unsigned char *) (uint32_t) mem_heapstart,
+ ((CFG_HEAP_SIZE)*1024));
+
+#if (INC_NAND_FLASH_DRIVER==1) && (defined(_BCM96816_) || defined(_BCM96362_) || defined(_BCM96328_))
+ if( ((MISC->miscStrapBus & MISC_STRAP_BUS_BOOT_SEL_MASK) >>
+ MISC_STRAP_BUS_BOOT_SEL_SHIFT) == MISC_STRAP_BUS_BOOT_NAND )
+ {
+ bootImageFromNand(); /* Will not return. */
+ }
+#elif (INC_NAND_FLASH_DRIVER==1) && defined(_BCM96368_)
+ if( ((GPIO->StrapBus & MISC_STRAP_BUS_BOOT_SEL_MASK) >>
+ MISC_STRAP_BUS_BOOT_SEL_SHIFT) == MISC_STRAP_BUS_BOOT_NAND )
+ {
+ bootImageFromNand(); /* Will not return. */
+ }
+#endif
+
+ entryPoint = (unsigned int*) binArrayStart;
+ pucSrc = (unsigned char *) (binArrayStart + 4);
+
+ pucDst = (unsigned char *) *entryPoint;
+ ret = decompressLZMA((unsigned char*)pucSrc,
+ (unsigned int)dataLen,
+ (unsigned char *) pucDst,
+ 23*1024*1024);
+
+ if (ret != 0)
+ while (1); // if not decompressed ok, loop for EJTAG
+
+ cfe_launch((unsigned long) pucDst); // never return...
+}
+#else
+/* 0x694b6f31 (iKo1) is replaced with actual address during the build process.*/
+unsigned long cfeRamStartAddr=0x694b6f31;
+void cfe_main(int a,int b)
+{
+ cfe_size_ram();
+ cfe_launch(cfeRamStartAddr); // never return...
+}
+#endif
+
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c
new file mode 100755
index 0000000..310fb40
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c
@@ -0,0 +1,1031 @@
+/*
+ *----------------------------------------------------------------------------*
+ * Collection of Memory Tests.
+ *----------------------------------------------------------------------------*
+ */
+
+//
+// NOTE: Blatant inlining ... (not sure whether caller supports EABI calls).
+// WARNING CFE: Must NOT use function calls !!!
+//
+#define _ALWAYS_INLINE_ __attribute__((always_inline))
+#define _INLINE_ inline static
+
+typedef enum memTestResult {
+ MEMTEST_FAILURE = 0,
+ MEMTEST_SUCCESS,
+ MEMTEST_ERROR,
+} MemTestResult_t;
+
+/* ------------------------------------------------------------------------- */
+
+#undef PATTERN
+#define PATTERN(x) PATTERN_##x,
+
+/*
+ * For each pattern listed, the inverse pattern is also automatically used.
+ * E.g. 0x55555555, the inverse of defined 0xAAAAAAAA is covered.
+ */
+typedef enum pattern {
+ PATTERN(0x00000000)
+ PATTERN(0xAAAAAAAA)
+ PATTERN(0xCCCCCCCC)
+ PATTERN(0x77777777)
+ PATTERN(0xF0F0F0F0)
+ PATTERN(0xFF00FF00)
+ PATTERN(0xFFFF0000)
+ PATTERN(0x01234567)
+ PATTERN(0x89ABCDEF)
+ PATTERN_MAX,
+} Pattern_t;
+
+#undef PATTERN
+#define PATTERN(x) x,
+const uint32_t pattern[] = {
+ PATTERN(0x00000000)
+ PATTERN(0xAAAAAAAA)
+ PATTERN(0xCCCCCCCC)
+ PATTERN(0x77777777)
+ PATTERN(0xF0F0F0F0)
+ PATTERN(0xFF00FF00)
+ PATTERN(0xFFFF0000)
+ PATTERN(0x01234567)
+ PATTERN(0x89ABCDEF)
+ PATTERN_MAX,
+};
+
+/* ------------------------------------------------------------------------- */
+
+#ifndef NBBY
+#define NBBY 8 /* FreeBSD style: Number Bits per BYte */
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define NBITS(type) (sizeof(type) * NBBY)
+#define NBITVAL(nbits) (1 << (nbits))
+#define MAXBITVAL(nbits) ( NBITVAL(nbits) - 1)
+#define NBITMASK(nbits) MAXBITVAL(nbits)
+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * NBBY)
+
+#define DIVBY(val32,by) ((val32)>>(by))
+#define MODBY(val32,by) ((val32) & ((1 <<(by)) - 1) )
+
+#define IS_POWEROF2(val32) ( (((val32)-1) & (val32)) == 0 )
+
+#define ROUNDDN(addr, align) ( (addr) & ~((align) - 1) )
+#define ROUNDUP(addr, align) ( ((addr) + (align) - 1) & ~((align) - 1) )
+//#define ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
+#define ALIGN_ADDR(addr, bytes) (void *)( ((uint32_t *)(addr) + (bytes) - 1) \
+ & ~((bytes) - 1) )
+#define IS_ALIGNED(addr, bytes) (((uint32_t)(addr) & ((bytes)-1)) == 0)
+
+#define OFFSET_OF(stype,member) ((uint32_t) &((struct stype *)0)->member)
+#define RELOC(base,stype,member) ((base) + OFFSET_OF(stype, member))
+
+#define RROTATE32(val32) (((val32) << 31) | ((val32) >> 1))
+#define LROTATE32(val32) (((val32) << 1) | ((val32) >> 31))
+
+/* ------------------------------------------------------------------------- */
+
+/* Aligned (32bit register) read/write access */
+#define RD16(addr16) (*(volatile uint32_t *)(addr16))
+#define WR16(addr16,val16) (*(volatile uint32_t *)(addr16))=(val16)
+#define RD32(addr32) (*(volatile uint32_t *)(addr32))
+#define WR32(addr32,val32) (*(volatile uint32_t *)(addr32))=(val32)
+
+/*---------------------------------------------------------------------------*/
+
+/* Forward declaration */
+_INLINE_ void fill_memory( uint32_t * addr, uint32_t bytes, uint32_t fill32)
+ _ALWAYS_INLINE_;
+_INLINE_ void fill_alt_memory(uint32_t * addr, uint32_t bytes,
+ uint32_t fillA32, uint32_t fillB32) _ALWAYS_INLINE_;
+
+void fill_memory( uint32_t * addr, uint32_t bytes, uint32_t fill32)
+{
+ uint32_t * at, * end_p;
+ uint32_t words;
+ words = bytes / sizeof(uint32_t);
+ if ( words == 0 ) return;
+
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ WR32( at, fill32 );
+}
+
+void fill_alt_memory( uint32_t * addr, uint32_t bytes,
+ uint32_t fillA32, uint32_t fillB32)
+{
+ uint32_t * at, * end_p;
+ uint32_t words;
+ words = bytes / sizeof(uint32_t);
+ words = ROUNDDN( words, 2 );
+ if ( words == 0 ) return;
+
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at+=2 )
+ {
+ WR32( at+0, fillA32 );
+ WR32( at+1, fillB32 );
+ }
+}
+
+/* Forward declaration */
+_INLINE_ MemTestResult_t scanWordValue( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanBulkValue( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanBulkAltInv( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanWordSelf( uint32_t * addr, uint32_t bytes )
+ _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanBulkSelf( uint32_t * addr, uint32_t bytes )
+ _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t slidingAltInv( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t slidingDiag( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t memoryBulkCopy( uint32_t * saddr, uint32_t * daddr,
+ uint32_t bytes ) _ALWAYS_INLINE_;
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanWordValue
+ *
+ * Description:
+ * 4 Passes are conducted on the memory region.
+ * Pass 1. In INcreasing memory address, write a word with value and verify.
+ * Pass 2. In DEcreasing memory address, write a word with value and verify.
+ * Pass 3. In INcreasing memory address, write a word with INVERSE and verify.
+ * Pass 4. In DEcreasing memory address, write a word with INVERSE and verify.
+ * Pass 5. In INcreasing shifted memory address, write word with value verify.
+ * Pass 6. In INcreasing shifted memory address, write word with INVERSE verify.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: 32bit pattern, e.g. 0x0U, 0xAAAAAAAA, 0xFF00FF00, 0xFFFF0000,
+ * 0xF0F0F0F0, 0xC3C3C3C3, 0x87878787
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanWordValue( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 )
+ return MEMTEST_ERROR;
+
+ expected = pat32; /* ORIGINAL value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* PASS 5: Shifting address walk, ORIGINAL */
+ expected = pat32; /* ORIGINAL value */
+
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+
+ /* PASS 6: Shifting address walk, INVERSE */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanBulkValue
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with value
+ * then in INcreasing memory address read and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with value
+ * then in DEcreasing memory address read and verify.
+ * Pass 3. Fill entire memory in INcreasing memory address with inverse value
+ * then in INcreasing memory address read and verify.
+ * Pass 4. Fill entire memory in DEcreasing memory address with inverse value
+ * then in DEcreasing memory address read and verify.
+ * Pass 5. INcreasing shifted, ORIGINAL
+ * Pass 6. INcreasing shifted, INVERSE
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: 32bit pattern, e.g. 0x0U, 0xAAAAAAAA, 0xFF00FF00, 0xFFFF0000,
+ * 0xF0F0F0F0, 0xC3C3C3C3, 0x87878787
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanBulkValue( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ expected = pat32; /* ORIGINAL value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* Pass 5. INCREASING Shifted traversal */
+ expected = pat32; /* ORIGINAL value */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanBulkAltInv
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with alternating
+ * value, then in INcreasing memory address read and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with alternating
+ * value, then in DEcreasing memory address read and verify.
+ * Pass 3. Same as one but with shifted address.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: 32bit pattern, e.g. 0x0U, 0xAAAAAAAA, 0xFF00FF00, 0xFFFF0000,
+ * 0xF0F0F0F0, 0xC3C3C3C3, 0x87878787
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanBulkAltInv( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ words = ROUNDDN( words, 2 );
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at+=2 )
+ {
+ WR32( at+0, pat32 );
+ WR32( at+1, ~pat32 );
+ }
+ for ( at = addr; at < end_p; at+=2 )
+ {
+ read = RD32( at+0 );
+ if ( read != pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ read = RD32( at+1 );
+ if ( read != ~pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-=2 )
+ {
+ WR32( at+0, pat32 );
+ WR32( at+1, ~pat32 );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-=2 )
+ {
+ read = RD32( at+0 );
+ if ( read != pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ read = RD32( at+1 );
+ if ( read != ~pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING SHIFTED traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at+0, pat32 );
+ WR32( addr, 0 );
+ WR32( at+1, ~pat32 );
+ WR32( addr, 0 );
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32( at+0 );
+ if ( read != pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ read = RD32( at+1 );
+ if ( read != ~pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanWordSelf
+ *
+ * Description:
+ * 4 Passes are conducted on the memory region.
+ * Pass 1. In INcreasing memory address, write a word with selfaddr and verify.
+ * Pass 2. In DEcreasing memory address, write a word with INVERSE and verify.
+ * Pass 3. In INcreasing memory address, write a word with INVERSE and verify.
+ * Pass 4. In DEcreasing memory address, write a word with selfaddr and verify.
+ * Pass 5. value = ORIGINAL address, INCREASING SHIFTED traversal.
+ * Pass 6. value = INVERSE address, INCREASING SHIFTED traversal.
+ *
+ * In Pass 2 Read+Modify+Write, and in Pass 3, Read+Write is used
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ *
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanWordSelf( uint32_t * addr, uint32_t bytes )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_FAILURE;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ /* ORIGINAL value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ expected = (uint32_t)at;
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ expected = ~( (uint32_t)RD32(at) );
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ expected = ((uint32_t)RD32(at));
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ expected = ~((uint32_t)at);
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* value = ORIGINAL address, INCREASING SHIFTED traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ expected = (uint32_t)at; /* Not read modify write */
+ WR32( at, expected );
+ WR32( addr, ~expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* value = INVERSE address, INCREASING SHIFTED traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ expected = ~(uint32_t)(at); /* Not read modify write */
+ WR32( at, expected );
+ WR32( addr, ~expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanBulkSelf
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with self address
+ * then in INcreasing memory address read and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with self address
+ * then in DEcreasing memory address read and verify.
+ * Pass 3. Fill entire memory in INcreasing memory address with inverse addr
+ * then in INcreasing memory address read and verify.
+ * Pass 4. Fill entire memory in DEcreasing memory address with inverse addr
+ * then in DEcreasing memory address read and verify.
+ * Pass 5. Same as Pass 1 but with shifted address
+ * Pass 6. Same as Pass 3 but with shifted address
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanBulkSelf( uint32_t * addr, uint32_t bytes )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, (uint32_t)at );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != (uint32_t)at )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, (uint32_t)at );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != (uint32_t)at )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, ~((uint32_t)at) );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != ~((uint32_t)at) )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, ~((uint32_t)at) );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != ~((uint32_t)at) )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, (uint32_t)at );
+ WR32( addr, ~((uint32_t)at) );
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != (uint32_t)at )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, ~((uint32_t)at) );
+ WR32( addr, ((uint32_t)at) );
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != ~((uint32_t)at) )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: slidingAltInv
+ *
+ * Description:
+ * This is the same as scanBulkAltInv, where in each invocation the value is
+ * rotated to the right. The starting value is usedefined.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: pattern to slide per pass
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t slidingAltInv( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ uint32_t sliding_pat32, i;
+
+ if ( pat32 == 0x0 ) pat32 = 0x80000000;
+ if ( pat32 == ~0x0 ) pat32 = 0x7FFFFFFF;
+
+ sliding_pat32 = pat32;
+
+ for ( i=0; i<32; i++ )
+ {
+ if ( scanBulkAltInv( addr, bytes, sliding_pat32 )
+ == MEMTEST_FAILURE )
+ {
+ return MEMTEST_FAILURE;
+ }
+
+ sliding_pat32 = RROTATE32( sliding_pat32 );
+ }
+
+ sliding_pat32 = pat32;
+ for (i=0; i<32; i++)
+ {
+ if ( scanBulkAltInv( addr, bytes, sliding_pat32 )
+ == MEMTEST_FAILURE )
+ {
+ return MEMTEST_FAILURE;
+ }
+
+ sliding_pat32 = LROTATE32( sliding_pat32 );
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: slidingDiag
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with pattern right
+ * shifted. Then read in INcreasing order and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with inverse of
+ * read value. Then read in DEcreasing order and verify.
+ * Pass 3. Fill entire memory in DEcreasing memory address with pattern right
+ * shifted. Then read in DEcreasing order and verify.
+ * Pass 4. Fill entire memory in INcreasing memory address with inverse of
+ * read value. Then read in INcreasing order and verify.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: pattern to be filled shifted each write
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t slidingDiag( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read = 0, words, last;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+
+ /* INCREASING traversal */
+ expected = pat32; /* ORIGINAL value */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ expected = RROTATE32( expected ); /* next expected */
+ }
+ expected = pat32; /* ORIGINAL value */
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = RROTATE32( expected ); /* next expected */
+ }
+
+ last = ~( read ); /* Starting value for decreasing traversal, next */
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ expected = ~( RD32(at) );
+ WR32( at, expected );
+ }
+ expected = last;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = LROTATE32( expected );
+ }
+
+ /* DECREASING traversal */
+ expected = pat32; /* ORIGINAL value */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ expected = RROTATE32( expected ); /* next expected */
+ }
+ expected = pat32; /* ORIGINAL value */
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = RROTATE32( expected ); /* next expected */
+ }
+
+ last = ~( read );
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ expected = ~( RD32(at) );
+ WR32( at, expected );
+ }
+ expected = last;
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = LROTATE32( expected );
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: memoryBulkCopy
+ *
+ * Description:
+ * Pass 1. Copy entire ORIGINAL memory in INcreasing memory address, then verify
+ * Pass 2. Copy entire ORIGINAL memory in DEcreasing memory address, then verify
+ * Pass 3. Copy entire INVERSE memory in INcreasing memory address, then verify
+ * Pass 4. Copy entire INVERSE memory in DEcreasing memory address, then verify
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t memoryBulkCopy( uint32_t * saddr, uint32_t * daddr,
+ uint32_t bytes )
+{
+ volatile uint32_t * src_p, * dst_p, * end_p;
+ uint32_t expected, read, words;
+
+ if ( ! IS_ALIGNED(saddr,4) ) return MEMTEST_ERROR;
+ if ( ! IS_ALIGNED(daddr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ if ( (uint32_t)saddr < (uint32_t)daddr )
+ {
+ if ( (uint32_t)(saddr + words) > (uint32_t)daddr )
+ return MEMTEST_ERROR;
+ }
+ else if ( (uint32_t)daddr < (uint32_t)saddr )
+ {
+ if ( (uint32_t)(daddr + words) > (uint32_t)saddr )
+ return MEMTEST_ERROR;
+ }
+
+ /* INCREASING traversal ORIGINAL */
+ end_p = saddr + words;
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = RD32( dst_p );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = RD32( dst_p );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal ORIGINAL */
+ end_p = saddr;
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = RD32( dst_p );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = RD32( dst_p );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal INVERSE */
+ end_p = saddr + words;
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = ~( RD32( dst_p ) );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = ~( RD32( dst_p ) );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal INVERSE */
+ end_p = saddr;
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = ~( RD32( dst_p ) );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = ~( RD32( dst_p ) );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*---------------------------------------------------------------------------*/
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/rom_cfe.mk b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/rom_cfe.mk
new file mode 100755
index 0000000..c45aea7
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/rom_cfe.mk
@@ -0,0 +1,370 @@
+
+#
+# CFE's version number
+#
+
+include ${TOP}/main/cfe_version.mk
+
+#
+# Default values for certain parameters
+#
+
+CFG_MLONG64 ?= 0
+CFG_LITTLE ?= 0
+CFG_RELOC ?= 0
+CFG_UNCACHED ?= 0
+CFG_NEWRELOC ?= 0
+CFG_BOOTRAM ?= 0
+CFG_VGACONSOLE ?= 0
+CFG_PCI ?= 1
+CFG_LDT_REV_017 ?= 0
+CFG_ZLIB ?= 0
+CFG_BIENDIAN ?= 0
+CFG_DOWNLOAD ?= 0
+CFG_RAMAPP ?= 0
+CFG_USB ?= 0
+
+#
+# Paths to other parts of the firmware. Everything's relative to ${TOP}
+# so that you can actually do a build anywhere you want.
+#
+
+ARCH_TOP = ${TOP}/arch/${ARCH}
+ARCH_SRC = ${ARCH_TOP}/common/src
+ARCH_INC = ${ARCH_TOP}/common/include
+CPU_SRC = ${ARCH_TOP}/cpu/${CPU}/src
+CPU_INC = ${ARCH_TOP}/cpu/${CPU}/include
+#
+# It's actually optional to have a 'board'
+# directory. If you don't specify BOARD,
+# don't include the files.
+#
+
+ifneq ("$(strip ${BOARD})","")
+BOARD_SRC = ${ARCH_TOP}/board/${BOARD}/src
+BOARD_INC = ${ARCH_TOP}/board/${BOARD}/include
+endif
+
+#
+# Preprocessor defines for CFE's version number
+#
+
+VDEF = -DCFE_VER_MAJ=${CFE_VER_MAJ} -DCFE_VER_MIN=${CFE_VER_MIN} -DCFE_VER_ECO=${CFE_VER_ECO}
+
+#
+# Construct the list of paths that will eventually become the include
+# paths and VPATH
+#
+
+SRCDIRS = ${ARCH_SRC} ${CPU_SRC} ${BOARD_SRC} ${TOP}/main ${TOP}/vendor ${TOP}/include ${TOP}/net ${TOP}/dev ${TOP}/pci ${TOP}/ui ${TOP}/lib ${TOP}/common ${TOP}/verif ${TOP}/lzma
+
+CFE_INC = ${TOP}/include ${TOP}/pci ${TOP}/net
+
+ifeq ($(strip ${CFG_VGACONSOLE}),1)
+SRCDIRS += ${TOP}/x86emu ${TOP}/pccons
+CFE_INC += ${TOP}/x86emu ${TOP}/pccons
+endif
+
+ifeq ($(strip ${CFG_VAPI}),1)
+SRCDIRS += ${TOP}/verif
+CFE_INC += ${TOP}/verif
+endif
+
+ifeq ($(strip ${CFG_ZLIB}),1)
+SRCDIRS += ${TOP}/zlib
+CFE_INC += ${TOP}/zlib
+endif
+
+
+INCDIRS = $(patsubst %,-I%,$(subst :, ,$(ARCH_INC) $(CPU_INC) $(BOARD_INC) $(CFE_INC)))
+
+VPATH = $(SRCDIRS)
+
+#
+# Bi-endian support: If we're building the little-endian
+# version, use a different linker script so we can locate the
+# ROM at a higher address. You'd think we could do this with
+# normal linker command line switches, but there appears to be no
+# command-line way to override the 'AT' qualifier in the linker script.
+#
+
+CFG_TEXTAT1MB=0
+ifeq ($(strip ${CFG_BIENDIAN}),1)
+ ifeq ($(strip ${CFG_LITTLE}),1)
+ CFG_TEXTAT1MB=1
+ endif
+endif
+
+
+#
+# Configure tools and basic tools flags. This include sets up
+# macros for calling the C compiler, basic flags,
+# and linker scripts.
+#
+
+include ${ARCH_SRC}/tools.mk
+
+#
+# Add some common flags that are used on any architecture.
+#
+
+CFLAGS += -I. $(INCDIRS)
+CFLAGS += -D_CFE_ ${VDEF} -DCFG_BOARDNAME=\"${CFG_BOARDNAME}\"
+
+#
+# Gross - allow more options to be supplied from command line
+#
+
+ifdef CFG_OPTIONS
+OPTFLAGS = $(patsubst %,-D%,$(subst :, ,$(CFG_OPTIONS)))
+CFLAGS += ${OPTFLAGS}
+endif
+
+ifeq ($(strip $(BRCM_IKOS)),y)
+CFLAGS += -DCONFIG_BRCM_IKOS
+endif
+
+#
+# Add flash driver support.
+#
+
+ifeq ($(strip $(BLD_NAND)),1)
+# BUILD NAND flash boot loader
+ifeq ($(strip $(BRCM_CHIP)),6328)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=0
+INC_NAND_FLASH_DRIVER=1
+endif
+ifeq ($(strip $(BRCM_CHIP)),6362)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=0
+INC_NAND_FLASH_DRIVER=1
+endif
+ifeq ($(strip $(BRCM_CHIP)),6368)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=0
+INC_NAND_FLASH_DRIVER=1
+endif
+ifeq ($(strip $(BRCM_CHIP)),6816)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=0
+INC_NAND_FLASH_DRIVER=1
+endif
+
+else
+# BUILD NOR flash boot loader
+ifeq ($(strip $(BRCM_CHIP)),6328)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=1
+INC_NAND_FLASH_DRIVER=0
+endif
+ifeq ($(strip $(BRCM_CHIP)),6362)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=1
+INC_NAND_FLASH_DRIVER=0
+endif
+ifeq ($(strip $(BRCM_CHIP)),6368)
+INC_CFI_FLASH_DRIVER=1
+INC_SPI_FLASH_DRIVER=1
+INC_NAND_FLASH_DRIVER=0
+endif
+ifeq ($(strip $(BRCM_CHIP)),6816)
+INC_CFI_FLASH_DRIVER=1
+INC_SPI_FLASH_DRIVER=1
+INC_NAND_FLASH_DRIVER=0
+endif
+endif
+
+ifeq ($(strip $(BLD_SPI_NAND)),1)
+INC_CFI_FLASH_DRIVER=0
+INC_SPI_FLASH_DRIVER=1
+INC_NAND_FLASH_DRIVER=0
+INC_SPI_PROG_NAND=1
+else
+INC_SPI_PROG_NAND=0
+endif
+
+CFLAGS += -DINC_CFI_FLASH_DRIVER=$(INC_CFI_FLASH_DRIVER)
+CFLAGS += -DINC_SPI_FLASH_DRIVER=$(INC_SPI_FLASH_DRIVER)
+CFLAGS += -DINC_NAND_FLASH_DRIVER=$(INC_NAND_FLASH_DRIVER)
+CFLAGS += -DINC_SPI_PROG_NAND=$(INC_SPI_PROG_NAND)
+
+#
+# This is the makefile's main target. Note that we actually
+# do most of the work in 'ALL' not 'all', since we include
+# other makefiles after this point.
+#
+
+all : build_date.c ALL
+
+#
+# Macros that expand to the list of arch-independent files
+#
+
+LZMAOBJS = LzmaDecode.o dcapi.o
+DEVOBJS = lib_malloc.o
+## dev_newflash.o dev_null.o dev_promice.o dev_ide_common.o dev_ns16550.o dev_ds17887clock.o dev_flash.o
+
+##lib_hssubr.o lib_physio.o lib_printf.o lib_misc.o \ lib_arena.o lib_queue.o
+## lib_qsort.o lib_string.o lib_string2.o
+
+NETOBJS =
+## net_tcp.o net_tcpbuf.o dev_tcpconsole.o net_dhcp.o net_icmp.o net_ether.o net_tftp.o net_ip.o net_udp.o net_dns.o net_arp.o net_api.o
+
+CFEOBJS =
+## cfe_iocb_dispatch.o cfe_devfuncs.o \ cfe_console.o cfe_timer.o cfe_attach.o cfe_background.o cfe_zlibfs.o
+## cfe_mem.o
+## cfe_error.o build_date.o \
+## cfe_rawfs.o cfe_xreq.o cfe_filesys.o
+## cfe_fatfs.o cfe_httpfs.o cfe_ldr_srec.o cfe_autoboot.o cfe_boot.o cfe_ldr_elf.o cfe_ldr_raw.o cfe_loader.o
+## cfe_main.o nvram_subr.o url.o cfe_savedata.o env_subr.o
+UIOBJS =
+##ui_command.o ui_cmddisp.o
+## ui_pcicmds.o \ui_tcpcmds.o ui_memcmds.o ui_loadcmds.o ui_flash.o ui_netcmds.o ui_envcmds.o ui_devcmds.o
+## ui_examcmds.o ui_misccmds.o \
+## ui_test_disk.o ui_test_ether.o ui_test_flash.o ui_test_uart.o
+
+#
+# Add more object files if we're supporting PCI
+#
+
+ifeq ($(strip ${CFG_PCI}),1)
+PCIOBJS = pciconf.o ldtinit.o pci_subr.o
+PCIOBJS += pci_devs.o
+DEVOBJS += dev_sp1011.o dev_ht7520.o
+DEVOBJS += dev_ide_pci.o dev_ns16550_pci.o
+DEVOBJS += dev_tulip.o dev_dp83815.o
+CFLAGS += -DCFG_PCI=1
+ifeq ($(strip ${CFG_LDT_REV_017}),1)
+CFLAGS += -DCFG_LDT_REV_017=1
+endif
+ifeq ($(strip ${CFG_DOWNLOAD}),1)
+DEVOBJS += dev_bcm1250.o download.data
+CFLAGS += -DCFG_DOWNLOAD=1
+endif
+endif
+
+#
+# If doing bi-endian, add the compiler switch to change
+# the way the vectors are generated. These switches are
+# only added to the big-endian portion of the ROM,
+# which is located at the real boot vector.
+#
+
+ifeq ($(strip ${CFG_BIENDIAN}),1)
+ ifeq ($(strip ${CFG_LITTLE}),0)
+ CFLAGS += -DCFG_BIENDIAN=1
+ endif
+endif
+
+#
+# Include the makefiles for the architecture-common, cpu-specific,
+# and board-specific directories. Each of these will supply
+# some files to "ALLOBJS". The BOARD directory is optional
+# as some ports are so simple they don't need boad-specific stuff.
+#
+
+include ${ARCH_SRC}/Makefile
+include ${CPU_SRC}/Makefile
+
+ifneq ("$(strip ${BOARD})","")
+include ${BOARD_SRC}/Makefile
+endif
+
+#
+# Add the common object files here.
+#
+
+ALLOBJS += $(LIBOBJS) $(DEVOBJS) $(CFEOBJS) $(VENOBJS) $(UIOBJS) $(NETOBJS)
+#$(PCIOBJS)
+
+#
+# VAPI continues to be a special case.
+#
+
+ifeq ($(strip ${CFG_VAPI}),1)
+include ${TOP}/verif/Makefile
+endif
+
+#
+# USB support
+#
+
+ifeq ($(strip ${CFG_USB}),1)
+SRCDIRS += ${TOP}/usb
+CFE_INC += ${TOP}/usb
+include ${TOP}/usb/Makefile
+endif
+
+#
+# If we're doing the VGA console thing, pull in the x86 emulator
+# and the pcconsole subsystem
+#
+
+ifeq ($(strip ${CFG_VGACONSOLE}),1)
+include ${TOP}/x86emu/Makefile
+include ${TOP}/pccons/Makefile
+endif
+
+#
+# If we're including ZLIB, then add its makefile.
+#
+
+##ifeq ($(strip ${CFG_ZLIB}),1)
+##include ${TOP}/zlib/Makefile
+CFLAGS += -DCFG_ZLIB=1 -DMY_ZCALLOC -DNO_MEMCPY
+##endif
+
+.PHONY : all
+.PHONY : ALL
+.PHONY : build_date.c
+
+#
+# Build the local tools that we use to construct other source files
+#
+
+mkpcidb : ${TOP}/hosttools/mkpcidb.c
+ gcc -o mkpcidb ${TOP}/hosttools/mkpcidb.c
+
+memconfig : ${TOP}/hosttools/memconfig.c
+ gcc -o memconfig -D_MCSTANDALONE_ -D_MCSTANDALONE_NOISY_ -I${TOP}/arch/mips/cpu/sb1250/include ${TOP}/hosttools/memconfig.c ${TOP}/arch/${ARCH}/cpu/${CPU}/src/sb1250_draminit.c
+
+pcidevs_data2.h : mkpcidb ${TOP}/pci/pcidevs_data.h
+ ./mkpcidb > pcidevs_data2.h
+
+mkflashimage : ${TOP}/hosttools/mkflashimage.c
+ gcc -o mkflashimage -I${TOP}/include ${TOP}/hosttools/mkflashimage.c
+
+pci_subr.o : ${TOP}/pci/pci_subr.c pcidevs_data2.h
+
+##build_date.c :
+## echo "const char *builddate = \"`date`\";" > build_date.c
+## echo "const char *builduser = \"`whoami`@`hostname`\";" >> build_date.c
+
+#
+# Make a define for the board name
+#
+
+CFLAGS += -D_$(patsubst "%",%,${CFG_BOARDNAME})_
+
+LIBCFE = libcfe.a
+
+%.o : %.c
+ $(GCC) $(CFLAGS) -o $@ $<
+
+%.o : %.S
+ $(GCC) $(CFLAGS) -o $@ $<
+
+#
+# This rule constructs "libcfe.a" which contains most of the object
+# files.
+#
+
+$(LIBCFE) : $(ALLOBJS)
+ rm -f $(LIBCFE)
+ $(AR) cr $(LIBCFE) $(ALLOBJS)
+ $(RANLIB) $(LIBCFE)
+
+
+
+