分享

基于ar9331 mips架构AP121 uboot分析(4) 启动流程 Stage1 | Imagination中文技术社区

 云将东游 2016-02-24

cpu/mips/start_bootstrap.S代码分析

/*
* Startup Code for MIPS32 CPU-core
*
* Copyright (c) 2003 Wolfgang Denk
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/

#include
#include
#include
#include

#define AR7100_SPI_CLOCK 0xbf000004

#define RVECENT(f,n) \ /* 简单的跳转指令,f为一个标记,b为跳转指令。*/
b f; nop

#define XVECENT(f,bev) \
b f ; \
li k0,bev

.set noreorder

.globl _start_bootstrap
.text
_start_bootstrap:
RVECENT(reset,0) /* U-boot entry point */
RVECENT(reset,1) /* software reboot */
RVECENT(romReserved,2)
RVECENT(romReserved,3)
RVECENT(romReserved,4)
RVECENT(romReserved,5)
RVECENT(romReserved,6)
RVECENT(romReserved,7)
RVECENT(romReserved,8)
RVECENT(romReserved,9)
RVECENT(romReserved,10)
RVECENT(romReserved,11)
RVECENT(romReserved,12)
RVECENT(romReserved,13)
RVECENT(romReserved,14)
RVECENT(romReserved,15)
RVECENT(romReserved,16)
RVECENT(romReserved,17)
RVECENT(romReserved,18)
RVECENT(romReserved,19)
RVECENT(romReserved,20)
RVECENT(romReserved,21)
RVECENT(romReserved,22)
RVECENT(romReserved,23)
RVECENT(romReserved,24)
RVECENT(romReserved,25)
RVECENT(romReserved,26)
RVECENT(romReserved,27)
RVECENT(romReserved,28)
RVECENT(romReserved,29)
RVECENT(romReserved,30)
RVECENT(romReserved,31)
RVECENT(romReserved,32)
RVECENT(romReserved,33)
RVECENT(romReserved,34)
RVECENT(romReserved,35)
RVECENT(romReserved,36)
RVECENT(romReserved,37)
RVECENT(romReserved,38)
RVECENT(romReserved,39)
RVECENT(romReserved,40)
RVECENT(romReserved,41)
RVECENT(romReserved,42)
RVECENT(romReserved,43)
RVECENT(romReserved,44)
RVECENT(romReserved,45)
RVECENT(romReserved,46)
RVECENT(romReserved,47)
RVECENT(romReserved,48)
RVECENT(romReserved,49)
RVECENT(romReserved,50)
RVECENT(romReserved,51)
RVECENT(romReserved,52)
RVECENT(romReserved,53)
RVECENT(romReserved,54)
RVECENT(romReserved,55)
RVECENT(romReserved,56)
RVECENT(romReserved,57)
RVECENT(romReserved,58)
RVECENT(romReserved,59)
RVECENT(romReserved,60)
RVECENT(romReserved,61)
RVECENT(romReserved,62)
RVECENT(romReserved,63)
XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */
RVECENT(romReserved,65)
RVECENT(romReserved,66)
RVECENT(romReserved,67)
RVECENT(romReserved,68)
RVECENT(romReserved,69)
RVECENT(romReserved,70)
RVECENT(romReserved,71)
RVECENT(romReserved,72)
RVECENT(romReserved,73)
RVECENT(romReserved,74)
RVECENT(romReserved,75)
RVECENT(romReserved,76)
RVECENT(romReserved,77)
RVECENT(romReserved,78)
RVECENT(romReserved,79)
XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */
RVECENT(romReserved,81)
RVECENT(romReserved,82)
RVECENT(romReserved,83)
RVECENT(romReserved,84)
RVECENT(romReserved,85)
RVECENT(romReserved,86)
RVECENT(romReserved,87)
RVECENT(romReserved,88)
RVECENT(romReserved,89)
RVECENT(romReserved,90)
RVECENT(romReserved,91)
RVECENT(romReserved,92)
RVECENT(romReserved,93)
RVECENT(romReserved,94)
RVECENT(romReserved,95)
XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */
RVECENT(romReserved,97)
RVECENT(romReserved,98)
RVECENT(romReserved,99)
RVECENT(romReserved,100)
RVECENT(romReserved,101)
RVECENT(romReserved,102)
RVECENT(romReserved,103)
RVECENT(romReserved,104)
RVECENT(romReserved,105)
RVECENT(romReserved,106)
RVECENT(romReserved,107)
RVECENT(romReserved,108)
RVECENT(romReserved,109)
RVECENT(romReserved,110)
RVECENT(romReserved,111)
XVECENT(romExcHandle,0x380) /* bfc00380: R4000 general vector */
RVECENT(romReserved,113)
RVECENT(romReserved,114)
RVECENT(romReserved,115)
RVECENT(romReserved,116)
RVECENT(romReserved,116)
RVECENT(romReserved,118)
RVECENT(romReserved,119)
RVECENT(romReserved,120)
RVECENT(romReserved,121)
RVECENT(romReserved,122)
RVECENT(romReserved,123)
RVECENT(romReserved,124)
RVECENT(romReserved,125)
RVECENT(romReserved,126)
RVECENT(romReserved,127)

