]> git.sur5r.net Git - u-boot/blobdiff - cpu/mpc83xx/start.S
powerpc: Fix bootm to boot up again with a Ramdisk
[u-boot] / cpu / mpc83xx / start.S
index 309eb30e8e97b423218d5f5f761461c5fedf1e3b..14bfbdade8f7b1a9ddbf9b10e4674b2467b94ec3 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1998  Dan Malek <dmalek@jlc.net>
  * Copyright (C) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
  * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de>
- * Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved.
+ * Copyright Freescale Semiconductor, Inc. 2004, 2006, 2008.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
 #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
 #endif
 
+#if !defined(CONFIG_NAND_SPL) && !defined(CFG_RAMBOOT)
+#define CFG_FLASHBOOT
+#endif
+
 /*
  * Set up GOT: Global Offset Table
  *
  */
        START_GOT
        GOT_ENTRY(_GOT2_TABLE_)
-       GOT_ENTRY(_FIXUP_TABLE_)
+       GOT_ENTRY(__bss_start)
+       GOT_ENTRY(_end)
 
+#ifndef CONFIG_NAND_SPL
+       GOT_ENTRY(_FIXUP_TABLE_)
        GOT_ENTRY(_start)
        GOT_ENTRY(_start_of_vectors)
        GOT_ENTRY(_end_of_vectors)
        GOT_ENTRY(transfer_to_handler)
-
-       GOT_ENTRY(__init_end)
-       GOT_ENTRY(_end)
-       GOT_ENTRY(__bss_start)
+#endif
        END_GOT
 
 /*
@@ -165,7 +169,7 @@ boot_warm: /* time t 5 */
 
        bl      init_e300_core
 
-#ifndef CFG_RAMBOOT
+#ifdef CFG_FLASHBOOT
 
        /* Inflate flash location so it appears everywhere, calculate */
        /* the absolute address in final location of the FLASH, jump  */
@@ -181,7 +185,7 @@ in_flash:
 #if 1 /* Remapping flash with LAW0. */
        bl remap_flash_by_law0
 #endif
-#endif /* CFG_RAMBOOT */
+#endif /* CFG_FLASHBOOT */
 
        /* setup the bats */
        bl      setup_bats
@@ -204,7 +208,7 @@ in_flash:
        bl      enable_addr_trans
        sync
 
-       /* enable and invalidate the data cache */
+       /* enable the data cache */
        bl      dcache_enable
        sync
 #ifdef CFG_INIT_RAM_LOCK
@@ -239,6 +243,7 @@ in_flash:
        /* run 1st part of board init code (in Flash)*/
        bl      board_init_f
 
+#ifndef CONFIG_NAND_SPL
 /*
  * Vector Table
  */
@@ -428,6 +433,7 @@ int_return:
        lwz     r1,GPR1(r1)
        SYNC
        rfi
+#endif /* !CONFIG_NAND_SPL */
 
 /*
  * This code initialises the E300 processor core
@@ -477,17 +483,29 @@ init_e300_core: /* time t 10 */
 1:
 #endif /* CONFIG_WATCHDOG */
 
+#if defined(CONFIG_MASK_AER_AO)
+       /* Write the Arbiter Event Enable to mask Address Only traps. */
+       /* This prevents the dcbz instruction from being trapped when */
+       /* HID0_ABE Address Broadcast Enable is set and the MEMORY    */
+       /* COHERENCY bit is set in the WIMG bits, which is often      */
+       /* needed for PCI operation.                                  */
+       lwz     r4, 0x0808(r3)
+       rlwinm  r0, r4, 0, ~AER_AO
+       stw     r0, 0x0808(r3)
+#endif /* CONFIG_MASK_AER_AO */
+
        /* Initialize the Hardware Implementation-dependent Registers */
        /* HID0 also contains cache control                     */
+       /* - force invalidation of data and instruction caches  */
        /*------------------------------------------------------*/
 
        lis     r3, CFG_HID0_INIT@h
