关闭

powerpc(mpc8315erdb)平台u-boot起始代码分析

1312人阅读 评论(0) 收藏 举报
该平台出自于freescale,  该系列cpu主要有两种启动方式,  由控制字BMS(boot memory space)决定那种方式.
1, BMS为0时, 系统默认从地址0x0000 0000启动,  pc指针指向0x0000 0100(即从0x0000 0100取第一条指令).
2, BMS为1时, 系统默认从地址0xFFF0 0000启动,  pc指针指向0x0000 0100(即从0xFFF0 0100取第一条指令).

cpu在上电默认只映射启动地址开始的8M空间.即  BMS = 0,  0x0000 0000 -- 0x0080 0000
                                                                             BMS = 1, 0xFF80 0000 -- 0xFFFF FFFF
u-boot存放对应开始或结尾的1M.

mpc8315增加了elbc(enhanced local bus controller)模块,  并且BMS不在使用硬件设置,   而是提供了四个引脚, 利用四个引脚可以设置cpu在上电时从哪里获取启动关键字,  该控制字主要设置启动寄存器, 其中包括BMS位,  cpu根据该组寄存器确定cpu启动的一系列动作.

CFG_RESET_SOURCE[0:3]  Meaning
0000 Reset configuration word is loaded from NOR Flash
0001 Reset configuration word is loaded from NAND Flash memory (8-bit small page).
0010 Reserved
0011 Reserved
0100 Reset configuration word is loaded from an I2C EEPROM. PCI_CLK/PCI_SYNC_IN is
         valid for any PCI frequency up to 66.666 MHz (range of 24–66.666 MHz).
0101 Reset configuration word is loaded from NAND Flash memory (8-bit large page).
0110 Reserved
0111 Reserved
1000 Hard-coded option 0. Reset configuration word is not loaded.
1001 Hard-coded option 1. Reset configuration word is not loaded.
1010 Hard-coded option 2. Reset configuration word is not loaded.
1011 Hard-coded option 3. Reset configuration word is not loaded.
1100 Hard-coded option 4. Reset configuration word is not loaded.
1101 Reserved
1110 Reserved
1111 Reserved

当设置cpu从flash读取控制字时,  flash开始地址存放该控制字, 可以通过u-boot设置该段值  这就要求u-boot的启动地址要设为BMS = 0, 如果设置BMS = 1, 需要管理flash的两部分,.极为不便.  但是设置BMS = 0虽然可以方便管理flash空间, 但是地址0x0000 0000 在u-boot初始化内存时会默认作为内存的地址,  这就要求u-boot在启动后先将flash空间进行重映射,  以便后边初始化内存使用. 
下面是重映射代码部分.
. = EXC_OFF_SYS_RESET

    .globl    _start
_start: /* time t 0  0x0000 0100 or 0xfff00100*/   
    li    r19, BOOTFLAG_COLD  /* Normal Power-On: Boot from FLASH*/
    nop
    b    boot_cold


boot_cold: /* time t 3 */
    lis    r4, CONFIG_DEFAULT_IMMR@h
    nop
boot_warm: /* time t 5 */
    mfmsr    r5            /* save msr contents    */
    lis    r3, CFG_IMMR@h
    ori    r3, r3, CFG_IMMR@l
    stw    r3, IMMRBAR(r4)

    /* Initialise the E300 processor core        */
    /*------------------------------------------*/

    bl    init_e300_core

#if !defined(CFG_RAMBOOT) && !defined(CONFIG_NAND_U_BOOT)

    /* Inflate flash location so it appears everywhere, calculate */
    /* the absolute address in final location of the FLASH, jump  */
    /* there and deflate the flash size back to minimal size      */
    /*------------------------------------------------------------*/
    bl map_flash_by_law1
    lis r4, (CFG_MONITOR_BASE)@h
    ori r4, r4, (CFG_MONITOR_BASE)@l
    addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET
    mtlr r5
    blr
in_flash:
#if 1 /* Remapping flash with LAW0. */
    bl remap_flash_by_law0
#endif
#endif    /* !defined(CFG_RAMBOOT) && !defined(CONFIG_NAND_U_BOOT) */

    /* setup the bats */
    bl    setup_bats
    sync

    /*
     * Cache must be enabled here for stack-in-cache trick.
     * This means we need to enable the BATS.
     * This means:
     *   1) for the EVB, original gt regs need to be mapped
     *   2) need to have an IBAT for the 0xf region,
     *      we are running there!
     * Cache should be turned on after BATs, since by default
     * everything is write-through.
     * The init-mem BAT can be reused after reloc. The old
     * gt-regs BAT can be reused after board_init_f calls
     * board_early_init_f (EVB only).
     */
    /* enable address translation */
    bl    enable_addr_trans
    sync

    /* enable and invalidate the data cache */
    bl    dcache_enable
    sync
#ifdef CFG_INIT_RAM_LOCK
    bl    lock_ram_in_cache
    sync
