Booting Linux Kernel on MPC8560

Deepak Gaur dgaur at cdotd.ernet.in
Sat Apr 5 17:49:41 EST 2008


Hi all,

I have a task to boot Mvista kernel on MPC8560 based board. The bootloader in U-boot.
After decompression my final image is located at address 0x1fff0040 in SDRAM (starts
from 0) CCSRBAR register value is 0x000A0000 Bd_t is located at 0x7FFEA0 cmd line :
cmd_start 0x7FFF00 cmd_end 0x800D01 in SDRAM. After the u-boot transfers the control to
kernel it starts executing head_fsl_booke.S file . The execution get struck after
executing a few lines ... on a rfi instruction 
---------------------------------------------------------------------------
head_fsl_booke.S  First instruction("nop") at 0x1FFF0040 (SDRAM)
---------------------------------------------------------------------------
#include <linux/config.h>
#include <linux/threads.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#include "head_booke.h"

/* As with the other PowerPC ports, it is expected that when code
 * execution begins here, the following registers contain valid, yet
 * optional, information:
 *
 *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
 *   r4 - Starting address of the init RAM disk
 *   r5 - Ending address of the init RAM disk
 *   r6 - Start of kernel command line string (e.g. "mem=128")
 *   r7 - End of kernel command line string
 *
 */
        .text
_GLOBAL(_stext)
_GLOBAL(_start)
        /*
         * Reserve a word at a fixed location to store the address
         * of abatron_pteptrs
         */
SD:0x1fff0040:        nop
/*
 * Save parameters we are passed
 */
        mr      r31,r3
        mr      r30,r4
        mr      r29,r5
        mr      r28,r6
        mr      r27,r7
                                                                                       
                           li      r24,0           /* CPU number */

/* We try to not make any assumptions about how the boot loader
 * setup or used the TLBs.  We invalidate all mappings from the
 * boot loader and load a single entry in TLB1[0] to map the
 * first 16M of kernel memory.  Any boot info passed from the
 * bootloader needs to live in this first 16M.
 *
 * Requirement on bootloader:
 *  - The page we're executing in needs to reside in TLB1 and
 *    have IPROT=1.  If not an invalidate broadcast could
 *    evict the entry we're currently executing in.
 *
 *  r3 = Index of TLB1 were executing in
 *  r4 = Current MSR[IS]
 *  r5 = Index of TLB1 temp mapping
 *
 * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0]
 * if needed
 */

/* 1. Find the index of the entry we're executing in */
        bl      invstr                          /* Find our address */
invstr: mflr    r6                              /* Make it accessible */
        mfmsr   r7
        rlwinm  r4,r7,27,31,31                  /* extract MSR[IS] */
        mfspr   r7, SPRN_PID0
        slwi    r7,r7,16
        or      r7,r7,r4
        mtspr   SPRN_MAS6,r7
        tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
#ifndef CONFIG_E200
 mfspr   r7,SPRN_MAS1
        andis.  r7,r7,MAS1_VALID at h
        bne     match_TLB
        mfspr   r7,SPRN_PID1
        slwi    r7,r7,16
        or      r7,r7,r4
        mtspr   SPRN_MAS6,r7
        tlbsx   0,r6                            /* search MSR[IS], SPID=PID1 */
        mfspr   r7,SPRN_MAS1
        andis.  r7,r7,MAS1_VALID at h
        bne     match_TLB
        mfspr   r7, SPRN_PID2
        slwi    r7,r7,16
        or      r7,r7,r4
        mtspr   SPRN_MAS6,r7
        tlbsx   0,r6                            /* Fall through, we had to match */
#endif
match_TLB:
        mfspr   r7,SPRN_MAS0
        rlwinm  r3,r7,16,20,31                  /* Extract MAS0(Entry) */

        mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
        oris    r7,r7,MAS1_IPROT at h
        mtspr   SPRN_MAS1,r7
        tlbwe

/* 2. Invalidate all entries except the entry we're executing in */
        mfspr   r9,SPRN_TLB1CFG
        andi.   r9,r9,0xfff
        li      r6,0                            /* Set Entry counter to 0 */
1:      lis     r7,0x1000                       /* Set MAS0(TLBSEL) = 1 */
        rlwimi  r7,r6,16,4,15                   /* Setup MAS0 = TLBSEL | ESEL(r6) */
        mtspr   SPRN_MAS0,r7
        tlbre
        mfspr   r7,SPRN_MAS1
        rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
        cmpw    r3,r6
        beq     skpinv                          /* Dont update the current execution TLB */
        mtspr   SPRN_MAS1,r7
  tlbwe
        isync
skpinv: addi    r6,r6,1                         /* Increment */
        cmpw    r6,r9                           /* Are we done? */
        bne     1b                              /* If not, repeat */

        /* Invalidate TLB0 */
        li      r6,0x04
        tlbivax 0,r6
#ifdef CONFIG_SMP
        tlbsync
#endif
        /* Invalidate TLB1 */
        li      r6,0x0c
        tlbivax 0,r6
#ifdef CONFIG_SMP
        tlbsync
#endif
        msync

/* 3. Setup a temp mapping and jump to it */
        andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
        addi    r5, r5, 0x1
        lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
        rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
        mtspr   SPRN_MAS0,r7
        tlbre

        /* Just modify the entry ID and EPN for the temp mapping */
        lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
        rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
        mtspr   SPRN_MAS0,r7
        xori    r6,r4,1         /* Setup TMP mapping in the other Address space */
        slwi    r6,r6,12
        oris    r6,r6,(MAS1_VALID|MAS1_IPROT)@h
        ori     r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
        mtspr   SPRN_MAS1,r6
        mfspr   r6,SPRN_MAS2
        li      r7,0            /* temp EPN = 0 */
    rlwimi  r7,r6,0,20,31
        mtspr   SPRN_MAS2,r7
        tlbwe

        xori    r6,r4,1
        slwi    r6,r6,5         /* setup new context with other address space */
        bl      1f              /* Find our address */
1:      mflr    r9
        rlwimi  r7,r9,0,20,31
        addi    r7,r7,24
        mtspr   SRR0,r7     <------------------------ SRR0 1A40
        mtspr   SRR1,r6     <------------------------ SRR1 20
        rfi                 <------------------------ It goes to LOCATION 0x00001A40

/* 4. Clear out PIDs & Search info */
SD: 0x1fff01A40        li      r6,0
                       mtspr   SPRN_PID0,r6

SD memory locattion as reported by ICE

The SRR0 contains 0x00001A40 address for rfi. The memory location of next instruction
happens to be similar to contents of SRR0 . It is 0x1fff01a40. It is that the SRR0
should have contained 0x1fff01A40 or 0x00001A40 is correct. Actually on 0x00001A40 there
 no instruction is defined (as reported by ICE it is "undef")

Please help me in understanding this behaviour and more specifically need of "rfi"
instruction in this file.

Thanks

Deepak Gaur



More information about the Linuxppc-embedded mailing list