summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips')
-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
-rw-r--r--cfe/cfe/arch/mips/common/include/addrspace.h63
-rw-r--r--cfe/cfe/arch/mips/common/include/disasm.h61
-rw-r--r--cfe/cfe/arch/mips/common/include/exception.h223
-rw-r--r--cfe/cfe/arch/mips/common/include/exchandler.h85
-rw-r--r--cfe/cfe/arch/mips/common/include/initdata.h68
-rw-r--r--cfe/cfe/arch/mips/common/include/lib_hssubr.h84
-rw-r--r--cfe/cfe/arch/mips/common/include/lib_physio.h100
-rw-r--r--cfe/cfe/arch/mips/common/include/lib_setjmp.h81
-rwxr-xr-xcfe/cfe/arch/mips/common/include/mipsmacros.h376
-rwxr-xr-xcfe/cfe/arch/mips/common/include/segtable.h97
-rwxr-xr-xcfe/cfe/arch/mips/common/src/Makefile38
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds40
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds40
-rwxr-xr-xcfe/cfe/arch/mips/common/src/cfe_ramapp.lds41
-rwxr-xr-xcfe/cfe/arch/mips/common/src/cfe_rom_cached.lds40
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds43
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds49
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds41
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds39
-rw-r--r--cfe/cfe/arch/mips/common/src/dev_flash_all.S220
-rw-r--r--cfe/cfe/arch/mips/common/src/dev_flashop_engine.S695
-rw-r--r--cfe/cfe/arch/mips/common/src/disasm.c2111
-rw-r--r--cfe/cfe/arch/mips/common/src/exception.S546
-rw-r--r--cfe/cfe/arch/mips/common/src/exchandler.c580
-rwxr-xr-xcfe/cfe/arch/mips/common/src/init_mips.S683
-rwxr-xr-xcfe/cfe/arch/mips/common/src/init_ram.S889
-rw-r--r--cfe/cfe/arch/mips/common/src/lib_hssubr.S194
-rw-r--r--cfe/cfe/arch/mips/common/src/lib_physio.S173
-rw-r--r--cfe/cfe/arch/mips/common/src/lib_setjmp.S94
-rw-r--r--cfe/cfe/arch/mips/common/src/mips_arena.c186
-rwxr-xr-xcfe/cfe/arch/mips/common/src/tools.mk83
-rw-r--r--cfe/cfe/arch/mips/common/src/ui_memtest.c282
-rw-r--r--cfe/cfe/arch/mips/cpu/SIBYTE_PRIVATE_FILES2
-rw-r--r--cfe/cfe/arch/mips/cpu/bcmcore/include/bcm4710.h58
-rw-r--r--cfe/cfe/arch/mips/cpu/bcmcore/include/bcm47xx.h8
-rw-r--r--cfe/cfe/arch/mips/cpu/bcmcore/include/bcmnvram.h123
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/include/cpu_config.h62
-rw-r--r--cfe/cfe/arch/mips/cpu/bcmcore/include/sbmips.h670
-rw-r--r--cfe/cfe/arch/mips/cpu/bcmcore/include/sbsdram.h92
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/Makefile8
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c170
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S490
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S219
79 files changed, 26528 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)
+
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/addrspace.h b/cfe/cfe/arch/mips/common/include/addrspace.h
new file mode 100644
index 0000000..6330851
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/addrspace.h
@@ -0,0 +1,63 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Address space macros File: addrspace.h
+ *
+ * Macros to deal with physical, virtual, and uncached addresses.
+ * for MIPS, these map to the appropriate KSEG0/KSEG1 macros
+ *
+ * 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 "sbmips.h"
+
+#define PHYSADDR(x) K0_TO_PHYS(x)
+
+/* If running uncached, force all kernel addresses to be uncached */
+#if CFG_RUNFROMKSEG0
+#define KERNADDR(x) PHYS_TO_K0(x)
+#else
+#define KERNADDR(x) PHYS_TO_K1(x)
+#endif
+
+#define UNCADDR(x) PHYS_TO_K1(x)
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/disasm.h b/cfe/cfe/arch/mips/common/include/disasm.h
new file mode 100644
index 0000000..8a8e7b7
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/disasm.h
@@ -0,0 +1,61 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS disassembler File: disasm.h
+ *
+ * MIPS disassembler (used by ui_examcmds.c)
+ *
+ * Author: Justin Carlson (carlson@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.
+ ********************************************************************* */
+
+#ifndef DISASM_H
+#define DISASM_H
+
+/* Returns a pointer to a read-only string containing the intstruction name */
+char *disasm_inst_name(uint32_t inst);
+
+/* Copies a disassembled version of the instruction into buf, null terminating the
+string. Will not exceed buf_size bytes written; if the disassembled string is
+longer than buf_size, buf_size-1 bytes of the string will be written and that string
+will be null-terminated */
+void disasm_inst(char *buf, int buf_size, uint32_t inst, uint64_t pc);
+#endif
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/exception.h b/cfe/cfe/arch/mips/common/include/exception.h
new file mode 100644
index 0000000..70e87c2
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/exception.h
@@ -0,0 +1,223 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Exception/trap handler defs File: exception.h
+ *
+ * This module describes the exception handlers, exception
+ * trap frames, and dispatch.
+ *
+ * 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.
+ ********************************************************************* */
+
+#ifdef __ASSEMBLER__
+#define _XAIDX(x) (8*(x))
+#else
+#define _XAIDX(x) (x)
+#endif
+
+
+/* *********************************************************************
+ * Exception vectors from the MIPS specification
+ ********************************************************************* */
+
+#define MIPS_ROM_VEC_RESET 0x0000
+#define MIPS_ROM_VEC_TLBFILL 0x0200
+#define MIPS_ROM_VEC_XTLBFILL 0x0280
+#define MIPS_ROM_VEC_CACHEERR 0x0300
+#define MIPS_ROM_VEC_EXCEPTION 0x0380
+#define MIPS_ROM_VEC_INTERRUPT 0x0400
+#define MIPS_ROM_VEC_EJTAG 0x0480
+
+#define MIPS_RAM_VEC_TLBFILL 0x0000
+#define MIPS_RAM_VEC_XTLBFILL 0x0080
+#define MIPS_RAM_VEC_EXCEPTION 0x0180
+#define MIPS_RAM_VEC_INTERRUPT 0x0200
+#define MIPS_RAM_VEC_CACHEERR 0x0100
+#define MIPS_RAM_VEC_END 0x0300
+
+#define MIPS_RAM_EXL_VEC_TLBFILL 0x0100
+#define MIPS_RAM_EXL_VEC_XTLBFILL 0x0180
+
+
+/* *********************************************************************
+ * Fixed locations of other low-memory objects. We stuff some
+ * important data in the spaces between the vectors.
+ ********************************************************************* */
+
+#define CFE_LOCORE_GLOBAL_GP 0x0040 /* our "handle" */
+#define CFE_LOCORE_GLOBAL_SP 0x0048 /* Stack pointer for exceptions */
+#define CFE_LOCORE_GLOBAL_K0TMP 0x0050 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_K1TMP 0x0058 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_RATMP 0x0060 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_GPTMP 0x0068 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_CERRH 0x0070 /* Pointer to cache error handler */
+
+#define CFE_LOCORE_GLOBAL_T0TMP 0x0240 /* used by cache error handler */
+#define CFE_LOCORE_GLOBAL_T1TMP 0x0248 /* used by cache error handler */
+#define CFE_LOCORE_GLOBAL_T2TMP 0x0250 /* used by cache error handler */
+#define CFE_LOCORE_GLOBAL_T3TMP 0x0258 /* used by cache error handler */
+
+/* *********************************************************************
+ * Offsets into our exception handler table.
+ ********************************************************************* */
+
+#define XTYPE_RESET 0
+#define XTYPE_TLBFILL 8
+#define XTYPE_XTLBFILL 16
+#define XTYPE_CACHEERR 24
+#define XTYPE_EXCEPTION 32
+#define XTYPE_INTERRUPT 40
+#define XTYPE_EJTAG 48
+
+/* *********************************************************************
+ * Exception frame definitions.
+ ********************************************************************* */
+
+/*
+ * The exception frame is divided up into pieces, representing the different
+ * parts of the processor that the data comes from:
+ *
+ * CP0: Words 0..7
+ * Int Regs: Words 8..41
+ * FP Regs: Words 42..73
+ * Total size: 74 words
+ */
+
+#define EXCEPTION_SIZE _XAIDX(74)
+
+#define XCP0_BASE 0
+#define XGR_BASE 8
+#define XFR_BASE 42
+
+#define _XCP0IDX(x) _XAIDX((x)+XCP0_BASE)
+#define XCP0_SR _XCP0IDX(0)
+#define XCP0_CAUSE _XCP0IDX(1)
+#define XCP0_EPC _XCP0IDX(2)
+#define XCP0_VADDR _XCP0IDX(3)
+#define XCP0_PRID _XCP0IDX(4)
+
+#define _XGRIDX(x) _XAIDX((x)+XGR_BASE)
+#define XGR_ZERO _XGRIDX(0)
+#define XGR_AT _XGRIDX(1)
+#define XGR_V0 _XGRIDX(2)
+#define XGR_V1 _XGRIDX(3)
+#define XGR_A0 _XGRIDX(4)
+#define XGR_A1 _XGRIDX(5)
+#define XGR_A2 _XGRIDX(6)
+#define XGR_A3 _XGRIDX(7)
+#define XGR_T0 _XGRIDX(8)
+#define XGR_T1 _XGRIDX(9)
+#define XGR_T2 _XGRIDX(10)
+#define XGR_T3 _XGRIDX(11)
+#define XGR_T4 _XGRIDX(12)
+#define XGR_T5 _XGRIDX(13)
+#define XGR_T6 _XGRIDX(14)
+#define XGR_T7 _XGRIDX(15)
+#define XGR_S0 _XGRIDX(16)
+#define XGR_S1 _XGRIDX(17)
+#define XGR_S2 _XGRIDX(18)
+#define XGR_S3 _XGRIDX(19)
+#define XGR_S4 _XGRIDX(20)
+#define XGR_S5 _XGRIDX(21)
+#define XGR_S6 _XGRIDX(22)
+#define XGR_S7 _XGRIDX(23)
+#define XGR_T8 _XGRIDX(24)
+#define XGR_T9 _XGRIDX(25)
+#define XGR_K0 _XGRIDX(26)
+#define XGR_K1 _XGRIDX(27)
+#define XGR_GP _XGRIDX(28)
+#define XGR_SP _XGRIDX(29)
+#define XGR_FP _XGRIDX(30)
+#define XGR_RA _XGRIDX(31)
+#define XGR_LO _XGRIDX(32)
+#define XGR_HI _XGRIDX(33)
+
+
+#define _XFRIDX(x) _XAIDX((x)+XFR_BASE)
+#define XR_F0 _XFRIDX(0)
+#define XR_F1 _XFRIDX(1)
+#define XR_F2 _XFRIDX(2)
+#define XR_F3 _XFRIDX(3)
+#define XR_F4 _XFRIDX(4)
+#define XR_F5 _XFRIDX(5)
+#define XR_F6 _XFRIDX(6)
+#define XR_F7 _XFRIDX(7)
+#define XR_F8 _XFRIDX(8)
+#define XR_F9 _XFRIDX(9)
+#define XR_F10 _XFRIDX(10)
+#define XR_F11 _XFRIDX(11)
+#define XR_F12 _XFRIDX(12)
+#define XR_F13 _XFRIDX(13)
+#define XR_F14 _XFRIDX(14)
+#define XR_F15 _XFRIDX(15)
+#define XR_F16 _XFRIDX(16)
+#define XR_F17 _XFRIDX(17)
+#define XR_F18 _XFRIDX(18)
+#define XR_F19 _XFRIDX(19)
+#define XR_F20 _XFRIDX(20)
+#define XR_F21 _XFRIDX(21)
+#define XR_F22 _XFRIDX(22)
+#define XR_F23 _XFRIDX(23)
+#define XR_F24 _XFRIDX(24)
+#define XR_F25 _XFRIDX(25)
+#define XR_F26 _XFRIDX(26)
+#define XR_F27 _XFRIDX(27)
+#define XR_F28 _XFRIDX(28)
+#define XR_F29 _XFRIDX(29)
+#define XR_F30 _XFRIDX(30)
+#define XR_F31 _XFRIDX(31)
+#define XR_FCR _XFRIDX(32)
+#define XR_FID _XFRIDX(33)
+
+
+#ifndef __ASSEMBLER__
+extern void _exc_setvector(int vectype, void *vecaddr);
+extern void _exc_crash_sim(void);
+extern void _exc_cache_crash_sim(void);
+extern void _exc_restart(void);
+extern void _exc_clear_sr_exl(void);
+extern void _exc_clear_sr_erl(void);
+void cfe_exception(int code,uint64_t *info);
+void cfe_setup_exceptions(void);
+#endif
+
+
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/exchandler.h b/cfe/cfe/arch/mips/common/include/exchandler.h
new file mode 100644
index 0000000..af268f1
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/exchandler.h
@@ -0,0 +1,85 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Exception Handler definitions File: exchandler.h
+ *
+ * Exception handler functions and constants
+ *
+ * Author: Binh Vo (binh@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.
+ ********************************************************************* */
+
+
+#ifndef _LIB_SETJMP_H
+#include "lib_setjmp.h"
+#endif
+
+#ifndef _LIB_QUEUE_H
+#include "lib_queue.h"
+#endif
+
+#define MEM_BYTE 1
+#define MEM_HALFWORD 2
+#define MEM_WORD 3
+#define MEM_QUADWORD 4
+
+#define EXC_NORMAL_RETURN 0
+#define EXC_CHAIN_EXC 1
+
+typedef struct jmpbuf_s {
+ queue_t stack;
+ jmp_buf jmpbuf;
+} jmpbuf_t;
+
+typedef struct exc_handler_s {
+ int catch_exc;
+ int chain_exc;
+ queue_t jmpbuf_stack;
+} exc_handler_t;
+
+extern exc_handler_t exc_handler;
+
+jmpbuf_t *exc_initialize_block(void);
+void exc_cleanup_block(jmpbuf_t *);
+void exc_cleanup_handler(jmpbuf_t *, int);
+void exc_longjmp_handler(void);
+int mem_peek(void*, long, int);
+int mem_poke(long, uint64_t, int);
+
+
+#define exc_try(jb) (lib_setjmp(((jb)->jmpbuf)))
diff --git a/cfe/cfe/arch/mips/common/include/initdata.h b/cfe/cfe/arch/mips/common/include/initdata.h
new file mode 100644
index 0000000..c5fc0d8
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/initdata.h
@@ -0,0 +1,68 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Data stored in initialization module File: initdata.h
+ *
+ * This file contains data declared by the init module. It also
+ * contains externs for that data so we can keep the types straight.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#if defined(__ASSEMBLER__)
+#define DECLARE_INITVAR(x) \
+ .globl x ; \
+x: _LONG_ 0
+#else
+#define DECLARE_INITVAR(x) \
+ extern long x;
+#endif
+
+DECLARE_INITVAR(mem_textreloc)
+DECLARE_INITVAR(mem_textbase)
+DECLARE_INITVAR(mem_textsize)
+DECLARE_INITVAR(mem_totalsize)
+DECLARE_INITVAR(mem_topofmem)
+DECLARE_INITVAR(mem_heapstart)
+DECLARE_INITVAR(mem_bottomofmem)
+DECLARE_INITVAR(mem_datareloc)
+DECLARE_INITVAR(cpu_prid)
+
+
diff --git a/cfe/cfe/arch/mips/common/include/lib_hssubr.h b/cfe/cfe/arch/mips/common/include/lib_hssubr.h
new file mode 100644
index 0000000..b4df439
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/lib_hssubr.h
@@ -0,0 +1,84 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * "Hyperspace" access routines File: lib_hssubr.h
+ *
+ * Constants, macros, and definitions for routines to deal with
+ * hyperspace (beyond 256MB) on MIPS processors.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#ifndef _LIB_HSSUBR_H
+#define _LIB_HSSUBR_H
+
+/*
+ * If __long64 we can do this via macros. Otherwise, call
+ * the magic functions.
+ */
+
+#if __long64
+
+typedef long hsaddr_t;
+
+#define hs_write8(a,b) *((volatile uint8_t *) (a)) = (b)
+#define hs_write16(a,b) *((volatile uint16_t *) (a)) = (b)
+#define hs_write32(a,b) *((volatile uint32_t *) (a)) = (b)
+#define hs_write64(a,b) *((volatile uint32_t *) (a)) = (b)
+#define hs_read8(a) *((volatile uint8_t *) (a))
+#define hs_read16(a) *((volatile uint16_t *) (a))
+#define hs_read32(a) *((volatile uint32_t *) (a))
+#define hs_read64(a) *((volatile uint64_t *) (a))
+
+#else /* not __long64 */
+
+typedef long long hsaddr_t;
+
+extern void hs_write8(hsaddr_t a,uint8_t b);
+extern void hs_write16(hsaddr_t a,uint16_t b);
+extern void hs_write32(hsaddr_t a,uint32_t b);
+extern void hs_write64(hsaddr_t a,uint64_t b);
+extern uint8_t hs_read8(hsaddr_t a);
+extern uint16_t hs_read16(hsaddr_t a);
+extern uint32_t hs_read32(hsaddr_t a);
+extern uint64_t hs_read64(hsaddr_t a);
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/common/include/lib_physio.h b/cfe/cfe/arch/mips/common/include/lib_physio.h
new file mode 100644
index 0000000..00d0093
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/lib_physio.h
@@ -0,0 +1,100 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical memory peek/poke routines File: lib_physio.h
+ *
+ * Little stub routines to allow access to arbitrary physical
+ * addresses. In most cases this should not be needed, as
+ * many physical addresses are within kseg1, but this handles
+ * the cases that are not automagically, so we don't need
+ * to mess up the code with icky macros and such.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#ifndef _LIB_PHYSIO_H
+#define _LIB_PHYSIO_H
+
+//#ifndef _SB_MIPS_H
+//#include "sbmips.h"
+//#endif
+
+/*
+ * If __long64 we can do this via macros. Otherwise, call
+ * the magic functions.
+ */
+
+#if __long64
+
+typedef long physaddr_t;
+#define _PHYSADDR_T_DEFINED_
+
+/*#define __UNCADDRX(x) PHYS_TO_XKSEG_UNCACHED(x)*/
+#define __UNCADDRX(x) (((physaddr_t)(x))|0x9000000000000000)
+
+
+#define phys_write8(a,b) *((volatile uint8_t *) __UNCADDRX(a)) = (b)
+#define phys_write16(a,b) *((volatile uint16_t *) __UNCADDRX(a)) = (b)
+#define phys_write32(a,b) *((volatile uint32_t *) __UNCADDRX(a)) = (b)
+#define phys_write64(a,b) *((volatile uint64_t *) __UNCADDRX(a)) = (b)
+#define phys_read8(a) *((volatile uint8_t *) __UNCADDRX(a))
+#define phys_read16(a) *((volatile uint16_t *) __UNCADDRX(a))
+#define phys_read32(a) *((volatile uint32_t *) __UNCADDRX(a))
+#define phys_read64(a) *((volatile uint64_t *) __UNCADDRX(a))
+
+#else /* not __long64 */
+
+#ifdef _MIPSREGS32_
+typedef long physaddr_t; /* 32-bit-only processors can't have >32bit pa's */
+#else
+typedef long long physaddr_t; /* Otherwise, they might. */
+#endif
+
+extern void phys_write8(physaddr_t a,uint8_t b);
+extern void phys_write16(physaddr_t a,uint16_t b);
+extern void phys_write32(physaddr_t a,uint32_t b);
+extern void phys_write64(physaddr_t a,uint64_t b);
+extern uint8_t phys_read8(physaddr_t a);
+extern uint16_t phys_read16(physaddr_t a);
+extern uint32_t phys_read32(physaddr_t a);
+extern uint64_t phys_read64(physaddr_t a);
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/common/include/lib_setjmp.h b/cfe/cfe/arch/mips/common/include/lib_setjmp.h
new file mode 100644
index 0000000..b673222
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/lib_setjmp.h
@@ -0,0 +1,81 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * setjmp/longjmp defs File: lib_setjmp.h
+ *
+ * Description of the jmp_buf structure for setjmp and longjmp
+ *
+ * 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.
+ ********************************************************************* */
+
+
+/*
+ * Note that while lib_setjmp() and lib_longjmp() behave like setjmp()
+ * and longjmp() normally do, gcc 3.1.x (and later) assumes things about
+ * how setjmp() and longjmp() should work (even with -fno-builtins). We
+ * don't want it to do those, so these functions must be named differently.
+ */
+
+#ifdef __ASSEMBLER__
+#define _JBIDX(x) (8*(x))
+#else
+#define _JBIDX(x) (x)
+#endif
+
+
+#define JMPB_S0 _JBIDX(0)
+#define JMPB_S1 _JBIDX(1)
+#define JMPB_S2 _JBIDX(2)
+#define JMPB_S3 _JBIDX(3)
+#define JMPB_S4 _JBIDX(4)
+#define JMPB_S5 _JBIDX(5)
+#define JMPB_S6 _JBIDX(6)
+#define JMPB_S7 _JBIDX(7)
+#define JMPB_FP _JBIDX(8)
+#define JMPB_SP _JBIDX(9)
+#define JMPB_RA _JBIDX(10)
+
+#define JMPB_SIZE _JBIDX(11)
+
+#ifndef __ASSEMBLER__
+typedef long long jmp_buf[JMPB_SIZE];
+extern int lib_setjmp(jmp_buf);
+extern void lib_longjmp(jmp_buf,int val);
+#endif
+
diff --git a/cfe/cfe/arch/mips/common/include/mipsmacros.h b/cfe/cfe/arch/mips/common/include/mipsmacros.h
new file mode 100755
index 0000000..072a5e6
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/mipsmacros.h
@@ -0,0 +1,376 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS Macros File: mipsmacros.h
+ *
+ * Macros to deal with various mips-related things.
+ *
+ * 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.
+ ********************************************************************* */
+
+/* *********************************************************************
+ * 32/64-bit macros
+ ********************************************************************* */
+
+#ifdef __long64
+#define _VECT_ .dword
+#define _LONG_ .dword
+#define SR sd
+#define LR ld
+#define ADD dadd
+#define SUB dsub
+#define MFC0 dmfc0
+#define MTC0 dmtc0
+#define REGSIZE 8
+#define BPWSIZE 3 /* bits per word size */
+#define _TBLIDX(x) ((x)*REGSIZE)
+#else
+#define _VECT_ .word
+#define _LONG_ .word
+#define SR sw
+#define LR lw
+#define ADD add
+#define SUB sub
+#define MFC0 mfc0
+#define MTC0 mtc0
+#define REGSIZE 4
+#define BPWSIZE 2
+#define _TBLIDX(x) ((x)*REGSIZE)
+#endif
+
+
+/* *********************************************************************
+ * NORMAL_VECTOR(addr,vecname,vecdest)
+ * NORMAL_XVECTOR(addr,vecname,vecdest,code)
+ *
+ * Declare a trap or dispatch vector. There are two flavors,
+ * DECLARE_XVECTOR sets up an indentifying code in k0 before
+ * jumping to the dispatch routine.
+ *
+ * Input parameters:
+ * addr - vector address
+ * vecname - for label at that address
+ * vecdest - destination (place vector jumps to)
+ * code - code to place in k0 before jumping
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+#define NORMAL_VECTOR(addr,vecname,vecdest) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: b vecdest ; \
+ nop;
+
+#define NORMAL_XVECTOR(addr,vecname,vecdest,code) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: b vecdest ; \
+ li k0,code ; \
+ nop;
+
+
+/* *********************************************************************
+ * Evil macros for bi-endian support.
+ *
+ * The magic here is in the instruction encoded as 0x10000014.
+ *
+ * This instruction in big-endian is: "b .+0x54"
+ * this instruction in little-endian is: "bne zero,zero,.+0x44"
+ *
+ * So, depending on what the system endianness is, it will either
+ * branch to .+0x54 or not branch at all.
+ *
+ * the instructions that follow are:
+ *
+ * 0x10000014 "magic branch" (either-endian)
+ * 0x00000000 nop (bds) (either-endian)
+ * 0xD0BF1A3C lui k0,0xBFD0 (little-endian)
+ * 0xxxxx5A27 addu k0,vector (little-endian)
+ * 0x08004003 jr k0 (little-endian)
+ * 0x00000000 nop (bds) (little-endian)
+ * ... space up to offset 0x54
+ * ......... b vecaddr (big-endian)
+ *
+ * The idea is that the big-endian firmware is first, from 0..1MB
+ * in the flash, and the little-endian firmware is second,
+ * from 1..2MB in the flash. The little-endian firmware is
+ * set to load at BFD00000, so that its initial routines will
+ * work until relocation is completed.
+ *
+ * the instructions at the vectors will either jump to the
+ * big-endian or little-endian code based on system endianness.
+ *
+ * The ROM is built by compiling CFE twice, first with
+ * CFG_BIENDIAN=1 and CFG_LITTLE=0 (big-endian) and again
+ * with CFG_BIENDIAN=1 and CFG_LITTLE=1. The resulting
+ * cfe.bin files are located at 0xBFC00000 and 0xBFD00000
+ * for big and little-endian versions, respectively.
+ *
+ * More information about how this works can be found in the
+ * CFE Manual.
+ ********************************************************************* */
+
+#define __SWAPW(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))
+
+#define BIENDIAN_VECTOR(addr,vecname,vecdest) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: .word 0x10000014 ; \
+ .word 0 ; \
+ .word ((__SWAPW(BIENDIAN_LE_BASE >> 16)) << 16) | 0x1A3C ; \
+ .word (0x00005A27 | (((addr) & 0xFF) << 24) | (((addr) & 0xFF00) << 8)) ; \
+ .word 0x08004003 ; \
+ .word 0 ; \
+ .org ((addr) + 0x54) ; \
+ b vecdest ; \
+ nop;
+
+#define BIENDIAN_XVECTOR(addr,vecname,vecdest,code) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: .word 0x10000014 ; \
+ .word 0 ; \
+ .word ((__SWAPW(BIENDIAN_LE_BASE >> 16)) << 16) | 0x1A3C ; \
+ .word (0x00005A27 | (((addr) & 0xFF) << 24) | (((addr) & 0xFF00) << 8)) ; \
+ .word 0x08004003 ; \
+ .word 0 ; \
+ .org ((addr) + 0x54) ; \
+ b vecdest ; \
+ li k0,code ; \
+ nop;
+
+
+
+/* *********************************************************************
+ * Declare the right versions of DECLARE_VECTOR and
+ * DECLARE_XVECTOR depending on how we're building stuff.
+ * Generally, we only use the biendian version if we're building
+ * as CFG_BIENDIAN=1 and we're doing the big-endian MIPS version.
+ ********************************************************************* */
+
+#if (CFG_BIENDIAN) && defined(__MIPSEB)
+#define DECLARE_VECTOR BIENDIAN_VECTOR
+#define DECLARE_XVECTOR BIENDIAN_XVECTOR
+#else
+#define DECLARE_VECTOR NORMAL_VECTOR
+#define DECLARE_XVECTOR NORMAL_XVECTOR
+#endif
+
+
+
+/* *********************************************************************
+ * LOADREL(reg,label)
+ *
+ * Load the address of a label, but do it in a position-independent
+ * way.
+ *
+ * Input parameters:
+ * reg - register to load
+ * label - label whose address to load
+ *
+ * Return value:
+ * ra is trashed!
+ ********************************************************************* */
+
+#if (!(CFG_RAMAPP))
+#define LOADREL(reg,label) \
+ la reg, label ; \
+ la ra, 100f ; \
+ sub reg, ra ; \
+ .set push ; \
+ .set noreorder ; \
+ bal 100f ; \
+ nop ; \
+ .set pop ; \
+100: ; \
+ addu reg, ra
+#else
+#define LOADREL(reg,label) \
+ la reg,label
+#endif
+
+#if (CFG_RAMAPP)
+#define FIXUP(addr)
+#else
+#define FIXUP(addr) \
+ addu addr, s6
+#endif
+
+
+
+/* *********************************************************************
+ * CALLINIT_KSEG1(label,table,offset)
+ * CALLINIT_KSEG0(label,table,offset)
+ *
+ * Call an initialization routine (usually in another module).
+ * If initialization routine lives in KSEG1 it may need
+ * special fixing if using the cached version of CFE (this is
+ * the default case). CFE is linked at a KSEG0 address.
+ *
+ * Embedded PIC is especially tricky, since the "la"
+ * instruction expands to calculations involving GP.
+ * In that case, use our table of offsets to
+ * load the routine address from a table in memory.
+ *
+ * Input parameters:
+ * label - routine to call if we can call directly
+ * table - symbol name of table containing routine addresses
+ * offset - offset within the above table
+ *
+ * Return value:
+ * k1,ra is trashed.
+ ********************************************************************* */
+
+
+#if CFG_RUNFROMKSEG0
+/* Cached PIC code - call indirect through table */
+#define CALLINIT_KSEG1(table,tableoffset) \
+ LOADREL(k1,table) ; \
+ or k1,K1BASE ; \
+ LR k1,tableoffset(k1) ; \
+ FIXUP (k1); \
+ or k1,K1BASE ; \
+ jal k1
+#define CALLINIT_KSEG0(table,tableoffset) \
+ LOADREL(k1,table) ; \
+ LR k1,tableoffset(k1) ; \
+ FIXUP (k1); \
+ jal k1
+#else
+/* Uncached PIC code - call indirect through table, always same KSEG */
+#define CALLINIT_KSEG1(table,tableoffset) \
+ LOADREL(k1,table) ; \
+ LR k1,tableoffset(k1) ; \
+ FIXUP (k1); \
+ jal k1
+#define CALLINIT_KSEG0 CALLINIT_KSEG1
+#endif
+
+/*
+ * CALLINIT_RELOC is used once CFE's relocation is complete and
+ * the "mem_textreloc" variable is set up. (yes, this is nasty.)
+ * If 'gp' is set, we can presume that we've relocated
+ * and it's safe to read "mem_textreloc", otherwise use the
+ * address as-is from the table.
+ */
+
+#define CALLINIT_RELOC CALLINIT_KSEG0
+
+/* *********************************************************************
+ * SPIN_LOCK(lock,reg1,reg2)
+ *
+ * Acquire a spin lock.
+ *
+ * Input parameters:
+ * lock - symbol (address) of lock to acquire
+ * reg1,reg2 - registers we can use to acquire lock
+ *
+ * Return value:
+ * nothing (lock acquired)
+ ********************************************************************* */
+
+#define SPIN_LOCK(lock,reg1,reg2) \
+ la reg1,lock ; \
+1: sync ; \
+ ll reg2,0(reg1) ; \
+ bne reg2,zero,1b ; \
+ li reg2,1 ; \
+ sc reg2,0(reg1) ; \
+ beq reg2,zero,1b ; \
+ nop
+
+/* *********************************************************************
+ * SPIN_UNLOCK(lock,reg1)
+ *
+ * Release a spin lock.
+ *
+ * Input parameters:
+ * lock - symbol (address) of lock to release
+ * reg1 - a register we can use
+ *
+ * Return value:
+ * nothing (lock released)
+ ********************************************************************* */
+
+
+#define SPIN_UNLOCK(lock,reg1) \
+ la reg1,lock ; \
+ sw zero,0(reg1)
+
+
+/* *********************************************************************
+ * SETCCAMODE(treg,mode)
+ *
+ * Set cacheability mode. For some of the pass1 workarounds we
+ * do this alot, so here's a handy macro.
+ *
+ * Input parameters:
+ * treg - temporary register we can use
+ * mode - new mode (K_CFG_K0COH_xxx)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+#define SETCCAMODE(treg,mode) \
+ mfc0 treg,C0_CONFIG ; \
+ srl treg,treg,3 ; \
+ sll treg,treg,3 ; \
+ or treg,treg,mode ; \
+ mtc0 treg,C0_CONFIG ; \
+ HAZARD
+
+
+/* *********************************************************************
+ * Declare variables
+ ********************************************************************* */
+
+#define DECLARE_LONG(x) \
+ .global x ; \
+x: _LONG_ 0
+
+
+
+
+/*
+ * end
+ */
diff --git a/cfe/cfe/arch/mips/common/include/segtable.h b/cfe/cfe/arch/mips/common/include/segtable.h
new file mode 100755
index 0000000..8a003f0
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/segtable.h
@@ -0,0 +1,97 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Segment Table definitions File: segtable.h
+ *
+ * The 'segment table' (bad name) is just a list of addresses
+ * of important stuff used during initialization. We use these
+ * indirections to make life less complicated during code
+ * relocation.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#if !defined(__ASSEMBLER__)
+#define _TBLIDX(x) (x) /* C handles indexing for us */
+typedef long segtable_t; /* 32 for long32, 64 for long64 */
+#endif
+
+/*
+ * Definitions for the segment_table
+ */
+
+#define R_SEG_ETEXT _TBLIDX(0) /* end of text segment */
+#define R_SEG_FDATA _TBLIDX(1) /* Beginning of data segment */
+#define R_SEG_EDATA _TBLIDX(2) /* end of data segment */
+#define R_SEG_END _TBLIDX(3) /* End of BSS */
+#define R_SEG_FTEXT _TBLIDX(4) /* Beginning of text segment */
+#define R_SEG_FBSS _TBLIDX(5) /* Beginning of BSS */
+#define R_SEG_GP _TBLIDX(6) /* Global Pointer */
+#define R_SEG_RELOCSTART _TBLIDX(7) /* Start of reloc table */
+#define R_SEG_RELOCEND _TBLIDX(8) /* End of reloc table */
+#define R_SEG_APIENTRY _TBLIDX(9) /* API Entry address */
+
+/*
+ * Definitions for the init_table
+ */
+
+#define R_INIT_EARLYINIT _TBLIDX(0) /* pointer to board_earlyinit */
+#define R_INIT_SETLEDS _TBLIDX(1) /* pointer to board_setleds */
+#define R_INIT_DRAMINFO _TBLIDX(2) /* pointer to board_draminfo */
+#define R_INIT_CPUINIT _TBLIDX(3) /* pointer tp cpuinit */
+#define R_INIT_ALTCPU_START1 _TBLIDX(4) /* pointer to altcpu_start1 */
+#define R_INIT_ALTCPU_START2 _TBLIDX(5) /* pointer to altcpu_start2 */
+#define R_INIT_ALTCPU_RESET _TBLIDX(6) /* pointer to altcpu_reset */
+#define R_INIT_CPURESTART _TBLIDX(7) /* pointer to cpurestart */
+#define R_INIT_DRAMINIT _TBLIDX(8) /* pointer to draminit */
+#define R_INIT_CACHEOPS _TBLIDX(9) /* pointer to cacheops */
+#define R_INIT_TLBHANDLER _TBLIDX(10) /* pointer to TLB fault handler */
+#define R_INIT_CMDSTART _TBLIDX(11) /* pointer to cfe_main */
+#define R_INIT_CMDRESTART _TBLIDX(12) /* pointer to cfe_cmd_restart */
+#define R_INIT_DOXREQ _TBLIDX(13) /* pointer to cfe_doxreq */
+#define R_INIT_TP1_SWITCH _TBLIDX(14) /* pointer to tp1_switch */
+#define R_INIT_SIZERAM _TBLIDX(15) /* pointer to board_sizeram */
+
+/*
+ * Definitions for the diag_table
+ */
+
+#define R_DIAG_TEST1 _TBLIDX(0) /* after CPU and cache init, before DRAM init */
+#define R_DIAG_TEST2 _TBLIDX(1) /* after DRAM init, before main */
diff --git a/cfe/cfe/arch/mips/common/src/Makefile b/cfe/cfe/arch/mips/common/src/Makefile
new file mode 100755
index 0000000..638113d
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/Makefile
@@ -0,0 +1,38 @@
+
+#
+# This is just a Makefile fragment -- it is included by the master
+# makefile, cfe.mk
+#
+# This file should just append object file names to "ALLOBJS",
+# but since it is mean to be linked *first*, it will append
+# modules to "CRT0OBJS"
+#
+
+ifndef INIT_MIPS
+INIT_MIPS = init_mips.o
+endif
+
+ifeq ($(strip ${CFG_RAMAPP}),1)
+CRT0OBJS += init_ram.o exception.o
+else
+CRT0OBJS += $(INIT_MIPS)
+endif
+
+ifeq ($(strip ${CFG_RAMAPP}),1)
+ALLOBJS += lib_hssubr.o lib_setjmp.o mips_arena.o exchandler.o
+ALLOBJS += dev_flash_all.o dev_flashop_engine.o
+ALLOBJS += ui_memtest.o
+endif
+
+makereg : ${TOP}/hosttools/makereg.c
+ gcc -o makereg ${TOP}/hosttools/makereg.c
+
+%.inc : %.regdef makereg
+ ./makereg $< $@
+
+ui_soccmds.o : ${CPU_SRC}/ui_soccmds.c ${CPU}_socregs.inc
+
+vapi.o : ${TOP}/verif/vapi.S sb1250_socregs.inc
+
+
+
diff --git a/cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds b/cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds
new file mode 100644
index 0000000..4b8ce87
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds
@@ -0,0 +1,40 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x9fc00000; /* was 0x9fc00000 */
+ .text :
+/* AT ( 0xBFC00000 ) */ /* was 0xbfc00000 */
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds b/cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds
new file mode 100644
index 0000000..4295fe4
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds
@@ -0,0 +1,40 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0xbfc00000; /* was 0x9fc00000 */
+ .text :
+/* AT ( 0xBFC00000 ) */ /* was 0xbfc00000 */
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_ramapp.lds b/cfe/cfe/arch/mips/common/src/cfe_ramapp.lds
new file mode 100755
index 0000000..5a7a377
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_ramapp.lds
@@ -0,0 +1,41 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x80601000;
+ .text :
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ *(.rodata.str1.4)
+ *(.gnu.linkonce.r.*)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_cached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_cached.lds
new file mode 100755
index 0000000..2ca1353
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_cached.lds
@@ -0,0 +1,40 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x80000000;
+ .text :
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ .reginfo : {}
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds
new file mode 100644
index 0000000..ee94831
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds
@@ -0,0 +1,43 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x9FC00000;
+ .text :
+ AT ( 0xBFC00000 )
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+ .data 0x80001000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _gp = ALIGN(16) + 0x8000;
+ _fdata = .;
+ *(.rdata)
+ *(.data)
+ CONSTRUCTORS
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds
new file mode 100644
index 0000000..78421a4
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds
@@ -0,0 +1,49 @@
+/*
+ * This linker script is exactly the same as cfe_rom_reloc_cached.lds
+ * except our start address is at BFD00000, 1MB into the
+ * ROM. We locate the little-endian version of CFE at this address
+ * in bi-endian ROM support.
+ */
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x9FD00000;
+ .text :
+ AT ( 0xBFD00000 )
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+ .data 0x80001000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _gp = ALIGN(16) + 0x8000;
+ _fdata = .;
+ *(.rdata)
+ *(.data)
+ CONSTRUCTORS
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds
new file mode 100644
index 0000000..0c62889
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds
@@ -0,0 +1,41 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0xBFC00000;
+ .text : {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+ .data 0xA0001000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _gp = ALIGN(16) + 0x8000;
+ _fdata = .;
+ *(.rdata)
+ *(.data)
+ CONSTRUCTORS
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds
new file mode 100644
index 0000000..a0362ba
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds
@@ -0,0 +1,39 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0xBFC00000;
+ .text : {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data 0xA1F00000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/dev_flash_all.S b/cfe/cfe/arch/mips/common/src/dev_flash_all.S
new file mode 100644
index 0000000..6dbb581
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/dev_flash_all.S
@@ -0,0 +1,220 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Flash "self-write" module File: flash_write_all.S
+ *
+ * This module takes care of the case of writing to the flash
+ * memory that CFE is currently reading its code from. It is
+ * assumed that you'll be doing a complete flash update,
+ * so this code erases the affected sectors, reprograms them,
+ * and jumps to the boot sector.
+ *
+ * Note: this code is written to be position-independent, even
+ * for non-PIC versions of CFE! It will be copied (with memcpy)
+ * into the heap for execution.
+ *
+ * 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 "sbmips.h"
+#include "dev_flash.h"
+#include "mipsmacros.h"
+
+#define WRITEFLASH(base,offset,value) \
+ li t0,value ; \
+ sb t0,offset(base)
+
+
+/* *********************************************************************
+ * flash_write_all(data,flashbase,size,secsize)
+ *
+ * Write bytes to flash, erasing affected sectors first.
+ *
+ * Input parameters:
+ * a0 - data - pointer to data to write
+ * a1 - flashbase - base (phys addr) of flash area
+ * a2 - size - number of bytes to write
+ * a3 - secsize - flash sector size
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+#define data a0
+#define flashbase a1
+#define datasize a2
+#define secsize a3
+
+#define secidx t4
+#define secptr t5
+
+LEAF(flash_write_all)
+
+ /*
+ * Mask all interrupts. An exception with BEV set would be very bad.
+ */
+
+ mfc0 v0,C0_SR # Get current interrupt flag
+ li v1,M_SR_IE # master interrupt control
+ not v1 # disable interrupts
+ and v0,v1 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+ /*
+ * Get KSEG1 addr of flash
+ */
+
+ or flashbase,K1BASE
+
+
+ /*
+ * Do an "unlock write" sequence (cycles 1-2)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /*
+ * send the erase command (cycle 3)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /*
+ * Do an "unlock write" sequence (cycles 4-5)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /*
+ * Send the "erase all" qualifier (cycle 6)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_ALL_6)
+
+ /*
+ * Wait for the erase to complete
+ */
+
+1: lb t0,0(secptr) # get byte
+ and t0,0xFF # test hi byte
+ bne t0,0xFF,1b # go till bit is set
+
+
+ /*
+ * Okay, now loop through the bytes and write them to the
+ * flash.
+ */
+
+ move secptr,flashbase
+ move secidx,datasize
+
+proglp:
+
+ /*
+ * Do an "unlock write" sequence
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /*
+ * Send a program command
+ */
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /*
+ * Write a byte
+ */
+
+ lbu t0,0(data)
+ sb t0,0(secptr) # t0 = byte written to flash
+
+
+ /*
+ * Wait for write to complete
+ */
+
+1: lbu t2,0(secptr) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /*
+ * next byte...
+ */
+
+ add a0,1 # next source byte
+ add secptr,1 # next dest byte
+ sub datasize,1 # one less count
+ bgt datasize,0,proglp
+
+ /*
+ * All done, reboot system
+ */
+
+ li v0,0xBFC00000
+ j v0
+
+flash_write_all_end:
+ nop
+
+END(flash_write_all)
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+ .sdata
+
+ .globl flash_write_all_ptr
+ .globl flash_write_all_len
+
+flash_write_all_ptr:
+ _VECT_ flash_write_all
+flash_write_all_len:
+ .word flash_write_all_end-flash_write_all
+
+
diff --git a/cfe/cfe/arch/mips/common/src/dev_flashop_engine.S b/cfe/cfe/arch/mips/common/src/dev_flashop_engine.S
new file mode 100644
index 0000000..29ade6a
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/dev_flashop_engine.S
@@ -0,0 +1,695 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Flash "self-write" module File: dev_flashop_engine.S
+ *
+ * This module takes care of the case of writing to the flash
+ * memory that CFE is currently reading its code from.
+ *
+ * Note: this code is written to be position-independent, even
+ * for non-PIC versions of CFE! It will be copied (with memcpy)
+ * into the heap for execution.
+ *
+ * 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 "sbmips.h"
+#include "mipsmacros.h"
+
+#include "bsp_config.h"
+#include "dev_newflash.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define FLASHCMD_8(base,offset,value) \
+ li t0,value ; \
+ sb t0,offset(base)
+
+#define FLASHCMD_16(base,offset,value) \
+ li t0,value ; \
+ sh t0,((offset)<<1)(base)
+
+#define FLASHCMD_16B(base,offset,value) \
+ li t0,value ; \
+ sb t0,((offset)<<1)(base)
+
+
+/* *********************************************************************
+ * flashop_engine
+ *
+ * This routine is written in a PIC method to allow us to do
+ * flash operations without any help from CFE. We need to do
+ * this when we're not relocated and want to muck with the
+ * flash we're running from.
+ *
+ * This routine follows some simple instructions in a table,
+ * so you can batch up the operations in one place.
+ *
+ * Input parameters:
+ * a0 - pointer to instruction list
+ *
+ * Return value:
+ * v0 - 0 if all instructions succeeded
+ * else less than zero, # of failing instructions
+ ********************************************************************* */
+
+ .text
+
+#define reg_op t3
+#define reg_base t4
+#define reg_dest t5
+#define reg_src t6
+#define reg_cnt t7
+
+LEAF(flashop_engine)
+
+instloop: LR reg_op,FEINST_OP(a0) /* Load instruction */
+ LR reg_base,FEINST_BASE(a0)
+ LR reg_dest,FEINST_DEST(a0)
+ LR reg_src,FEINST_SRC(a0)
+ LR reg_cnt,FEINST_CNT(a0)
+ li v0,0 /* total of result values */
+ li v1,0 /* result for this function */
+
+#ifdef __long64
+ dli t0,0x9000000000000000 /* uncached - XKPHYS */
+ or reg_base,t0 /* so we can access flash beyond KSEG */
+#else
+ or reg_base,K1BASE /* 32-bit, regular KSEG */
+#endif
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ bne reg_op,FEOP_RETURN,99f /* Return to main prog */
+
+ j ra
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_REBOOT,99f /* restart system */
+
+ li t0,0xBFC00000 /* jump to boot vector */
+ j t0
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_READ8,99f /* Read, 8-bit mode */
+
+ ADD reg_src,reg_src,reg_base
+
+1: lbu t0,0(reg_src) /* Copy user data */
+ sb t0,0(reg_dest)
+ ADD reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_READ16,99f /* Read, 16-bit mode */
+
+ ADD reg_src,reg_src,reg_base
+
+ li t0,1 /* test bottom bit */
+ and t0,t0,reg_src /* t0 == 1 if odd */
+ beq t0,zero,1f /* no odd byte to worry about */
+
+ SUB reg_src,reg_src,t0 /* make even value */
+ lh t0,0(reg_src) /* interesting byte is odd */
+#ifdef __MIPSEB
+ sb t0,0(reg_dest) /* interesting byte in low 8 bits */
+#else
+ srl t0,t0,8 /* little endian */
+ sb t0,0(reg_dest) /* interesting byte is high 8 bits */
+#endif
+
+ ADD reg_src,2 /* advance one word (we made addr even above) */
+ add reg_dest,1 /* dest always written by bytes */
+ sub reg_cnt,1
+
+1: beq reg_cnt,zero,nextinst
+
+ lh t0,0(reg_src) /* Copy user data */
+
+#ifdef __MIPSEB
+ sb t0,1(reg_dest) /* Big endian to memory */
+ srl t0,t0,8 /* t0 = 0x1234 -> 0x12 0x34 */
+ sb t0,0(reg_dest)
+#else
+ sb t0,0(reg_dest) /* little endian */
+ srl t0,t0,8 /* t0 = 0x1234 -> 0x34 0x12 */
+ sb t0,1(reg_dest)
+#endif
+
+ ADD reg_src,2
+ add reg_dest,2
+ sub reg_cnt,2
+ bgt reg_cnt,1,1b
+
+ beq reg_cnt,zero,nextinst /* no straggler */
+
+ lh t0,0(reg_src) /* interesting byte is odd */
+#ifdef __MIPSEB
+ srl t0,t0,8 /* little endian */
+ sb t0,0(reg_dest) /* interesting byte in high 8 bits */
+#else
+ sb t0,0(reg_dest) /* interesting byte is low 8 bits */
+#endif
+
+ b nextinst
+/* CFI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if (FLASH_DRIVERS & FLASH_DRIVER_CFI)
+99: bne reg_op,FEOP_CFIQUERY8,99f /* CFI Query 8-bit */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
+
+1: lbu t0,0(reg_src) /* Copy CFI data */
+ sb t0,0(reg_dest)
+ ADD reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_CFIQUERY16,99f /* CFI Query 16-bit in word mode */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
+
+1: lh t0,0(reg_src) /* Copy CFI data */
+ sh t0,0(reg_dest)
+ ADD reg_src,2
+ add reg_dest,2
+ sub reg_cnt,2
+ bgt reg_cnt,zero,1b
+
+ FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_CFIQUERY16B,99f /* CFI Query 16-bit in byte mode */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
+
+1: lb t0,0(reg_src) /* Copy CFI data */
+ sb t0,0(reg_dest)
+ ADD reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
+
+ b nextinst
+#endif
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_MEMCPY,99f /* Generic memcpy */
+
+1: lbu t0,0(reg_src)
+ sb t0,0(reg_dest)
+ add reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ b nextinst
+
+
+/* AMD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if (FLASH_DRIVERS & FLASH_DRIVER_AMD)
+99: bne reg_op,FEOP_AMD_ERASE8,99f /* AMD erase (8-bit) */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* send the erase command (cycle 3) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /* Do an "unlock write" sequence (cycles 4-5) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send the "erase sector" qualifier (cycle 6) */
+
+ FLASHCMD_8(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
+
+ /* Wait for the erase to complete */
+
+1: lb t0,0(reg_dest) # get byte
+ and t0,0xFF # test hi byte
+ bne t0,0xFF,1b # go till bit is set
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_ERASE16,99f /* AMD erase (16-bit in word mode) */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* send the erase command (cycle 3) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /* Do an "unlock write" sequence (cycles 4-5) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send the "erase sector" qualifier (cycle 6) */
+
+ FLASHCMD_16(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
+
+ /* Wait for the erase to complete */
+
+1: lh t0,0(reg_dest) # get word
+ and t0,0xFF # test byte
+ bne t0,0xFF,1b # go till erased
+
+ b nextinst
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_ERASE16B,99f /* AMD erase (16-bit in byte mode) */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* send the erase command (cycle 3) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /* Do an "unlock write" sequence (cycles 4-5) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send the "erase sector" qualifier (cycle 6) */
+
+ FLASHCMD_16B(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
+
+ /* Wait for the erase to complete */
+
+1: lh t0,0(reg_dest) # get word
+ and t0,0xFF # test byte
+ bne t0,0xFF,1b # go till erased
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_PGM8,99f /* AMD 8-bit program */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+11:
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send a program command (cycle 3) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /* Write a byte (cycle 4) */
+
+ lbu t0,0(reg_src)
+ sb t0,0(reg_dest) # t0 = byte written to flash
+
+ /* Wait for write to complete */
+
+1: lbu t2,0(reg_dest) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /* next byte... */
+
+ add reg_src,1 # next source byte
+ ADD reg_dest,1 # next dest byte
+ sub reg_cnt,1 # one less count
+ bgt reg_cnt,0,11b
+
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_PGM16,99f /* AMD 16-bit program */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+11:
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send a program command (cycle 3) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /* Write a byte (cycle 4) */
+
+ lh t0,0(reg_src)
+ sh t0,0(reg_dest) # t0 = byte written to flash
+
+ /* Wait for write to complete */
+
+1: lh t2,0(reg_dest) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /* next byte... */
+
+ add reg_src,2 # next source word
+ ADD reg_dest,2 # next dest word
+ sub reg_cnt,2 # one less count
+ bgt reg_cnt,0,11b
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_PGM16B,99f /* AMD 16-bit pgm in 8-bit mode */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+11:
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send a program command (cycle 3) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /* Write a byte (cycle 4) */
+
+ lb t0,0(reg_src)
+ sb t0,0(reg_dest) # t0 = byte written to flash
+
+ /* Wait for write to complete */
+
+1: lb t2,0(reg_dest) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /* next byte... */
+
+ add reg_src,1 # next source word
+ ADD reg_dest,1 # next dest word
+ sub reg_cnt,1 # one less count
+ bgt reg_cnt,0,11b
+
+ b nextinst
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_DEVCODE8,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lbu t0,AMD_FLASH_DEVCODE8(reg_src)
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_DEVCODE16,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lw t0,0(reg_src)
+#ifdef __MIPSEB
+ srl t0,t0,8 /* ((3-AMD_FLASH_DEVCODE16)*8) */
+#else
+ srl t0,t0,16 /* (AMD_FLASH_DEVCODE16*8) */
+#endif
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_DEVCODE16B,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lw t0,0(reg_src)
+#ifdef __MIPSEB
+#else
+ srl t0,t0,16 /* (AMD_FLASH_DEVCODE16B*8)*/
+#endif
+
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_MANID8,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lbu t0,AMD_FLASH_MANID(reg_src)
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_MANID16,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lw t0,0(reg_src)
+#ifdef __MIPSEB
+ srl t0,t0,((3-AMD_FLASH_MANID)*8)
+#else
+ srl t0,t0,(AMD_FLASH_MANID*8)
+#endif
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_MANID16B,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lbu t0,AMD_FLASH_MANID(reg_src)
+
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+
+#endif
+
+/* INTEL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if (FLASH_DRIVERS & FLASH_DRIVER_INTEL)
+99: bne reg_op,FEOP_INTEL_ERASE8,99f /* Intel erase 8-bit */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
+
+1: lbu t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_INTEL_ERASE16,99f /* Intel erase 16-bit */
+
+ ADD reg_dest,reg_dest,reg_base
+
+/* XXX copy of 8-bit erase, is this right? */
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
+
+1: lbu t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_INTEL_PGM8,99f /* Intel 8-bit program */
+
+ ADD reg_dest,reg_dest,reg_base
+
+11: FLASHCMD_8(reg_dest,0,INTEL_FLASH_PROGRAM)
+
+ lbu t0,0(reg_src)
+ sb t0,0(reg_dest)
+
+1: lbu t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ lbu t0,0(reg_dest) /* contains final result */
+ /* If good, bits 1, 3, 4 will not be set */
+
+ add reg_src,1
+ ADD reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,11b
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_INTEL_PGM16,99f /* Intel 16-bit prog */
+
+ ADD reg_dest,reg_dest,reg_base
+
+11: FLASHCMD_16(reg_dest,0,INTEL_FLASH_PROGRAM)
+
+ lh t0,0(reg_src)
+ sh t0,0(reg_dest)
+
+1: lh t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ lh t0,0(reg_dest) /* contains final result */
+ /* If good, bits 1, 3, 4 will not be set */
+
+ add reg_src,2
+ ADD reg_dest,2
+ sub reg_cnt,2
+ bgt reg_cnt,zero,11b
+
+ FLASHCMD_16(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+#endif
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: li v1,-1 /* invalid command */
+
+nextinst: SR v1,FEINST_RESULT(a0) /* store result of instruction */
+ ADD v0,v0,v1 /* add to total */
+ ADD a0,FEINST_SIZE /* advance to next instr. */
+ b instloop
+
+flashop_engine_end:
+ nop
+
+END(flashop_engine)
+
+ .sdata
+
+ .globl flashop_engine_ptr
+ .globl flashop_engine_len
+
+flashop_engine_ptr:
+ _VECT_ flashop_engine
+flashop_engine_len:
+ .word flashop_engine_end-flashop_engine
+
+
+
+/* *********************************************************************
+ * end
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/disasm.c b/cfe/cfe/arch/mips/common/src/disasm.c
new file mode 100644
index 0000000..1b76fee
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/disasm.c
@@ -0,0 +1,2111 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS disassembler File: disasm.c
+ *
+ * MIPS disassembler (used by ui_examcmds.c)
+ *
+ * Author: Justin Carlson (carlson@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 "disasm.h"
+#include "lib_printf.h"
+
+#define UINT64_T(x) ((uint64_t) (x))
+#define PF_64 "ll"
+#define PF_32 ""
+/* These aren't guaranteed to be portable, either */
+#define SEXT_32(bit, val) \
+ ((((int32_t)(val))<<(31-(bit)))>>(31-(bit)))
+#define SEXT_64(bit, val) \
+ ((((int64_t)(val))<<(63-(bit)))>>(63-(bit)))
+
+#define DATASEG __attribute__ ((section(".text")))
+
+
+#define REGNAME(r) (&_regnames[(r)*5])
+static const char * const _regnames =
+ "zero\0"
+ "AT\0 "
+ "v0\0 "
+ "v1\0 "
+ "a0\0 "
+ "a1\0 "
+ "a2\0 "
+ "a3\0 "
+ "t0\0 "
+ "t1\0 "
+ "t2\0 "
+ "t3\0 "
+ "t4\0 "
+ "t5\0 "
+ "t6\0 "
+ "t7\0 "
+ "s0\0 "
+ "s1\0 "
+ "s2\0 "
+ "s3\0 "
+ "s4\0 "
+ "s5\0 "
+ "s6\0 "
+ "s7\0 "
+ "t8\0 "
+ "t9\0 "
+ "k0\0 "
+ "k1\0 "
+ "gp\0 "
+ "sp\0 "
+ "fp\0 "
+ "ra\0 ";
+
+#define CP0REGNAME(r) (&_cp0names[(r)*12])
+static const char * const _cp0names =
+ "C0_INX\0 "
+ "C0_RAND\0 "
+ "C0_TLBLO0\0 "
+ "C0_TLBLO1\0 "
+
+ "C0_CTEXT\0 "
+ "C0_PGMASK\0 "
+ "C0_WIRED\0 "
+ "C0_reserved\0"
+
+ "C0_BADVADDR\0"
+ "C0_COUNT\0 "
+ "C0_TLBHI\0 "
+ "C0_COMPARE\0 "
+
+ "C0_SR\0 "
+ "C0_CAUSE\0 "
+ "C0_EPC\0 "
+ "C0_PRID\0 "
+
+ "C0_CONFIG\0 "
+ "C0_LLADDR\0 "
+ "C0_WATCHLO\0 "
+ "C0_WATCHHI\0 "
+
+ "C0_XCTEXT\0 "
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+
+ "C0_TAGLO\0 "
+ "C0_TAGHI\0 "
+ "C0_ERREPC\0 "
+ "C0_reserved\0";
+
+
+
+/*
+ * MIPS instruction set disassembly module.
+ */
+
+typedef enum {
+ DC_RD_RS_RT,
+ DC_RD_RT_RS,
+ DC_RT_RS_SIMM,
+ DC_RT_RS_XIMM,
+ DC_RS_RT_OFS,
+ DC_RS_OFS,
+ DC_RD_RT_SA,
+ DC_RT_UIMM,
+ DC_RD,
+ DC_J,
+ DC_RD_RS,
+ DC_RS_RT,
+ DC_RT_RS,
+ DC_RT_RD_SEL,
+ DC_RT_CR_SEL,
+ DC_RS,
+ DC_RS_SIMM,
+ DC_RT_OFS_BASE,
+ DC_FT_OFS_BASE,
+ DC_FD_IDX_BASE,
+ DC_FS_IDX_BASE,
+ DC_FD_FS_FT,
+ DC_FD_FS_RT,
+ DC_FD_FS,
+ DC_PREF_OFS,
+ DC_PREF_IDX,
+ DC_CC_OFS,
+ DC_FD_FS_CC,
+ DC_RD_RS_CC,
+ DC_FD_FR_FS_FT,
+ DC_FD_FS_FT_RS,
+ DC_CC_FS_FT,
+ DC_BARE,
+ DC_RT_FS,
+ DC_SYSCALL,
+ DC_BREAK,
+ DC_VD_VS_VT_VEC,
+ DC_VD_VS_VT,
+ DC_VS_VT,
+ DC_VS_VT_VEC,
+ DC_VD_VS_VT_RS,
+ DC_VD_VS_VT_IMM,
+ DC_VD_VT,
+ DC_VD,
+ DC_VS,
+ DC_DEREF,
+ DC_OOPS
+} DISASM_CLASS;
+
+
+
+
+/* We're pulling some trickery here. Most of the time, this structure operates
+ exactly as one would expect. The special case, when type == DC_DREF,
+ means name points to a byte that is an index into a dereferencing array. */
+
+/*
+ * To make matters worse, the whole module has been coded to reduce the
+ * number of relocations present, so we don't actually store pointers
+ * in the dereferencing array. Instead, we store fixed-width strings
+ * and use digits to represent indicies into the deref array.
+ *
+ * This is all to make more things fit in the relocatable version,
+ * since every initialized pointer goes into our small data segment.
+ */
+
+typedef struct {
+ char name[15];
+ char type;
+} disasm_t;
+
+typedef struct {
+ const disasm_t *ptr;
+ int shift;
+ uint32_t mask;
+} disasm_deref_t;
+
+/* Forward declaration of deref array, we need this for the disasm_t definitions */
+
+
+extern const disasm_deref_t disasm_deref[];
+
+static const disasm_t disasm_normal[64] DATASEG =
+{{"$1" , DC_DEREF },
+ {"$2" , DC_DEREF },
+ {"j" , DC_J },
+ {"jal" , DC_J },
+ {"beq" , DC_RS_RT_OFS },
+ {"bne" , DC_RS_RT_OFS },
+ {"blez" , DC_RS_OFS },
+ {"bgtz" , DC_RS_OFS },
+ {"addi" , DC_RT_RS_SIMM },
+ {"addiu" , DC_RT_RS_SIMM },
+ {"slti" , DC_RT_RS_SIMM },
+ {"sltiu" , DC_RT_RS_SIMM },
+ {"andi" , DC_RT_RS_XIMM },
+ {"ori" , DC_RT_RS_XIMM },
+ {"xori" , DC_RT_RS_XIMM },
+ {"lui" , DC_RT_UIMM },
+ {"$4" , DC_DEREF },
+ {"$6" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"$15" , DC_DEREF },
+ {"beql" , DC_RS_RT_OFS },
+ {"bnel" , DC_RS_RT_OFS },
+ {"blezl" , DC_RS_OFS },
+ {"bgtzl" , DC_RS_OFS },
+ {"daddi" , DC_RT_RS_SIMM },
+ {"daddiu" , DC_RT_RS_SIMM },
+ {"ldl" , DC_RT_OFS_BASE },
+ {"ldr" , DC_RT_OFS_BASE },
+ {"$3" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"$18" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"lb" , DC_RT_OFS_BASE },
+ {"lh" , DC_RT_OFS_BASE },
+ {"lwl" , DC_RT_OFS_BASE },
+ {"lw" , DC_RT_OFS_BASE },
+ {"lbu" , DC_RT_OFS_BASE },
+ {"lhu" , DC_RT_OFS_BASE },
+ {"lwr" , DC_RT_OFS_BASE },
+ {"lwu" , DC_RT_OFS_BASE },
+ {"sb" , DC_RT_OFS_BASE },
+ {"sh" , DC_RT_OFS_BASE },
+ {"swl" , DC_RT_OFS_BASE },
+ {"sw" , DC_RT_OFS_BASE },
+ {"sdl" , DC_RT_OFS_BASE },
+ {"sdr" , DC_RT_OFS_BASE },
+ {"swr" , DC_RT_OFS_BASE },
+ {"cache" , DC_BARE },
+ {"ll" , DC_RT_OFS_BASE },
+ {"lwc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"pref" , DC_PREF_OFS },
+ {"lld" , DC_RT_OFS_BASE },
+ {"ldc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"ld" , DC_RT_OFS_BASE },
+ {"sc" , DC_RT_OFS_BASE },
+ {"swc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"scd" , DC_RT_OFS_BASE },
+ {"sdc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"sd" , DC_RT_OFS_BASE }};
+
+static const disasm_t disasm_special[64] DATASEG =
+{{"sll" , DC_RD_RT_SA },
+ {"$16" , DC_DEREF },
+ {"srl" , DC_RD_RT_SA },
+ {"sra" , DC_RD_RT_SA },
+ {"sllv" , DC_RD_RT_RS },
+ {"invalid" , DC_BARE },
+ {"srlv" , DC_RD_RT_RS },
+ {"srav" , DC_RD_RT_RS },
+ {"jr" , DC_RS },
+ {"jalr" , DC_RD_RS },
+ {"movz" , DC_RD_RS_RT },
+ {"movn" , DC_RD_RS_RT },
+ {"syscall" , DC_SYSCALL },
+ {"break" , DC_BREAK },
+ {"invalid" , DC_BARE },
+ {"sync" , DC_BARE },
+ {"mfhi" , DC_RD },
+ {"mthi" , DC_RS },
+ {"mflo" , DC_RD },
+ {"mtlo" , DC_RS },
+ {"dsllv" , DC_RD_RT_RS },
+ {"invalid" , DC_BARE },
+ {"dsrlv" , DC_RD_RT_RS },
+ {"dsrav" , DC_RD_RT_RS },
+ {"mult" , DC_RS_RT },
+ {"multu" , DC_RS_RT },
+ {"div" , DC_RS_RT },
+ {"divu" , DC_RS_RT },
+ {"dmult" , DC_RS_RT },
+ {"dmultu" , DC_RS_RT },
+ {"ddiv" , DC_RS_RT },
+ {"ddivu" , DC_RS_RT },
+ {"add" , DC_RD_RS_RT },
+ {"addu" , DC_RD_RS_RT },
+ {"sub" , DC_RD_RS_RT },
+ {"subu" , DC_RD_RS_RT },
+ {"and" , DC_RD_RS_RT },
+ {"or" , DC_RD_RS_RT },
+ {"xor" , DC_RD_RS_RT },
+ {"nor" , DC_RD_RS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"slt" , DC_RD_RS_RT },
+ {"sltu" , DC_RD_RS_RT },
+ {"dadd" , DC_RD_RS_RT },
+ {"daddu" , DC_RD_RS_RT },
+ {"dsub" , DC_RD_RS_RT },
+ {"dsubu" , DC_RD_RS_RT },
+ {"tge" , DC_RS_RT },
+ {"tgeu" , DC_RS_RT },
+ {"tlt" , DC_RS_RT },
+ {"tltu" , DC_RS_RT },
+ {"teq" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"tne" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"dsll" , DC_RD_RT_SA },
+ {"invalid" , DC_BARE },
+ {"dsrl" , DC_RD_RT_SA },
+ {"dsra" , DC_RD_RT_SA },
+ {"dsll32" , DC_RD_RT_SA },
+ {"invalid" , DC_BARE },
+ {"dsrl32" , DC_RD_RT_SA },
+ {"dsra32" , DC_RD_RT_SA }};
+
+static const disasm_t disasm_movci[2] DATASEG =
+{{"movf" , DC_RD_RS_CC },
+ {"movt" , DC_RD_RS_CC }};
+
+static const disasm_t disasm_regimm[32] DATASEG =
+{{"bltz" , DC_RS_OFS },
+ {"bgez" , DC_RS_OFS },
+ {"bltzl" , DC_RS_OFS },
+ {"bgezl" , DC_RS_OFS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tgei" , DC_RS_SIMM },
+ {"tgeiu" , DC_RS_SIMM },
+ {"tlti" , DC_RS_SIMM },
+ {"tltiu" , DC_RS_SIMM },
+ {"teqi" , DC_RS_SIMM },
+ {"invalid" , DC_BARE },
+ {"tnei" , DC_RS_SIMM },
+ {"invalid" , DC_BARE },
+ {"bltzal" , DC_RS_OFS },
+ {"bgezal" , DC_RS_OFS },
+ {"bltzall" , DC_RS_OFS },
+ {"bgezall" , DC_RS_OFS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_spec2[64] DATASEG =
+{{"madd" , DC_RS_RT },
+ {"maddu" , DC_RS_RT },
+ {"mul" , DC_RD_RS_RT },
+ {"invalid" , DC_BARE },
+ {"msub" , DC_RS_RT },
+ {"msubu" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"clz" , DC_RT_RS },
+ {"clo" , DC_RT_RS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"dclz" , DC_RT_RS },
+ {"dclo" , DC_RT_RS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"sdbbp" , DC_BARE }};
+
+static const disasm_t disasm_cop0[32] DATASEG =
+{{"mfc0@1" , DC_RT_CR_SEL },
+ {"dmfc0@1" , DC_RT_CR_SEL },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"mtc0@1" , DC_RT_CR_SEL },
+ {"dmtc0@1" , DC_RT_CR_SEL },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF }};
+
+static const disasm_t disasm_cop0_c0[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"tlbr" , DC_BARE },
+ {"tlbwi" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tlbwr" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tlbp" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"eret" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"deret" , DC_BARE },
+ {"wait" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1[32] DATASEG =
+{{"mfc1" , DC_RT_FS },
+ {"dmfc1" , DC_RT_FS },
+ {"cfc1" , DC_RT_FS },
+ {"invalid" , DC_BARE },
+ {"mtc1" , DC_RT_FS },
+ {"dmtc1" , DC_RT_FS },
+ {"ctc1" , DC_RT_FS },
+ {"invalid" , DC_BARE },
+ {"$17" , DC_DEREF },
+ {"$36" , DC_DEREF },
+ {"$37" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$7" , DC_DEREF },
+ {"$9" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$11" , DC_DEREF },
+ {"$12" , DC_DEREF },
+ {"$13" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_bc1[4] DATASEG =
+{{"bc1f" , DC_CC_OFS },
+ {"bc1t" , DC_CC_OFS },
+ {"bc1fl" , DC_CC_OFS },
+ {"bc1tl" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_bc1any2[2] DATASEG =
+{{"bc1any2f" , DC_CC_OFS },
+ {"bc1any2t" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_bc1any4[2] DATASEG =
+{{"bc1any4f" , DC_CC_OFS },
+ {"bc1any4t" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_s[64] DATASEG =
+{{"add.s" , DC_FD_FS_FT },
+ {"sub.s" , DC_FD_FS_FT },
+ {"mul.s" , DC_FD_FS_FT },
+ {"div.s" , DC_FD_FS_FT },
+ {"sqrt.s" , DC_FD_FS },
+ {"abs.s" , DC_FD_FS },
+ {"mov.s" , DC_FD_FS },
+ {"neg.s" , DC_FD_FS },
+ {"round.l.s" , DC_FD_FS },
+ {"trunc.l.s" , DC_FD_FS },
+ {"ceil.l.s" , DC_FD_FS },
+ {"floor.l.s" , DC_FD_FS },
+ {"round.w.s" , DC_FD_FS },
+ {"trunc.w.s" , DC_FD_FS },
+ {"ceil.w.s" , DC_FD_FS },
+ {"floor.w.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"$8" , DC_DEREF },
+ {"movz.s" , DC_FD_FS_RT },
+ {"movn.s" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"recip.s" , DC_FD_FS },
+ {"rsqrt.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"recip2.s" , DC_FD_FS_FT },
+ {"recip1.s" , DC_FD_FS },
+ {"rsqrt1.s" , DC_FD_FS },
+ {"rsqrt2.s" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"cvt.d.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.w.s" , DC_FD_FS },
+ {"cvt.l.s" , DC_FD_FS },
+ {"cvt.ps.s" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$38" , DC_DEREF },
+ {"$39" , DC_DEREF },
+ {"$40" , DC_DEREF },
+ {"$41" , DC_DEREF },
+ {"$42" , DC_DEREF },
+ {"$43" , DC_DEREF },
+ {"$44" , DC_DEREF },
+ {"$45" , DC_DEREF },
+ {"$46" , DC_DEREF },
+ {"$47" , DC_DEREF },
+ {"$48" , DC_DEREF },
+ {"$49" , DC_DEREF },
+ {"$50" , DC_DEREF },
+ {"$51" , DC_DEREF },
+ {"$52" , DC_DEREF },
+ {"$53" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_s_mvcf[2] DATASEG =
+{{"movf.s" , DC_FD_FS_CC },
+ {"movt.s" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1_d[64] DATASEG =
+{{"add.d" , DC_FD_FS_FT },
+ {"sub.d" , DC_FD_FS_FT },
+ {"mul.d" , DC_FD_FS_FT },
+ {"div.d" , DC_FD_FS_FT },
+ {"sqrt.d" , DC_FD_FS },
+ {"abs.d" , DC_FD_FS },
+ {"mov.d" , DC_FD_FS },
+ {"neg.d" , DC_FD_FS },
+ {"round.l.d" , DC_FD_FS },
+ {"trunc.l.d" , DC_FD_FS },
+ {"ceil.l.d" , DC_FD_FS },
+ {"floor.l.d" , DC_FD_FS },
+ {"round.w.d" , DC_FD_FS },
+ {"trunc.w.d" , DC_FD_FS },
+ {"ceil.w.d" , DC_FD_FS },
+ {"floor.w.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"$10" , DC_DEREF },
+ {"movz.d" , DC_FD_FS_RT },
+ {"movn.d" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"recip.d" , DC_FD_FS },
+ {"rsqrt.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"recip2.d" , DC_FD_FS_FT },
+ {"recip1.d" , DC_FD_FS },
+ {"rsqrt1.d" , DC_FD_FS },
+ {"rsqrt2.d" , DC_FD_FS_FT },
+ {"cvt.s.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.w.d" , DC_FD_FS },
+ {"cvt.l.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$54" , DC_DEREF },
+ {"$55" , DC_DEREF },
+ {"$56" , DC_DEREF },
+ {"$57" , DC_DEREF },
+ {"$58" , DC_DEREF },
+ {"$59" , DC_DEREF },
+ {"$60" , DC_DEREF },
+ {"$61" , DC_DEREF },
+ {"$62" , DC_DEREF },
+ {"$63" , DC_DEREF },
+ {"$64" , DC_DEREF },
+ {"$65" , DC_DEREF },
+ {"$66" , DC_DEREF },
+ {"$67" , DC_DEREF },
+ {"$68" , DC_DEREF },
+ {"$69" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_d_mvcf[2] DATASEG =
+{{"movf.d" , DC_FD_FS_CC },
+ {"movt.d" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1_w[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.w" , DC_FD_FS },
+ {"cvt.d.w" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.ps.pw" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_l[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.l" , DC_FD_FS },
+ {"cvt.d.l" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_ps[64] DATASEG =
+{{"add.ps" , DC_FD_FS_FT },
+ {"sub.ps" , DC_FD_FS_FT },
+ {"mul.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"abs.ps" , DC_FD_FS },
+ {"mov.ps" , DC_FD_FS },
+ {"neg.ps" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$14" , DC_DEREF },
+ {"movz.ps" , DC_FD_FS_RT },
+ {"movn.ps" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"addr.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"mulr.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"recip2.ps" , DC_FD_FS_FT },
+ {"recip1.ps" , DC_FD_FS },
+ {"rsqrt1.ps" , DC_FD_FS },
+ {"rsqrt2.ps" , DC_FD_FS_FT },
+ {"cvt.s.pu" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.pw.ps" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.pl" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"pll.ps" , DC_FD_FS_FT },
+ {"plu.ps" , DC_FD_FS_FT },
+ {"pul.ps" , DC_FD_FS_FT },
+ {"puu.ps" , DC_FD_FS_FT },
+ {"$70" , DC_DEREF },
+ {"$71" , DC_DEREF },
+ {"$72" , DC_DEREF },
+ {"$73" , DC_DEREF },
+ {"$74" , DC_DEREF },
+ {"$75" , DC_DEREF },
+ {"$76" , DC_DEREF },
+ {"$77" , DC_DEREF },
+ {"$78" , DC_DEREF },
+ {"$79" , DC_DEREF },
+ {"$80" , DC_DEREF },
+ {"$81" , DC_DEREF },
+ {"$82" , DC_DEREF },
+ {"$83" , DC_DEREF },
+ {"$84" , DC_DEREF },
+ {"$85" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_c_f_s[2] DATASEG =
+{{"c.f.s" , DC_CC_FS_FT },
+ {"cabs.f.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_s[2] DATASEG =
+{{"c.un.s" , DC_CC_FS_FT },
+ {"cabs.un.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_s[2] DATASEG =
+{{"c.eq.s" , DC_CC_FS_FT },
+ {"cabs.eq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_s[2] DATASEG =
+{{"c.ueq.s" , DC_CC_FS_FT },
+ {"cabs.ueq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_s[2] DATASEG =
+{{"c.olt.s" , DC_CC_FS_FT },
+ {"cabs.olt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_s[2] DATASEG =
+{{"c.ult.s" , DC_CC_FS_FT },
+ {"cabs.ult.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_s[2] DATASEG =
+{{"c.ole.s" , DC_CC_FS_FT },
+ {"cabs.ole.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_s[2] DATASEG =
+{{"c.ule.s" , DC_CC_FS_FT },
+ {"cabs.ule.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_s[2] DATASEG =
+{{"c.sf.s" , DC_CC_FS_FT },
+ {"cabs.sf.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_s[2] DATASEG =
+{{"c.ngle.s" , DC_CC_FS_FT },
+ {"cabs.ngle.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_s[2] DATASEG =
+{{"c.seq.s" , DC_CC_FS_FT },
+ {"cabs.seq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_s[2] DATASEG =
+{{"c.ngl.s" , DC_CC_FS_FT },
+ {"cabs.ngl.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_s[2] DATASEG =
+{{"c.lt.s" , DC_CC_FS_FT },
+ {"cabs.lt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_s[2] DATASEG =
+{{"c.nge.s" , DC_CC_FS_FT },
+ {"cabs.nge.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_s[2] DATASEG =
+{{"c.le.s" , DC_CC_FS_FT },
+ {"cabs.le.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_s[2] DATASEG =
+{{"c.ngt.s" , DC_CC_FS_FT },
+ {"cabs.ngt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_f_d[2] DATASEG =
+{{"c.f.d" , DC_CC_FS_FT },
+ {"cabs.f.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_d[2] DATASEG =
+{{"c.un.d" , DC_CC_FS_FT },
+ {"cabs.un.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_d[2] DATASEG =
+{{"c.eq.d" , DC_CC_FS_FT },
+ {"cabs.eq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_d[2] DATASEG =
+{{"c.ueq.d" , DC_CC_FS_FT },
+ {"cabs.ueq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_d[2] DATASEG =
+{{"c.olt.d" , DC_CC_FS_FT },
+ {"cabs.olt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_d[2] DATASEG =
+{{"c.ult.d" , DC_CC_FS_FT },
+ {"cabs.ult.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_d[2] DATASEG =
+{{"c.ole.d" , DC_CC_FS_FT },
+ {"cabs.ole.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_d[2] DATASEG =
+{{"c.ule.d" , DC_CC_FS_FT },
+ {"cabs.ule.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_d[2] DATASEG =
+{{"c.sf.d" , DC_CC_FS_FT },
+ {"cabs.sf.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_d[2] DATASEG =
+{{"c.ngle.d" , DC_CC_FS_FT },
+ {"cabs.ngle.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_d[2] DATASEG =
+{{"c.seq.d" , DC_CC_FS_FT },
+ {"cabs.seq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_d[2] DATASEG =
+{{"c.ngl.d" , DC_CC_FS_FT },
+ {"cabs.ngl.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_d[2] DATASEG =
+{{"c.lt.d" , DC_CC_FS_FT },
+ {"cabs.lt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_d[2] DATASEG =
+{{"c.nge.d" , DC_CC_FS_FT },
+ {"cabs.nge.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_d[2] DATASEG =
+{{"c.le.d" , DC_CC_FS_FT },
+ {"cabs.le.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_d[2] DATASEG =
+{{"c.ngt.d" , DC_CC_FS_FT },
+ {"cabs.ngt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_f_ps[2] DATASEG =
+{{"c.f.ps" , DC_CC_FS_FT },
+ {"cabs.f.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_ps[2] DATASEG =
+{{"c.un.ps" , DC_CC_FS_FT },
+ {"cabs.un.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_ps[2] DATASEG =
+{{"c.eq.ps" , DC_CC_FS_FT },
+ {"cabs.eq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_ps[2] DATASEG =
+{{"c.ueq.ps" , DC_CC_FS_FT },
+ {"cabs.ueq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_ps[2] DATASEG =
+{{"c.olt.ps" , DC_CC_FS_FT },
+ {"cabs.olt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_ps[2] DATASEG =
+{{"c.ult.ps" , DC_CC_FS_FT },
+ {"cabs.ult.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_ps[2] DATASEG =
+{{"c.ole.ps" , DC_CC_FS_FT },
+ {"cabs.ole.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_ps[2] DATASEG =
+{{"c.ule.ps" , DC_CC_FS_FT },
+ {"cabs.ule.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_ps[2] DATASEG =
+{{"c.sf.ps" , DC_CC_FS_FT },
+ {"cabs.sf.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_ps[2] DATASEG =
+{{"c.ngle.ps" , DC_CC_FS_FT },
+ {"cabs.ngle.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_ps[2] DATASEG =
+{{"c.seq.ps" , DC_CC_FS_FT },
+ {"cabs.seq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_ps[2] DATASEG =
+{{"c.ngl.ps" , DC_CC_FS_FT },
+ {"cabs.ngl.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_ps[2] DATASEG =
+{{"c.lt.ps" , DC_CC_FS_FT },
+ {"cabs.lt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_ps[2] DATASEG =
+{{"c.nge.ps" , DC_CC_FS_FT },
+ {"cabs.nge.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_ps[2] DATASEG =
+{{"c.le.ps" , DC_CC_FS_FT },
+ {"cabs.le.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_ps[2] DATASEG =
+{{"c.ngt.ps" , DC_CC_FS_FT },
+ {"cabs.ngt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_ps_mvcf[2] DATASEG =
+{{"movf.ps" , DC_FD_FS_CC },
+ {"movt.ps" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1x[64] DATASEG =
+{{"lwxc1" , DC_FD_IDX_BASE },
+ {"ldxc1" , DC_FD_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"luxc1" , DC_FD_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"swxc1" , DC_FS_IDX_BASE },
+ {"sdxc1" , DC_FS_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"suxc1" , DC_FS_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"prefx" , DC_PREF_IDX },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"alnv.ps" , DC_FD_FS_FT_RS },
+ {"invalid" , DC_BARE },
+ {"madd.s" , DC_FD_FR_FS_FT },
+ {"madd.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"madd.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"msub.s" , DC_FD_FR_FS_FT },
+ {"msub.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"msub.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"nmadd.s" , DC_FD_FR_FS_FT },
+ {"nmadd.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"nmadd.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"nmsub.s" , DC_FD_FR_FS_FT },
+ {"nmsub.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"nmsub.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_mdmx[8] DATASEG =
+{{ "$20" , DC_DEREF },
+ { "$19" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$33" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$19" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$33" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_qh[64] DATASEG =
+{{ "msgn.qh" , DC_VD_VS_VT_VEC},
+ { "c.eq.qh" , DC_VS_VT_VEC },
+ { "pickf.qh" , DC_VD_VS_VT_VEC},
+ { "pickt.qh" , DC_VD_VS_VT_VEC},
+ { "c.lt.qh" , DC_VS_VT_VEC },
+ { "c.le.qh" , DC_VS_VT_VEC },
+ { "min.qh" , DC_VD_VS_VT_VEC},
+ { "max.qh" , DC_VD_VS_VT_VEC},
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "sub.qh" , DC_VD_VS_VT_VEC},
+ { "add.qh" , DC_VD_VS_VT_VEC},
+ { "and.qh" , DC_VD_VS_VT_VEC},
+ { "xor.qh" , DC_VD_VS_VT_VEC},
+ { "or.qh" , DC_VD_VS_VT_VEC},
+ { "nor.qh" , DC_VD_VS_VT_VEC},
+
+ { "sll.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "srl.qh" , DC_VD_VS_VT_VEC},
+ { "sra.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$34" , DC_DEREF },
+
+ { "rzu.qh" , DC_VD_VT },
+ { "rnau.qh" , DC_VD_VT },
+ { "rneu.qh" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+ { "rzs.qh" , DC_VD_VT },
+ { "rnas.qh" , DC_VD_VT },
+ { "rnes.qh" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "mul.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "$21" , DC_DEREF },
+ { "$22" , DC_DEREF },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$23" , DC_DEREF },
+ { "$24" , DC_DEREF },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$25" , DC_DEREF },
+ { "$26" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_ob[64] DATASEG =
+{{ "invalid" , DC_BARE },
+ { "c.eq.ob" , DC_VS_VT_VEC },
+ { "pickf.ob" , DC_VD_VS_VT_VEC},
+ { "pickt.ob" , DC_VD_VS_VT_VEC},
+ { "c.lt.ob" , DC_VS_VT_VEC },
+ { "c.le.ob" , DC_VS_VT_VEC },
+ { "min.ob" , DC_VD_VS_VT_VEC},
+ { "max.ob" , DC_VD_VS_VT_VEC},
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "sub.ob" , DC_VD_VS_VT_VEC},
+ { "add.ob" , DC_VD_VS_VT_VEC},
+ { "and.ob" , DC_VD_VS_VT_VEC},
+ { "xor.ob" , DC_VD_VS_VT_VEC},
+ { "or.ob" , DC_VD_VS_VT_VEC},
+ { "nor.ob" , DC_VD_VS_VT_VEC},
+
+ { "sll.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "srl.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$35" , DC_DEREF },
+
+ { "rzu.ob" , DC_VD_VT },
+ { "rnau.ob" , DC_VD_VT },
+ { "rneu.ob" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "mul.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "$27" , DC_DEREF },
+ { "$28" , DC_DEREF },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$29" , DC_DEREF },
+ { "$30" , DC_DEREF },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$31" , DC_DEREF },
+ { "$32" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_alni[64] DATASEG =
+{{ "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_muls_qh[2] DATASEG =
+{{ "muls.qh" , DC_VS_VT_VEC },
+ { "mulsl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_mul_qh[2] DATASEG =
+{{ "mula.qh" , DC_VS_VT_VEC },
+ { "mull.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_sub_qh[2] DATASEG =
+{{ "suba.qh" , DC_VS_VT_VEC },
+ { "subl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_add_qh[2] DATASEG =
+{{ "adda.qh" , DC_VS_VT_VEC },
+ { "addl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_wac_qh[4] DATASEG =
+{{ "wacl.qh" , DC_VS_VT },
+ { "invalid" , DC_BARE },
+ { "wach.qh" , DC_VS },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_rac_qh[4] DATASEG =
+{{ "racl.qh" , DC_VD },
+ { "racm.qh" , DC_VD },
+ { "rach.qh" , DC_VD },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_muls_ob[2] DATASEG =
+{{ "muls.ob" , DC_VS_VT_VEC },
+ { "mulsl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_mul_ob[2] DATASEG =
+{{ "mula.ob" , DC_VS_VT_VEC },
+ { "mull.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_sub_ob[2] DATASEG =
+{{ "suba.ob" , DC_VS_VT_VEC },
+ { "subl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_add_ob[2] DATASEG =
+{{ "adda.ob" , DC_VS_VT_VEC },
+ { "addl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_wac_ob[4] DATASEG =
+{{ "wacl.ob" , DC_VS_VT },
+ { "invalid" , DC_BARE },
+ { "wach.ob" , DC_VS },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_rac_ob[4] DATASEG =
+{{ "racl.ob" , DC_VD },
+ { "racm.ob" , DC_VD },
+ { "rach.ob" , DC_VD },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_shfl_ob[16] DATASEG =
+{{ "shfl.upsl.ob" , DC_VD_VS_VT },
+ { "shfl.pach.ob" , DC_VD_VS_VT },
+ { "shfl.mixh.ob" , DC_VD_VS_VT },
+ { "shfl.mixl.ob" , DC_VD_VS_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_shfl_qh[8] DATASEG =
+{{ "shfl.bfla.qh" , DC_VD_VS_VT },
+ { "shfl.pach.qh" , DC_VD_VS_VT },
+ { "shfl.mixh.qh" , DC_VD_VS_VT },
+ { "shfl.mixl.qh" , DC_VD_VS_VT },
+ { "shfl.repa.qh" , DC_VD_VS_VT },
+ { "shfl.repb.qh" , DC_VD_VS_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+
+
+const disasm_deref_t disasm_deref[] =
+/* Disasm array shft msk */
+{{ disasm_normal , 26, 0x3f }, /* 0 */
+ { disasm_special , 0, 0x3f }, /* 1 */
+ { disasm_regimm , 16, 0x1f }, /* 2 */
+ { disasm_spec2 , 0, 0x3f }, /* 3 */
+ { disasm_cop0 , 21, 0x1f }, /* 4 */
+ { disasm_cop0_c0 , 0, 0x3f }, /* 5 */
+ { disasm_cop1 , 21, 0x1f }, /* 6 */
+ { disasm_cop1_s , 0, 0x3f }, /* 7 */
+ { disasm_cop1_s_mvcf , 16, 0x1 }, /* 8 */
+ { disasm_cop1_d , 0, 0x3f }, /* 9 */
+ { disasm_cop1_d_mvcf , 16, 0x1 }, /* 10 */
+ { disasm_cop1_w , 0, 0x3f }, /* 11 */
+ { disasm_cop1_l , 0, 0x3f }, /* 12 */
+ { disasm_cop1_ps , 0, 0x3f }, /* 13 */
+ { disasm_cop1_ps_mvcf, 16, 0x1 }, /* 14 */
+ { disasm_cop1x , 0, 0x3f }, /* 15 */
+ { disasm_movci , 16, 0x1 }, /* 16 */
+ { disasm_cop1_bc1 , 16, 0x3 }, /* 17 */
+ { disasm_mdmx , 21, 0x7 }, /* 18 */
+ { disasm_mdmx_qh , 0, 0x3f }, /* 19 */
+ { disasm_mdmx_ob , 0, 0x3f }, /* 20 */
+ { disasm_mdmx_muls_qh, 10, 0x1 }, /* 21 */
+ { disasm_mdmx_mul_qh , 10, 0x1 }, /* 22 */
+ { disasm_mdmx_sub_qh , 10, 0x1 }, /* 23 */
+ { disasm_mdmx_add_qh , 10, 0x1 }, /* 24 */
+ { disasm_mdmx_wac_qh , 24, 0x3 }, /* 25 */
+ { disasm_mdmx_rac_qh , 24, 0x3 }, /* 26 */
+ { disasm_mdmx_muls_ob, 10, 0x1 }, /* 27 */
+ { disasm_mdmx_mul_ob , 10, 0x1 }, /* 28 */
+ { disasm_mdmx_sub_ob , 10, 0x1 }, /* 29 */
+ { disasm_mdmx_add_ob , 10, 0x1 }, /* 30 */
+ { disasm_mdmx_wac_ob , 24, 0x3 }, /* 31 */
+ { disasm_mdmx_rac_ob , 24, 0x3 }, /* 32 */
+ { disasm_mdmx_alni , 0, 0x3f }, /* 33 */
+ { disasm_mdmx_shfl_ob, 22, 0xf }, /* 34 */
+ { disasm_mdmx_shfl_qh, 23, 0x7 }, /* 35 */
+ { disasm_cop1_bc1any2, 16, 0x1 }, /* 36 */
+ { disasm_cop1_bc1any4, 16, 0x1 }, /* 37 */
+ { disasm_cop1_c_f_s , 6, 0x1 }, /* 38 */
+ { disasm_cop1_c_un_s , 6, 0x1 }, /* 39 */
+ { disasm_cop1_c_eq_s , 6, 0x1 }, /* 40 */
+ { disasm_cop1_c_ueq_s, 6, 0x1 }, /* 41 */
+ { disasm_cop1_c_olt_s, 6, 0x1 }, /* 42 */
+ { disasm_cop1_c_ult_s, 6, 0x1 }, /* 43 */
+ { disasm_cop1_c_ole_s, 6, 0x1 }, /* 44 */
+ { disasm_cop1_c_ule_s, 6, 0x1 }, /* 45 */
+ { disasm_cop1_c_sf_s , 6, 0x1 }, /* 46 */
+ { disasm_cop1_c_ngle_s, 6, 0x1 }, /* 47 */
+ { disasm_cop1_c_seq_s, 6, 0x1 }, /* 48 */
+ { disasm_cop1_c_ngl_s, 6, 0x1 }, /* 49 */
+ { disasm_cop1_c_lt_s , 6, 0x1 }, /* 50 */
+ { disasm_cop1_c_nge_s, 6, 0x1 }, /* 51 */
+ { disasm_cop1_c_le_s , 6, 0x1 }, /* 52 */
+ { disasm_cop1_c_ngt_s, 6, 0x1 }, /* 53 */
+ { disasm_cop1_c_f_d , 6, 0x1 }, /* 54 */
+ { disasm_cop1_c_un_d , 6, 0x1 }, /* 55 */
+ { disasm_cop1_c_eq_d , 6, 0x1 }, /* 56 */
+ { disasm_cop1_c_ueq_d, 6, 0x1 }, /* 57 */
+ { disasm_cop1_c_olt_d, 6, 0x1 }, /* 58 */
+ { disasm_cop1_c_ult_d, 6, 0x1 }, /* 59 */
+ { disasm_cop1_c_ole_d, 6, 0x1 }, /* 60 */
+ { disasm_cop1_c_ule_d, 6, 0x1 }, /* 61 */
+ { disasm_cop1_c_sf_d , 6, 0x1 }, /* 62 */
+ { disasm_cop1_c_ngle_d, 6, 0x1 }, /* 63 */
+ { disasm_cop1_c_seq_d, 6, 0x1 }, /* 64 */
+ { disasm_cop1_c_ngl_d, 6, 0x1 }, /* 65 */
+ { disasm_cop1_c_lt_d , 6, 0x1 }, /* 66 */
+ { disasm_cop1_c_nge_d, 6, 0x1 }, /* 67 */
+ { disasm_cop1_c_le_d , 6, 0x1 }, /* 68 */
+ { disasm_cop1_c_ngt_d, 6, 0x1 }, /* 69 */
+ { disasm_cop1_c_f_ps , 6, 0x1 }, /* 70 */
+ { disasm_cop1_c_un_ps, 6, 0x1 }, /* 71 */
+ { disasm_cop1_c_eq_ps, 6, 0x1 }, /* 72 */
+ { disasm_cop1_c_ueq_ps, 6, 0x1 }, /* 73 */
+ { disasm_cop1_c_olt_ps, 6, 0x1 }, /* 74 */
+ { disasm_cop1_c_ult_ps, 6, 0x1 }, /* 75 */
+ { disasm_cop1_c_ole_ps, 6, 0x1 }, /* 76 */
+ { disasm_cop1_c_ule_ps, 6, 0x1 }, /* 77 */
+ { disasm_cop1_c_sf_ps, 6, 0x1 }, /* 78 */
+ { disasm_cop1_c_ngle_ps, 6, 0x1 }, /* 79 */
+ { disasm_cop1_c_seq_ps, 6, 0x1 }, /* 80 */
+ { disasm_cop1_c_ngl_ps, 6, 0x1 }, /* 81 */
+ { disasm_cop1_c_lt_ps, 6, 0x1 }, /* 82 */
+ { disasm_cop1_c_nge_ps, 6, 0x1 }, /* 83 */
+ { disasm_cop1_c_le_ps, 6, 0x1 }, /* 84 */
+ { disasm_cop1_c_ngt_ps, 6, 0x1 }, /* 85 */
+};
+
+#define PREFHINT(x) (&pref_hints[(x)*9])
+static char *pref_hints =
+ "load \0"
+ "store \0"
+ "reserved\0"
+ "reserved\0"
+
+ "ld_strm \0"
+ "st_strm \0"
+ "ld_retn \0"
+ "st_retn \0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "wb_inval\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0";
+
+
+static int snprintf(char *buf,int len,const char *templat,...)
+{
+ va_list marker;
+ int count;
+
+ va_start(marker,templat);
+ count = xvsprintf(buf,templat,marker);
+ va_end(marker);
+
+ return count;
+}
+
+static const disasm_t *get_disasm_field(uint32_t inst)
+{
+ const disasm_deref_t *tmp = &disasm_deref[0];
+ const disasm_t *rec;
+ do {
+ rec = &(tmp->ptr[(inst>>tmp->shift) & tmp->mask]);
+ tmp = &disasm_deref[atoi(&(rec->name[1]))];
+ } while (rec->type == DC_DEREF);
+ return rec;
+}
+
+char *disasm_inst_name(uint32_t inst)
+{
+ return (char *)(get_disasm_field(inst)->name);
+}
+
+void disasm_inst(char *buf, int buf_size, uint32_t inst, uint64_t pc)
+{
+ const disasm_t *tmp;
+ char instname[32];
+ int commentmode = 0;
+ char *x;
+
+ tmp = get_disasm_field(inst);
+
+ strcpy(instname,(char *) tmp->name);
+
+ if ((x = strchr(instname,'@'))) {
+ *x++ = 0;
+ commentmode = atoi(x);
+ }
+
+ switch (tmp->type) {
+ case DC_RD_RS_RT:
+ snprintf(buf, buf_size, "%-8s %s,%s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_RD_RT_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RT_RS_SIMM:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%" PF_32 "d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ SEXT_32(15, inst & 0xffff));
+ break;
+ case DC_RT_RS_XIMM:
+ snprintf(buf, buf_size, "%-8s %s,%s,#0x%" PF_32 "x",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ inst & 0xffff);
+ break;
+ case DC_RS_RT_OFS:
+ snprintf(buf, buf_size, "%-8s %s,%s,0x%" PF_64 "x",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ pc + 4 + (SEXT_64(15, inst & 0xffff)<<2));
+ break;
+ case DC_RS_OFS:
+ snprintf(buf, buf_size, "%-8s %s,0x%" PF_64 "x",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ pc + 4 + (SEXT_64(16, inst & 0xffff)<<2));
+ break;
+ case DC_RD_RT_SA:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%d",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>6) & 0x1f);
+ break;
+ case DC_RT_UIMM:
+ snprintf(buf, buf_size, "%-8s %s,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ inst & 0xffff);
+ break;
+ case DC_RD:
+ snprintf(buf, buf_size, "%-8s %s",
+ instname,
+ REGNAME((inst>>11) & 0x1f));
+ break;
+ case DC_J:
+ snprintf(buf, buf_size, "%-8s 0x%" PF_64 "x",
+ instname,
+ (pc & UINT64_T(0xfffffffff0000000)) | ((inst & 0x3ffffff)<<2));
+ break;
+ case DC_RD_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RS_RT:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_RT_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RT_RD_SEL:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>11) & 0x1f),
+ inst & 0x3);
+ break;
+ case DC_RT_CR_SEL:
+ snprintf(buf, buf_size, "%-8s %s,%d,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>11) & 0x1f,
+ inst & 0x3);
+ break;
+ case DC_RS:
+ snprintf(buf, buf_size, "%-8s %s",
+ instname,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RS_SIMM:
+ snprintf(buf, buf_size, "%-8s %s,#%" PF_32 "d",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ SEXT_32(15, inst & 0xffff));
+ break;
+ case DC_RT_OFS_BASE:
+ snprintf(buf, buf_size, "%-8s %s,#%" PF_32 "d(%s)",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ SEXT_32(15, inst),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FT_OFS_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,#%" PF_32 "d(%s)",
+ instname,
+ (inst>>16) & 0x1f,
+ SEXT_32(15, inst),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FD_IDX_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,%s(%s)",
+ instname,
+ (inst>>6) & 0x1f,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FS_IDX_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,%s(%s)",
+ instname,
+ (inst>>11) & 0x1f,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FD_FS_FT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_FD_FS_RT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_FD_FS:
+ snprintf(buf, buf_size, "%-8s f%d,f%d",
+ instname,
+ (inst>>6)&0x1f,
+ (inst>>11)&0x1f);
+ break;
+ case DC_PREF_OFS:
+ snprintf(buf, buf_size, "%-8s #%" PF_32 "d(%s) /* %s */",
+ instname,
+ SEXT_32(15, inst & 0xffff),
+ REGNAME((inst>>21) & 0x1f),
+ PREFHINT((inst>>16) & 0x1f));
+ break;
+ case DC_PREF_IDX:
+ snprintf(buf, buf_size, "%-8s %s(%s) /* %s */",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ PREFHINT((inst>>16) & 0x1f));
+ break;
+ case DC_CC_OFS:
+ snprintf(buf, buf_size, "%-8s %d,0x%" PF_64 "x",
+ instname,
+ (inst>>18) & 0x7,
+ pc + 4 + (SEXT_64(15, inst & 0xffff)<<2));
+ break;
+ case DC_RD_RS_CC:
+ snprintf(buf, buf_size, "%-8s %s,%s,%d",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ (inst>>18) & 0x7);
+ break;
+ case DC_FD_FS_CC:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>18) & 0x7);
+ break;
+ case DC_FD_FR_FS_FT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d,f%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>21) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_FD_FS_FT_RS:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_CC_FS_FT:
+ snprintf(buf, buf_size, "%-8s %d,f%d,f%d",
+ instname,
+ (inst>>8) & 0x7,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_BARE:
+ snprintf(buf, buf_size, "%-8s", instname);
+ break;
+ case DC_RT_FS:
+ snprintf(buf, buf_size, "%-8s %s,f%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>11) & 0x1f);
+ break;
+ case DC_VS:
+ snprintf(buf, buf_size, "%-8s $v%d",
+ instname,
+ (inst>>11) & 0x1f);
+ break;
+ case DC_VD:
+ snprintf(buf, buf_size, "%-8s $v%d",
+ instname,
+ (inst>>6) & 0x1f);
+ break;
+ case DC_VD_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VD_VS_VT_IMM:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d,#%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>21) & 0x7);
+ break;
+ case DC_VD_VS_VT_RS:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_VD_VS_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VS_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VS_VT_VEC:
+ switch((inst>>24) & 0x3) {
+ case 0:
+ case 1:
+ /* element select */
+ if ((inst>>21) & 1) {
+ /* QH */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d[%d]",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>23) & 0x3);
+ } else {
+ /* OB */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d[%d]",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>22) & 0x7);
+
+ }
+ break;
+ case 2:
+ /* Vector select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case 3:
+ /* immediate select */
+ snprintf(buf, buf_size, "%-8s $v%d,$#%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ }
+ break;
+
+ case DC_VD_VS_VT_VEC:
+ switch((inst>>24) & 0x3) {
+ case 0:
+ case 1:
+ /* element select */
+ if ((inst>>21) & 1) {
+ /* QH */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d[%d]",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>23) & 0x3);
+ } else {
+ /* OB */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d[%d]",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>22) & 0x7);
+
+ }
+ break;
+ case 2:
+ /* Vector select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case 3:
+ /* immediate select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$#%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ }
+ break;
+
+ case DC_SYSCALL:
+ snprintf(buf, buf_size, "%-8s #%d",
+ instname,
+ (inst>>6) & 0xfffff);
+ break;
+ case DC_BREAK:
+ snprintf(buf, buf_size, "%-8s %d", instname, (inst>>6)&0xfffff);
+ break;
+ case DC_OOPS:
+ snprintf(buf, buf_size, "%s OOPS! FIXME!", instname);
+ break;
+ default:
+ /* Hit something we don't know about...Shouldn't happen. */
+ break;
+ }
+
+ /*
+ * Handle comment field
+ */
+
+
+ switch (commentmode) {
+ case 1: /* CP0 ops */
+ if ((inst & 3) == 0) { /* select 0 */
+ snprintf(buf + strlen(buf),buf_size-strlen(buf)," /* %s */",
+ CP0REGNAME((inst >> 11) & 0x1f));
+ }
+ break;
+ default:
+ break;
+ }
+
+ buf[buf_size-1] = 0;
+
+}
diff --git a/cfe/cfe/arch/mips/common/src/exception.S b/cfe/cfe/arch/mips/common/src/exception.S
new file mode 100644
index 0000000..8036b35
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/exception.S
@@ -0,0 +1,546 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Exception Handler File: exception.S
+ *
+ * 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 "sbmips.h"
+#include "exception.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD and ERET */
+#include "bsp_config.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#ifdef _MIPSREGS32_
+#define LREG lw
+#define SREG sw
+#define SRL srl
+#define SLL sll
+#else
+#define LREG ld
+#define SREG sd
+#define SRL dsrl
+#define SLL dsll
+#endif
+
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+ .sdata
+
+ .globl _exc_vectab
+_exc_vectab: _LONG_ 0 # XTYPE_RESET
+ _LONG_ 0 # XTYPE_TLBFILL (not used)
+ _LONG_ 0 # XTYPE_XTLBFILL
+ _LONG_ 0 # XTYPE_CACHEERR (not used)
+ _LONG_ 0 # XTYPE_EXCEPTION
+ _LONG_ 0 # XTYPE_INTERRUPT
+ _LONG_ 0 # XTYPE_EJTAG
+
+/* *********************************************************************
+ * Common Data
+ ********************************************************************* */
+
+ .bss
+
+
+/* *********************************************************************
+ * Code
+ ********************************************************************* */
+
+ .text
+
+#define R_EXC_CERR_TEMPLATE _TBLIDX(0)
+#define R_EXC_CERR_TEMPLATE_END _TBLIDX(1)
+
+ .globl _exc_cerr_htable
+_exc_cerr_htable:
+ _LONG_ _exc_cerr_template
+ _LONG_ _exc_cerr_template_end
+
+
+/* *********************************************************************
+ * _exc_cerr_template
+ *
+ * This is a template routine for our cache error handler.
+ * We save a couple of registers in our magic save area, then
+ * dispatch to code elsewhere in CFE.
+ *
+ * This code is copied right to the vector address, so it has
+ * to be kept tiny!
+ *
+ * Input parameters:
+ * nothing - running uncached, all registers trashed
+ *
+ * Return value:
+ * might return, might not
+ ********************************************************************* */
+
+LEAF(_exc_cerr_template)
+
+ /*
+ * Magic! When the cache error handler is running,
+ * we are in a very special state, running uncached
+ * and with translations turned off. We can use offsets
+ * from r0(zero) to store registers we need to use
+ * during the error handler.
+ */
+
+ .set push ; .set noreorder
+
+ SR k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
+ SR k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
+ SR ra,CFE_LOCORE_GLOBAL_RATMP(zero)
+ SR gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
+
+ LR k0,CFE_LOCORE_GLOBAL_CERRH(zero)
+ jal k0
+ nop
+
+ LR k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
+ LR k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
+ LR ra,CFE_LOCORE_GLOBAL_RATMP(zero)
+ LR gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
+ ERET
+
+ .set pop
+
+ /*
+ * Note: make sure this routine does not exceed 128 bytes
+ */
+
+_exc_cerr_template_end:
+
+END(_exc_cerr_template)
+
+/* *********************************************************************
+ * _exc_setup_locore(cerrh)
+ *
+ * Set global data into the low-memory region. We do this in
+ * assembly language so it's easier to deal with the 32-bit/64-bit
+ * issues that arise in the "C" code.
+ *
+ * Input parameters:
+ * a0 - cache error handler
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_setup_locore)
+
+ move t4,ra
+
+ /*
+ * Save GP for easy re-use, using uncached writes.
+ */
+
+ li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_GP)
+ SR gp,0(t0)
+
+ /*
+ * Initialize cache error handler pointer. Make it
+ * uncached, since cache error handlers should not
+ * touch the cache.
+ */
+
+ li t1,(K0SIZE-1)
+ and a0,a0,t1 # keep just physical part
+ li t1,K1BASE
+ or a0,a0,t1 # make into an uncached address
+
+ li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_CERRH)
+ SR a0,0(t0)
+
+ /*
+ * Move the cache error handler into low RAM.
+ */
+
+ li t0,PHYS_TO_K1(MIPS_RAM_VEC_CACHEERR)
+
+ LOADREL(t1,_exc_cerr_htable)
+ LR t2,R_EXC_CERR_TEMPLATE_END(t1)
+ LR t1,R_EXC_CERR_TEMPLATE(t1)
+
+1: lw t3,0(t1) # get a word
+ sw t3,0(t0) # write a word
+ ADD t0,4 # next word...
+ ADD t1,4
+ blt t1,t2,1b # till done
+
+ /*
+ * Now do the whole thing again, but with cached writes.
+ * Writing uncached makes sure the data is actually in memory,
+ * and writing cached makes sure we write the same
+ * stuff again when the cache is evicted.
+ * This way we don't have to bother with cacheops,
+ * a bonus on the BCM1250 with its funky L2.
+ */
+
+ li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
+ SR gp,0(t0)
+
+ li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_CERRH)
+ SR a0,0(t0)
+
+ li t0,PHYS_TO_K0(MIPS_RAM_VEC_CACHEERR)
+
+ LOADREL(t1,_exc_cerr_htable)
+ LR t2,R_EXC_CERR_TEMPLATE_END(t1)
+ LR t1,R_EXC_CERR_TEMPLATE(t1)
+
+1: lw t3,0(t1) # get a word
+ sw t3,0(t0) # write a word
+ ADD t0,4 # next word...
+ ADD t1,4
+ blt t1,t2,1b # till done
+
+
+ /*
+ * done!
+ */
+
+ move ra,t4
+ j ra
+
+END(_exc_setup_locore)
+
+
+
+
+/* *********************************************************************
+ * _exc_setvector(xtype,addr)
+ *
+ * Set an exception vector address
+ *
+ * Input parameters:
+ * xtype - exception vector type
+ * addr - routine address
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_setvector)
+
+ la v0,_exc_vectab
+ srl a0,3 /* convert 8-byte index to array index */
+ sll a0,BPWSIZE /* convert back to index appropriate for word size */
+ add v0,a0
+ SR a1,(v0)
+ j ra
+
+END(_exc_setvector)
+
+
+/* *********************************************************************
+ * _exc_crash_sim()
+ *
+ * Crash the GDB simulator, causing it to exit.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing - does not return
+ ********************************************************************* */
+
+
+LEAF(_exc_crash_sim)
+
+ li $2,1
+ li $3,0xdead
+ li $4,0
+ syscall 0xca
+1: b 1b
+
+END(_exc_crash_sim)
+
+
+/* *********************************************************************
+ * _exc_cache_crash_sim()
+ *
+ * As _exc_crash_sim, but distinguish cache error exception.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing - does not return
+ ********************************************************************* */
+
+
+LEAF(_exc_cache_crash_sim)
+
+ li $2,1
+ li $3,0xbadc
+ li $4,0
+ syscall 0xca
+1: b 1b
+
+END(_exc_cache_crash_sim)
+
+
+/* *********************************************************************
+ * _exc_restart()
+ *
+ * Restart the firmware at the boot address
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_restart)
+
+ li t0,0xBFC00000 # ROM restart vector
+ jr t0
+
+END(_exc_restart)
+
+/* *********************************************************************
+ * _exc_entry(k0)
+ *
+ * Main exception entry point.
+ *
+ * Input parameters:
+ * k0 - exception type
+ *
+ * Return value:
+ * ...
+ ********************************************************************* */
+
+LEAF(_exc_entry)
+
+ .set noreorder
+ .set noat
+
+ subu k1,sp,EXCEPTION_SIZE
+ SRL k1,3
+ SLL k1,3
+
+ SREG zero,XGR_ZERO(k1)
+ SREG AT,XGR_AT(k1)
+
+ SREG v0,XGR_V0(k1)
+ SREG v1,XGR_V1(k1)
+
+ SREG a0,XGR_A0(k1)
+ SREG a1,XGR_A1(k1)
+ SREG a2,XGR_A2(k1)
+ SREG a3,XGR_A3(k1)
+
+ SREG t0,XGR_T0(k1)
+ SREG t1,XGR_T1(k1)
+ SREG t2,XGR_T2(k1)
+ SREG t3,XGR_T3(k1)
+ SREG t4,XGR_T4(k1)
+ SREG t5,XGR_T5(k1)
+ SREG t6,XGR_T6(k1)
+ SREG t7,XGR_T7(k1)
+
+ SREG s0,XGR_S0(k1)
+ SREG s1,XGR_S1(k1)
+ SREG s2,XGR_S2(k1)
+ SREG s3,XGR_S3(k1)
+ SREG s4,XGR_S4(k1)
+ SREG s5,XGR_S5(k1)
+ SREG s6,XGR_S6(k1)
+ SREG s7,XGR_S7(k1)
+
+ SREG t8,XGR_T8(k1)
+ SREG t9,XGR_T9(k1)
+
+ SREG gp,XGR_GP(k1)
+ SREG sp,XGR_SP(k1)
+ SREG fp,XGR_FP(k1)
+ SREG ra,XGR_RA(k1)
+
+ mfc0 t0,C0_CAUSE
+ mfc0 t1,C0_SR
+ MFC0 t2,C0_BADVADDR
+ MFC0 t3,C0_EPC
+ mfc0 t4,C0_PRID
+ mflo t5
+ mfhi t6
+ SREG t0,XCP0_CAUSE(k1)
+ SREG t1,XCP0_SR(k1)
+ SREG t2,XCP0_VADDR(k1)
+ SREG t3,XCP0_EPC(k1)
+ SREG t4,XCP0_PRID(k1)
+ SREG t5,XGR_LO(k1)
+ SREG t6,XGR_HI(k1)
+
+#if CFG_EMBEDDED_PIC
+ la gp,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
+ LR gp,0(gp) # get our GP handle from low memory vector
+#else
+ la gp,_gp # Load up GP, not relocated so it's easy
+#endif
+
+ move a0,k0 # Pass exception type
+ move a1,k1 # Pass frame to exception handler
+ la t0,_exc_vectab # get base of exception vectors
+ srl k0,3 # convert 8-byte index to array index
+ sll k0,BPWSIZE # convert back to index appropriate for word size
+ addu t0,k0 # get vector address
+ LR t0,(t0) # to call handler
+
+ move sp,k1 # "C" gets fresh stack area
+
+ jalr t0 # Call exception handler
+ nop
+
+ move k1, sp
+ LREG AT,XGR_AT(k1)
+
+ LREG t0,XGR_LO(k1)
+ LREG t1,XGR_HI(k1)
+ mtlo t0
+ mthi t1
+
+ LREG a0,XGR_A0(k1)
+ LREG a1,XGR_A1(k1)
+ LREG a2,XGR_A2(k1)
+ LREG a3,XGR_A3(k1)
+
+ LREG t0,XGR_T0(k1)
+ LREG t1,XGR_T1(k1)
+ LREG t2,XGR_T2(k1)
+ LREG t3,XGR_T3(k1)
+ LREG t4,XGR_T4(k1)
+ LREG t5,XGR_T5(k1)
+ LREG t6,XGR_T6(k1)
+ LREG t7,XGR_T7(k1)
+
+ LREG s0,XGR_S0(k1)
+ LREG s1,XGR_S1(k1)
+ LREG s2,XGR_S2(k1)
+ LREG s3,XGR_S3(k1)
+ LREG s4,XGR_S4(k1)
+ LREG s5,XGR_S5(k1)
+ LREG s6,XGR_S6(k1)
+ LREG s7,XGR_S7(k1)
+
+ LREG t8,XGR_T8(k1)
+ LREG t9,XGR_T9(k1)
+
+ LREG gp,XGR_GP(k1)
+ LREG sp,XGR_SP(k1)
+ LREG fp,XGR_FP(k1)
+ LREG ra,XGR_RA(k1)
+
+/* do any CP0 cleanup here */
+
+ LREG v0,XGR_V0(k1)
+ LREG v1,XGR_V1(k1)
+
+ ERET
+
+ .set at
+ .set reorder
+
+
+END(_exc_entry)
+
+
+/* *********************************************************************
+ * _exc_clear_sr_exl()
+ *
+ * Clear SR(EXL) and return to caller.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_clear_sr_exl)
+
+ mfc0 t0,C0_SR
+ and t0,t0,~(0x02) # clear SR(EXL). Bit 1
+ mtc0 t0,C0_SR
+
+ HAZARD
+
+ j ra
+
+END(_exc_clear_sr_exl)
+
+/* *********************************************************************
+ * _exc_clear_sr_erl()
+ *
+ * Clear SR(ERL) and return to caller.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_clear_sr_erl)
+
+ mfc0 t0,C0_SR
+ and t0,t0,~(0x04) # clear SR(ERL). Bit 2
+ mtc0 t0,C0_SR
+
+ HAZARD
+
+ j ra
+
+END(_exc_clear_sr_erl)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/exchandler.c b/cfe/cfe/arch/mips/common/src/exchandler.c
new file mode 100644
index 0000000..d69b980
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/exchandler.c
@@ -0,0 +1,580 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Exception Handler File: exchandler.c
+ *
+ * This is the "C" part of the exception handler and the
+ * associated setup routines. We call these routines from
+ * the assembly-language exception handler.
+ *
+ * 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 "sbmips.h"
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "exception.h"
+#include "cfe.h"
+#include "cfe_error.h"
+#include "cfe_iocb.h"
+#include "exchandler.h"
+#include "cpu_config.h"
+#include "bsp_config.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+/*
+ * Temporary until all our CPU packages support a cache error handler
+ */
+
+#ifndef CPUCFG_CERRHANDLER
+#define CPUCFG_CERRHANDLER 0xBFC00000
+#else
+extern void CPUCFG_CERRHANDLER(void);
+#endif
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+exc_handler_t exc_handler;
+extern void _exc_entry(void);
+extern void _exc_setup_locore(long);
+extern void CPUCFG_TLBHANDLER(void);
+extern void cfe_flushcache(uint32_t,long,long);
+extern uint32_t _getstatus(void);
+extern void _setstatus(uint32_t);
+
+static const char *regnames = "0 ATv0v1a0a1a2a3t0t1t2t3t4t5t6t7"
+ "s0s1s2s3s4s5s6s7t8t9k0k1gpspfpra";
+static const char *excnames =
+ "Interrupt" /* 0 */
+ "TLBMod " /* 1 */
+ "TLBMissRd" /* 2 */
+ "TLBMissWr" /* 3 */
+ "AddrErrRd" /* 4 */
+ "AddrErrWr" /* 5 */
+ "BusErrRd " /* 6 */
+ "BusErrWr " /* 7 */
+ "Syscall " /* 8 */
+ "Breakpt " /* 9 */
+ "InvOpcode" /* 10 */
+ "CoProcUnu" /* 11 */
+ "ArithOvfl" /* 12 */
+ "TrapExc " /* 13 */
+ "VCEI " /* 14 */
+ "FPUExc " /* 15 */
+ "CP2Exc " /* 16 */
+ "Exc17 " /* 17 */
+ "Exc18 " /* 18 */
+ "Exc19 " /* 19 */
+ "Exc20 " /* 20 */
+ "Exc21 " /* 21 */
+ "Exc22 " /* 22 */
+ "Watchpt " /* 23 */
+ "Exc24 " /* 24 */
+ "Exc25 " /* 25 */
+ "Exc26 " /* 26 */
+ "Exc27 " /* 27 */
+ "Exc28 " /* 28 */
+ "Exc29 " /* 29 */
+ "Exc30 " /* 30 */
+ "VCED "; /* 31 */
+
+
+
+/* *********************************************************************
+ * cfe_exception(code,info)
+ *
+ * Exception handler. This routine is called when any CPU
+ * exception that is handled by the assembly-language
+ * vectors is reached. The usual thing to do here is just to
+ * reboot.
+ *
+ * Input parameters:
+ * code - exception type
+ * info - exception stack frame
+ *
+ * Return value:
+ * usually reboots
+ ********************************************************************* */
+
+void cfe_exception(int code,uint64_t *info)
+{
+ int idx;
+
+ SETLEDS("EXC!");
+
+ if(exc_handler.catch_exc == 1) {
+ /*Deal with exception without restarting CFE.*/
+
+ /*Clear relevant SR bits*/
+ _exc_clear_sr_exl();
+ _exc_clear_sr_erl();
+
+ /*Reset flag*/
+ exc_handler.catch_exc = 0;
+
+ exc_longjmp_handler();
+ }
+
+
+#ifdef _MIPSREGS32_
+ xprintf("**Exception %d: EPC=%08X, Cause=%08X (%9s)\n",
+ code,(uint32_t)info[XCP0_EPC],
+ (uint32_t)info[XCP0_CAUSE],
+ excnames + G_CAUSE_EXC((uint32_t)info[XCP0_CAUSE])*9);
+ xprintf(" RA=%08X, VAddr=%08X\n",
+ (uint32_t)info[XGR_RA],(uint32_t)info[XCP0_VADDR]);
+ xprintf("\n");
+ for (idx = 0;idx < 32; idx+= 2) {
+ xprintf(" %2s ($%2d) = %08X %2s ($%2d) = %08X\n",
+ regnames+(idx*2),
+ idx,(uint32_t)info[XGR_ZERO+idx],
+ regnames+((idx+1)*2),
+ idx+1,(uint32_t)info[XGR_ZERO+idx+1]);
+ }
+#else
+ xprintf("**Exception %d: EPC=%016llX, Cause=%08X (%9s)\n",
+ code,info[XCP0_EPC],info[XCP0_CAUSE],
+ excnames + G_CAUSE_EXC((uint32_t)info[XCP0_CAUSE])*9);
+ xprintf(" RA=%016llX, VAddr=%016llX\n",
+ info[XGR_RA],info[XCP0_VADDR]);
+ xprintf("\n");
+ for (idx = 0;idx < 32; idx+= 2) {
+ xprintf(" %2s ($%2d) = %016llX %2s ($%2d) = %016llX\n",
+ regnames+(idx*2),
+ idx,info[XGR_ZERO+idx],
+ regnames+((idx+1)*2),
+ idx+1,info[XGR_ZERO+idx+1]);
+ }
+#endif
+
+ xprintf("\n");
+ _exc_restart();
+}
+
+#if (!CFG_BOOTRAM) && (CFG_RUNFROMKSEG0)
+/* *********************************************************************
+ * exc_setup_hw_vector(vecoffset,target,k0code)
+ *
+ * Install a patch of code at the specified offset in low
+ * KSEG0 memory that will jump to 'target' and load k0
+ * with the specified code value. This is used when we
+ * run with RAM vectors.
+ *
+ * Input parameters:
+ * vecoffset - offset into KSEG0
+ * target - location where we should branch when vector is called
+ * k0code - value to load into K0 before branching
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void exc_setup_hw_vector(uint32_t vecoffset,
+ void *target,
+ uint32_t k0code)
+{
+ uint32_t *vec;
+ uint32_t new;
+ uint32_t lower,upper;
+
+ new = (uint32_t) (intptr_t) target; /* warning: assumes compatibility addresses! */
+
+ lower = new & 0xffff;
+ upper = (new >> 16) & 0xffff;
+ if ((lower & 0x8000) != 0) {
+ upper++;
+ }
+
+ /*
+ * Get a KSEG0 version of the vector offset.
+ */
+ vec = (uint32_t *) PHYS_TO_K0(vecoffset);
+
+ /*
+ * Patch in the vector. Note that we have to flush
+ * the L1 Dcache and invalidate the L1 Icache before
+ * we can use this.
+ */
+
+ vec[0] = 0x3c1b0000 | upper; /* lui k1, HIGH(new) */
+ vec[1] = 0x277b0000 | lower; /* addiu k1, k1, LOW(new) */
+ vec[2] = 0x03600008; /* jr k1 */
+ vec[3] = 0x241a0000 | k0code; /* li k0, code */
+
+}
+
+
+/* *********************************************************************
+ * exc_install_ram_vectors()
+ *
+ * Install all of the hardware vectors into low memory,
+ * flush the cache, and clear the BEV bit so we can start
+ * using them.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void exc_install_ram_vectors(void)
+{
+ uint32_t *ptr;
+ int idx;
+
+ /* Debug: blow away the vector area so we can see what we did */
+ ptr = (uint32_t *) PHYS_TO_K0(0);
+ for (idx = 0; idx < 0x1000/sizeof(uint32_t); idx++) *ptr++ = 0;
+
+ /*
+ * Set up the vectors. The cache error handler is set up
+ * specially.
+ */
+
+ exc_setup_hw_vector(MIPS_RAM_VEC_TLBFILL, CPUCFG_TLBHANDLER,XTYPE_TLBFILL);
+ exc_setup_hw_vector(MIPS_RAM_VEC_XTLBFILL, _exc_entry,XTYPE_XTLBFILL);
+ exc_setup_hw_vector(MIPS_RAM_VEC_CACHEERR, _exc_entry,XTYPE_CACHEERR);
+ exc_setup_hw_vector(MIPS_RAM_VEC_EXCEPTION,_exc_entry,XTYPE_EXCEPTION);
+ exc_setup_hw_vector(MIPS_RAM_VEC_INTERRUPT,_exc_entry,XTYPE_INTERRUPT);
+
+ /*
+ * Flush the D-cache and invalidate the I-cache so we can start
+ * using these vectors.
+ */
+
+ cfe_flushcache(CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I,0,0);
+
+ /*
+ * Write the handle into our low memory space. If we need to save
+ * other stuff down there, this is a good place to do it.
+ * This call uses uncached writes - we have not touched the
+ * memory in the handlers just yet, so they should not be
+ * in our caches.
+ */
+
+ _exc_setup_locore((intptr_t) CPUCFG_CERRHANDLER);
+
+ /*
+ * Finally, clear BEV so we'll use the vectors in RAM.
+ */
+
+ _setstatus(_getstatus() & ~M_SR_BEV);
+
+ /*
+ * XXX There's a hazard here, but we're not going to worry about
+ * XXX it. It is unlikely we'll use the vectors any time soon.
+ */
+}
+#endif
+
+/* *********************************************************************
+ * cfe_setup_exceptions()
+ *
+ * Set up the exception handlers.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void cfe_setup_exceptions(void)
+{
+ _exc_setvector(XTYPE_TLBFILL, (void *) cfe_exception);
+ _exc_setvector(XTYPE_XTLBFILL, (void *) cfe_exception);
+ _exc_setvector(XTYPE_CACHEERR, (void *) _exc_cache_crash_sim);
+ _exc_setvector(XTYPE_EXCEPTION,(void *) cfe_exception);
+ _exc_setvector(XTYPE_INTERRUPT,(void *) cfe_exception);
+ _exc_setvector(XTYPE_EJTAG, (void *) cfe_exception);
+
+ exc_handler.catch_exc = 0;
+ q_init( &(exc_handler.jmpbuf_stack));
+
+#if (!CFG_BOOTRAM) && (CFG_RUNFROMKSEG0)
+ /*
+ * Install RAM vectors, and clear the BEV bit in the status
+ * register. Don't do this if we're running from PromICE RAM
+ */
+ exc_install_ram_vectors();
+#endif
+}
+
+
+
+/* *********************************************************************
+ * exc_initialize_block()
+ *
+ * Set up the exception handler. Allow exceptions to be caught.
+ * Allocate memory for jmpbuf and store it away.
+ *
+ * Returns NULL if error in memory allocation.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * jmpbuf_t structure, or NULL if no memory
+ ********************************************************************* */
+jmpbuf_t *exc_initialize_block(void)
+{
+ jmpbuf_t *jmpbuf_local;
+
+ exc_handler.catch_exc = 1;
+
+ /* Create the jmpbuf_t object */
+ jmpbuf_local = (jmpbuf_t *) KMALLOC((sizeof(jmpbuf_t)),0);
+
+ if (jmpbuf_local == NULL) {
+ return NULL;
+ }
+
+ q_enqueue( &(exc_handler.jmpbuf_stack), &((*jmpbuf_local).stack));
+
+ return jmpbuf_local;
+}
+
+/* *********************************************************************
+ * exc_cleanup_block(dq_jmpbuf)
+ *
+ * Remove dq_jmpbuf from the exception handler stack and free
+ * the memory.
+ *
+ * Input parameters:
+ * dq_jmpbuf - block to deallocate
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void exc_cleanup_block(jmpbuf_t *dq_jmpbuf)
+{
+ int count;
+
+ if (dq_jmpbuf == NULL) {
+ return;
+ }
+
+ count = q_count( &(exc_handler.jmpbuf_stack));
+
+ if( count > 0 ) {
+ q_dequeue( &(*dq_jmpbuf).stack );
+ KFREE(dq_jmpbuf);
+ }
+}
+
+/* *********************************************************************
+ * exc_cleanup_handler(dq_jmpbuf,chain_exc)
+ *
+ * Clean a block, then chain to the next exception if required.
+ *
+ * Input parameters:
+ * dq_jmpbuf - current exception
+ * chain_exc - true if we should chain to the next handler
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void exc_cleanup_handler(jmpbuf_t *dq_jmpbuf, int chain_exc)
+{
+ exc_cleanup_block(dq_jmpbuf);
+
+ if( chain_exc == EXC_CHAIN_EXC ) {
+ /*Go to next exception on stack */
+ exc_longjmp_handler();
+ }
+}
+
+
+
+/* *********************************************************************
+ * exc_longjmp_handler()
+ *
+ * This routine long jumps to the exception handler on the top
+ * of the exception stack.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void exc_longjmp_handler(void)
+{
+ int count;
+ jmpbuf_t *jmpbuf_local;
+
+ count = q_count( &(exc_handler.jmpbuf_stack));
+
+ if( count > 0 ) {
+ jmpbuf_local = (jmpbuf_t *) q_getlast(&(exc_handler.jmpbuf_stack));
+
+ SETLEDS("CFE ");
+
+ lib_longjmp( (*jmpbuf_local).jmpbuf, -1);
+ }
+}
+
+
+/* *********************************************************************
+ * mem_peek(d,addr,type)
+ *
+ * Read memory of the specified type at the specified address.
+ * Exceptions are caught in the case of a bad memory reference.
+ *
+ * Input parameters:
+ * d - pointer to where data should be placed
+ * addr - address to read
+ * type - type of read to do (MEM_BYTE, etc.)
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+
+int mem_peek(void *d, long addr, int type)
+{
+
+ jmpbuf_t *jb;
+
+ jb = exc_initialize_block();
+ if( jb == NULL ) {
+ return CFE_ERR_NOMEM;
+ }
+
+ if (exc_try(jb) == 0) {
+
+ switch (type) {
+ case MEM_BYTE:
+ *(uint8_t *)d = *((volatile uint8_t *) addr);
+ break;
+ case MEM_HALFWORD:
+ *(uint16_t *)d = *((volatile uint16_t *) addr);
+ break;
+ case MEM_WORD:
+ *(uint32_t *)d = *((volatile uint32_t *) addr);
+ break;
+ case MEM_QUADWORD:
+ *(uint64_t *)d = *((volatile uint64_t *) addr);
+ break;
+ default:
+ return CFE_ERR_INV_PARAM;
+ }
+
+ exc_cleanup_block(jb);
+ }
+ else {
+ /*Exception handler*/
+
+ exc_cleanup_handler(jb, EXC_NORMAL_RETURN);
+ return CFE_ERR_GETMEM;
+ }
+
+ return 0;
+}
+
+/* *********************************************************************
+ * Write memory of type at address addr with value val.
+ * Exceptions are caught, handled (error message) and function
+ * returns with 0.
+ *
+ * 1 success
+ * 0 failure
+ ********************************************************************* */
+
+int mem_poke(long addr, uint64_t val, int type)
+{
+
+ jmpbuf_t *jb;
+
+ jb = exc_initialize_block();
+ if( jb == NULL ) {
+ return CFE_ERR_NOMEM;
+ }
+
+ if (exc_try(jb) == 0) {
+
+ switch (type) {
+ case MEM_BYTE:
+ *((volatile uint8_t *) addr) = (uint8_t) val;
+ break;
+ case MEM_HALFWORD:
+ *((volatile uint16_t *) addr) = (uint16_t) val;
+ break;
+ case MEM_WORD:
+ *((volatile uint32_t *) addr) = (uint32_t) val;
+ break;
+ case MEM_QUADWORD:
+ *((volatile uint64_t *) addr) = (uint64_t) val;
+ break;
+ default:
+ return CFE_ERR_INV_PARAM;
+ }
+
+ exc_cleanup_block(jb);
+ }
+ else {
+ /*Exception handler*/
+
+ exc_cleanup_handler(jb, EXC_NORMAL_RETURN);
+ return CFE_ERR_SETMEM;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/cfe/cfe/arch/mips/common/src/init_mips.S b/cfe/cfe/arch/mips/common/src/init_mips.S
new file mode 100755
index 0000000..3f59539
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/init_mips.S
@@ -0,0 +1,683 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * CPU init module File: init_mips.S
+ *
+ * This module contains the vectors and lowest-level CPU startup
+ * functions for 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.
+ ********************************************************************* */
+
+
+#include "sbmips.h"
+#include "exception.h"
+
+#include "bsp_config.h"
+#include "cpu_config.h"
+
+#ifdef _CFE_
+#include "cfe_devfuncs.h"
+#else
+
+#define cfe_command_restart 0
+#endif
+
+/* BCM63XX specific change. */
+#include "bcm_hwdefs.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#include "mipsmacros.h"
+
+
+/* *********************************************************************
+ * SETLEDS(a,b,c,d)
+ * SETLEDS1(a,b,c,d)
+ *
+ * Sets the on-board LED display (if present). Two variants
+ * of this routine are provided. If you're running KSEG1,
+ * call the SETLEDS1 variant, else call SETLEDS.
+ *
+ * Input parameters:
+ * a,b,c,d - four ASCII characters (literal constants)
+ *
+ * Return value:
+ * a0,k1,ra trashed
+ ********************************************************************* */
+
+#define SETLEDS(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG0(init_table,R_INIT_SETLEDS)
+
+#define SETLEDS1(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG1(init_table,R_INIT_SETLEDS)
+
+
+/* *********************************************************************
+ * Other constants
+ ********************************************************************* */
+
+/*
+ * This is the size of the stack, rounded to KByte boundaries.
+ */
+
+#ifndef CFG_STACK_SIZE
+#error "CFG_STACK_SIZE not defined"
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+#ifdef __MIPSEB
+#define TEXTSECTION 0x2e746578 # ".tex", big-endian
+#else
+#define TEXTSECTION 0x7865742e # ".tex", little-endian
+#endif
+
+/*
+ * Duplicates from cfe_iocb.h -- warning!
+ */
+
+#define CFE_CACHE_FLUSH_D 1
+#define CFE_CACHE_INVAL_I 2
+#define CFE_CACHE_INVAL_D 4
+#define CFE_CACHE_INVAL_L2 8
+#define CFE_CACHE_FLUSH_L2 16
+#define CFE_CACHE_INVAL_RANGE 32
+#define CFE_CACHE_FLUSH_RANGE 64
+
+
+/*
+ * To make life easier reading this code, define "KSEGBASE"
+ * to either K0BASE or K1BASE depending on whether we're running
+ * uncached.
+ */
+
+#if CFG_RUNFROMKSEG0
+#define KSEGBASE K0BASE
+#else
+#define KSEGBASE K1BASE
+#endif
+
+
+/* *********************************************************************
+ * Names of registers used in this module
+ ********************************************************************* */
+
+#define RELOCOFFSET s8 /* $30 (fp) */
+#define TEXTOFFSET t9 /* $25 (t9) */
+#define MEMTOP t8 /* $24 (t8) */
+#define TEXTBASE s7 /* $23 (s7) */
+#undef BOOT_OFFSET
+#define BOOT_OFFSET s6 /* $22 (s6) */
+
+ .sdata
+
+#include "initdata.h" /* declare variables we use here */
+
+#if CFG_MULTI_CPUS
+ .globl cfe_spinlock
+cfe_spinlock: .word 0
+#endif
+
+ .extern _fdata
+ .extern _edata
+ .extern _etext
+
+/* *********************************************************************
+ * uninitialized data
+ ********************************************************************* */
+
+ .bss
+
+ .comm __junk,4
+
+/* *********************************************************************
+ * Exception Vectors
+ ********************************************************************* */
+
+ .text
+
+ .set noreorder
+
+/*
+ * Declare the actual vectors. This expands to code that
+ * must be at the very beginning of the text segment.
+ */
+
+DECLARE_VECTOR(0x0000,vec_reset,cpu_reset)
+
+ .set reorder
+
+/* *********************************************************************
+ * Some offsets depend on our current configuration
+ ********************************************************************* */
+
+#define RUNTIME_RELOC_START 0
+#define RUNTIME_RELOC_STOP 0
+
+/* *********************************************************************
+ * Segment Table.
+ *
+ * Addresses of data segments and of certain routines we're going
+ * to call from KSEG1. These are here mostly for the embedded
+ * PIC case, since we can't count on the 'la' instruction to
+ * do the expected thing (the assembler expands it into a macro
+ * for doing GP-relative stuff, and the code is NOT GP-relative.
+ * So, we (relocatably) get the offset of this table and then
+ * index within it.
+ *
+ * Pointer values in this segment will be relative to KSEG0 for
+ * cached versions of CFE, so we need to OR in K1BASE in the
+ * case of calling to a uncached address.
+ *
+ * The LOADREL macro handles most of the nastiness here.
+ ********************************************************************* */
+
+#include "segtable.h"
+#include "cfe.h"
+
+ .org 0x570
+ .byte 'c','f','e','-','v',CFE_VER_MAJOR,CFE_VER_MINOR,CFE_VER_BUILD,BCM63XX_MAJOR,BCM63XX_MINOR # CFE version info for applications
+ .org 0x580 # move past exception vectors
+
+ /*
+ * BCM963XX NVRAM Data Storage
+ */
+
+ .globl nvram_data_storage
+nvram_data_storage:
+ .word NVRAM_DATA_ID
+ .space 0x400
+
+ .globl segment_table
+segment_table:
+ _LONG_ _etext # [ 0] End of text (R_SEG_ETEXT)
+ _LONG_ _fdata # [ 1] Beginning of data (R_SEG_FDATA)
+ _LONG_ _edata # [ 2] End of data (R_SEG_EDATA)
+ _LONG_ _end # [ 3] End of BSS (R_SEG_END)
+ _LONG_ _ftext # [ 4] Beginning of text (R_SEG_FTEXT)
+ _LONG_ _fbss # [ 5] Beginning of BSS (R_SEG_FBSS)
+ _LONG_ _gp # [ 6] Global Pointer (R_SEG_GP)
+ _LONG_ 0 # [ 7] Beginning of reloc entries
+ _LONG_ 0 # [ 8] End of reloc entries
+ _LONG_ 0 # [ 9] R_SEG_APIENTRY
+
+/* *********************************************************************
+ * Init Table.
+ *
+ * This is like segment_table except it contains pointers to
+ * routines used during initialization. It serves both as a
+ * table for doing PIC stuff and also to separate out
+ * machine-specific init routines.
+ *
+ * The CALLINIT_xxx macros are used to call routines in this table.
+ ********************************************************************* */
+
+
+ .globl init_table
+init_table:
+ _LONG_ board_earlyinit # [ 0] R_INIT_EARLYINIT
+ _LONG_ board_setleds # [ 1] R_INIT_SETLEDS
+ _LONG_ board_draminfo # [ 2] R_INIT_DRAMINFO
+ _LONG_ CPUCFG_CPUINIT # [ 3] R_INIT_CPUINIT
+ _LONG_ CPUCFG_ALTCPU_START1 # [ 4] R_INIT_ALTCPU_START1
+ _LONG_ CPUCFG_ALTCPU_START2 # [ 5] R_INIT_ALTCPU_START2
+ _LONG_ CPUCFG_ALTCPU_RESET # [ 6] R_INIT_ALTCPU_RESET
+ _LONG_ CPUCFG_CPURESTART # [ 7] R_INIT_CPURESTART
+ _LONG_ CPUCFG_DRAMINIT # [ 8] R_INIT_DRAMINIT
+ _LONG_ CPUCFG_CACHEOPS # [ 9] R_INIT_CACHEOPS
+ _LONG_ CPUCFG_TLBHANDLER # [ 10] R_INIT_TLBHANDLER
+ _LONG_ cfe_main # [ 11] R_INIT_CMDSTART
+ _LONG_ cfe_command_restart # [ 12] R_INIT_CMDRESTART
+ _LONG_ cfe_doxreq # [ 13] R_INIT_DOXREQ
+ _LONG_ CPUCFG_TP1_SWITCH # [ 14] R_INIT_TP1_SWITCH
+ _LONG_ cfe_size_ram # [ 15] R_INIT_SIZERAM
+
+/* *********************************************************************
+ * CPU Startup Code
+ ********************************************************************* */
+
+cpu_reset:
+
+ /*
+ * Start with GP as zero. Nobody should touch
+ * this or set it to any other value until we're ready
+ * to use it. This is used to tell when we should start
+ * using relocated references in the init table,
+ * so beware! (see CALLINIT_RELOC in mipsmacros.h)
+ */
+
+ move gp,zero # start with no GP.
+
+ .set noreorder
+ bal 1f
+ nop
+1: nop
+ .set reorder
+ li BOOT_OFFSET, 0x1fff0000
+ and BOOT_OFFSET, ra
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Do low-level board initialization. This is our first
+ * chance to customize the startup sequence.
+ */
+ move a0, BOOT_OFFSET
+
+ CALLINIT_KSEG1(init_table,R_INIT_EARLYINIT)
+
+ SETLEDS1('H','E','L','O')
+
+ CALLINIT_KSEG1(init_table,R_INIT_CPUINIT)
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Now, switch from KSEG1 to KSEG0
+ */
+
+#if CFG_RUNFROMKSEG0
+ bal cpu_kseg0_switch
+#endif
+
+#------------------------------------------------------------------------------
+ /*
+ * Now running on cpu0 in K0SEG.
+ */
+
+#if CFG_CMT
+ /*
+ * 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.
+ */
+ CALLINIT_KSEG0(init_table,R_INIT_TP1_SWITCH)
+#endif
+
+#if CFG_INIT_DRAM
+ SETLEDS('D','R','A','M')
+
+ CALLINIT_KSEG0(init_table,R_INIT_DRAMINFO)
+
+ move a0,v0 # pass these params
+ CALLINIT_KSEG0(init_table,R_INIT_DRAMINIT)
+ CALLINIT_KSEG0(init_table,R_INIT_SIZERAM)
+ move k0,v0 # Save in k0 for now
+#else
+ li k0,(CFG_DRAM_SIZE * 1024)
+#endif
+
+#------------------------------------------------------------------------------
+
+#if CFG_BOOTRAM
+ b have_ram # No RAM is ok if using emulator RAM
+#endif
+
+ bne k0,zero,have_ram
+
+ SETLEDS('R','A','M','X') # die here if no ram
+
+die1: b die1
+
+have_ram:
+
+ /*
+ * If this is the 64-bit version, turn on the KX bit
+ * to allow 64-bit accesses.
+ */
+
+#ifdef __long64
+ mfc0 t0,C0_SR
+ or t0,t0,M_SR_KX
+ mtc0 t0,C0_SR
+#endif
+
+#------------------------------------------------------------------------------
+ /*
+ * K0 contains the RAM size (and therefore the top of RAM
+ * offset). Start there, and subtract the amount of memory
+ * we expect to use. If we have more than 256MB of
+ * physical memory, work backwards from the 256MB
+ * boundary.
+ */
+
+__CalcMemTop: li MEMTOP,256 # 256MB boundary
+ bgt k0,MEMTOP,1f # use 256MB if k0 is greater
+ move MEMTOP,k0 # otherwise keep top
+1: sll MEMTOP,20 # make into byte amount
+
+ li RELOCOFFSET,0 # not relocating, no offset
+ li TEXTOFFSET,0
+
+ /*
+ * DRAM is now running, and we're alive in cacheable memory
+ * on cpu0 in K0SEG. Set up GP.
+ */
+
+ LOADREL(a0,segment_table)
+ LR gp,R_SEG_GP(a0)
+ add gp,RELOCOFFSET
+
+#------------------------------------------------------------------------------
+ /*
+ * Zero BSS
+ */
+
+ SETLEDS('Z','B','S','S')
+
+ LOADREL(a0,segment_table)
+__ZeroBss:
+
+ LR v0,R_SEG_FBSS(a0)
+ LR v1,R_SEG_END(a0)
+ ADD v0,RELOCOFFSET # Relocate to actual data segment
+ ADD v1,RELOCOFFSET
+
+1: SR zero,0(v0) # Zero one cacheline at a time
+ SR zero,(REGSIZE*1)(v0)
+ SR zero,(REGSIZE*2)(v0)
+ SR zero,(REGSIZE*3)(v0)
+ add v0,REGSIZE*4
+ blt v0,v1,1b
+
+#------------------------------------------------------------------------------
+ /*
+ * Copy code
+ */
+
+ SETLEDS('C','O','D','E')
+
+ LOADREL(a0,segment_table)
+__CopyCode:
+
+ LR t1,R_SEG_FTEXT(a0) # destination address
+ move TEXTBASE,t1
+
+ LR t2,R_SEG_FTEXT(a0) # Source address
+ FIXUP (t2);
+ LR t3,R_SEG_ETEXT(a0)
+ FIXUP (t3);
+
+1: LR t4,0(t2) # read one cache line
+ LR t5,(REGSIZE*1)(t2)
+ LR t6,(REGSIZE*2)(t2)
+ LR t7,(REGSIZE*3)(t2)
+ SR t4,0(t1) # write one cache line
+ SR t5,(REGSIZE*1)(t1)
+ SR t6,(REGSIZE*2)(t1)
+ SR t7,(REGSIZE*3)(t1)
+ add t1,REGSIZE*4
+ add t2,REGSIZE*4
+ bltu t2,t3,1b
+
+#------------------------------------------------------------------------------
+ /*
+ * Copy initialized data
+ */
+
+#if (CFG_BOOTRAM == 0)
+
+ SETLEDS('D','A','T','A')
+
+ LOADREL(a0,segment_table)
+
+__CopyData:
+ LR t1,R_SEG_FDATA(a0)
+ FIXUP (t1);
+ li t0,15
+ add t1,t0
+ not t0
+ and t1,t0 # t1 = _etext rounded up to 16-byte boundary
+
+ LR t2,R_SEG_FDATA(a0)
+ LR t3,R_SEG_EDATA(a0)
+ ADD t2,RELOCOFFSET # Relocate to actual data segment
+ ADD t3,RELOCOFFSET
+
+1: LR t4,0(t1) # read one cache line
+ LR t5,(REGSIZE*1)(t1)
+ LR t6,(REGSIZE*2)(t1)
+ LR t7,(REGSIZE*3)(t1)
+ SR t4,0(t2) # write one cache line
+ SR t5,(REGSIZE*1)(t2)
+ SR t6,(REGSIZE*2)(t2)
+ SR t7,(REGSIZE*3)(t2)
+ add t1,(REGSIZE*4)
+ add t2,(REGSIZE*4)
+ bltu t2,t3,1b
+
+#endif
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Flush the cache, then switch to relocated code
+ * We need to flush the cache since we just moved the code and
+ * it may still live in our L1 DCache. We also need to
+ * flush L2, since there are some rare times we run
+ * uncached from DRAM, like when we start/stop a CPU.
+ *
+ * In the case of running completely uncached, don't flush the
+ * cache. It should not have any dirty lines in it, but you
+ * never know...
+ */
+
+__GoRelo:
+
+#if CFG_RUNFROMKSEG0
+ SETLEDS('L','1','2','F')
+
+ li a0,CFE_CACHE_FLUSH_D | CFE_CACHE_FLUSH_L2
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+ li a0,CFE_CACHE_INVAL_I
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+#endif /* CFG_RUNFROMKSEG0 */
+
+ la t0,gorelo # Now jump to an address code was compiled for
+ j t0 # and go there
+gorelo: nop
+ li BOOT_OFFSET, 0 # no longer running at offset
+
+ /*
+ * Remember total amount of memory. This is *still* in k0
+ * after all this time. Hopefully.
+ */
+
+__MemVars:
+ SR k0,mem_totalsize
+ SR RELOCOFFSET,mem_datareloc
+
+ move v0,zero
+
+ LOADREL(a0,segment_table) # trashed by l2 cache flush
+ LR v0,R_SEG_FDATA(a0)
+ ADD v0,RELOCOFFSET
+ LR v1,R_SEG_END(a0)
+ ADD v1,RELOCOFFSET
+
+ SR v0,mem_bottomofmem
+ SR v1,mem_heapstart
+
+ add v1,(CFG_HEAP_SIZE*1024) # Otherwise
+ add v1,STACK_SIZE
+ SR v1,mem_topofmem
+
+ SR TEXTOFFSET,mem_textreloc
+
+ /* At this point it's safe to use the CALLINIT_RELOC macro */
+
+ LR t1,R_SEG_FTEXT(a0)
+ FIXUP (t1);
+ LR t0,R_SEG_ETEXT(a0)
+ FIXUP (t0);
+ sub t0,t0,t1
+ SR t0,mem_textsize
+ add t1,TEXTOFFSET
+ SR t1,mem_textbase
+
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Stash away some config register stuff
+ */
+
+ mfc0 v0,C0_PRID
+ SR v0,cpu_prid
+
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Set up the "C" stack and jump to the main routine.
+ */
+
+ SETLEDS('M','A','I','N')
+
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+ li a0,0 # call as "cfe_main(0,0)"
+ li a1,0
+
+ CALLINIT_RELOC(init_table,R_INIT_CMDSTART) # should not return
+
+/* *********************************************************************
+ * CFE_LAUNCH
+ *
+ * Start the user program. The program is passed a handle
+ * that must be passed back when calling the firmware.
+ *
+ * Parameters passed to the called program are as follows:
+ *
+ * a0 - CFE handle
+ * a1 - entry vector
+ * a2 - reserved, will be 0
+ * a3 - entrypoint signature.
+ *
+ * Input parameters:
+ * a0 - entry vector
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+LEAF(cfe_launch)
+
+ sub sp,8
+ SR a0,0(sp)
+
+ /*
+ * This function runs in RAM so BOOT_OFFSET is 0. It is called from
+ * C which could have modified the BOOT_OFFSET register, s6.
+ */
+ li BOOT_OFFSET, 0
+
+
+ /*
+ * Mask all interrupts.
+ */
+ mfc0 v0,C0_SR # Get current interrupt flag
+ li v1,M_SR_IE # master interrupt control
+ not v1 # disable interrupts
+ and v0,v1 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+
+ /*
+ * Flush the D-Cache, since the program we loaded is "data".
+ * Invalidate the I-Cache, so that addresses in the program
+ * region will miss and need to be filled from the data we
+ * just flushed above.
+ */
+
+ li a0,CFE_CACHE_FLUSH_D|CFE_CACHE_INVAL_I
+ CALLINIT_RELOC(init_table,R_INIT_CACHEOPS)
+
+
+ /*
+ * Set things up for launching the program. Pass the
+ * handle in A0 - apps need to remember that and pass it
+ * back.
+ */
+
+ j RunProgram
+
+END(cfe_launch)
+
+ /*
+ * This is a nice place to set a breakpoint.
+ */
+LEAF(RunProgram)
+ LR t0,0(sp) # entry point
+
+ j t0 # go for it.
+END(RunProgram)
+
+/* *********************************************************************
+ * CPU_KSEG0_SWITCH
+ *
+ * Hack the return address so we will come back in KSEG0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cpu_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(cpu_kseg0_switch)
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/init_ram.S b/cfe/cfe/arch/mips/common/src/init_ram.S
new file mode 100755
index 0000000..2531700
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/init_ram.S
@@ -0,0 +1,889 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * CPU init module File: init_ram.S
+ *
+ * This module contains the vectors and lowest-level CPU startup
+ * functions for CFE.
+ *
+ * This is very similar to "init_mips.S" but is used when
+ * you want to locate CFE in DRAM, loading it like an
+ * application program.
+ *
+ * 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 "sbmips.h"
+#include "exception.h"
+
+#include "bsp_config.h"
+#include "cpu_config.h"
+
+#include "cfe_devfuncs.h"
+
+/* *********************************************************************
+ * Check some stuff
+ ********************************************************************* */
+
+#if CFG_RELOC
+#error "RAM version is not compatible with relocation."
+#endif
+#if !(CFG_RUNFROMKSEG0)
+#error "RAM version should be run cached"
+#endif
+
+#if CFG_MULTI_CPUS
+#error "Multiple CPUs not compatible with RAM version"
+#endif
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#include "mipsmacros.h"
+
+
+/* *********************************************************************
+ * SETLEDS(a,b,c,d)
+ *
+ * Sets the on-board LED display (if present).
+ *
+ * Input parameters:
+ * a,b,c,d - four ASCII characters (literal constants)
+ *
+ * Return value:
+ * a0,k1,ra trashed
+ ********************************************************************* */
+
+
+#define SETLEDS(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ jal board_setleds ;
+
+
+/* *********************************************************************
+ * Other constants
+ ********************************************************************* */
+
+/*
+ * This is the size of the stack, rounded to KByte boundaries.
+ */
+
+#ifndef CFG_STACK_SIZE
+#error "CFG_STACK_SIZE not defined"
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+/*
+ * Duplicates from cfe_iocb.h -- warning!
+ */
+
+#define CFE_CACHE_FLUSH_D 1
+#define CFE_CACHE_INVAL_I 2
+#define CFE_CACHE_INVAL_D 4
+#define CFE_CACHE_INVAL_L2 8
+#define CFE_CACHE_FLUSH_L2 16
+#define CFE_CACHE_INVAL_RANGE 32
+#define CFE_CACHE_FLUSH_RANGE 64
+
+
+/*
+ * To make life easier reading this code, define "KSEGBASE"
+ * to either K0BASE or K1BASE depending on whether we're running
+ * uncached.
+ */
+
+#define KSEGBASE K0BASE /* RAM version always cached */
+
+
+/* *********************************************************************
+ * Names of registers used in this module
+ ********************************************************************* */
+
+ .sdata
+
+#include "initdata.h" /* declare variables we use here */
+
+#if CFG_MULTI_CPUS
+ .globl cfe_spinlock
+cfe_spinlock: .word 0
+#endif
+
+ .extern _fdata
+ .extern _edata
+ .extern _etext
+
+/* *********************************************************************
+ * uninitialized data
+ ********************************************************************* */
+
+ .bss
+
+ .comm __junk,4
+
+ .text
+
+ .set noreorder
+
+
+/* *********************************************************************
+ * CFE Entry Point (used by OS boot loaders and such)
+ ********************************************************************* */
+
+ .set noreorder
+
+ .globl vec_reset
+
+vec_reset: b cpu_reset
+ nop
+
+
+vec_apientry: b cpu_apientry
+ nop
+ .word CFE_EPTSEAL
+ .word CFE_EPTSEAL
+
+ .set reorder
+
+
+/* *********************************************************************
+ * Segment Table.
+ *
+ * Addresses of data segments and of certain routines we're going
+ * to call from KSEG1. These are here mostly for the embedded
+ * PIC case, since we can't count on the 'la' instruction to
+ * do the expected thing (the assembler expands it into a macro
+ * for doing GP-relative stuff, and the code is NOT GP-relative.
+ * So, we (relocatably) get the offset of this table and then
+ * index within it.
+ *
+ * Pointer values in this segment will be relative to KSEG0 for
+ * cached versions of CFE, so we need to OR in K1BASE in the
+ * case of calling to a uncached address.
+ *
+ * The LOADREL macro handles most of the nastiness here.
+ ********************************************************************* */
+
+
+#include "segtable.h"
+
+ .globl segment_table
+segment_table:
+ _LONG_ _etext # [ 0] End of text (R_SEG_ETEXT)
+ _LONG_ _fdata # [ 1] Beginning of data (R_SEG_FDATA)
+ _LONG_ _edata # [ 2] End of data (R_SEG_EDATA)
+ _LONG_ _end # [ 3] End of BSS (R_SEG_END)
+ _LONG_ _ftext # [ 4] Beginning of text (R_SEG_FTEXT)
+ _LONG_ _fbss # [ 5] Beginning of BSS (R_SEG_FBSS)
+ _LONG_ _gp # [ 6] Global Pointer (R_SEG_GP)
+ _LONG_ 0 # [ 7] Beginning of reloc entries
+ _LONG_ 0 # [ 8] End of reloc entries
+ _LONG_ cpu_apientry # [ 9] R_SEG_APIENTRY
+
+
+/* *********************************************************************
+ * Init Table.
+ *
+ * This is like segment_table except it contains pointers to
+ * routines used during initialization. It serves both as a
+ * table for doing PIC stuff and also to separate out
+ * machine-specific init routines.
+ *
+ * The CALLINIT_xxx macros are used to call routines in this table.
+ ********************************************************************* */
+
+
+ .globl init_table
+init_table:
+ _LONG_ board_earlyinit # [ 0] R_INIT_EARLYINIT
+ _LONG_ board_setleds # [ 1] R_INIT_SETLEDS
+ _LONG_ board_draminfo # [ 2] R_INIT_DRAMINFO
+ _LONG_ CPUCFG_CPUINIT # [ 3] R_INIT_CPUINIT
+ _LONG_ CPUCFG_ALTCPU_START1 # [ 4] R_INIT_ALTCPU_START1
+ _LONG_ CPUCFG_ALTCPU_START2 # [ 5] R_INIT_ALTCPU_START2
+ _LONG_ CPUCFG_ALTCPU_RESET # [ 6] R_INIT_ALTCPU_RESET
+ _LONG_ CPUCFG_CPURESTART # [ 7] R_INIT_CPURESTART
+ _LONG_ CPUCFG_DRAMINIT # [ 8] R_INIT_DRAMINIT
+ _LONG_ CPUCFG_CACHEOPS # [ 9] R_INIT_CACHEOPS
+ _LONG_ CPUCFG_TLBHANDLER # [ 10] R_INIT_TLBHANDLER
+ _LONG_ cfe_main # [ 11] R_INIT_CMDSTART
+ _LONG_ cfe_command_restart # [ 12] R_INIT_CMDRESTART
+ _LONG_ cfe_doxreq # [ 13] R_INIT_DOXREQ
+ _LONG_ CPUCFG_TP1_SWITCH # [ 14] R_INIT_TP1_SWITCH
+ _LONG_ bcmcore_null # [ 15] R_INIT_SIZERAM
+
+/* *********************************************************************
+ * CPU Startup Code
+ ********************************************************************* */
+
+
+cpu_reset:
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Do low-level board initialization. This is our first
+ * chance to customize the startup sequence.
+ */
+
+ CALLINIT_KSEG0(init_table,R_INIT_EARLYINIT)
+
+ SETLEDS('H','E','L','O')
+
+#------------------------------------------------------------------------------
+
+ /*
+ * DRAM is now running, and we're alive in cacheable memory
+ * on cpu0 in K0SEG. Set up GP.
+ */
+
+ LOADREL(a0,segment_table)
+ LR gp,R_SEG_GP(a0)
+
+#------------------------------------------------------------------------------
+ /*
+ * Zero BSS
+ */
+
+ SETLEDS('Z','B','S','S')
+
+ LOADREL(a0,segment_table)
+__ZeroBss:
+
+ LR v0,R_SEG_FBSS(a0)
+ LR v1,R_SEG_END(a0)
+
+1: SR zero,0(v0) # Zero one cacheline at a time
+ SR zero,(REGSIZE*1)(v0)
+ SR zero,(REGSIZE*2)(v0)
+ SR zero,(REGSIZE*3)(v0)
+ add v0,REGSIZE*4
+ blt v0,v1,1b
+
+
+#------------------------------------------------------------------------------
+
+ li k0,256 # memory size in megabytes
+
+
+#ifdef __long64
+ mfc0 t0,C0_SR
+ or t0,t0,M_SR_KX
+ mtc0 t0,C0_SR
+#endif
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Remember total amount of memory. This is *still* in k0
+ * after all this time. Hopefully.
+ */
+
+__MemVars:
+ SR k0,mem_totalsize
+ SR zero,mem_datareloc
+
+ move v0,zero
+
+ LOADREL(a0,segment_table) # trashed by l2 cache flush
+ LR v0,R_SEG_FTEXT(a0) # bottom = beginning of text
+ LR v1,R_SEG_END(a0)
+
+ SR v0,mem_bottomofmem
+ SR v1,mem_heapstart
+
+ add v1,(CFG_HEAP_SIZE*1024) # Otherwise
+ add v1,STACK_SIZE
+ SR v1,mem_topofmem
+
+ SR zero,mem_textreloc
+
+
+ LR t1,R_SEG_FTEXT(a0)
+ LR t0,R_SEG_ETEXT(a0)
+ sub t0,t0,t1
+ SR t0,mem_textsize
+ SR t1,mem_textbase
+
+
+#------------------------------------------------------------------------------
+
+#if CFG_MULTI_CPUS
+ /*
+ * Let secondary CPU(s) run their idle loops. Set the
+ * mailbox register to our relocation factor so we can read
+ * it out of the mailbox register and relocate GP properly.
+ */
+
+ move a0,zero
+ CALLINIT_KSEG0(init_table,R_INIT_ALTCPU_START2)
+#endif
+
+ /*
+ * Stash away some config register stuff
+ */
+
+ mfc0 v0,C0_PRID
+ SR v0,cpu_prid
+
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Set up the "C" stack and jump to the main routine.
+ */
+
+ SETLEDS('M','A','I','N')
+
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+ li a0,0 # call as "cfe_main(0,0)"
+ li a1,0
+
+ CALLINIT_KSEG0(init_table,R_INIT_CMDSTART) # should not return
+
+
+ /*
+ * Terminate the simulator.
+ */
+
+crash_sim: li $2,1
+ li $4,0
+ syscall 0xCA
+ b cpu_reset
+
+
+
+/* *********************************************************************
+ * CFE_WARMSTART
+ *
+ * Restart the command interpreter
+ *
+ * Input parameters:
+ * A0 - command status
+ * nothing (GP has already been set up for us)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cfe_warmstart)
+
+ SR a0,0(sp) # store on old stack
+ LOADREL(v0,init_table)
+ LR v0,R_INIT_CPURESTART(v0)
+ jal v0 # had better not trash GP or K1
+ LR a0,0(sp)
+
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+
+ /*
+ * If someone called the API to do a warm start, clear the
+ * spin lock, since the call will never return.
+ */
+
+#if CFG_MULTI_CPUS
+ SPIN_UNLOCK(cfe_spinlock,t0)
+#endif
+
+ CALLINIT_KSEG0(init_table,R_INIT_CMDRESTART) # should not return
+
+END(cfe_warmstart)
+
+/* *********************************************************************
+ * CFE_FLUSHCACHE
+ *
+ * Perform certain cache operations
+ *
+ * Input parameters:
+ * a0 - flags (CFE_CACHE_xxx flags, or zero for a default)
+ * a1,a2 - start/end of range for "range invalidate" operations
+ * (not used otherwise)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_cfe_flushcache)
+
+ sub sp,32
+ SR ra,0(sp)
+ SR a0,8(sp)
+ SR s0,16(sp)
+ SR v1,24(sp)
+
+
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+
+ LR v1,24(sp)
+ LR s0,16(sp)
+ LR a0,8(sp)
+ LR ra,0(sp)
+ add sp,32
+ j ra
+
+END(_cfe_flushcache)
+
+
+/* *********************************************************************
+ * CFE_LAUNCH
+ *
+ * Start the user program. The program is passed a handle
+ * that must be passed back when calling the firmware.
+ *
+ * Parameters passed to the called program are as follows:
+ *
+ * a0 - CFE handle
+ * a1 - entry vector
+ * a2 - reserved, will be 0
+ * a3 - entrypoint signature.
+ *
+ * Input parameters:
+ * a0 - entry vector
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+LEAF(cfe_launch)
+
+ sub sp,8
+ SR a0,0(sp)
+
+ /*
+ * Mask all interrupts.
+ */
+ mfc0 v0,C0_SR # Get current interrupt flag
+ li v1,M_SR_IE # master interrupt control
+ not v1 # disable interrupts
+ and v0,v1 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+ /*
+ * Flush the D-Cache, since the program we loaded is "data".
+ * Invalidate the I-Cache, so that addresses in the program
+ * region will miss and need to be filled from the data we
+ * just flushed above.
+ */
+
+ li a0,CFE_CACHE_FLUSH_D|CFE_CACHE_INVAL_I
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+
+ /*
+ * Set things up for launching the program. Pass the
+ * handle in A0 - apps need to remember that and pass it
+ * back.
+ */
+
+ j RunProgram
+
+END(cfe_launch)
+
+ /*
+ * This is a nice place to set a breakpoint.
+ */
+LEAF(RunProgram)
+
+ LOADREL(a2,segment_table)
+ LR a2,R_SEG_APIENTRY(a2) # A2 = code entry
+ move t0,a0 #
+ move a1,zero # A1 = 0
+ move a0,gp # A0 = handle
+ li a3,CFE_EPTSEAL # A3 = entrypoint signature
+ LR t0,0(sp) # entry point
+ j t0 # go for it.
+END(RunProgram)
+
+
+
+
+/* *********************************************************************
+ * CFE_LEDS
+ *
+ * Set the on-board LEDs.
+ *
+ * Input parameters:
+ * a0 - LEDs
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cfe_leds)
+
+ j board_setleds # jump to BSP routine
+
+END(cfe_leds)
+
+/* *********************************************************************
+ * TLB Fill Exeption Handler
+ ********************************************************************* */
+
+cpu_tlbfill:
+ move k0,ra # Save, we're about to trash
+ LOADREL(k1,init_table) # Load offset of init table
+ LR k1,R_INIT_TLBHANDLER(k1) # Get entry from table
+ move ra,k0 # restore trashed ra
+ j k1 # Dispatch to handler
+
+/* *********************************************************************
+ * XTLB Fill Exception Handler
+ ********************************************************************* */
+
+cpu_xtlbfill:
+ j _exc_entry
+
+/* *********************************************************************
+ * Cache Error Exception Handler
+ ********************************************************************* */
+
+cpu_cacheerr:
+ j _exc_entry
+
+
+/* *********************************************************************
+ * General Exception Handler
+ ********************************************************************* */
+
+cpu_exception:
+ j _exc_entry
+
+
+/* *********************************************************************
+ * General Interrupt Handler
+ ********************************************************************* */
+
+cpu_interrupt:
+ j _exc_entry
+
+
+/* *********************************************************************
+ * EJTAG Debug Exception Handler
+ ********************************************************************* */
+
+cpu_ejtag:
+ j cpu_reset
+
+/* *********************************************************************
+ * cpu_apientry(handle,iocb)
+ *
+ * API entry point for external apps.
+ *
+ * Input parameters:
+ * a0 - firmware handle (used to determine the location of
+ * our relocated data)
+ * a1 - pointer to IOCB to execute
+ *
+ * Return value:
+ * v0 - return code, 0 if ok
+ ********************************************************************* */
+
+#define _regidx(x) ((x)*8)
+
+#define CAE_SRSAVE _regidx(0)
+#define CAE_GPSAVE _regidx(1)
+#define CAE_RASAVE _regidx(2)
+#define CAE_S0SAVE _regidx(3)
+#define CAE_S1SAVE _regidx(4)
+#define CAE_S2SAVE _regidx(5)
+#define CAE_S3SAVE _regidx(6)
+#define CAE_S4SAVE _regidx(7)
+#define CAE_S5SAVE _regidx(8)
+#define CAE_S6SAVE _regidx(9)
+#define CAE_S7SAVE _regidx(10)
+
+#define CAE_STKSIZE _regidx(11)
+
+LEAF(cpu_apientry)
+
+ sub sp,CAE_STKSIZE # Make room for our stuff
+
+ mfc0 v0,C0_SR # Get current interrupt flag
+ SR v0,CAE_SRSAVE(sp) # save on stack
+ li t0,M_SR_IE # master interrupt control
+ not t0 # disable interrupts
+ and v0,t0 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+ SR gp,CAE_GPSAVE(sp) # save GP
+ SR ra,CAE_RASAVE(sp) # and old RA
+
+ SR s0,CAE_S0SAVE(sp)
+ SR s1,CAE_S1SAVE(sp)
+ SR s2,CAE_S2SAVE(sp)
+ SR s3,CAE_S3SAVE(sp)
+ SR s4,CAE_S4SAVE(sp)
+ SR s5,CAE_S5SAVE(sp)
+ SR s6,CAE_S6SAVE(sp)
+ SR s7,CAE_S7SAVE(sp)
+
+ move gp,a0 # set up new GP
+ move a0,a1 # A0 points at IOCB
+
+
+#if CFG_MULTI_CPUS
+ SPIN_LOCK(cfe_spinlock,t0,t1)
+#endif
+
+ CALLINIT_KSEG0(init_table,R_INIT_DOXREQ) # should not return
+
+#if CFG_MULTI_CPUS
+ SPIN_UNLOCK(cfe_spinlock,t0)
+#endif
+
+ #
+ # Restore the saved registers.
+ #
+
+ LR s7,CAE_S7SAVE(sp)
+ LR s6,CAE_S6SAVE(sp)
+ LR s5,CAE_S5SAVE(sp)
+ LR s4,CAE_S4SAVE(sp)
+ LR s3,CAE_S3SAVE(sp)
+ LR s2,CAE_S2SAVE(sp)
+ LR s1,CAE_S1SAVE(sp)
+ LR s0,CAE_S0SAVE(sp)
+
+ LR ra,CAE_RASAVE(sp) # unwind the stack
+ LR gp,CAE_GPSAVE(sp)
+
+ LR t0,CAE_SRSAVE(sp) # old interrupt mask
+
+ add sp,CAE_STKSIZE # restore old stack pointer
+
+ mtc0 t0,C0_SR # restore interrupts
+ j ra
+ nop
+
+END(cpu_apientry)
+
+
+/* *********************************************************************
+ * CPU_KSEG0_SWITCH
+ *
+ * Hack the return address so we will come back in KSEG0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cpu_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(cpu_kseg0_switch)
+
+
+
+
+/* *********************************************************************
+ * _GETSTATUS()
+ *
+ * Read the STATUS register into v0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - Status register
+ ********************************************************************* */
+
+LEAF(_getstatus)
+
+ mfc0 v0,C0_SR
+ j ra
+END(_getstatus)
+
+
+/* *********************************************************************
+ * _SETSTATUS()
+ *
+ * Set the STATUS register to the value in a0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - Status register
+ ********************************************************************* */
+
+LEAF(_setstatus)
+
+ mtc0 a0,C0_SR
+ j ra
+END(_setstatus)
+
+/* *********************************************************************
+ * _GETCAUSE()
+ *
+ * Read the CAUSE register into v0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - Cause register
+ ********************************************************************* */
+
+LEAF(_getcause)
+
+ mfc0 v0,C0_CAUSE
+ j ra
+END(_getcause)
+
+
+/* *********************************************************************
+ * _GETTICKS()
+ *
+ * Read the COUNT register into v0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - count register
+ ********************************************************************* */
+
+LEAF(_getticks)
+
+ mfc0 v0,C0_COUNT
+ j ra
+END(_getticks)
+
+
+/* *********************************************************************
+ * _SETALARM(ticks)
+ *
+ * Set the C0_Compare register from a0
+ *
+ * Input parameters:
+ * a0 - compare register
+ *
+ * Return value:
+ * none
+ ********************************************************************* */
+
+LEAF(_setalarm)
+
+ mtc0 a0,C0_COMPARE
+ j ra
+END(_setalarm)
+
+
+/* *********************************************************************
+ * _SETCONTEXT()
+ *
+ * Set the CONTEXT register.
+ *
+ * Input parameters:
+ * a0 - context
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_setcontext)
+
+ mtc0 a0,C0_CTEXT
+ j ra
+END(_setcontext)
+
+/* *********************************************************************
+ * _GETSEGTBL()
+ *
+ * Return the address of the segment table. We use this
+ * to display the startup messages.
+ *
+ * You can't just address the table from C because it lives
+ * in the text segment.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * address of table
+ ********************************************************************* */
+
+
+LEAF(_getsegtbl)
+ move t0,ra
+ LOADREL(v0,segment_table)
+ move ra,t0
+ j ra
+END(_getsegtbl)
+
+
+/* *********************************************************************
+ * _wbflush()
+ *
+ * Flush the write buffer. This is probably not necessary
+ * on SiByte CPUs, but we have it for completeness.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_wbflush)
+
+ sync /* drain the buffers */
+ la t0,__junk /* do an uncached read to force it out */
+ or t0,K1BASE
+ lw zero,0(t0)
+ j ra
+
+END(_wbflush)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/lib_hssubr.S b/cfe/cfe/arch/mips/common/src/lib_hssubr.S
new file mode 100644
index 0000000..07085e3
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/lib_hssubr.S
@@ -0,0 +1,194 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Hyperspace Subroutines File: lib_hssubr.S
+ *
+ * Little stub routines to allow access to KXSEG from 32-bit progs.
+ *
+ * Author: Mitch Lichtenberg (mitch@sibyte.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 "sbmips.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD */
+
+
+/* *********************************************************************
+ * hs_read8 - read 8-bit bytes
+ ********************************************************************* */
+
+
+LEAF(hs_read8)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ lbu v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read8)
+
+/* *********************************************************************
+ * hs_read16 - read 16-bit shorts
+ ********************************************************************* */
+
+LEAF(hs_read16)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ lhu v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read16)
+
+/* *********************************************************************
+ * hs_read32 - read 32-bit ints
+ ********************************************************************* */
+
+LEAF(hs_read32)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ lw v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read32)
+
+/* *********************************************************************
+ * hs_read64 - read 64-bit longs
+ ********************************************************************* */
+
+LEAF(hs_read64)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ ld v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read64)
+
+/* *********************************************************************
+ * hs_write8 - write 8-bit bytes
+ ********************************************************************* */
+
+LEAF(hs_write8)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sb a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write8)
+
+/* *********************************************************************
+ * hs_write16 - write 16-bit shorts
+ ********************************************************************* */
+
+LEAF(hs_write16)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sh a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write16)
+
+/* *********************************************************************
+ * hs_write32 - write 32-bit longs
+ ********************************************************************* */
+
+LEAF(hs_write32)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sw a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write32)
+
+/* *********************************************************************
+ * hs_write64 - write 64-bit longs
+ ********************************************************************* */
+
+LEAF(hs_write64)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sd a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write64)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
diff --git a/cfe/cfe/arch/mips/common/src/lib_physio.S b/cfe/cfe/arch/mips/common/src/lib_physio.S
new file mode 100644
index 0000000..7f57fea
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/lib_physio.S
@@ -0,0 +1,173 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical memory peek/poke routines File: lib_physio.S
+ *
+ * Little stub routines to allow access to arbitrary physical
+ * addresses. In most cases this should not be needed, as
+ * many physical addresses are within kseg1, but this handles
+ * the cases that are not automagically, so we don't need
+ * to mess up the code with icky macros and such.
+ *
+ * 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 "sbmips.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD */
+
+
+/* *********************************************************************
+ * PHYSOP(inst,a)
+ *
+ * Macro to construct code for doing the physical I/O
+ * We try to avoid messing with KX or doing 64-bit stuff
+ * unless necessary.
+ *
+ * Input parameters:
+ * INST - instruction name to run
+ * A - register containing arg or return value
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+
+#ifdef _MIPSREGS32_
+#define PHYSOP(INST,A) \
+ or a0,a0,K1BASE ; \
+ INST A,0(a0) ; \
+ j ra ;
+#else
+#define PHYSOP(INST,A) \
+ lui t0,0x2000 ; \
+ bgeu a0,t0,1f ; \
+ or a0,a0,K1BASE ; \
+ INST A,0(a0) ; \
+ j ra ; \
+1: lui t0,0x9000 ; \
+ dsll t0,t0,32 ; \
+ or a0,a0,t0 ; \
+ mfc0 t1,C0_SR ; \
+ and t0,t1,M_SR_KX ; \
+ beq t0,zero,1f ; \
+ INST A,0(a0) ; \
+ j ra ; \
+1: or t0,t1,M_SR_KX ; \
+ mtc0 t0,C0_SR ; \
+ HAZARD ; \
+ INST A,0(a0) ; \
+ mtc0 t1,C0_SR ; \
+ HAZARD ; \
+ j ra ;
+#endif
+
+
+/* *********************************************************************
+ * phys_read8 - read 8-bit bytes
+ ********************************************************************* */
+
+
+LEAF(phys_read8)
+PHYSOP(lbu,v0)
+END(phys_read8)
+
+/* *********************************************************************
+ * phys_read16 - read 16-bit shorts
+ ********************************************************************* */
+
+LEAF(phys_read16)
+PHYSOP(lh,v0)
+END(phys_read16)
+
+/* *********************************************************************
+ * phys_read32 - read 32-bit ints
+ ********************************************************************* */
+
+LEAF(phys_read32)
+PHYSOP(lw,v0)
+END(phys_read32)
+
+/* *********************************************************************
+ * phys_read64 - read 64-bit longs
+ ********************************************************************* */
+
+LEAF(phys_read64)
+PHYSOP(ld,v0)
+END(phys_read64)
+
+/* *********************************************************************
+ * phys_write8 - write 8-bit bytes
+ ********************************************************************* */
+
+LEAF(phys_write8)
+PHYSOP(sb,a1)
+END(phys_write8)
+
+/* *********************************************************************
+ * phys_write16 - write 16-bit shorts
+ ********************************************************************* */
+
+LEAF(phys_write16)
+PHYSOP(sh,a1)
+END(phys_write16)
+
+/* *********************************************************************
+ * phys_write32 - write 32-bit longs
+ ********************************************************************* */
+
+LEAF(phys_write32)
+PHYSOP(sw,a1)
+END(phys_write32)
+
+/* *********************************************************************
+ * phys_write64 - write 64-bit longs
+ ********************************************************************* */
+
+LEAF(phys_write64)
+PHYSOP(sd,a1)
+END(phys_write64)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
diff --git a/cfe/cfe/arch/mips/common/src/lib_setjmp.S b/cfe/cfe/arch/mips/common/src/lib_setjmp.S
new file mode 100644
index 0000000..b8c82b3
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/lib_setjmp.S
@@ -0,0 +1,94 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Simple setjmp/longjmp File: lib_setjmp.S
+ *
+ * A very simple SETJMP and LONGJMP
+ *
+ * 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 "sbmips.h"
+#include "lib_setjmp.h"
+
+#ifdef _MIPSREGS32_
+#define SREG sw
+#define LREG lw
+#else
+#define SREG sd
+#define LREG ld
+#endif
+
+LEAF(lib_setjmp)
+
+ SREG s0,JMPB_S0(a0)
+ SREG s1,JMPB_S1(a0)
+ SREG s2,JMPB_S2(a0)
+ SREG s3,JMPB_S3(a0)
+ SREG s4,JMPB_S4(a0)
+ SREG s5,JMPB_S5(a0)
+ SREG s6,JMPB_S6(a0)
+ SREG s7,JMPB_S7(a0)
+ SREG fp,JMPB_FP(a0)
+ SREG sp,JMPB_SP(a0)
+ SREG ra,JMPB_RA(a0)
+ move v0,zero
+ j ra
+
+END(lib_setjmp)
+
+LEAF(lib_longjmp)
+ LREG s0,JMPB_S0(a0)
+ LREG s1,JMPB_S1(a0)
+ LREG s2,JMPB_S2(a0)
+ LREG s3,JMPB_S3(a0)
+ LREG s4,JMPB_S4(a0)
+ LREG s5,JMPB_S5(a0)
+ LREG s6,JMPB_S6(a0)
+ LREG s7,JMPB_S7(a0)
+ LREG fp,JMPB_FP(a0)
+ LREG sp,JMPB_SP(a0)
+ LREG ra,JMPB_RA(a0)
+ move v0,a1
+ jr ra
+END(lib_longjmp)
+
diff --git a/cfe/cfe/arch/mips/common/src/mips_arena.c b/cfe/cfe/arch/mips/common/src/mips_arena.c
new file mode 100644
index 0000000..d96fee6
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/mips_arena.c
@@ -0,0 +1,186 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical Memory (arena) manager File: sb1250_arena.c
+ *
+ * This module describes the physical memory available to the
+ * firmware.
+ *
+ * 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 "lib_arena.h"
+
+#include "cfe_error.h"
+
+#include "cfe.h"
+#include "cfe_mem.h"
+
+#include "initdata.h"
+
+#define _NOPROTOS_
+#include "cfe_boot.h"
+#undef _NOPROTOS_
+
+#include "cpu_config.h"
+
+#include "addrspace.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+
+#define MEG (1024*1024)
+#define KB 1024
+#define PAGESIZE 4096
+#define CFE_BOOTAREA_SIZE (256*KB)
+#define CFE_BOOTAREA_ADDR 0x20000000
+
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+extern arena_t cfe_arena;
+uint64_t *cfe_pagetable = NULL;
+
+extern void CPUCFG_PAGETBLINIT(uint64_t *ptaddr,unsigned int ptstart);
+
+void cfe_bootarea_init(void);
+extern void _setcontext(int64_t);
+
+
+/* *********************************************************************
+ * CFE_BOOTAREA_INIT()
+ *
+ * Initialize the page table and map our boot program area.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void cfe_bootarea_init(void)
+{
+ unsigned char *pte;
+ int64_t pte_int;
+ unsigned int addr = 16*MEG;
+ unsigned int topmem;
+ unsigned int topcfe;
+ unsigned int botcfe;
+ unsigned int beforecfe;
+ unsigned int aftercfe;
+
+ /*
+ * Calculate the location where the boot area will
+ * live. It lives either above or below the
+ * firmware, depending on where there's more space.
+ */
+
+ /*
+ * The firmware will always be loaded in the first
+ * 256M. Calculate the top of that region. The bottom
+ * of that region is always the beginning of our
+ * data segment.
+ */
+ if (mem_totalsize > (uint64_t)256) {
+ topmem = 256*MEG;
+ }
+ else {
+ topmem = (unsigned int) (mem_totalsize << 20);
+ }
+ botcfe = (unsigned int) K1_TO_PHYS(mem_bottomofmem);
+ topcfe = (unsigned int) K1_TO_PHYS(mem_topofmem);
+
+ beforecfe = botcfe;
+ aftercfe = topmem-topcfe;
+
+ if (beforecfe > aftercfe) {
+ botcfe -= (PAGESIZE-1);
+ botcfe &= ~(PAGESIZE-1); /* round down to page boundary */
+ addr = botcfe - CFE_BOOTAREA_SIZE; /* this is the address */
+ }
+ else {
+ topcfe += (PAGESIZE-1); /* round *up* to a page address */
+ topcfe &= ~(PAGESIZE-1);
+ addr = topcfe;
+ }
+
+ mem_bootarea_start = addr;
+ mem_bootarea_size = CFE_BOOTAREA_SIZE;
+
+ /*
+ * Allocate the page table
+ */
+
+ pte = KMALLOC(1024,1024);
+
+#ifdef __long64
+ pte_int = (int64_t) pte;
+#else
+ pte_int = (int64_t) ((int) pte);
+#endif
+
+ /*
+ * Set the CP0 CONTEXT register to point at the page table
+ */
+
+ pte_int <<= 13;
+ cfe_pagetable = (uint64_t *) pte;
+
+ _setcontext(pte_int);
+
+
+ /*
+ * Initialize page table entries
+ */
+
+ CPUCFG_PAGETBLINIT(cfe_pagetable,addr);
+
+
+}
+
diff --git a/cfe/cfe/arch/mips/common/src/tools.mk b/cfe/cfe/arch/mips/common/src/tools.mk
new file mode 100755
index 0000000..d195de9
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/tools.mk
@@ -0,0 +1,83 @@
+#
+# Basic compiler options and preprocessor flags
+#
+
+CFLAGS += -g -c -ffreestanding
+CFLAGS += -O1 -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
+
+#
+# Tools locations
+#
+
+ifndef TOOLS
+TOOLS=/opt/toolchains/uclibc-crosstools-gcc-4.4.2-1/usr/bin/mips-linux-
+endif
+
+GCC ?= $(TOOLS)gcc
+GLD ?= $(TOOLS)ld
+AR ?= $(TOOLS)ar
+OBJDUMP ?= $(TOOLS)objdump
+OBJCOPY ?= $(TOOLS)objcopy
+RANLIB ?= $(TOOLS)ranlib
+
+#
+# Check for 64-bit mode
+#
+
+ifeq ($(strip ${CFG_MLONG64}),1)
+ CFLAGS += -mlong64 -D__long64
+endif
+
+#
+# Figure out which linker script to use
+#
+
+ifeq ($(strip ${CFG_RAMAPP}),1)
+ CFLAGS += -DCFG_RAMAPP=1
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_ramapp.lds
+ CFLAGS += -DCFG_RUNFROMKSEG0=1
+else
+ ifeq ($(strip ${CFG_RELOC}),0)
+ ifeq ($(strip ${CFG_BOOTRAM}),1)
+ CFLAGS += -DCFG_BOOTRAM=1
+ ROMRAM = ram
+ else
+ CFLAGS += -DCFG_BOOTRAM=0
+ ROMRAM = rom
+ endif
+ ifeq ($(strip ${CFG_UNCACHED}),1)
+ CFLAGS += -DCFG_RUNFROMKSEG0=0
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_${ROMRAM}_uncached.lds
+ else
+ CFLAGS += -DCFG_RUNFROMKSEG0=1
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_${ROMRAM}_cached.lds
+ endif
+ else
+ CFLAGS += -membedded-pic -mlong-calls -DCFG_EMBEDDED_PIC=1
+ ifeq ($(strip ${CFG_UNCACHED}),1)
+ CFLAGS += -DCFG_RUNFROMKSEG0=0
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_rom_reloc_uncached.lds --embedded-relocs
+ else
+ CFLAGS += -DCFG_RUNFROMKSEG0=1
+ ifeq ($(strip ${CFG_TEXTAT1MB}),1)
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_rom_reloc_cached_biendian.lds --embedded-relocs
+ else
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_rom_reloc_cached.lds --embedded-relocs
+ endif
+ endif
+ endif
+endif
+#
+# Determine target endianness
+#
+
+ifeq ($(strip ${CFG_LITTLE}),1)
+ ENDIAN = -EL
+ CFLAGS += -EL
+ LDFLAGS += -EL
+else
+ ENDIAN = -EB
+ CFLAGS += -EB
+ LDFLAGS += -EB
+endif
+
diff --git a/cfe/cfe/arch/mips/common/src/ui_memtest.c b/cfe/cfe/arch/mips/common/src/ui_memtest.c
new file mode 100644
index 0000000..5388fd8
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/ui_memtest.c
@@ -0,0 +1,282 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Test commands File: ui_memtest.c
+ *
+ * A simple memory test
+ *
+ * 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 "sbmips.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_error.h"
+
+#include "ui_command.h"
+#include "cfe.h"
+
+#include "bsp_config.h"
+
+#include "cfe_mem.h"
+
+
+#ifdef __long64
+static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]);
+#endif
+
+#ifndef _SB_MAKE64
+#define _SB_MAKE64(x) ((uint64_t)(x))
+#endif
+#ifndef _SB_MAKEMASK
+#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n))
+#endif
+#ifndef _SB_MAKEMASK1
+#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
+#endif
+
+
+int ui_init_memtestcmds(void);
+
+int ui_init_memtestcmds(void)
+{
+#ifdef __long64
+ cmd_addcmd("memorytest",
+ ui_cmd_memorytest,
+ NULL,
+ "Tests all available memory",
+ "",
+ "-loop;Loop forever or until keypress|"
+ "-stoponerror;Stop if error occurs while looping|"
+ "-cca=*;Use specified cacheability attribute|"
+ "-arena=*;Test only specified arena index");
+#endif
+ return 0;
+}
+
+
+#ifdef __long64
+/* extensive memory tests */
+
+static void inline uacwrite(volatile long *srcadr,long *dstadr)
+{
+__asm __volatile ("ld $8, 0(%0) ; "
+ "ld $9, 8(%0) ; "
+ "ld $10, 16(%0) ; "
+ "ld $11, 24(%0) ; "
+ "sync ; "
+ "sd $8, 0(%1) ; "
+ "sd $9, 8(%1) ; "
+ "sd $10, 16(%1) ; "
+ "sd $11, 24(%1) ; "
+ "sync" :: "r"(srcadr),"r"(dstadr) : "$8","$9","$10","$11");
+}
+
+
+#define TEST_DATA_LEN 4
+#define CACHE_LINE_LEN 32
+
+static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[])
+{
+
+ static volatile long test_data[TEST_DATA_LEN] = {
+ 0xaaaaaaaaaaaaaaaa, 0x5555555555555555, 0xcccccccccccccccc, 0x3333333333333333, /* one cache line */
+ };
+ int arena, exitLoop;
+ int error;
+ int arena_type;
+ uint64_t arena_start, arena_size;
+ long phys_addr, offset, mem_base, cache_mem_base, i;
+ long *dst_adr, *cache_dst_adr;
+ long cda,tda;
+ int forever;
+ int passcnt;
+ int stoponerr = 0;
+ int cca = K_CALG_UNCACHED_ACCEL;
+ int arenanum = -1;
+ char *x;
+
+ arena = 0;
+ exitLoop = 0;
+ offset = 0;
+ mem_base = 0;
+ passcnt = 0;
+ error = 0;
+
+ forever = cmd_sw_isset(cmd,"-loop");
+ stoponerr = cmd_sw_isset(cmd,"-stoponerror");
+ if (cmd_sw_value(cmd,"-cca",&x)) cca = atoi(x);
+ if (cmd_sw_value(cmd,"-arena",&x)) arenanum = atoi(x);
+
+ printf("Available memory arenas:\n");
+ while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) {
+ phys_addr = (long) arena_start; /* actual physical address */
+ mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */
+ xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size);
+ arena++;
+ }
+
+ printf("\nTesting memory.\n");
+ do {
+
+ passcnt++;
+ if (forever) {
+ if (console_status()) break;
+ printf("***** Iteration %d *****\n",passcnt);
+ }
+
+ arena = 0;
+ exitLoop = 0;
+ error = 0;
+
+ while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) {
+
+ if ((arenanum >= 0) && (arena != arenanum)) {
+ arena++;
+ continue;
+ }
+
+ test_data[0] = 0xAAAAAAAAAAAAAAAA;
+ test_data[1] = 0x5555555555555555;
+ test_data[2] = 0xCCCCCCCCCCCCCCCC;
+ test_data[3] = 0x3333333333333333;
+
+ phys_addr = (long) arena_start; /* actual physical address */
+ mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */
+ cache_mem_base = PHYS_TO_K0(phys_addr);
+
+ xprintf("\n");
+ xprintf("Testing: phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size);
+
+ xprintf("Writing: a/5/c/3\n");
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ uacwrite(test_data, dst_adr);
+ }
+
+ xprintf("Reading: a/5/c/3\n");
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ cache_dst_adr = (long*)(mem_base+offset);
+ for (i = 0; i < TEST_DATA_LEN; i++) {
+ cda = cache_dst_adr[i];
+ tda = test_data[i];
+ if (cda != tda) {
+ xprintf("mem[%016llX] %016llX != %016llX\n",
+ mem_base+offset+(i*8), cda, tda);
+ exitLoop = 1;
+ }
+ }
+ if (exitLoop) break;
+ }
+
+
+ if (exitLoop) {
+ exitLoop = 0;
+ error++;
+ arena++;
+ continue;
+ }
+
+ xprintf("Writing: address|5555/inv/aaaa|address\n");
+ exitLoop = 0;
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ test_data[0] = ((long)dst_adr<<32)|0x55555555;
+ test_data[1] = ~test_data[0];
+ test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff);
+ test_data[3] = ~test_data[2];
+ uacwrite(test_data, dst_adr);
+ }
+
+ xprintf("Reading: address|5555/inv/aaaa|address\n");
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ test_data[0] = ((long)dst_adr<<32)|0x55555555;
+ test_data[1] = ~test_data[0];
+ test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff);
+ test_data[3] = ~test_data[2];
+ cache_dst_adr = (long*)(mem_base+offset);
+ for (i = 0; i < TEST_DATA_LEN; i++) {
+ cda = cache_dst_adr[i];
+ tda = test_data[i];
+ if (cda != tda) {
+ xprintf("mem[%016llX] %016llX != %016llX\n",
+ mem_base+offset+(i*8),cda,tda);
+ exitLoop = 1;
+ }
+ }
+ if (exitLoop) break;
+ }
+
+ if (exitLoop) {
+ error++;
+ exitLoop = 0;
+ if (stoponerr) forever = 0;
+ }
+
+ arena++;
+ }
+ } while (forever);
+
+ if (error) printf("Failing address: %016llX\n",mem_base+offset);
+
+ return error ? -1 : 0;
+}
+
+#endif
+
+
+
+
diff --git a/cfe/cfe/arch/mips/cpu/SIBYTE_PRIVATE_FILES b/cfe/cfe/arch/mips/cpu/SIBYTE_PRIVATE_FILES
new file mode 100644
index 0000000..1e7d4b6
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/SIBYTE_PRIVATE_FILES
@@ -0,0 +1,2 @@
+bcmcore
+bcm1400
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/include/bcm4710.h b/cfe/cfe/arch/mips/cpu/bcmcore/include/bcm4710.h
new file mode 100644
index 0000000..f499bc9
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/include/bcm4710.h
@@ -0,0 +1,58 @@
+/*
+ Copyright 2001, Broadcom Corporation
+ All Rights Reserved.
+
+ This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ the contents of this file may not be disclosed to third parties, copied or
+ duplicated in any form, in whole or in part, without the prior written
+ permission of Broadcom Corporation.
+*/
+/*
+ * BCM4710 address space map and definitions
+ *
+ * Think twice before adding to this file, this is not the kitchen sink
+ * These definitions are not guaranteed for all 47xx chips, only the 4710
+ *
+ * Copyright (C) 2000 Broadcom Corporation
+ * $Id: bcm4710.h,v 1.1 2001/10/31 18:49:25 mpl Exp $
+ */
+
+#ifndef _bcm4710_h_
+#define _bcm4710_h_
+
+/* Address map */
+#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
+#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
+#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
+#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
+#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
+#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
+
+/* Core register space */
+#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
+#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
+#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
+#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
+#define BCM4710_REG_USB 0x18004000 /* USB core registers */
+#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
+#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
+#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
+#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
+
+#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
+#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
+
+#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
+
+#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
+#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
+
+#ifdef CONFIG_VSIM
+#define BCM4710_TRACE(trval) do { *((int *)0xa0002ff8) = (trval); } while (0)
+#else
+#define BCM4710_TRACE(trval) do { *((unsigned char *)KSEG1ADDR(BCM4710_LED)) = (trval); \
+ *((int *)0xa0002ff8) = (trval); } while (0)
+#endif
+
+
+#endif /* _bcm4710_h_ */
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/include/bcm47xx.h b/cfe/cfe/arch/mips/cpu/bcmcore/include/bcm47xx.h
new file mode 100644
index 0000000..eb752e5
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/include/bcm47xx.h
@@ -0,0 +1,8 @@
+#ifndef _BCM47XX_H
+#define _BCM47XX_H
+
+/* uart defaults */
+#define DIV_LO 0x36
+#define DIV_HI 0
+
+#endif
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/include/bcmnvram.h b/cfe/cfe/arch/mips/cpu/bcmcore/include/bcmnvram.h
new file mode 100644
index 0000000..b9d37e6
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/include/bcmnvram.h
@@ -0,0 +1,123 @@
+/*
+ Copyright 2001, Broadcom Corporation
+ All Rights Reserved.
+
+ This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ the contents of this file may not be disclosed to third parties, copied or
+ duplicated in any form, in whole or in part, without the prior written
+ permission of Broadcom Corporation.
+*/
+/*
+ * NVRAM variable manipulation
+ *
+ * Copyright (C) 2001 Broadcom Corporation
+ *
+ * $Id: bcmnvram.h,v 1.1 2001/10/31 18:49:25 mpl Exp $
+ */
+
+#ifndef _bcmnvram_h_
+#define _bcmnvram_h_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+struct nvram_header {
+ unsigned long magic;
+ unsigned long len;
+ unsigned long crc_ver_init; /* 0:7 crc, 8:15 ver, 16:27 init, mem. test 28, 29-31 reserved */
+ unsigned long config_refresh; /* 0:15 config, 16:31 refresh */
+ unsigned long reserved;
+};
+
+struct nvram_tuple {
+ char *name;
+ char *value;
+ struct nvram_tuple *next;
+};
+
+/* Compatibility */
+typedef struct nvram_tuple EnvRec;
+
+/*
+ * Get the value of an NVRAM variable
+ * @param name name of variable to get
+ * @return value of variable or NULL if undefined
+ */
+extern char * nvram_get(const char *name);
+
+/*
+ * Get the value of an NVRAM variable
+ * @param name name of variable to get
+ * @return value of variable or NUL if undefined
+ */
+#define nvram_safe_get(name) (nvram_get(name) ? : "")
+
+/*
+ * Match an NVRAM variable
+ * @param name name of variable to match
+ * @param match value to compare against value of variable
+ * @return TRUE if variable is defined and its value is string equal to match or FALSE otherwise
+ */
+#define nvram_match(name, match) ({ \
+ const char *value = nvram_get(name); \
+ (value && !strcmp(value, match)); \
+})
+
+/*
+ * Match an NVRAM variable
+ * @param name name of variable to match
+ * @param match value to compare against value of variable
+ * @return TRUE if variable is defined and its value is not string equal to invmatch or FALSE otherwise
+ */
+#define nvram_invmatch(name, invmatch) ({ \
+ const char *value = nvram_get(name); \
+ (value && strcmp(value, invmatch)); \
+})
+
+/*
+ * Set the value of an NVRAM variable
+ * @param name name of variable to set
+ * @param value value of variable
+ * @return 0 on success and errno on failure
+ * NOTE: use nvram_commit to commit this change to flash.
+ */
+extern int nvram_set(const char *name, const char *value);
+
+/*
+ * Unset an NVRAM variable
+ * @param name name of variable to unset
+ * @return 0 on success and errno on failure
+ * NOTE: use nvram_commit to commit this change to flash.
+ */
+extern int nvram_unset(const char *name);
+
+/*
+ * Permanently commit NVRAM variables
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_commit(void);
+
+/*
+ * Get all NVRAM variables (format name=value\0 ... \0\0)
+ * @param buf buffer to store variables
+ * @param count size of buffer in bytes
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_getall(char *buf, int count);
+
+/*
+ * Invalidate the current NVRAM header
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_invalidate(void);
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
+#define NVRAM_VERSION 1
+#define NVRAM_HEADER_SIZE 20
+#define NVRAM_FIRST_LOC 0xbfcf8000
+#define NVRAM_LAST_LOC 0xbfff8000
+#define NVRAM_LOC_GAP 0x100000
+#define NVRAM_SPACE 0x8000
+
+#endif /* _bcmnvram_h_ */
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/include/cpu_config.h b/cfe/cfe/arch/mips/cpu/bcmcore/include/cpu_config.h
new file mode 100755
index 0000000..51cf4e1
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/include/cpu_config.h
@@ -0,0 +1,62 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * CPU Configuration file File: cpu_config.h
+ *
+ * This file contains the names of the routines to be used
+ * in the dispatch table in init_mips.S
+ *
+ * It lives here in the CPU directory so we can direct
+ * the init calls to routines named in this directory.
+ *
+ * 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.
+ ********************************************************************* */
+
+/*
+ */
+
+#define CPUCFG_CPUINIT bcmcore_cpuinit
+#define CPUCFG_ALTCPU_START1 bcmcore_null
+#define CPUCFG_ALTCPU_START2 bcmcore_null
+#define CPUCFG_ALTCPU_RESET bcmcore_null
+#define CPUCFG_CPURESTART bcmcore_cpurestart
+#define CPUCFG_DRAMINIT board_draminit /* no dram on CPU */
+#define CPUCFG_CACHEOPS bcmcore_cacheops
+#define CPUCFG_ARENAINIT bcmcore_arena_init
+#define CPUCFG_PAGETBLINIT bcmcore_pagetable_init
+#define CPUCFG_TLBHANDLER bcmcore_tlbhandler
+#define CPUCFG_DIAG_TEST1 bcmcore_null
+#define CPUCFG_DIAG_TEST2 bcmcore_null
+#if CFG_CMT
+#define CPUCFG_TP1_SWITCH bcmcore_tp1_switch
+#else
+#define CPUCFG_TP1_SWITCH bcmcore_null
+#endif
+/*
+ * The BCMCORE ticks CP0 every other cycle.
+ */
+
+#define CPUCFG_CYCLESPERCPUTICK 2
+
+/*
+ * Hazard macro
+ */
+
+#define HAZARD nop ; nop ; nop ; nop ; nop ; nop ; nop
+#define ERET \
+ .set push ; \
+ .set mips4 ; \
+ eret ; \
+ .set pop
+
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/include/sbmips.h b/cfe/cfe/arch/mips/cpu/bcmcore/include/sbmips.h
new file mode 100644
index 0000000..0f4e055
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/include/sbmips.h
@@ -0,0 +1,670 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * MIPS64 CPU definitions File: sbmips.h
+ *
+ * This module contains constants and macros specific to the
+ * SB1 MIPS64 core.
+ *
+ * Author: Mitch Lichtenberg (mitch@sibyte.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.
+ ********************************************************************* */
+
+#ifndef _SB_MIPS_H
+#define _SB_MIPS_H
+
+/* *********************************************************************
+ * Configure language
+ ********************************************************************* */
+
+#if defined(__ASSEMBLER__)
+#define _ATYPE_
+#define _ATYPE32_
+#define _ATYPE64_
+#else
+#define _ATYPE_ (__SIZE_TYPE__)
+#define _ATYPE32_ (int)
+#define _ATYPE64_ (long long)
+#endif
+
+
+/* *********************************************************************
+ * Bitfield macros
+ ********************************************************************* */
+
+/*
+ * Make a mask for 1 bit at position 'n'
+ */
+
+#define _MM_MAKEMASK1(n) (1 << (n))
+
+/*
+ * Make a mask for 'v' bits at position 'n'
+ */
+
+#define _MM_MAKEMASK(v,n) (((1<<(v))-1) << (n))
+
+/*
+ * Make a value at 'v' at bit position 'n'
+ */
+
+#define _MM_MAKEVALUE(v,n) ((v) << (n))
+
+/*
+ * Retrieve a value from 'v' at bit position 'n' with 'm' mask bits
+ */
+
+#define _MM_GETVALUE(v,n,m) (((v) & (m)) >> (n))
+
+
+
+/* *********************************************************************
+ * 32-bit MIPS Address Spaces
+ ********************************************************************* */
+
+#ifdef __ASSEMBLER__
+#define _ACAST32_
+#define _ACAST64_
+#else
+#define _ACAST32_ _ATYPE_ _ATYPE32_ /* widen if necessary */
+#define _ACAST64_ _ATYPE64_ /* do _not_ narrow */
+#endif
+
+/* 32-bit address map */
+#define UBASE 0x00000000 /* user+ mapped */
+#define USIZE 0x80000000
+#define K0BASE (_ACAST32_ 0x80000000) /* kernel unmapped cached */
+#define K0SIZE 0x20000000
+#define K1BASE (_ACAST32_ 0xa0000000) /* kernel unmapped uncached */
+#define K1SIZE 0x20000000
+#define KSBASE (_ACAST32_ 0xc0000000) /* supervisor+ mapped */
+#define KSSIZE 0x20000000
+#define K3BASE (_ACAST32_ 0xe0000000) /* kernel mapped */
+#define K3SIZE 0x20000000
+
+/* 64-bit address map additions to the above (sign-extended) ranges */
+#define XUBASE (_ACAST64_ 0x0000000080000000) /* user+ mapped */
+#define XUSIZE (_ACAST64_ 0x00000FFF80000000)
+#define XSSEGBASE (_ACAST64_ 0x4000000000000000) /* supervisor+ mapped */
+#define XSSEGSIZE (_ACAST64_ 0x0000100000000000)
+#define XKPHYSBASE (_ACAST64_ 0x8000000000000000) /* kernel unmapped */
+#define XKPHYSSIZE (_ACAST64_ 0x0000100000000000)
+#define XKSEGBASE (_ACAST64_ 0xC000000000000000) /* kernel mapped */
+#define XKSEGSIZE (_ACAST64_ 0x00000FFF80000000)
+
+#define GEN_VECT (_ACAST32_ 0x80000080)
+#define UTLB_VECT (_ACAST32_ 0x80000000)
+
+/* *********************************************************************
+ * Address space coercion macros
+ ********************************************************************* */
+
+#define PHYS_TO_K0(pa) (K0BASE | (pa))
+#define PHYS_TO_K1(pa) (K1BASE | (pa))
+#define K0_TO_PHYS(va) ((va) & (K0SIZE-1))
+#define K1_TO_PHYS(va) ((va) & (K1SIZE-1))
+#define K0_TO_K1(va) ((va) | K1SIZE)
+#define K1_TO_K0(va) ((va) & ~K1SIZE)
+
+#define PHYS_TO_XK1(p) (_ACAST64_ (0xffffffffa0000000 | (p)))
+#define XK1_TO_PHYS(p) ((p) & (K1SIZE-1))
+#define PHYS_TO_XKPHYS(cca,p) (_SB_MAKEMASK1(63) | (_SB_MAKE64(cca) << 59) | (p))
+#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p))
+#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p))
+#define XKPHYS_TO_PHYS(p) ((p) & _SB_MAKEMASK(0,59))
+
+
+#if !defined(__ASSEMBLER__)
+#define mips_wbflush() __asm__ __volatile__ ("sync" : : : "memory")
+#define ISK0SEG(va) ((va) >= K0BASE && (va) <= (K0BASE + K0SIZE - 1))
+#define ISK1SEG(va) ((va) >= K1BASE && (va) <= (K1BASE + K1SIZE - 1))
+#endif
+
+/* *********************************************************************
+ * Register aliases
+ ********************************************************************* */
+
+#if defined(__ASSEMBLER__)
+#define zero $0
+#define AT $1 /* assembler temporaries */
+#define v0 $2 /* value holders */
+#define v1 $3
+#define a0 $4 /* arguments */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 /* temporaries */
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define ta0 $12
+#define ta1 $13
+#define ta2 $14
+#define ta3 $15
+#define s0 $16 /* saved registers */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* temporaries */
+#define t9 $25
+#define k0 $26 /* kernel registers */
+#define k1 $27
+#define gp $28 /* global pointer */
+#define sp $29 /* stack pointer */
+#define s8 $30 /* saved register */
+#define fp $30 /* frame pointer */
+#define ra $31 /* return address */
+#endif
+
+/* *********************************************************************
+ * CP0 Registers
+ ********************************************************************* */
+
+#if defined(__ASSEMBLER__)
+#define C0_INX $0 /* CP0: TLB Index */
+#define C0_RAND $1 /* CP0: TLB Random */
+#define C0_TLBLO0 $2 /* CP0: TLB EntryLo0 */
+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
+#define C0_TLBLO1 $3 /* CP0: TLB EntryLo1 */
+#define C0_CTEXT $4 /* CP0: Context */
+#define C0_PGMASK $5 /* CP0: TLB PageMask */
+#define C0_WIRED $6 /* CP0: TLB Wired */
+#define C0_BADVADDR $8 /* CP0: Bad Virtual Address */
+#define C0_COUNT $9 /* CP0: Count */
+#define C0_TLBHI $10 /* CP0: TLB EntryHi */
+#define C0_COMPARE $11 /* CP0: Compare */
+#define C0_SR $12 /* CP0: Processor Status */
+#define C0_STATUS C0_SR /* CP0: Processor Status */
+#define C0_CAUSE $13 /* CP0: Exception Cause */
+#define C0_EPC $14 /* CP0: Exception PC */
+#define C0_PRID $15 /* CP0: Processor Revision Indentifier */
+#define C0_CONFIG $16 /* CP0: Config */
+#define C0_LLADDR $17 /* CP0: LLAddr */
+#define C0_WATCHLO $18 /* CP0: WatchpointLo */
+#define C0_WATCHHI $19 /* CP0: WatchpointHi */
+#define C0_XCTEXT $20 /* CP0: XContext */
+#define C0_ECC $26 /* CP0: ECC */
+#define C0_CACHEERR $27 /* CP0: CacheErr */
+#define C0_TAGLO $28 /* CP0: TagLo */
+#define C0_TAGHI $29 /* CP0: TagHi */
+#define C0_ERREPC $30 /* CP0: ErrorEPC */
+#else
+#define C0_INX 0 /* CP0: TLB Index */
+#define C0_RAND 1 /* CP0: TLB Random */
+#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */
+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
+#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */
+#define C0_CTEXT 4 /* CP0: Context */
+#define C0_PGMASK 5 /* CP0: TLB PageMask */
+#define C0_WIRED 6 /* CP0: TLB Wired */
+#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
+#define C0_COUNT 9 /* CP0: Count */
+#define C0_TLBHI 10 /* CP0: TLB EntryHi */
+#define C0_COMPARE 11 /* CP0: Compare */
+#define C0_SR 12 /* CP0: Processor Status */
+#define C0_STATUS C0_SR /* CP0: Processor Status */
+#define C0_CAUSE 13 /* CP0: Exception Cause */
+#define C0_EPC 14 /* CP0: Exception PC */
+#define C0_PRID 15 /* CP0: Processor Revision Indentifier */
+#define C0_CONFIG 16 /* CP0: Config */
+#define C0_LLADDR 17 /* CP0: LLAddr */
+#define C0_WATCHLO 18 /* CP0: WatchpointLo */
+#define C0_WATCHHI 19 /* CP0: WatchpointHi */
+#define C0_XCTEXT 20 /* CP0: XContext */
+#define C0_ECC 26 /* CP0: ECC */
+#define C0_CACHEERR 27 /* CP0: CacheErr */
+#define C0_TAGLO 28 /* CP0: TagLo */
+#define C0_TAGHI 29 /* CP0: TagHi */
+#define C0_ERREPC 30 /* CP0: ErrorEPC */
+#endif
+
+/* *********************************************************************
+ * CP1 (floating point) control registers
+ ********************************************************************* */
+
+#define FPA_IRR 0 /* CP1: Implementation/Revision */
+#define FPA_CSR 31 /* CP1: Control/Status */
+
+/* *********************************************************************
+ * Macros for generating assembly language routines
+ ********************************************************************* */
+
+#if defined(__ASSEMBLER__)
+
+/* global leaf function (does not call other functions) */
+#define LEAF(name) \
+ .globl name; \
+ .ent name; \
+name:
+
+/* global alternate entry to (local or global) leaf function */
+#define XLEAF(name) \
+ .globl name; \
+ .aent name; \
+name:
+
+/* end of a global function */
+#define END(name) \
+ .size name,.-name; \
+ .end name
+
+/* local leaf function (does not call other functions) */
+#define SLEAF(name) \
+ .ent name; \
+name:
+
+/* local alternate entry to (local or global) leaf function */
+#define SXLEAF(name) \
+ .aent name; \
+name:
+
+/* end of a local function */
+#define SEND(name) \
+ END(name)
+
+/* define & export a symbol */
+#define EXPORT(name) \
+ .globl name; \
+name:
+
+/* import a symbol */
+#define IMPORT(name, size) \
+ .extern name,size
+
+/* define a zero-fill common block (BSS if not overridden) with a global name */
+#define COMM(name,size) \
+ .comm name,size
+
+/* define a zero-fill common block (BSS if not overridden) with a local name */
+#define LCOMM(name,size) \
+ .lcomm name,size
+
+#endif
+
+
+/* Floating-Point Control register bits */
+#define CSR_C 0x00800000
+#define CSR_EXC 0x0003f000
+#define CSR_EE 0x00020000
+#define CSR_EV 0x00010000
+#define CSR_EZ 0x00008000
+#define CSR_EO 0x00004000
+#define CSR_EU 0x00002000
+#define CSR_EI 0x00001000
+#define CSR_TV 0x00000800
+#define CSR_TZ 0x00000400
+#define CSR_TO 0x00000200
+#define CSR_TU 0x00000100
+#define CSR_TI 0x00000080
+#define CSR_SV 0x00000040
+#define CSR_SZ 0x00000020
+#define CSR_SO 0x00000010
+#define CSR_SU 0x00000008
+#define CSR_SI 0x00000004
+#define CSR_RM 0x00000003
+
+/* Status Register */
+#define M_SR_CUMASK _MM_MAKEMASK(4,28) /* coprocessor usable bits */
+#define M_SR_CU3 _MM_MAKEMASK1(31) /* coprocessor 3 usable */
+#define M_SR_CU2 _MM_MAKEMASK1(30) /* coprocessor 2 usable */
+#define M_SR_CU1 _MM_MAKEMASK1(29) /* coprocessor 1 usable */
+#define M_SR_CU0 _MM_MAKEMASK1(28) /* coprocessor 0 usable */
+
+#define M_SR_RP _MM_MAKEMASK1(27) /* reduced power mode */
+#define M_SR_FR _MM_MAKEMASK1(26) /* fpu regs any data */
+#define M_SR_RE _MM_MAKEMASK1(25) /* reverse endian */
+#define M_SR_MX _MM_MAKEMASK1(24) /* MDMX */
+#define M_SR_PX _MM_MAKEMASK1(23) /* 64-bit ops in user mode */
+#define M_SR_BEV _MM_MAKEMASK1(22) /* boot exception vectors */
+#define M_SR_TS _MM_MAKEMASK1(21) /* TLB is shut down */
+#define M_SR_SR _MM_MAKEMASK1(20) /* soft reset */
+#define M_SR_NMI _MM_MAKEMASK1(19) /* nonmaskable interrupt */
+
+#define M_SR_IMASK _MM_MAKEMASK(8,8) /* all interrupt mask bits */
+
+#define M_SR_IBIT8 _MM_MAKEMASK1(15) /* individual bits */
+#define M_SR_IBIT7 _MM_MAKEMASK1(14)
+#define M_SR_IBIT6 _MM_MAKEMASK1(13)
+#define M_SR_IBIT5 _MM_MAKEMASK1(12)
+#define M_SR_IBIT4 _MM_MAKEMASK1(11)
+#define M_SR_IBIT3 _MM_MAKEMASK1(10)
+#define M_SR_IBIT2 _MM_MAKEMASK1(9)
+#define M_SR_IBIT1 _MM_MAKEMASK1(8)
+
+#define M_SR_IMASK8 0 /* masks for nested int levels */
+#define M_SR_IMASK7 _MM_MAKEMASK(1,15)
+#define M_SR_IMASK6 _MM_MAKEMASK(2,14)
+#define M_SR_IMASK5 _MM_MAKEMASK(3,13)
+#define M_SR_IMASK4 _MM_MAKEMASK(4,12)
+#define M_SR_IMASK3 _MM_MAKEMASK(5,11)
+#define M_SR_IMASK2 _MM_MAKEMASK(6,10)
+#define M_SR_IMASK1 _MM_MAKEMASK(7,9)
+#define M_SR_IMASK0 _MM_MAKEMASK(8,8)
+
+#define M_SR_KX _MM_MAKEMASK1(7) /* 64-bit access for kernel */
+#define M_SR_SX _MM_MAKEMASK1(6) /* .. for supervisor */
+#define M_SR_UX _MM_MAKEMASK1(5) /* .. for user */
+
+#define S_SR_KSU 3 /* base operating mode mode */
+#define M_SR_KSU _MM_MAKEMASK(2,S_SR_KSU)
+#define V_SR_KSU(x) _MM_MAKEVALUE(x,S_SR_KSU)
+#define G_SR_KSU(x) _MM_GETVALUE(x,S_SR_KSU,M_SR_KSU)
+#define K_SR_KSU_KERNEL 0
+#define K_SR_KSU_SUPR 1
+#define K_SR_KSU_USER 2
+
+#define M_SR_UM _MM_MAKEMASK1(4)
+#define M_SR_ERL _MM_MAKEMASK1(2)
+#define M_SR_EXL _MM_MAKEMASK1(1)
+#define M_SR_IE _MM_MAKEMASK1(0)
+
+/*
+ * Cause Register
+ */
+#define M_CAUSE_BD _MM_MAKEMASK1(31) /* exception in BD slot */
+
+#define S_CAUSE_CE 28 /* coprocessor error */
+#define M_CAUSE_CE _MM_MAKEMASK(2,S_CAUSE_CE)
+#define V_CAUSE_CE(x) _MM_MAKEVALUE(x,S_CAUSE_CE)
+#define G_CAUSE_CE(x) _MM_GETVALUE(x,S_CAUSE_CE,M_CAUSE_CE)
+
+#define M_CAUSE_IV _MM_MAKEMASK1(23) /* special interrupt */
+#define M_CAUSE_WP _MM_MAKEMASK1(22) /* watch interrupt deferred */
+
+#define S_CAUSE_IPMASK 8
+#define M_CAUSE_IPMASK _MM_MAKEMASK(8,S_CAUSE_IPMASK)
+#define M_CAUSE_IP8 _MM_MAKEMASK1(15) /* hardware interrupts */
+#define M_CAUSE_IP7 _MM_MAKEMASK1(14)
+#define M_CAUSE_IP6 _MM_MAKEMASK1(13)
+#define M_CAUSE_IP5 _MM_MAKEMASK1(12)
+#define M_CAUSE_IP4 _MM_MAKEMASK1(11)
+#define M_CAUSE_IP3 _MM_MAKEMASK1(10)
+#define M_CAUSE_SW2 _MM_MAKEMASK1(9) /* software interrupts */
+#define M_CAUSE_SW1 _MM_MAKEMASK1(8)
+
+#define S_CAUSE_EXC 2
+#define M_CAUSE_EXC _MM_MAKEMASK(5,S_CAUSE_EXC)
+#define V_CAUSE_EXC(x) _MM_MAKEVALUE(x,S_CAUSE_EXC)
+#define G_CAUSE_EXC(x) _MM_GETVALUE(x,S_CAUSE_EXC,M_CAUSE_EXC)
+
+/* Exception Code */
+#define K_CAUSE_EXC_INT 0 /* External interrupt */
+#define K_CAUSE_EXC_MOD 1 /* TLB modification */
+#define K_CAUSE_EXC_TLBL 2 /* TLB miss (Load or Ifetch) */
+#define K_CAUSE_EXC_TLBS 3 /* TLB miss (Save) */
+#define K_CAUSE_EXC_ADEL 4 /* Address error (Load or Ifetch) */
+#define K_CAUSE_EXC_ADES 5 /* Address error (Save) */
+#define K_CAUSE_EXC_IBE 6 /* Bus error (Ifetch) */
+#define K_CAUSE_EXC_DBE 7 /* Bus error (data load or store) */
+#define K_CAUSE_EXC_SYS 8 /* System call */
+#define K_CAUSE_EXC_BP 9 /* Break point */
+#define K_CAUSE_EXC_RI 10 /* Reserved instruction */
+#define K_CAUSE_EXC_CPU 11 /* Coprocessor unusable */
+#define K_CAUSE_EXC_OVF 12 /* Arithmetic overflow */
+#define K_CAUSE_EXC_TRAP 13 /* Trap exception */
+#define K_CAUSE_EXC_VCEI 14 /* Virtual Coherency Exception (I) */
+#define K_CAUSE_EXC_FPE 15 /* Floating Point Exception */
+#define K_CAUSE_EXC_CP2 16 /* Cp2 Exception */
+#define K_CAUSE_EXC_WATCH 23 /* Watchpoint exception */
+#define K_CAUSE_EXC_VCED 31 /* Virtual Coherency Exception (D) */
+
+#define K_NTLBENTRIES 64
+
+#define HI_HALF(x) ((x) >> 16)
+#define LO_HALF(x) ((x) & 0xffff)
+
+/* FPU stuff */
+
+#if defined(__ASSEMBLER__)
+#define C1_CSR $31
+#define C1_FRID $0
+#else
+#define C1_CSR 31
+#define C1_FRID 0
+#endif
+
+#define S_FCSR_CAUSE 12
+#define M_FCSR_CAUSE _MM_MAKEMASK(5,S_FCSR_CAUSE)
+#define V_FCSR_CAUSE(x) _MM_MAKEVALUE(x,S_FCSR_CAUSE)
+#define G_FCSR_CAUSE(x) _MM_GETVALUE(x,S_FCSR_CAUSE,M_FCSR_CAUSE)
+
+#define S_FCSR_ENABLES 7
+#define M_FCSR_ENABLES _MM_MAKEMASK(5,S_FCSR_ENABLES)
+#define V_FCSR_ENABLES(x) _MM_MAKEVALUE(x,S_FCSR_ENABLES)
+#define G_FCSR_ENABLES(x) _MM_GETVALUE(x,S_FCSR_ENABLES,M_FCSR_ENABLES)
+
+#define S_FCSR_FLAGS 2
+#define M_FCSR_FLAGS _MM_MAKEMASK(5,S_FCSR_FLAGS)
+#define V_FCSR_FLAGS(x) _MM_MAKEVALUE(x,S_FCSR_FLAGS)
+#define G_FCSR_FLAGS(x) _MM_GETVALUE(x,S_FCSR_FLAGS,M_FCSR_FLAGS)
+
+
+/*
+ * MIPS64 Config Register (select 0)
+ */
+#define M_CFG_CFG1 _MM_MAKEMASK1(31) /* config1 select1 is impl */
+#define M_CFG_BE _MM_MAKEMASK1(15) /* big-endian mode */
+
+#define S_CFG_AT 13 /* Architecture Type */
+#define M_CFG_AT _MM_MAKEMASK(2,S_CFG_AT)
+#define V_CFG_AT(x) _MM_MAKEVALUE(x,S_CFG_AT)
+#define G_CFG_AT(x) _MM_GETVALUE(x,S_CFG_AT,M_CFG_AT)
+#define K_CFG_AT_MIPS32 0
+#define K_CFG_AT_MIPS64_32 1
+#define K_CFG_AT_MIPS64 2
+
+#define S_CFG_AR 10 /* Architecture Revision */
+#define M_CFG_AR _MM_MAKEMASK(3,S_CFG_AR)
+#define V_CFG_AR(x) _MM_MAKEVALUE(x,S_CFG_AR)
+#define G_CFG_AR(x) _MM_GETVALUE(x,S_CFG_AR,M_CFG_AR)
+#define K_CFG_AR_REV1 0
+
+#define S_CFG_MMU 7 /* MMU Type */
+#define M_CFG_MMU _MM_MAKEMASK(3,S_CFG_MMU)
+#define V_CFG_MMU(x) _MM_MAKEVALUE(x,S_CFG_MMU)
+#define G_CFG_MMU(x) _MM_GETVALUE(x,S_CFG_MMU,M_CFG_MMU)
+#define K_CFG_MMU_NONE 0
+#define K_CFG_MMU_TLB 1
+#define K_CFG_MMU_BAT 2
+#define K_CFG_MMU_FIXED 3
+
+#define S_CFG_K0COH 0 /* K0seg coherency */
+#define M_CFG_K0COH _MM_MAKEMASK(3,S_CFG_K0COH)
+#define V_CFG_K0COH(x) _MM_MAKEVALUE(x,S_CFG_K0COH)
+#define G_CFG_K0COH(x) _MM_GETVALUE(x,S_CFG_K0COH,M_CFG_K0COH)
+#define K_CFG_K0COH_UNCACHED 2
+#define K_CFG_K0COH_CACHEABLE 3
+#define K_CFG_K0COH_COHERENT 5
+
+/*
+ * MIPS64 Config Register (select 1)
+ */
+
+#define M_CFG_CFG2 _MM_MAKEMASK1(31) /* config2 select2 is impl */
+
+#define S_CFG_MMUSIZE 25
+#define M_CFG_MMUSIZE _MM_MAKEMASK(6,S_CFG_MMUSIZE)
+
+#define S_CFG_IS 22
+#define M_CFG_IS _MM_MAKEMASK(3,S_CFG_IS)
+#define V_CFG_IS(x) _MM_MAKEVALUE(x,S_CFG_IS)
+#define G_CFG_IS(x) _MM_GETVALUE(x,S_CFG_IS,M_CFG_IS)
+
+#define S_CFG_IL 19
+#define M_CFG_IL _MM_MAKEMASK(S_CFG_IL,3)
+#define V_CFG_IL(x) _MM_MAKEVALUE(x,S_CFG_IL)
+#define G_CFG_IL(x) _MM_GETVALUE(x,S_CFG_IL,M_CFG_IL)
+
+#define S_CFG_IA 16
+#define M_CFG_IA _MM_MAKEMASK(3,S_CFG_IA)
+#define V_CFG_IA(x) _MM_MAKEVALUE(x,S_CFG_IA)
+#define G_CFG_IA(x) _MM_GETVALUE(x,S_CFG_IA,M_CFG_IA)
+
+#define S_CFG_DS 13
+#define M_CFG_DS _MM_MAKEMASK(3,S_CFG_DS)
+#define V_CFG_DS(x) _MM_MAKEVALUE(x,S_CFG_DS)
+#define G_CFG_DS(x) _MM_GETVALUE(x,S_CFG_DS,M_CFG_DS)
+
+#define S_CFG_DL 10
+#define M_CFG_DL _MM_MAKEMASK(3,S_CFG_DL)
+#define V_CFG_DL(x) _MM_MAKEVALUE(x,S_CFG_DL)
+#define G_CFG_DL(x) _MM_GETVALUE(x,S_CFG_DL,M_CFG_DL)
+
+#define S_CFG_DA 7
+#define M_CFG_DA _MM_MAKEMASK(3,S_CFG_DA)
+#define V_CFG_DA(x) _MM_MAKEVALUE(x,S_CFG_DA)
+#define G_CFG_DA(x) _MM_GETVALUE(x,S_CFG_DA,M_CFG_DA)
+
+#define M_CFG_PC _MM_MAKEMASK1(4) /* perf ctrs present */
+#define M_CFG_WR _MM_MAKEMASK1(3) /* watch regs present */
+#define M_CFG_CA _MM_MAKEMASK1(2) /* MIPS16 present */
+#define M_CFG_EP _MM_MAKEMASK1(1) /* EJTAG present */
+#define M_CFG_FP _MM_MAKEMASK1(0) /* FPU present */
+
+
+
+/*
+ * Primary Cache TagLo
+ */
+
+#define S_TAGLO_PTAG 8
+#define M_TAGLO_PTAG _MM_MAKEMASK(56,S_TAGLO_PTAG)
+
+#define S_TAGLO_PSTATE 6
+#define M_TAGLO_PSTATE _MM_MAKEMASK(2,S_TAGLO_PSTATE)
+#define V_TAGLO_PSTATE(x) _MM_MAKEVALUE(x,S_TAGLO_PSTATE)
+#define G_TAGLO_PSTATE(x) _MM_GETVALUE(x,S_TAGLO_PSTATE,M_TAGLO_PSTATE)
+#define K_TAGLO_PSTATE_INVAL 0
+#define K_TAGLO_PSTATE_SHARED 1
+#define K_TAGLO_PSTATE_CLEAN_EXCL 2
+#define K_TAGLO_PSTATE_DIRTY_EXCL 3
+
+#define M_TAGLO_LOCK _MM_MAKEMASK1(5)
+#define M_TAGLO_PARITY _MM_MAKEMASK1(0)
+
+
+/*
+ * CP0 CacheErr register
+ */
+#define M_CERR_DATA _MM_MAKEMASK1(31) /* err in D space */
+#define M_CERR_SCACHE _MM_MAKEMASK1(30) /* err in l2, not l1 */
+#define M_CERR_DERR _MM_MAKEMASK1(29) /* data error */
+#define M_CERR_TERR _MM_MAKEMASK1(28) /* tag error */
+#define M_CERR_EXTRQ _MM_MAKEMASK1(27) /* external req caused err */
+#define M_CERR_BPAR _MM_MAKEMASK1(26) /* bus parity err */
+#define M_CERR_ADATA _MM_MAKEMASK1(25) /* additional data */
+#define M_CERR_IDX _MM_MAKEMASK(22,0)
+
+
+
+/*
+ * Primary Cache operations
+ */
+#define Index_Invalidate_I 0x0 /* 0 0 */
+#define Index_Writeback_Inv_D 0x1 /* 0 1 */
+#define Index_Invalidate_SI 0x2 /* 0 2 */
+#define Index_Writeback_Inv_SD 0x3 /* 0 3 */
+#define Index_Load_Tag_I 0x4 /* 1 0 */
+#define Index_Load_Tag_D 0x5 /* 1 1 */
+#define Index_Load_Tag_SI 0x6 /* 1 2 */
+#define Index_Load_Tag_SD 0x7 /* 1 3 */
+#define Index_Store_Tag_I 0x8 /* 2 0 */
+#define Index_Store_Tag_D 0x9 /* 2 1 */
+#define Index_Store_Tag_SI 0xA /* 2 2 */
+#define Index_Store_Tag_SD 0xB /* 2 3 */
+#define Create_Dirty_Exc_D 0xD /* 3 1 */
+#define Create_Dirty_Exc_SD 0xF /* 3 3 */
+#define Hit_Invalidate_I 0x10 /* 4 0 */
+#define Hit_Invalidate_D 0x11 /* 4 1 */
+#define Hit_Invalidate_SI 0x12 /* 4 2 */
+#define Hit_Invalidate_SD 0x13 /* 4 3 */
+#define Fill_I 0x14 /* 5 0 */
+#define Hit_Writeback_Inv_D 0x15 /* 5 1 */
+#define Hit_Writeback_Inv_SD 0x17 /* 5 3 */
+#define Hit_Writeback_I 0x18 /* 6 0 */
+#define Hit_Writeback_D 0x19 /* 6 1 */
+#define Hit_Writeback_SD 0x1B /* 6 3 */
+#define Hit_Set_Virtual_SI 0x1E /* 7 2 */
+#define Hit_Set_Virtual_SD 0x1F /* 7 3 */
+
+/* Watchpoint Register */
+#define M_WATCH_PA 0xfffffff8
+#define M_WATCH_R 0x00000002
+#define M_WATCH_W 0x00000001
+
+
+/* TLB entries */
+#define M_TLBHI_ASID _MM_MAKEMASK(0,8)
+#define M_TLBHI_VPN2 _MM_MAKEMASK(27,13)
+
+#define M_TLBLO_G _MM_MAKEMASK1(0)
+#define M_TLBLO_V _MM_MAKEMASK1(1)
+#define M_TLBLO_D _MM_MAKEMASK1(2)
+
+#define S_TLBLO_CALG 3
+#define M_TLBLO_CALG _MM_MAKEMASK(3,S_TLBLO_CALG)
+#define V_TLBLO_CALG(x) _MM_MAKEVALUE(x,S_TLBLO_CALG)
+#define G_TLBLO_CALG(x) _MM_GETVALUE(x,S_TLBLO_CALG,M_TLBLO_CALG)
+
+#define K_CALG_COH_EXCL1_NOL2 0
+#define K_CALG_COH_SHRL1_NOL2 1
+#define K_CALG_UNCACHED 2
+#define K_CALG_NONCOHERENT 3
+#define K_CALG_COH_EXCL 4
+#define K_CALG_COH_SHAREABLE 5
+#define K_CALG_NOTUSED 6
+#define K_CALG_UNCACHED_ACCEL 7
+
+#define S_TLBLO_PFNMASK 6
+#define M_TLBLO_PFNMASK _MM_MAKEMASK(24,S_TLBLO_PFNMASK)
+#define V_TLBLO_PFNMASK(x) _MM_MAKEVALUE(x,S_TLBLO_PFNMASK)
+#define G_TLBLO_PFNMASK(x) _MM_GETVALUE(x,S_TLBLO_PFNMASK,M_TLBLO_PFNMASK)
+
+
+
+#endif /* _SB_MIPS_H */
+
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/include/sbsdram.h b/cfe/cfe/arch/mips/cpu/bcmcore/include/sbsdram.h
new file mode 100644
index 0000000..80e93e3
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/include/sbsdram.h
@@ -0,0 +1,92 @@
+/*
+ Copyright 2001, Broadcom Corporation
+ All Rights Reserved.
+
+ This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+ the contents of this file may not be disclosed to third parties, copied or
+ duplicated in any form, in whole or in part, without the prior written
+ permission of Broadcom Corporation.
+*/
+/*
+ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
+ *
+ * $Id: sbsdram.h,v 1.1 2001/10/31 18:49:26 mpl Exp $
+ */
+
+#ifndef _SBSDRAM_H
+#define _SBSDRAM_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* Sonics side: SDRAM core registers */
+typedef volatile struct sbsdramregs {
+ uint32 initcontrol; /* Generates external SDRAM initialization sequence */
+ uint32 config; /* Initializes external SDRAM mode register */
+ uint32 refresh; /* Controls external SDRAM refresh rate */
+ uint32 pad1;
+ uint32 pad2;
+} sbsdramregs_t;
+
+#endif
+
+/* SDRAM initialization control (initcontrol) register bits */
+#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */
+#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */
+#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */
+#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */
+#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */
+#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */
+#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */
+#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */
+#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */
+#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */
+#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */
+#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */
+#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */
+
+/* SDRAM configuration (config) register bits */
+#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */
+#define SDRAM_BURST8 0x0001 /* Use burst of 8 */
+#define SDRAM_BURST4 0x0002 /* Use burst of 4 */
+#define SDRAM_BURST2 0x0003 /* Use burst of 2 */
+#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */
+#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */
+
+/* SDRAM refresh control (refresh) register bits */
+#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */
+#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */
+
+/* SDRAM Core Init values (OCP ID 0x803) */
+
+#define SDRAM_CONFIG SDRAM_BURSTFULL
+#define SDRAM_REFRESH SDRAM_REF(0x40)
+
+#if defined(MEM1MX16_KM)
+#define SDRAM_INIT 0x009
+#elif defined(MEM1MX16X2_KM)
+#define SDRAM_INIT 0x409
+#elif defined(MEM2MX8X2_KM)
+#define SDRAM_INIT 0x809
+#elif defined(MEM2MX8X4_KM)
+#define SDRAM_INIT 0xc09
+#elif defined(MEM2MX32_KM)
+#define SDRAM_INIT 0x439
+#elif defined(MEM4MX16_KM)
+#define SDRAM_INIT 0x019
+#elif defined(MEM4MX16X2_KM)
+#define SDRAM_INIT 0x419
+#elif defined(MEM8MX8X2_KM)
+#define SDRAM_INIT 0x819
+#elif defined(MEM8MX8X4_KM)
+#define SDRAM_INIT 0xc19
+#elif defined(MEM8MX16_KM)
+#define SDRAM_INIT 0x829
+#elif defined(MEM8MX16X2_KM)
+#define SDRAM_INIT 0xc29
+#elif defined(MEM4MX32_KM)
+#define SDRAM_INIT 0x429
+#else /* DEFAULT MEM */
+#define SDRAM_INIT 0x419
+#endif
+
+#endif /* _SBSDRAM_H */
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/Makefile b/cfe/cfe/arch/mips/cpu/bcmcore/src/Makefile
new file mode 100755
index 0000000..76662a0
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/Makefile
@@ -0,0 +1,8 @@
+
+ALLOBJS += bcmcore_cpuinit.o bcmcore_l1cache.o
+ifeq ($(strip ${CFG_RAMAPP}),1)
+ALLOBJS += bcmcore_arena.o
+endif
+CFLAGS += -mips32 -D_MIPSREGS32_ -mno-abicalls -fPIC
+# CFLAGS += -mips2 -D_MIPSREGS32_
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c
new file mode 100755
index 0000000..b368158
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c
@@ -0,0 +1,170 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical Memory (arena) manager File: bcmcore_arena.c
+ *
+ * This module describes the physical memory available to the
+ * firmware.
+ *
+ * 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 "sbmips.h"
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "lib_arena.h"
+
+#include "cfe_error.h"
+
+#include "cfe.h"
+#include "cfe_mem.h"
+
+#include "initdata.h"
+
+#define _NOPROTOS_
+#include "cfe_boot.h"
+#undef _NOPROTOS_
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define ARENA_RANGE(bottom,top,type) arena_markrange(&cfe_arena,(uint64_t)(bottom), \
+ (uint64_t)(top)-(uint64_t)bottom+1,(type),NULL)
+
+#define MEG (1024*1024)
+#define KB 1024
+#define PAGESIZE 4096
+#define CFE_BOOTAREA_SIZE (256*KB)
+#define CFE_BOOTAREA_ADDR 0x20000000
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+extern arena_t cfe_arena;
+
+unsigned int mem_bootarea_start;
+unsigned int mem_bootarea_size;
+
+void bcmcore_arena_init(void);
+void bcmcore_pagetable_init(uint64_t *ptaddr,unsigned int physaddr);
+
+
+/* *********************************************************************
+ * bcmcore_arena_init()
+ *
+ * Create the initial map of physical memory
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void bcmcore_arena_init(void)
+{
+ int64_t memleft;
+
+#if 1 /* defined(CONFIG_MIPS_BRCM) */
+ arena_init(&cfe_arena,0x0,0x0); /* 2^32 physical bytes */
+#else
+ arena_init(&cfe_arena,0x0,0x100000000); /* 2^32 physical bytes */
+#endif
+
+ /*
+ * Mark the ranges from the SB1250's memory map
+ */
+
+ ARENA_RANGE(0x0000000000,0x000FFFFFFF,MEMTYPE_DRAM_NOTINSTALLED);
+
+ /*
+ * Now, fix up the map with what is known about *this* system.
+ *
+ * Do each 256MB chunk.
+ */
+
+ memleft = ((int64_t) mem_totalsize) << 20;
+
+ arena_markrange(&cfe_arena,0x00000000,memleft,MEMTYPE_DRAM_AVAILABLE,NULL);
+
+ /*
+ * Do the boot ROM
+ */
+
+ arena_markrange(&cfe_arena,0x1FC00000,2*1024*1024,MEMTYPE_BOOTROM,NULL);
+
+}
+
+
+/* *********************************************************************
+ * BCMCORE_PAGETABLE_INIT(ptaddr,physaddr)
+ *
+ * This routine constructs the page table. 256KB is mapped
+ * starting at physical address 'physaddr' - the resulting
+ * table entries are placed at 'ptaddr'
+ *
+ * Input parameters:
+ * ptaddr - base of page table
+ * physaddr - starting physical addr of area to map
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void bcmcore_pagetable_init(uint64_t *ptaddr,unsigned int physaddr)
+{
+ int idx;
+
+ for (idx = 0; idx < (CFE_BOOTAREA_SIZE/PAGESIZE); idx++) {
+ ptaddr[idx] = (physaddr >> 6) |
+ V_TLBLO_CALG(K_CALG_NONCOHERENT) |
+ M_TLBLO_V |
+ M_TLBLO_D;
+ physaddr += PAGESIZE;
+ }
+
+}
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S
new file mode 100755
index 0000000..7c04b51
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S
@@ -0,0 +1,490 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * CPU initialization File: bcmcore_cpuinit.S
+ *
+ * This module contains code to initialize the CPU cores.
+ *
+ * Note: all the routines in this module rely on registers only,
+ * since DRAM may not be active yet.
+ *
+ * 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 "sbmips.h"
+#include "exception.h"
+#include "bsp_config.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for ERET and HAZARD */
+
+
+ .text
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define LINESIZE 16
+
+#define CACHEOP(cachename,op) ((cachename) | ((op) << 2))
+
+#define CACHE_OP_IDXINVAL 0
+#define CACHE_OP_IDXLOADTAG 1
+#define CACHE_OP_IDXSTORETAG 2
+#define CACHE_OP_IMPLRSVD 3
+#define CACHE_OP_HITINVAL 4
+#define CACHE_OP_FILL 5
+#define CACHE_OP_HITWRITEBACK_INVAL 5
+#define CACHE_OP_HITWRITEBACK 6
+#define CACHE_OP_FETCHLOCK 7
+
+#define L2C 3
+#define L1C_I 0
+#define L1C_D 1
+
+
+/*
+ * Duplicates from cfe_iocb.h -- warning!
+ */
+
+#define CFE_CACHE_FLUSH_D 1
+#define CFE_CACHE_INVAL_I 2
+#define CFE_CACHE_INVAL_D 4
+#define CFE_CACHE_INVAL_L2 8
+#define CFE_CACHE_FLUSH_L2 16
+#define CFE_CACHE_INVAL_RANGE 32
+#define CFE_CACHE_FLUSH_RANGE 64
+
+#define BCMCORE_NTLBENTRIES 32
+
+
+
+#define SENDCHAR(c) \
+ li t0,0xBF800000 ; \
+ li t1,c ; \
+ sb t1,0(t0)
+
+
+#define R_CPU_CP0INIT _TBLIDX(0)
+#define R_CPU_L1CINIT _TBLIDX(1)
+#define R_CPU_SETLEDS _TBLIDX(2)
+#define R_CPU_L1CFLASHD _TBLIDX(3)
+#define R_CPU_L1CINVALI _TBLIDX(4)
+
+#define SETLEDS1(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_SETLEDS)
+#define SETLEDS(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG0(cpuinit_table,R_CPU_SETLEDS)
+
+cpuinit_table:
+ _LONG_ bcmcore_cp0_init # [ 0 ] R_CPU_CP0INIT
+ _LONG_ bcmcore_l1cache_init # [ 1 ] R_CPU_L1CINIT
+ _LONG_ board_setleds # [ 2 ] R_CPU_SETLEDS
+ _LONG_ bcmcore_l1cache_flush_d # [ 3 ] R_CPU_L1CFLASHD
+ _LONG_ bcmcore_l1cache_inval_i # [ 4 ] R_CPU_L1CINVALI
+
+
+/* *********************************************************************
+ * BCMCORE_CP0_INIT()
+ *
+ * Initialize an BCMCORE CPU's CP0 registers
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * all
+ ********************************************************************* */
+
+
+LEAF(bcmcore_cp0_init)
+
+ .set noreorder
+
+ mtc0 zero,C0_WATCHLO # Watch registers.
+ mtc0 zero,C0_WATCHHI
+ mtc0 zero,C0_CAUSE # must clear before writing SR
+
+ mfc0 v0,C0_SR # Get status register
+ and v0,M_SR_SR # preserve soft reset
+#ifdef DEBUG_ENV_ICE
+ and v0,~M_SR_BEV
+#else
+ or v0,M_SR_BEV # exceptions to boot vector
+#endif
+ mtc0 v0,C0_SR # set up the status register
+
+
+ mfc0 v0,C0_CONFIG # get current CONFIG register
+ srl v0,v0,3 # strip out K0 bits
+ sll v0,v0,3 # k0 bits now zero
+ or v0,v0,K_CFG_K0COH_CACHEABLE # K0 is cacheable.
+ mtc0 v0,C0_CONFIG
+ nop
+
+ mtc0 zero,C0_WATCHLO # Watch registers.
+ mtc0 zero,C0_WATCHHI
+
+ mtc0 zero,C0_TLBHI # TLB entry (high half)
+ nop
+
+
+ #
+ # This is probably not the right init value for C0_COMPARE,
+ # but it seems to be necessary for the sim model right now.
+ #
+
+ li v0,-1
+ mtc0 v0,C0_COMPARE
+ nop
+
+ #
+ # Initialize all the TLB entries to some invalid value
+ #
+
+ mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */
+ nop
+ mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */
+ nop
+ mtc0 zero,C0_PGMASK /* 4K pages */
+ nop
+
+ li t0,K1BASE /* tlbhi = impossible vpn */
+ li t1,(BCMCORE_NTLBENTRIES-1) /* index */
+
+
+ nop
+1: mtc0 t0,C0_TLBHI
+ nop
+ mtc0 t1,C0_INX
+ nop
+ addu t0,0x2000 /* inc vpn */
+ tlbwi
+ bnez t1,1b
+ subu t1,1 # BDSLOT
+ .set reorder
+
+
+/*
+ * XXX What other CP0 initialization do I need?
+ */
+
+ jr ra
+
+
+END(bcmcore_cp0_init)
+
+
+/* *********************************************************************
+ * BCMCORE_CPUINIT
+ *
+ * Do initialization of the Broadcom core
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+LEAF(bcmcore_cpuinit)
+
+ move fp,ra
+
+ SETLEDS1('C','P','U','I')
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_CP0INIT)
+
+ SETLEDS1('L','1','C','I')
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINIT)
+
+ move ra,fp
+ j ra
+
+END(bcmcore_cpuinit)
+
+
+/* *********************************************************************
+ * BCMCORE_KSEG0_SWITCH
+ *
+ * Return to the address of the routine that called us, except
+ * in K0seg instead of K1seg
+ *
+ * Input parameters:
+ * nothing - ra is return address
+ *
+ * Return value:
+ * ra = same return address in K0
+ ********************************************************************* */
+
+LEAF(bcmcore_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(bcmcore_kseg0_switch)
+
+/* *********************************************************************
+ * BCMCORE_NULL
+ *
+ * Dummy handler for routines we don't need to implement, like
+ * the multiprocessor stuff
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * none
+ ********************************************************************* */
+
+LEAF(bcmcore_null)
+
+ j ra
+
+END(bcmcore_null)
+
+
+/* *********************************************************************
+ * BCMCORE_CPURESTART
+ *
+ * This routine is called when someone soft-exits to CFE. We
+ * reinitialize any CP0 stuff here.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(bcmcore_cpurestart)
+
+ j ra
+
+END(bcmcore_cpurestart)
+
+
+/* *********************************************************************
+ * BCMCORE_CACHEOPS
+ *
+ * Perform various cache operations on a BCM Core
+ *
+ * Input parameters:
+ * a0 - flag bits (CFE_CACHE_xxx)
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2,t3,v1,s0
+ ********************************************************************* */
+
+LEAF(bcmcore_cacheops)
+
+ move s0,ra
+
+ move v1,a0
+
+ /*
+ * With no flags, we flush L1D and invalid L1I
+ */
+
+ bne v1,zero,1f
+ li v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I
+1:
+
+ /*
+ * Flush the D-Cache, since the program we loaded is "data".
+ */
+
+ and a0,v1,CFE_CACHE_FLUSH_D
+ beq a0,zero,1f
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CFLASHD)
+1:
+
+ /*
+ * Invalidate the I-Cache, so that addresses in the program
+ * region will miss and need to be filled from the data we
+ * just flushed above.
+ */
+
+ and a0,v1,CFE_CACHE_INVAL_I
+ beq a0,zero,1f
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINVALI)
+1:
+
+
+ .set push
+ .set mips32
+
+ /*
+ * Invalidate cache range
+ */
+
+ and a0,v1,CFE_CACHE_INVAL_RANGE
+ beq a0,zero,2f
+
+ move t0,a1
+1: cache CACHEOP(L1C_D,CACHE_OP_HITINVAL),0(t0)
+ add t0,LINESIZE
+ blt t0,a2,1b
+
+ /*
+ * Flush cache range
+ */
+
+
+2:
+ and a0,v1,CFE_CACHE_FLUSH_RANGE
+ beq a0,zero,2f
+
+ move t0,a1
+1: cache CACHEOP(L1C_D,CACHE_OP_HITWRITEBACK_INVAL),0(t0)
+ add t0,LINESIZE
+ blt t0,a2,1b
+
+2:
+
+ .set pop
+
+
+ move ra,s0
+ j ra
+
+END(bcmcore_cacheops)
+
+
+
+/* *********************************************************************
+ * BCMCORE_TLBHANDLER
+ *
+ * This is the TLB exception handler for the bcmcore
+ *
+ * Note: only K0 and K1 are available to us at this time.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+LEAF(bcmcore_tlbhandler)
+ .set noreorder
+ .set noat
+
+/*
+ * XXX XXX XXX XXX XXX
+ *
+ * This won't work as-is on the BCMCORE. The CONTEXT register is not
+ * wide enough! In fact, it's broken on all pre-mips4 CPUs.
+ *
+ * XXX XXX XXX XXX XXX
+ */
+
+/*
+ * This requires a bit of explanation: We only support 256KB
+ * of mapped space for the boot program. This space will be
+ * mapped from 0x2000_0000 to 0x2004_0000 to some physical
+ * memory allocated by the firmware. This is 64 pages
+ * of 4KB each.
+ *
+ * We know our BadVPN2 will be in the range
+ * 0x100000 to 0x1001F0, since the memory is mapped from
+ * 0x2000_0000 to 0x2004_0000. BadVPN2 plus the four bits
+ * of zeroes at the end are bits 31..9
+ *
+ * We also want to place the PTEbase on something other than
+ * a 16MB boundary. Each entry is 16 bytes, and there
+ * are 64 entries, so we need only 10 bits to address
+ * the entire table (it can therefore be aligned on a
+ * 1KB boundary).
+ *
+ * To make this work, we'll shift PTEbase to the right, leaving
+ * the bottom ten bits for the page number, as:
+ *
+ * Bits 31..10: PTEbase
+ * Bits 9..4: BadVPN
+ * Bits 3..0: 16 bytes for table entry
+ *
+ * Therefore:
+ * PTEbase gets shifted right 13 bits.
+ * BadVPN gets masked at 6 bits (mask is 0x3F0)
+ * The bottom 4 bits are zero.
+ *
+ * To range check the address, we can shift the Bad VPN
+ * right by 9 bits, and check for values of 0x1000 and
+ * 0x1001.
+ */
+
+
+ /*
+ * This part range checks the VPN2 field in the
+ * context register. We only handle
+ * VPN2s in the range 0x100000 to 0x1001F0
+ */
+ mfc0 k0,C0_TLBHI
+
+ mfc0 k0,C0_CTEXT # Get context
+ sra k0,8 # keep hi part
+ and k0,0x1FFF # of VPN2
+ li k1,0x1000 # 0x1000 is ok
+ beq k0,k1,1f #
+ nop # BDSLOT
+ li k1,0x1001 # 0x1001 is ok
+ beq k0,k1,1f #
+ nop # BDSLOT
+
+ li k0,XTYPE_TLBFILL # all other bits are not
+ b _exc_entry
+ nop # BDSLOT
+
+1: mfc0 k0,C0_CTEXT # Get context
+ sra k0,13 # Shift PTEbase
+ li k1,0x3FF # Generate mask to kill
+ not k1 # BadVPN2 bits
+ and k0,k1 # keep only PTEBase part.
+
+ mfc0 k1,C0_CTEXT # Get Context
+ and k1,0x3F0 # Keep only BadVPN2 bits
+ or k1,k0 # Replace PTEBase
+
+ ld k0,0(k1) # Load entrylo0
+ ld k1,8(k1) # Load entrylo1
+ mtc0 k0,C0_TLBLO0 # and write to CP0
+ mtc0 k1,C0_TLBLO1
+ tlbwr # put it in the TLB
+ ERET
+ nop
+
+ .set reorder
+ .set at
+
+END(bcmcore_tlbhandler)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S
new file mode 100755
index 0000000..fa39bfd
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S
@@ -0,0 +1,219 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * L1C initialization File: bcmcore_l1cache.S
+ *
+ * This module contains code to initialize the CPU's caches
+ *
+ * Note: all the routines in this module rely on registers only,
+ * since DRAM may not be active yet.
+ *
+ * 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 "sbmips.h"
+#include "bsp_config.h"
+
+ .text
+
+ .set push
+ .set mips32
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define CP0_CFG_ISMSK (0x7 << 22)
+#define CP0_CFG_ISSHF 22
+#define CP0_CFG_ILMSK (0x7 << 19)
+#define CP0_CFG_ILSHF 19
+#define CP0_CFG_IAMSK (0x7 << 16)
+#define CP0_CFG_IASHF 16
+#define CP0_CFG_DSMSK (0x7 << 13)
+#define CP0_CFG_DSSHF 13
+#define CP0_CFG_DLMSK (0x7 << 10)
+#define CP0_CFG_DLSHF 10
+#define CP0_CFG_DAMSK (0x7 << 7)
+#define CP0_CFG_DASHF 7
+
+#define cacheop(kva, size, linesize, op) \
+ .set noreorder; \
+ addu t1, kva, size; \
+ subu t2, linesize, 1; \
+ not t2; \
+ and t0, kva, t2; \
+ addu t1, -1; \
+ and t1, t2; \
+10: cache op, 0(t0); \
+ bne t0, t1, 10b; \
+ addu t0, linesize; \
+11: \
+ .set reorder
+
+#define size_icache(size, linesize) \
+ mfc0 t7, C0_CONFIG, 1; \
+ and t0, t7, CP0_CFG_ILMSK; \
+ srl t0, t0, CP0_CFG_ILSHF; \
+ move linesize, zero; \
+ beq t0, zero,1f; \
+ add t0, 1; \
+ li linesize, 1; \
+ sll linesize, t0; \
+1: and t0, t7, CP0_CFG_ISMSK; \
+ srl t0, t0, CP0_CFG_ISSHF; \
+ li size, 64; \
+ sll size, t0; \
+ and t0, t7, CP0_CFG_IAMSK; \
+ srl t0, t0, CP0_CFG_IASHF; \
+ add t0, 1; \
+ mult size, t0; \
+ mflo size; \
+ mult size, linesize; \
+ mflo size
+
+#define size_dcache(size, linesize) \
+ mfc0 t7, C0_CONFIG, 1; \
+ and t0, t7, CP0_CFG_DLMSK; \
+ srl t0, t0, CP0_CFG_DLSHF; \
+ move linesize, zero; \
+ beq t0, zero,1f; \
+ add t0, 1; \
+ li linesize, 1; \
+ sll linesize, t0; \
+1: and t0, t7, CP0_CFG_DSMSK; \
+ srl t0, t0, CP0_CFG_DSSHF; \
+ li size, 64; \
+ sll size, t0; \
+ and t0, t7, CP0_CFG_DAMSK; \
+ srl t0, t0, CP0_CFG_DASHF; \
+ add t0, 1; \
+ mult size, t0; \
+ mflo size; \
+ mult size, linesize; \
+ mflo size
+
+
+/* *********************************************************************
+ * BCMCORE_L1CACHE_INIT()
+ *
+ * Initialize the L1 Cache
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2
+ ********************************************************************* */
+
+LEAF(bcmcore_l1cache_init)
+
+ mtc0 zero, C0_TAGLO # Initialize TAGLO register
+ mtc0 zero, C0_TAGLO,1 # Initialize DataLo register
+
+ li a0, K0BASE # Initialise primary instruction cache.
+ size_icache(a1, a2)
+ cacheop(a0, a1, a2, Index_Store_Tag_I)
+
+ li a0, K0BASE # Initialise primary data cache.
+ size_dcache(a1, a2)
+ cacheop(a0, a1, a2, Index_Store_Tag_D)
+
+ jr ra
+
+END(bcmcore_l1cache_init)
+
+/* *********************************************************************
+ * BCMCORE_L1CACHE_INVAL_I()
+ *
+ * Invalidate the entire ICache
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2
+ ********************************************************************* */
+LEAF(bcmcore_l1cache_inval_i)
+
+ li a0, K0BASE
+ size_icache(a1, a2)
+ cacheop(a0, a1, a2, Index_Invalidate_I)
+
+ j ra
+
+END(bcmcore_l1cache_inval_i)
+
+/* *********************************************************************
+ * BCMCORE_L1CACHE_FLUSH_D()
+ *
+ * Flush the entire DCache
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2
+ ********************************************************************* */
+LEAF(bcmcore_l1cache_flush_d)
+
+ li a0, K0BASE
+ size_dcache(a1, a2)
+
+# before flushing cache clear tags pointing to flash memory to avoid writes into flash
+ addu t1, a0, a1
+ subu t2, a2, 1
+ not t2
+ and t0, a0, t2
+ addu t1, -1
+ and t1, t2
+1:
+ cache Index_Load_Tag_D, 0(t0)
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ mfc0 t2, C0_TAGLO # Read TAGLO register
+ and t2, 0x1f000000 # check address
+ li t3, 0x1f000000
+ bne t2, t3, 2f
+ mtc0 zero, C0_TAGLO
+ cache Index_Store_Tag_D, 0(t0) # Reset tag for flash memory locations
+2:
+ .set noreorder;
+ bne t0, t1, 1b
+ addu t0, a2
+ .set reorder
+
+ cacheop(a0, a1, a2, Index_Writeback_Inv_D)
+
+ j ra
+
+END(bcmcore_l1cache_flush_d)
+
+ .set pop
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+