#endif

    /* set up the stack pointer in our newly created
     * cache-ram (r1) */
    lis    r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
    ori    r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l

    li    r0, 0        /* Make room for stack frame header and    */
    stwu    r0, -4(r1)    /* clear final stack frame so that    */
    stwu    r0, -4(r1)    /* stack backtraces terminate cleanly    */


    /* let the C-code set up the rest                        */
    /*                                            */
    /* Be careful to keep code relocatable & stack humble   */
    /*------------------------------------------------------*/

    GET_GOT            /* initialize GOT access    */

    /* r3: IMMR */
    lis    r3, CFG_IMMR@h
    /* run low-level CPU init code (in Flash)*/
    bl    cpu_init_f

#if !defined(CONFIG_NAND_SPL)
    /* r3: BOOTFLAG */
    mr    r3, r19
    /* run 1st part of board init code (in Flash)*/
    bl    board_init_f  (该函数不返回)

实现空间重映射的两个函数如下:

map_flash_by_law1:
    /* When booting from ROM (Flash or EPROM), clear the  */
    /* Address Mask in OR0 so ROM appears everywhere      */
    /*----------------------------------------------------*/
    lis    r3, (CFG_IMMR)@h  /* r3 <= CFG_IMMR    */
    lwz    r4, OR0@l(r3)
    li    r5, 0x7fff        /* r5 <= 0x00007FFFF */
    and    r4, r4, r5
    stw    r4, OR0@l(r3)     /* OR0 <= OR0 & 0x00007FFFF */

    /* As MPC8349E User's Manual presented, when RCW[BMS] is set to 0,
     * system will boot from 0x0000_0100, and the LBLAWBAR0[BASE_ADDR]
     * reset value is 0x00000; when RCW[BMS] is set to 1, system will boot
     * from 0xFFF0_0100, and the LBLAWBAR0[BASE_ADDR] reset value is
     * 0xFF800.  From the hard resetting to here, the processor fetched and
     * executed the instructions one by one.  There is not absolutely
     * jumping happened.  Laterly, the u-boot code has to do an absolutely
     * jumping to tell the CPU instruction fetching component what the
     * u-boot TEXT base address is.  Because the TEXT base resides in the
     * boot ROM memory space, to garantee the code can run smoothly after
     * that jumping, we must map in the entire boot ROM by Local Access
     * Window.  Sometimes, we desire an non-0x00000 or non-0xFF800 starting
     * address for boot ROM, such as 0xFE000000.  In this case, the default
     * LBIU Local Access Widow 0 will not cover this memory space.  So, we
     * need another window to map in it.
     */
    lis r4, (CFG_FLASH_BASE)@h
    ori r4, r4, (CFG_FLASH_BASE)@l
    stw r4, LBLAWBAR1(r3) /* LBLAWBAR1 <= CFG_FLASH_BASE */

    /* Store 0x80000012 + log2(CFG_FLASH_SIZE) into LBLAWAR1 */
    lis r4, (0x80000012)@h
    ori r4, r4, (0x80000012)@l
    li r5, CFG_FLASH_SIZE
1:    srawi. r5, r5, 1    /* r5 = r5 >> 1 */
    addi r4, r4, 1
    bne 1b

    stw r4, LBLAWAR1(r3) /* LBLAWAR1 <= Flash Size */
    blr

    /* Though all the LBIU Local Access Windows and LBC Banks will be
     * initialized in the C code, we'd better configure boot ROM's
     * window 0 and bank 0 correctly at here.
     */
remap_flash_by_law0:
    /* Initialize the BR0 with the boot ROM starting address. */
    lwz r4, BR0(r3)
    li  r5, 0x7FFF
    and r4, r4, r5
    lis r5, (CFG_FLASH_BASE & 0xFFFF8000)@h
    ori r5, r5, (CFG_FLASH_BASE & 0xFFFF8000)@l
    or  r5, r5, r4
    stw r5, BR0(r3) /* r5 <= (CFG_FLASH_BASE & 0xFFFF8000) | (BR0 & 0x00007FFF) */

    lwz r4, OR0(r3)
    lis r5, ~((CFG_FLASH_SIZE << 4) - 1)
    or r4, r4, r5
    stw r4, OR0(r3)

    lis r4, (CFG_FLASH_BASE)@h
    ori r4, r4, (CFG_FLASH_BASE)@l
    stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CFG_FLASH_BASE */

    /* Store 0x80000012 + log2(CFG_FLASH_SIZE) into LBLAWAR0 */
    lis r4, (0x80000012)@h
    ori r4, r4, (0x80000012)@l
    li r5, CFG_FLASH_SIZE
1:    srawi. r5, r5, 1 /* r5 = r5 >> 1 */
    addi r4, r4, 1
    bne 1b
    stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= Flash Size */


    xor r4, r4, r4
    stw r4, LBLAWBAR1(r3)
    stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
    blr
#endif /* CONFIG_NAND_SPL */

理解该函数关键是对寄存器BR0的理解,  该寄存器决定flash片选信号.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:540451次
    • 积分:6624
    • 等级:
    • 排名:第3721名
    • 原创:110篇
    • 转载:216篇
    • 译文:1篇
    • 评论:35条
    最新评论