/*
- * Copyright 2004, 2007 Freescale Semiconductor.
+ * Copyright 2004, 2007-2010 Freescale Semiconductor, Inc.
* Copyright (C) 2003 Motorola,Inc.
*
* See file CREDITS for list of people who contributed to this
#include <config.h>
#include <mpc85xx.h>
+#include <timestamp.h>
#include <version.h>
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
/*
* Set up GOT: Global Offset Table
*
- * Use r14 to access the GOT
+ * Use r12 to access the GOT
*/
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
+#ifndef CONFIG_NAND_SPL
GOT_ENTRY(_start)
GOT_ENTRY(_start_of_vectors)
GOT_ENTRY(_end_of_vectors)
GOT_ENTRY(transfer_to_handler)
+#endif
GOT_ENTRY(__init_end)
GOT_ENTRY(_end)
/* L1 */
li r0,2
mtspr L1CSR0,r0 /* invalidate d-cache */
- mtspr L1CSR1,r0 /* invalidate i-cache */
+ mtspr L1CSR1,r0 /* invalidate i-cache */
mfspr r1,DBSR
mtspr DBSR,r1 /* Clear all valid bits */
*
*/
- lis r2,L1CSR0_CPE@H /* enable parity */
- ori r2,r2,L1CSR0_DCE
- mtspr L1CSR0,r2 /* enable L1 Dcache */
+#if defined(CONFIG_E500MC) && defined(CONFIG_SYS_CACHE_STASHING)
+ /* set stash id to (coreID) * 2 + 32 + L1 CT (0) */
+ li r2,(32 + 0)
+ mtspr L1CSR2,r2
+#endif
+
+ /* Enable/invalidate the I-Cache */
+ lis r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@h
+ ori r2,r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@l
+ mtspr SPRN_L1CSR1,r2
+1:
+ mfspr r3,SPRN_L1CSR1
+ and. r1,r3,r2
+ bne 1b
+
+ lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h
+ ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l
+ mtspr SPRN_L1CSR1,r3
isync
- mtspr L1CSR1,r2 /* enable L1 Icache */
+2:
+ mfspr r3,SPRN_L1CSR1
+ andi. r1,r3,L1CSR1_ICE@l
+ beq 2b
+
+ /* Enable/invalidate the D-Cache */
+ lis r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@h
+ ori r2,r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@l
+ mtspr SPRN_L1CSR0,r2
+1:
+ mfspr r3,SPRN_L1CSR0
+ and. r1,r3,r2
+ bne 1b
+
+ lis r3,(L1CSR0_CPE|L1CSR0_DCE)@h
+ ori r3,r3,(L1CSR0_CPE|L1CSR0_DCE)@l
+ mtspr SPRN_L1CSR0,r3
isync
- msync
+2:
+ mfspr r3,SPRN_L1CSR0
+ andi. r1,r3,L1CSR0_DCE@l
+ beq 2b
/* Setup interrupt vectors */
lis r1,TEXT_BASE@h
mtspr MCSR,r0 /* machine check syndrome register */
mtxer r0 /* clear integer exception register */
+#ifdef CONFIG_SYS_BOOK3E_HV
+ mtspr MAS8,r0 /* make sure MAS8 is clear */
+#endif
+
/* Enable Time Base and Select Time Base Clock */
lis r0,HID0_EMCP@h /* Enable machine check */
#if defined(CONFIG_ENABLE_36BIT_PHYS)
ori r0,r0,HID0_ENMAS7@l /* Enable MAS7 */
#endif
+#ifndef CONFIG_E500MC
ori r0,r0,HID0_TBEN@l /* Enable Timebase */
+#endif
mtspr HID0,r0
+#ifndef CONFIG_E500MC
li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */
+ mfspr r3,PVR
+ andi. r3,r3, 0xff
+ cmpwi r3,0x50@l /* if we are rev 5.0 or greater set MBDD */
+ blt 1f
+ /* Set MBDD bit also */
+ ori r0, r0, HID1_MBDD@l
+1:
mtspr HID1,r0
+#endif
/* Enable Branch Prediction */
#if defined(CONFIG_BTB)
- li r0,0x201 /* BBFI = 1, BPEN = 1 */
- mtspr BUCSR,r0
+ lis r0,BUCSR_ENABLE@h
+ ori r0,r0,BUCSR_ENABLE@l
+ mtspr SPRN_BUCSR,r0
#endif
-#if defined(CFG_INIT_DBCR)
+#if defined(CONFIG_SYS_INIT_DBCR)
lis r1,0xffff
ori r1,r1,0xffff
mtspr DBSR,r1 /* Clear all status bits */
- lis r0,CFG_INIT_DBCR@h /* DBCR0[IDM] must be set */
- ori r0,r0,CFG_INIT_DBCR@l
+ lis r0,CONFIG_SYS_INIT_DBCR@h /* DBCR0[IDM] must be set */
+ ori r0,r0,CONFIG_SYS_INIT_DBCR@l
mtspr DBCR0,r0
#endif
- /* create a temp mapping in AS=1 to the boot window */
+#ifdef CONFIG_MPC8569
+#define CONFIG_SYS_LBC_ADDR (CONFIG_SYS_CCSRBAR_DEFAULT + 0x5000)
+#define CONFIG_SYS_LBCR_ADDR (CONFIG_SYS_LBC_ADDR + 0xd0)
+
+ /* MPC8569 Rev.0 silcon needs to set bit 13 of LBCR to allow elBC to
+ * use address space which is more than 12bits, and it must be done in
+ * the 4K boot page. So we set this bit here.
+ */
+
+ /* create a temp mapping TLB0[0] for LBCR */
+ lis r6,FSL_BOOKE_MAS0(0, 0, 0)@h
+ ori r6,r6,FSL_BOOKE_MAS0(0, 0, 0)@l
+
+ lis r7,FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h
+ ori r7,r7,FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@l
+
+ lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G)@h
+ ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G)@l
+
+ lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_LBC_ADDR, 0,
+ (MAS3_SX|MAS3_SW|MAS3_SR))@h
+ ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_LBC_ADDR, 0,
+ (MAS3_SX|MAS3_SW|MAS3_SR))@l
+
+ mtspr MAS0,r6
+ mtspr MAS1,r7
+ mtspr MAS2,r8
+ mtspr MAS3,r9
+ isync
+ msync
+ tlbwe
+
+ /* Set LBCR register */
+ lis r4,CONFIG_SYS_LBCR_ADDR@h
+ ori r4,r4,CONFIG_SYS_LBCR_ADDR@l
+
+ lis r5,CONFIG_SYS_LBC_LBCR@h
+ ori r5,r5,CONFIG_SYS_LBC_LBCR@l
+ stw r5,0(r4)
+ isync
+
+ /* invalidate this temp TLB */
+ lis r4,CONFIG_SYS_LBC_ADDR@h
+ ori r4,r4,CONFIG_SYS_LBC_ADDR@l
+ tlbivax 0,r4
+ isync
+
+#endif /* CONFIG_MPC8569 */
+
lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h
ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
- lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@h
- ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@l
+#ifndef CONFIG_SYS_RAMBOOT
+ /* create a temp mapping in AS=1 to the 4M boot window */
+ lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h
+ ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l
+
+ lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@h
+ ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@l
+
+ /* The 85xx has the default boot window 0xff800000 - 0xffffffff */
+ lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
+ ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
+#else
+ /*
+ * create a temp mapping in AS=1 to the 1M TEXT_BASE space, the main
+ * image has been relocated to TEXT_BASE on the second stage.
+ */
+ lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h
+ ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l
lis r8,FSL_BOOKE_MAS2(TEXT_BASE, (MAS2_I|MAS2_G))@h
ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE, (MAS2_I|MAS2_G))@l
- lis r9,FSL_BOOKE_MAS3(0xff800000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
- ori r9,r9,FSL_BOOKE_MAS3(0xff800000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
+ lis r9,FSL_BOOKE_MAS3(TEXT_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
+ ori r9,r9,FSL_BOOKE_MAS3(TEXT_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
+#endif
mtspr MAS0,r6
mtspr MAS1,r7
lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h
ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l
- lis r8,FSL_BOOKE_MAS2(CFG_INIT_RAM_ADDR, 0)@h
- ori r8,r8,FSL_BOOKE_MAS2(CFG_INIT_RAM_ADDR, 0)@l
+ lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h
+ ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l
- lis r9,FSL_BOOKE_MAS3(CFG_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
- ori r9,r9,FSL_BOOKE_MAS3(CFG_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
+ lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
+ ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
mtspr MAS0,r6
mtspr MAS1,r7
msync
tlbwe
- lis r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@h
- ori r6,r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@l
+ lis r6,MSR_IS|MSR_DS@h
+ ori r6,r6,MSR_IS|MSR_DS@l
lis r7,switch_as@h
ori r7,r7,switch_as@l
/* Allocate Initial RAM in data cache.
*/
- lis r3,CFG_INIT_RAM_ADDR@h
- ori r3,r3,CFG_INIT_RAM_ADDR@l
+ lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
+ ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
mfspr r2, L1CFG0
andi. r2, r2, 0x1ff
/* cache size * 1024 / (2 * L1 line size) */
1:
dcbz r0,r3
dcbtls 0,r0,r3
- addi r3,r3,CFG_CACHELINE_SIZE
+ addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
bdnz 1b
/* Jump out the last 4K page and continue to 'normal' start */
-#ifdef CFG_RAMBOOT
+#ifdef CONFIG_SYS_RAMBOOT
b _start_cont
#else
/* Calculate absolute address in FLASH and jump there */
/*--------------------------------------------------------------*/
- lis r3,CFG_MONITOR_BASE@h
- ori r3,r3,CFG_MONITOR_BASE@l
+ lis r3,CONFIG_SYS_MONITOR_BASE@h
+ ori r3,r3,CONFIG_SYS_MONITOR_BASE@l
addi r3,r3,_start_cont - _start + _START_OFFSET
mtlr r3
blr
.globl version_string
version_string:
.ascii U_BOOT_VERSION
- .ascii " (", __DATE__, " - ", __TIME__, ")"
+ .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
.ascii CONFIG_IDENT_STRING, "\0"
.align 4
.globl _start_cont
_start_cont:
/* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
- lis r1,CFG_INIT_RAM_ADDR@h
- ori r1,r1,CFG_INIT_SP_OFFSET@l
+ lis r1,CONFIG_SYS_INIT_RAM_ADDR@h
+ ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l
li r0,0
stwu r0,-4(r1)
bl board_init_f
isync
+#ifndef CONFIG_NAND_SPL
. = EXC_OFF_SYS_RESET
.globl _start_of_vectors
_start_of_vectors:
mfspr r5,DSISR
stw r5,_DSISR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
- li r20,MSR_KERNEL
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
- lwz r6,GOT(transfer_to_handler)
- mtlr r6
- blrl
-.L_Alignment:
- .long AlignmentException - _start + _START_OFFSET
- .long int_return - _start + _START_OFFSET
+ EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
/* Program check exception */
. = 0x0700
ProgramCheck:
EXCEPTION_PROLOG(SRR0, SRR1)
addi r3,r1,STACK_FRAME_OVERHEAD
- li r20,MSR_KERNEL
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
- lwz r6,GOT(transfer_to_handler)
- mtlr r6
- blrl
-.L_ProgramCheck:
- .long ProgramCheckException - _start + _START_OFFSET
- .long int_return - _start + _START_OFFSET
+ EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
+ MSR_KERNEL, COPY_EE)
/* No FPU on MPC85xx. This exception is not supposed to happen.
*/
/* Cache functions.
*/
+.globl invalidate_icache
invalidate_icache:
mfspr r0,L1CSR1
ori r0,r0,L1CSR1_ICFI
isync
blr /* entire I cache */
+.globl invalidate_dcache
invalidate_dcache:
mfspr r0,L1CSR0
ori r0,r0,L1CSR0_DCFI
in32r:
lwbrx r3,r0,r3
blr
+#endif /* !CONFIG_NAND_SPL */
/*------------------------------------------------------------------------------*/
/*
+ * void write_tlb(mas0, mas1, mas2, mas3, mas7)
+ */
+ .globl write_tlb
+write_tlb:
+ mtspr MAS0,r3
+ mtspr MAS1,r4
+ mtspr MAS2,r5
+ mtspr MAS3,r6
+#ifdef CONFIG_ENABLE_36BIT_PHYS
+ mtspr MAS7,r7
+#endif
+ li r3,0
+#ifdef CONFIG_SYS_BOOK3E_HV
+ mtspr MAS8,r3
+#endif
+ isync
+ tlbwe
+ msync
+ isync
+ blr
+
+/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
mr r9,r4 /* Save copy of Init Data pointer */
mr r10,r5 /* Save copy of Destination Address */
+ GET_GOT
mr r3,r5 /* Destination Address */
- lis r4,CFG_MONITOR_BASE@h /* Source Address */
- ori r4,r4,CFG_MONITOR_BASE@l
+ lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */
+ ori r4,r4,CONFIG_SYS_MONITOR_BASE@l
lwz r5,GOT(__init_end)
sub r5,r5,r4
- li r6,CFG_CACHELINE_SIZE /* Cache Line Size */
+ li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
/*
* Fix GOT pointer:
*
- * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+ * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
*
* Offset:
*/
sub r15,r10,r4
/* First our own GOT */
- add r14,r14,r15
+ add r12,r12,r15
/* the the one used by the C code */
add r30,r30,r15
in_ram:
/*
- * Relocation Function, r14 point to got2+0x8000
+ * Relocation Function, r12 point to got2+0x8000
*
* Adjust got2 pointers, no need to check for 0, this code
* already puts a few entries in the table.
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
+ cmpwi r0,0
+ beq- 2f
add r0,r0,r11
stw r0,0(r3)
- bdnz 1b
+2: bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
-2: li r0,__fixup_entries@sectoff@l
+ li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
mr r4,r10 /* Destination Address */
bl board_init_r
+#ifndef CONFIG_NAND_SPL
/*
* Copy exception vector code to low memory
*
*/
.globl trap_init
trap_init:
+ mflr r4 /* save link register */
+ GET_GOT
lwz r7,GOT(_start_of_vectors)
lwz r8,GOT(_end_of_vectors)
cmplw 0,r7,r8
bgelr /* return if r7>=r8 - just in case */
-
- mflr r4 /* save link register */
1:
lwz r0,0(r7)
stw r0,0(r9)
mtlr r4 /* restore link register */
blr
- /*
- * Function: relocate entries for one exception vector
- */
-trap_reloc:
- lwz r0,0(r7) /* hdlr ... */
- add r0,r0,r3 /* ... += dest_addr */
- stw r0,0(r7)
-
- lwz r0,4(r7) /* int_return ... */
- add r0,r0,r3 /* ... += dest_addr */
- stw r0,4(r7)
-
- blr
-
.globl unlock_ram_in_cache
unlock_ram_in_cache:
/* invalidate the INIT_RAM section */
- lis r3,(CFG_INIT_RAM_ADDR & ~31)@h
- ori r3,r3,(CFG_INIT_RAM_ADDR & ~31)@l
+ lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h
+ ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l
mfspr r4,L1CFG0
andi. r4,r4,0x1ff
slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT)
mtctr r4
1: dcbi r0,r3
- addi r3,r3,CFG_CACHELINE_SIZE
+ addi r3,r3,CONFIG_SYS_CACHELINE_SIZE
bdnz 1b
sync
/* Invalidate the TLB entries for the cache */
- lis r3,CFG_INIT_RAM_ADDR@h
- ori r3,r3,CFG_INIT_RAM_ADDR@l
+ lis r3,CONFIG_SYS_INIT_RAM_ADDR@h
+ ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
tlbivax 0,r3
addi r3,r3,0x1000
tlbivax 0,r3
tlbivax 0,r3
isync
blr
+
+.globl flush_dcache
+flush_dcache:
+ mfspr r3,SPRN_L1CFG0
+
+ rlwinm r5,r3,9,3 /* Extract cache block size */
+ twlgti r5,1 /* Only 32 and 64 byte cache blocks
+ * are currently defined.
+ */
+ li r4,32
+ subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -
+ * log2(number of ways)
+ */
+ slw r5,r4,r5 /* r5 = cache block size */
+
+ rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */
+ mulli r7,r7,13 /* An 8-way cache will require 13
+ * loads per set.
+ */
+ slw r7,r7,r6
+
+ /* save off HID0 and set DCFA */
+ mfspr r8,SPRN_HID0
+ ori r9,r8,HID0_DCFA@l
+ mtspr SPRN_HID0,r9
+ isync
+
+ lis r4,0
+ mtctr r7
+
+1: lwz r3,0(r4) /* Load... */
+ add r4,r4,r5
+ bdnz 1b
+
+ msync
+ lis r4,0
+ mtctr r7
+
+1: dcbf 0,r4 /* ...and flush. */
+ add r4,r4,r5
+ bdnz 1b
+
+ /* restore HID0 */
+ mtspr SPRN_HID0,r8
+ isync
+
+ blr
+
+.globl setup_ivors
+setup_ivors:
+
+#include "fixed_ivor.S"
+ blr
+#endif /* !CONFIG_NAND_SPL */