/* We hope there are no more reserved vectors!
* 128 * 8 == 1024 == 0x400
* so this is address R_VEC+0x400 == 0xbfc00400
*/
.align 4
reset:
/*
* Clearing CP0 registers - This is generally required for the MIPS-24k
* core used by Atheros./* 在 uboot/include/asm-mips/regdef.h中定义了mips 32个通用寄存器的别名和用途*/
*/
mtc0 zero, $0 /* mtc0:把一个数据从特殊寄存器复制到通用寄存器 从$0 读到0 到$0-$31中,$12除外 */
mtc0 zero, $1
mtc0 zero, $2
mtc0 zero, $3
mtc0 zero, $4
mtc0 zero, $5
mtc0 zero, $6
mtc0 zero, $7
mtc0 zero, $8
mtc0 zero, $9
mtc0 zero, $10
mtc0 zero, $11
li t0, 0x10000004
mtc0 t0, $12
mtc0 zero, $13
mtc0 zero, $14
mtc0 zero, $15
mtc0 zero, $16
mtc0 zero, $17
mtc0 zero, $18
mtc0 zero, $19
mtc0 zero, $20
mtc0 zero, $21
mtc0 zero, $22
mtc0 zero, $23
mtc0 zero, $24
mtc0 zero, $25
mtc0 zero, $26
mtc0 zero, $27
mtc0 zero, $28

/*
* Clear watch registers. /* 在 uboot/include/asm-mips/mipsregs.h中定义了CP0的寄存器 */
*/

mtc0 zero, CP0_WATCHLO
mtc0 zero, CP0_WATCHHI

/* STATUS register */
mfc0 k0, CP0_STATUS /* mfc0:把一个数据从通用寄存器复制到特殊寄存器 */
li k1, ~ST0_IE /*li是load immediate value into destination register*/
and k0, k1
mtc0 zero, CP0_CAUSE
mtc0 k0, CP0_STATUS

/* CAUSE register */
mtc0 zero, CP0_CAUSE

/* Init Timer */
mtc0 zero, CP0_COUNT
mtc0 zero, CP0_COMPARE

/* CONFIG0 register */
li t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG

/* Initialize GOT pointer.*/ /*so luck:http://blog./uid-20259080-id-1752694.html */
bal 1f /*TODO: ?bal 1f */
nop
.word _GLOBAL_OFFSET_TABLE_
1:
move gp, ra
lw t1, 0(ra) /*lw :从ra存储器中读取一个字的数据到寄存器t1中 */
move gp, t1

#if defined(CONFIG_MACH_HORNET) && defined(CONFIG_HORNET_1_1_WAR)
/**************************************************************************/
/*
* WAR: Hornet 1.1 currently need a reset once we boot to let the resetb has
* enough time to stable, so that trigger reset at 1st boot, system team
* is investigaing the issue, will remove in short
*/

do_reset_normal:

li t7, 0xbd000000
lw t8, 0(t7) // t8 : value of 0xbd000000
li t9, 0x12345678
bne t8, t9, do_reset // if value of 0xbd000000 != 0x12345678 , go to do_reset
nop
li t9, 0xffffffff
sw t9, 0(t7) /*sw :把一个字的数据从寄存器存储到存储器中 */
b normal_path
nop

do_reset:
sw t9, 0(t7)
li t7, 0xb806001c // load reset register 0x1806001c
lw t8, 0(t7)
li t9, 0x1000000 // bit24, fullchip reset
or t8, t8, t9
sw t8, 0(t7)
do_reset_loop:
b do_reset_loop
nop

normal_path:
#endif /* CONFIG_MACH_HORNET */

/**************************************************************************/

/* Initialize any external memory.
*/
#if defined(CONFIG_AR7100) || defined(CONFIG_AR7240)
la t9, lowlevel_init /* /u-boot/board/ar7240/common/lowlevle_init.S 但是又跳转到/board/ap7240/ap121/hornet_pll_init.S中执行hornet_pll_init*/
jalr t9 /* jalr 使用寄存器的跳转指令,并且带有链接功能,指令的跳转地址在寄存器中,跳转发生时指令的放回地址放在R31这个寄存器中 */
nop
nop