-       ori     r3, r3, CFG_HID0_INIT@l
+       ori     r3, r3, (CFG_HID0_INIT | HID0_ICFI | HID0_DCFI)@l
        SYNC
        mtspr   HID0, r3
 
        lis     r3, CFG_HID0_FINAL@h
-       ori     r3, r3, CFG_HID0_FINAL@l
+       ori     r3, r3, (CFG_HID0_FINAL & ~(HID0_ICFI | HID0_DCFI))@l
        SYNC
        mtspr   HID0, r3
 
@@ -496,88 +514,10 @@ init_e300_core: /* time t 10 */
        SYNC
        mtspr   HID2, r3
 
-       /* clear all BAT's                                      */
-       /*----------------------------------*/
-
-       xor     r0, r0, r0
-       mtspr   DBAT0U, r0
-       mtspr   DBAT0L, r0
-       mtspr   DBAT1U, r0
-       mtspr   DBAT1L, r0
-       mtspr   DBAT2U, r0
-       mtspr   DBAT2L, r0
-       mtspr   DBAT3U, r0
-       mtspr   DBAT3L, r0
-       mtspr   IBAT0U, r0
-       mtspr   IBAT0L, r0
-       mtspr   IBAT1U, r0
-       mtspr   IBAT1L, r0
-       mtspr   IBAT2U, r0
-       mtspr   IBAT2L, r0
-       mtspr   IBAT3U, r0
-       mtspr   IBAT3L, r0
-       SYNC
-
-       /* invalidate all tlb's
-        *
-        * From the 603e User Manual: "The 603e provides the ability to
-        * invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
-        * instruction invalidates the TLB entry indexed by the EA, and
-        * operates on both the instruction and data TLBs simultaneously
-        * invalidating four TLB entries (both sets in each TLB). The
-        * index corresponds to bits 15-19 of the EA. To invalidate all
-        * entries within both TLBs, 32 tlbie instructions should be
-        * issued, incrementing this field by one each time."
-        *
-        * "Note that the tlbia instruction is not implemented on the
-        * 603e."
-        *
-        * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
-        * incrementing by 0x1000 each time. The code below is sort of
-        * based on code in "flush_tlbs" from arch/ppc/kernel/head.S
-        *
-        */
-
-       li      r3, 32
-       mtctr   r3
-       li      r3, 0
-1:     tlbie   r3
-       addi    r3, r3, 0x1000
-       bdnz    1b
-       SYNC
-
        /* Done!                                                */
        /*------------------------------*/
        blr
 
-       .globl  invalidate_bats
-invalidate_bats:
-       /* invalidate BATs */
-       mtspr   IBAT0U, r0
-       mtspr   IBAT1U, r0
-       mtspr   IBAT2U, r0
-       mtspr   IBAT3U, r0
-#if (CFG_HID2 & HID2_HBE)
-       mtspr   IBAT4U, r0
-       mtspr   IBAT5U, r0
-       mtspr   IBAT6U, r0
-       mtspr   IBAT7U, r0
-#endif
-       isync
-       mtspr   DBAT0U, r0
-       mtspr   DBAT1U, r0
-       mtspr   DBAT2U, r0
-       mtspr   DBAT3U, r0
-#if (CFG_HID2 & HID2_HBE)
-       mtspr   DBAT4U, r0
-       mtspr   DBAT5U, r0
-       mtspr   DBAT6U, r0
-       mtspr   DBAT7U, r0
-#endif
-       isync
-       sync
-       blr
-
        /* setup_bats - set them up to some initial state */
        .globl  setup_bats
 setup_bats:
@@ -590,7 +530,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT0U@l
        mtspr   IBAT0L, r4
        mtspr   IBAT0U, r3
-       isync
 
        /* DBAT 0 */
        addis   r4, r0, CFG_DBAT0L@h
