summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/board/bcm63xx_rom
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_rom')
-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
7 files changed, 4878 insertions, 0 deletions
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)
+
+
+
+