#if defined(CONFIG_MACH_HORNET)
la t9, hornet_ddr_init /*/u-boot/cpu/mips/ar7240/hornet_ddr_init.S*/
jalr t9
nop
nop

#if 0
la t9, hornet_ddr_tap_init /*/u-boot/cpu/mips/ar7240/hornet_ddr_init.S*/
jalr t9
nop
#endif

#endif

la t0, rel_start
j t0
nop
#endif

rel_start:

#if defined(CONFIG_AR7100) || defined(CONFIG_AR7240)
/* REMAP_DISABLE */
// TODO: SPI flash clock?
li a0, AR7100_SPI_CLOCK
li t0, 0x42 // TODO: TEST TEST TEST, was 0x43
sw t0, 0(a0)
#endif

#if defined(CONFIG_AR9100) && defined(CFG_HOWL_1_2)
/* Disable remap for parallel flash */
li t7, AR9100_FLASH_CONFIG;
lw t8, 0(t7);
li t9, 0xffbf0000;
and t8, t8, t9;
li t9, 0x22fc;
or t8, t8, t9;
li t9, 0xffcfffff; /* scale = 0 */
and t8, t8, t9;
sw t8, 0(t7);

#endif

/* Initialize caches...
*/
la t9, simple_mips_cache_reset /* /u-boot/cpu/mips/cache.S*/
jalr t9
nop

/* ... and enable them.
*/
li t0, CONF_CM_CACHABLE_NONCOHERENT
mtc0 t0, CP0_CONFIG

#if !defined(CONFIG_AR7100) && !defined(CONFIG_AR7240)
/* Set up temporary stack.
*/
li a0, CFG_INIT_SP_OFFSET
la t9, mips_cache_lock
jalr t9
nop
#endif

#if defined(CONFIG_AR7100) || defined(CONFIG_AR7240)
la t9, mips_cache_lock_24k
jalr t9
nop
#endif

li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
la sp, 0(t0)

la t9, bootstrap_board_init_f
j t9
nop

/*
* void bootstrap_relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
* a0 = addr_sp
* a1 = gd
* a2 = destination address
*/
.globl bootstrap_relocate_code
.ent bootstrap_relocate_code
bootstrap_relocate_code:
move sp, a0 /* Set new stack pointer */

li t0, BOOTSTRAP_CFG_MONITOR_BASE
la t3, in_ram
lw t2, -12(t3) /* t2 <-- uboot_end_data_bootsrap */

/*
* Ideally, following line is not needed. However,
* the behaviour is flaky without it. U-boot boots on
* some boards, and doesn't on some boards. Even on the
* boards it boots, it doesn't boot all the time.
*
* Adding 256k to what needs to be read in actually.
* This introduces some delay that seems to help boot.
*/
li t3, (256 << 10)

add t2, t3
move t1, a2

/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - BOOTSTRAP_CFG_MONITOR_BASE) + Destination Address
*/
move t6, gp
sub gp, BOOTSTRAP_CFG_MONITOR_BASE
add gp, a2 /* gp now adjusted */
sub t6, gp, t6 /* t6 <-- relocation offset */

/*
* t0 = source address
* t1 = target address
* t2 = source end address
*/
1:
lw t3, 0(t0)
sw t3, 0(t1)
addu t0, 4
ble t0, t2, 1b
addu t1, 4 /* delay slot */

/* If caches were enabled, we would have to flush them here.
*/

/* Jump to where we've relocated ourselves.
*/
addi t0, a2, in_ram - _start_bootstrap
j t0
nop

.word uboot_end_data_bootstrap
.word uboot_end_bootstrap
.word num_got_entries

in_ram:
/* Now we want to update GOT.
*/
lw t3, -4(t0) /* t3 <-- num_got_entries */
addi t4, gp, 8 /* Skipping first two entries. */
li t2, 2
1:
lw t1, 0(t4)
beqz t1, 2f
add t1, t6
sw t1, 0(t4)
2:
addi t2, 1
blt t2, t3, 1b
addi t4, 4 /* delay slot */

/* Clear BSS.
*/
lw t1, -12(t0) /* t1 <-- uboot_end_data_bootstrap */
lw t2, -8(t0) /* t2 <-- uboot_end_bootstrap */
add t1, t6 /* adjust pointers */
add t2, t6

sub t1, 4
1: addi t1, 4
bltl t1, t2, 1b
sw zero, 0(t1) /* delay slot */

move a0, a1
la t9, bootstrap_board_init_r
j t9
move a1, a2 /* delay slot */

.end bootstrap_relocate_code

/* Exception handlers.
*/
romReserved:
b romReserved

romExcHandle:
b romExcHandle  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多