@@ -599,7 +538,6 @@ setup_bats:
        ori     r3, r3, CFG_DBAT0U@l
        mtspr   DBAT0L, r4
        mtspr   DBAT0U, r3
-       isync
 
        /* IBAT 1 */
        addis   r4, r0, CFG_IBAT1L@h
@@ -608,7 +546,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT1U@l
        mtspr   IBAT1L, r4
        mtspr   IBAT1U, r3
-       isync
 
        /* DBAT 1 */
        addis   r4, r0, CFG_DBAT1L@h
@@ -617,7 +554,6 @@ setup_bats:
        ori     r3, r3, CFG_DBAT1U@l
        mtspr   DBAT1L, r4
        mtspr   DBAT1U, r3
-       isync
 
        /* IBAT 2 */
        addis   r4, r0, CFG_IBAT2L@h
@@ -626,7 +562,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT2U@l
        mtspr   IBAT2L, r4
        mtspr   IBAT2U, r3
-       isync
 
        /* DBAT 2 */
        addis   r4, r0, CFG_DBAT2L@h
@@ -635,7 +570,6 @@ setup_bats:
        ori     r3, r3, CFG_DBAT2U@l
        mtspr   DBAT2L, r4
        mtspr   DBAT2U, r3
-       isync
 
        /* IBAT 3 */
        addis   r4, r0, CFG_IBAT3L@h
@@ -644,7 +578,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT3U@l
        mtspr   IBAT3L, r4
        mtspr   IBAT3U, r3
-       isync
 
        /* DBAT 3 */
        addis   r4, r0, CFG_DBAT3L@h
@@ -653,9 +586,8 @@ setup_bats:
        ori     r3, r3, CFG_DBAT3U@l
        mtspr   DBAT3L, r4
        mtspr   DBAT3U, r3
-       isync
 
-#if (CFG_HID2 & HID2_HBE)
+#ifdef CONFIG_HIGH_BATS
        /* IBAT 4 */
        addis   r4, r0, CFG_IBAT4L@h
        ori     r4, r4, CFG_IBAT4L@l
@@ -663,7 +595,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT4U@l
        mtspr   IBAT4L, r4
        mtspr   IBAT4U, r3
-       isync
 
        /* DBAT 4 */
        addis   r4, r0, CFG_DBAT4L@h
@@ -672,7 +603,6 @@ setup_bats:
        ori     r3, r3, CFG_DBAT4U@l
        mtspr   DBAT4L, r4
        mtspr   DBAT4U, r3
-       isync
 
        /* IBAT 5 */
        addis   r4, r0, CFG_IBAT5L@h
@@ -681,7 +611,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT5U@l
        mtspr   IBAT5L, r4
        mtspr   IBAT5U, r3
-       isync
 
        /* DBAT 5 */
        addis   r4, r0, CFG_DBAT5L@h
@@ -690,7 +619,6 @@ setup_bats:
        ori     r3, r3, CFG_DBAT5U@l
        mtspr   DBAT5L, r4
        mtspr   DBAT5U, r3
-       isync
 
        /* IBAT 6 */
        addis   r4, r0, CFG_IBAT6L@h
@@ -699,7 +627,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT6U@l
        mtspr   IBAT6L, r4
        mtspr   IBAT6U, r3
-       isync
 
        /* DBAT 6 */
        addis   r4, r0, CFG_DBAT6L@h
@@ -708,7 +635,6 @@ setup_bats:
        ori     r3, r3, CFG_DBAT6U@l
        mtspr   DBAT6L, r4
        mtspr   DBAT6U, r3
-       isync
 
        /* IBAT 7 */
        addis   r4, r0, CFG_IBAT7L@h
@@ -717,7 +643,6 @@ setup_bats:
        ori     r3, r3, CFG_IBAT7U@l
        mtspr   IBAT7L, r4
        mtspr   IBAT7U, r3
-       isync
 
        /* DBAT 7 */
        addis   r4, r0, CFG_DBAT7L@h
@@ -726,12 +651,28 @@ setup_bats:
        ori     r3, r3, CFG_DBAT7U@l
        mtspr   DBAT7L, r4
        mtspr   DBAT7U, r3
-       isync
 #endif
 
-       /* Invalidate TLBs.
-        * -> for (val = 0; val < 0x20000; val+=0x1000)
-        * ->   tlbie(val);
+       isync
+
+       /* invalidate all tlb's
+        *
+        * From the 603e User Manual: "The 603e provides the ability to
+        * invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
+        * instruction invalidates the TLB entry indexed by the EA, and
+        * operates on both the instruction and data TLBs simultaneously
+        * invalidating four TLB entries (both sets in each TLB). The
+        * index corresponds to bits 15-19 of the EA. To invalidate all
+        * entries within both TLBs, 32 tlbie instructions should be
+        * issued, incrementing this field by one each time."
+        *
+        * "Note that the tlbia instruction is not implemented on the
+        * 603e."
+        *
+        * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
+        * incrementing by 0x1000 each time. The code below is sort of
+        * based on code in "flush_tlbs" from arch/ppc/kernel/head.S
+        *
         */
        lis     r3, 0
        lis     r5, 2
@@ -774,8 +715,7 @@ disable_addr_trans:
 icache_enable:
        mfspr   r3, HID0
        ori     r3, r3, HID0_ICE
-       lis     r4, 0
-       ori     r4, r4, HID0_ILOCK
+       li      r4, HID0_ICFI|HID0_ILOCK
        andc    r3, r3, r4
        ori     r4, r3, HID0_ICFI
        isync
@@ -788,13 +728,10 @@ icache_enable:
 icache_disable:
        mfspr   r3, HID0
        lis     r4, 0
-       ori     r4, r4, HID0_ICE|HID0_ILOCK
+       ori     r4, r4, HID0_ICE|HID0_ICFI|HID0_ILOCK
        andc    r3, r3, r4
-       ori     r4, r3, HID0_ICFI
-       isync
-       mtspr   HID0, r4     /* sets invalidate, clears enable and lock*/
        isync
-       mtspr   HID0, r3        /* clears invalidate */
+       mtspr   HID0, r3        /* clears invalidate, enable and lock */
        blr
 
        .globl  icache_status
@@ -808,25 +745,24 @@ dcache_enable:
        mfspr   r3, HID0
        li      r5, HID0_DCFI|HID0_DLOCK
        andc    r3, r3, r5
-       mtspr   HID0, r3                /* no invalidate, unlock */
        ori     r3, r3, HID0_DCE
-       ori     r5, r3, HID0_DCFI
-       mtspr   HID0, r5                /* enable + invalidate */
-       mtspr   HID0, r3                /* enable */
        sync
+       mtspr   HID0, r3                /* enable, no invalidate */
        blr
 
        .globl  dcache_disable
 dcache_disable:
+       mflr    r4
+       bl      flush_dcache            /* uses r3 and r5 */
        mfspr   r3, HID0
-       lis     r4, 0
-       ori     r4, r4, HID0_DCE|HID0_DLOCK
-       andc    r3, r3, r4
-       ori     r4, r3, HID0_DCI
+       li      r5, HID0_DCE|HID0_DLOCK
+       andc    r3, r3, r5
+       ori     r5, r3, HID0_DCFI
        sync
-       mtspr   HID0, r4        /* sets invalidate, clears enable and lock */
+       mtspr   HID0, r5        /* sets invalidate, clears enable and lock */
        sync
        mtspr   HID0, r3        /* clears invalidate */
+       mtlr    r4
        blr
 
        .globl  dcache_status
@@ -835,6 +771,18 @@ dcache_status:
        rlwinm  r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31
        blr
 
+       .globl  flush_dcache
+flush_dcache:
+       lis     r3, 0
+       lis     r5, CFG_CACHELINE_SIZE
+1:     cmp     0, 1, r3, r5
+       bge     2f
+       lwz     r5, 0(r3)
+       lis     r5, CFG_CACHELINE_SIZE
+       addi    r3, r3, 0x4
+       b       1b
+2:     blr
+
        .globl get_pvr
 get_pvr:
        mfspr   r3, PVR
@@ -874,7 +822,7 @@ relocate_code:
        mr      r3,  r5                         /* Destination Address */
        lis     r4, CFG_MONITOR_BASE@h          /* Source      Address */
        ori     r4, r4, CFG_MONITOR_BASE@l
-       lwz     r5, GOT(__init_end)
+       lwz     r5, GOT(__bss_start)
        sub     r5, r5, r4
        li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size */
 
@@ -987,6 +935,7 @@ in_ram:
        stw     r0,0(r3)
        bdnz    1b
 
+#ifndef CONFIG_NAND_SPL
        /*
         * Now adjust the fixups and the pointers to the fixups
         * in case we need to move ourselves again.
@@ -1004,6 +953,8 @@ in_ram:
        stw     r0,0(r4)
        bdnz    3b
 4:
+#endif
+
 clear_bss:
        /*
         * Now clear BSS segment
@@ -1037,6 +988,7 @@ clear_bss:
        mr      r4, r10         /* Destination Address          */
        bl      board_init_r
 
+#ifndef CONFIG_NAND_SPL
        /*
         * Copy exception vector code to low memory
         *
@@ -1119,6 +1071,7 @@ trap_reloc:
        stw     r0, 4(r7)
 
        blr
+#endif /* !CONFIG_NAND_SPL */
 
 #ifdef CFG_INIT_RAM_LOCK
 lock_ram_in_cache:
@@ -1126,9 +1079,9 @@ lock_ram_in_cache:
         */
        lis     r3, (CFG_INIT_RAM_ADDR & ~31)@h
        ori     r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
-       li      r2, ((CFG_INIT_RAM_END & ~31) + \
+       li      r4, ((CFG_INIT_RAM_END & ~31) + \
                     (CFG_INIT_RAM_ADDR & 31) + 31) / 32
-       mtctr   r2
+       mtctr   r4
 1:
        dcbz    r0, r3
        addi    r3, r3, 32
@@ -1136,19 +1089,21 @@ lock_ram_in_cache:
 
        /* Lock the data cache */
        mfspr   r0, HID0
-       ori     r0, r0, 0x1000
+       ori     r0, r0, HID0_DLOCK
        sync
        mtspr   HID0, r0
        sync
        blr
 
+#ifndef CONFIG_NAND_SPL
 .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
-       li      r2,512
-       mtctr   r2
+       li      r4, ((CFG_INIT_RAM_END & ~31) + \
+                    (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+       mtctr   r4
 1:     icbi    r0, r3
        dcbi    r0, r3
        addi    r3, r3, 32
@@ -1161,12 +1116,15 @@ unlock_ram_in_cache:
        li      r5, HID0_DLOCK|HID0_DCFI
        andc    r3, r3, r5              /* no invalidate, unlock */
        ori     r5, r3, HID0_DCFI       /* invalidate, unlock */
+       sync
        mtspr   HID0, r5                /* invalidate, unlock */
-       mtspr   HID0, r3                /* no invalidate, unlock */
        sync
+       mtspr   HID0, r3                /* no invalidate, unlock */
        blr
-#endif
+#endif /* !CONFIG_NAND_SPL */
+#endif /* CFG_INIT_RAM_LOCK */
 
+#ifdef CFG_FLASHBOOT
 map_flash_by_law1:
        /* When booting from ROM (Flash or EPROM), clear the  */
        /* Address Mask in OR0 so ROM appears everywhere      */
@@ -1245,3 +1203,4 @@ remap_flash_by_law0:
        stw r4, LBLAWBAR1(r3)
        stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
        blr
+#endif /* CFG_FLASHBOOT */