您的位置:首页 > 其它

uboot源码阅读(三)江湖的历史 uboot第一阶段start.S

2011-07-24 20:03 375 查看
有江湖的地方就会的历史,忘记历史就意味着背叛。每天打打杀杀,如果不小心就会有人在背后给自己来一刀,这就是背叛的滋味。不要忘记历史,这是前人的血的教训。

cpu/s3c64xx/start.S

#include <config.h>
#include <version.h>
#ifdef CONFIG_ENABLE_MMU
#include <asm/proc/domain.h>
#endif
#include <regs.h>

#ifndef CONFIG_ENABLE_MMU
#ifndef CFG_PHY_UBOOT_BASE
#define CFG_PHY_UBOOT_BASE      CFG_UBOOT_BASE
#endif
#endif

/*
* ARM处理器为特殊的任务或者专门的功能指定了3个寄存器:r13,r14,r15.
* 寄存器r13通常用作堆栈指针(sp),保存当前处理器模式的堆栈的栈顶。
* 寄存器r14又被称为连接寄存器(lr),保存调用子程序的返回地址。
* 寄存器r15是程序计数器(pc),其内容是处理器要取的下一条指令的地址。
* 两个状态寄存器:cpsr和spsr,分别是当前和备份的程序状态寄存器。
*/

/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
/*
* ARM分支指令可以改变程序的执行流程或者调用子程序。这种指令使得一个程序可以使用子程序、if-then-else
* 结构及循环。执行流程的改变迫使程序计数器PC指向一个新的地址。
* B{<cond>}     lable     跳转  pc=lable
* BL{<cond>}    lable   带返回的跳转  pc=lable,lr=BL后面的第一条指令地址
* BX{<cond>}    Rm   跳转并切换状态 PC = Rm & 0xfffffffe,T=Rm&1
* BLX{<cond>}   lable | Rm 带返回的跳转并切换状态  pc = lable, T =1 pc =Rm & 0xfffffffe,T=Rm&1 lr=BLX后面的第一条指令地址
* 地址lable以一个有符号的相对于pc的偏移量保存在指令中,必须被限制在分支指令的约32MB范围内。T对应于cpsr中的Thumb位,如果指令设
* 置了T,那么ARM切换到Thumb状态。
*/
/*
* ldr属于load-store指令,它用于在存储器和处理器寄存器之间传输数据。load-store指令有三种类型:单寄存器传输指令
* 多寄存器传输指令和交换指令;
* 单寄存器传输指令用于把单个的数据传入或者传出一个寄存器。
* ldr/str  <cond> {B} Rd, addressing1 其中ldr是把一个字装入一个寄存器: Rd <--mem32[address];str是从一个寄存器保存一个字或者一个字节 Rd -->mem32[address]
*/
.globl _start
_start: b       reset
/*该部分为处理器的异常处理向量表。*/
ldr     pc, _undefined_instruction
ldr     pc, _software_interrupt
ldr     pc, _prefetch_abort
ldr     pc, _data_abort
ldr     pc, _not_used
ldr     pc, _irq
ldr     pc, _fiq
/*
* 在当前标号_undefined_instruction所在的地址处放入四字节的数据,这个数据就是undefined_instruction标号
* 的地址.意思就是说在当前_undefined_instruction对应的地址中放的是undefined_instruction的地址
*/
/*
.word伪操作用于分配一段字内存单元(分配的单元都是字对齐的),并用伪操作中的expr初始化。.long和.int作用与之相同。
*/
_undefined_instruction:
.word undefined_instruction
_software_interrupt:
.word software_interrupt
_prefetch_abort:
.word prefetch_abort
_data_abort:
.word data_abort
_not_used:
.word not_used
_irq:
.word irq
_fiq:
.word fiq
_pad:
.word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:

.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* setup Memory and board specific bits prior to relocation.
* relocate armboot to ram
* setup stack
*
*************************************************************************
*/
/*
* TEXT_BASE 在/board/config.mk文档中定义, 他定义了代码在运行时所在的地址, _TEXT_BASE中保存了这个地址
*/
_TEXT_BASE:
.word   TEXT_BASE

/*
* Below variable is very important because we use MMU in U-Boot.
* Without it, we cannot run code correctly before MMU is ON.
* by scsuh.
*/
_TEXT_PHY_BASE:
.word   CFG_PHY_UBOOT_BASE

.globl _armboot_start/*声明全局标志. 声明的该标号_armboot_start可以被外部使用*/
_armboot_start:
.word _start

/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start /*预处理标号  目的:让_bss_start指向__bss_start标号所在的地址*/
_bss_start:
.word __bss_start  /*在当前标号_bss_start所在的地址处放入__bss_start标号的地址*/

.globl _bss_end/*预处理标号 目的:让_bss_end指向_end标号所在的地址*/
_bss_end:
.word _end

#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START /*预处理标号 目的:让IRQ_STACK_START指向地址0x0badc0de(这个需要根据硬件更改)*/
IRQ_STACK_START:
.word   0x0badc0de

/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif

/*
* the actual reset code
*/
/*
* 复位向量是处理器上电后执行的第一条指令的位置。这条指令使处理器跳转到初始化代码处。
*/
/*
* 处理器模式决定了哪些寄存器是活动的以及对cpsr的访问权。处理器复位时则进入到管理模式(Supervisor,SVC)
*/
reset:
/*
* set the cpu to SVC32 mode
*/
/*
* ARM指令集提供了2条指令,可以直接控制程序状态寄存器(psr)。MRS指令用于把cpsr或者spsr的值传送到一个寄存器。
* MSR与MRS相反,把一个寄存器的内容传送到cpsr或者spsr。这两条指令可用于对cpsr和spsr进行读/写操作。
*/
mrs     r0,cpsr
bic     r0,r0,#0x1f /*EC: 模式位清零*//*bic是位清零(Bit Clear)指令,本语句是把r0的Bit[4:0]位清零(由0x1F指示),然后把结果写入r0中。*/
orr     r0,r0,#0xd3 /*EC: 工作模式位设置为10011,为管理模式,irq fiq设置为1,屏蔽中断*/
/*orr指令是按位求或,本语句是r0的 Bit7,Bit6,Bit4,Bit1,Bit0 置为1,其它位保持不变。*/
msr     cpsr,r0/*把寄存器r0的值传送到cpsr(当前程序状态寄存器)*/
/*执行完上述操作后,cpsr中的 I=1, F=1, T保持不变(默认为0),M[4:0]=10011,意思是禁止IRQ,禁止FIQ,工作在ARM状态,工作在SVC32模式。*/
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*//*数据处理指令对于存放在寄存器中的数据进行操作。*/
mov     r0, #0
/*协处理器指令用于扩展指令集P协处理器指令可用于提供附加的计算能力,有可用于控制包括cache和内存
* 管理的存储子系统。协处理器指令包括数据处理指令,寄存器传输指令及内存传输指令。协处理器指令只用于带
* 有协处理器的ARM内核。
* CDP {<cond>} cp, opcode1, Cd, Cn{,opcode2}  协处理器数据处理 -- 在协处理器内部执行一个数据处理操作
* <MRC/MCR> {<cond>} cp, opcode1, Rd, Cn, Cm{,opcode2} 协处理器寄存器传输 -- 把数据送入/取出协处理器寄存器
* <LDC/STC> {<cod>} cp, Cd, addressing  协处理器内存比较 -- 从协处理器装载/存储一个内存数据块
* 其中:cp域代表协处理器的编号,为p0~P15. opcode域描述要在协处理器中进行的操作。Cn, Cm及Cd描述在协处理器中的寄存器。
* 协处理器15(CP15)是为系统控制预留的,如内存管理,写缓冲控制,cache控制及寄存器识别等。
* MRC p15,0,r10,c0,c0,0 把协处理器15寄存器c0的内容拷贝到r10中,cp15寄存器c0中包含处理器标识,其内容拷贝到通用寄存器r10
*/
mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */

/*
* disable MMU stuff and caches
*/
mrc     p15, 0, r0, c1, c0, 0
bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
mcr     p15, 0, r0, c1, c0, 0

/* Peri port setup */
ldr     r0, =0x70000000
orr     r0, r0, #0x13
mcr     p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)

#ifdef CONFIG_BOOT_ONENAND
ldr     r0, =0x70000000         @ onenand controller setup
orr     r0, r0, #0x100000
ldr     r1, =0x4000
orr     r1, r1, #0xe0
str     r1, [r0]

#if defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430)
orr     r0, r0, #300            @ disable watchdog
mov     r1, #1
str     r1, [r0]

mov     r1, #0x23000000         @ start buffer register
orr     r1, r1, #0x30000
orr     r1, r1, #0xc800
#else
mov     r1, =0x20000000         @ start buffer register
orr     r1, r1, #0xc30000
orr     r1, r1, #0xc800
#endif

sub     r0, r1, #0x0400         @ start address1 register

ldr     r2, [r1, #0x84]         @ ecc bypass
orr     r2, r2, #0x100
str     r2, [r1, #0x84]

mov     r3, #0x0                @ DFS, FBA
str     r3, [r0, #0x00]
str     r3, [r0, #0x04]         @ select dataram for DDP as 0

mov     r4, #0x104              @ interrupt register
mov     r5, #0x0002             @ FPA, FSA
mov     r6, #0x0800             @ BSA

onenand_bl1_load:
str     r5, [r0, #0x1c]         @ save FPA, FSA
orr     r6, r6, #0x02           @ BSC
str     r6, [r1, #0x00]         @ save BSA, BSC
str     r3, [r1, r4]            @ clear interrupt
str     r3, [r1, #0x80]         @ write load command

mov     r7, #0x100              @ need small delay

onenand_wait_loop1:
subs    r7, r7, #0x1
bne     onenand_wait_loop1

add     r5, r5, #0x2            @ next FPA, FSA
sub     r6, r6, #0x2
add     r6, r6, #0x200          @ next BSA
cmp     r5, #0x8
bne     onenand_bl1_load
#endif

/*
* Go setup Memory and board specific bits prior to relocation.
*/
bl      lowlevel_init   /* go setup pll,mux,memory */

/* when we already run in ram, we don't need to relocate U-Boot.
* and actually, memory controller must be configured before U-Boot
* is running in ram.
*/
ldr     r0, =0xff000fff
bic     r1, pc, r0              /* r0 <- current base addr of code */
ldr     r2, _TEXT_BASE          /* r1 <- original base addr in ram */
bic     r2, r2, r0              /* r0 <- current base addr of code */
cmp     r1, r2                  /* compare r0, r1                  */
beq     after_copy              /* r0 == r1 then skip flash copy   */

#ifdef CONFIG_BOOT_NOR                  /* relocate U-Boot to RAM */
adr     r0, _start              /* r0 <- current position of code   */
ldr     r1, _TEXT_PHY_BASE      /* r1 <- destination                */
ldr     r2, _armboot_start
ldr     r3, _bss_start
sub     r2, r3, r2              /* r2 <- size of armboot            */
add     r2, r0, r2              /* r2 <- source end address         */

nor_copy_loop:
ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
cmp     r0, r2                  /* until source end addreee [r2]    */
ble     nor_copy_loop
b       after_copy
#endif

#ifdef CONFIG_BOOT_NAND
mov     r0, #0x1000
bl      copy_from_nand
#endif

#ifdef CONFIG_BOOT_MOVINAND
ldr     sp, _TEXT_PHY_BASE
bl      movi_bl2_copy
b       after_copy
#endif

#ifdef CONFIG_BOOT_ONENAND
ldr     sp, =0x50000000         @ temporary stack

#ifdef CONFIG_S3C6400
mov     r1, =0x20000000         @ start buffer register
orr     r1, r1, #0xc30000
orr     r1, r1, #0xc800
#else
mov     r1, #0x23000000         @ start buffer register
orr     r1, r1, #0x30000
orr     r1, r1, #0xc800
#endif

ldr     r2, [r1, #0x84]         @ ecc bypass
orr     r2, r2, #0x100
str     r2, [r1, #0x84]

sub     r0, r1, #0x0400         @ start address1 register

str     r3, [r0, #0x00]
str     r3, [r0, #0x04]         @ select dataram for DDP as 0

mov     r4, #0x104              @ interrupt register

mov     r6, #0x0c00             @ fixed dataram1 sector number
str     r6, [r1, #0x00]

mov     r3, #0x0                @ DFS, FBA
mov     r5, #0x0000             @ FPA, FSA
ldr     r9, =CFG_PHY_UBOOT_BASE @ destination

onenand_bl2_load:
str     r3, [r0, #0x00]         @ save DFS, FBA
str     r5, [r0, #0x1c]         @ save FPA, FSA

mov     r7, #0x0                @ clear interrupt
str     r7, [r1, r4]
str     r7, [r1, #0x80]         @ write load command

mov     r8, #0x1000
onenand_wait_loop2:
subs    r8, r8, #0x1
bne     onenand_wait_loop2

onenand_wait_int:                       @ wait INT and RI
ldr     r7, [r1, r4]
mov     r8, #0x8000
orr     r8, r8, #0x80
tst     r7, r8
beq     onenand_wait_int

mov     r7, #0x0                @ clear interrupt
str     r7, [r1, r4]

mov     r8, #0xc00              @ source address (dataram1)
mov     r10, #0x40              @ copy loop count (64 = 2048 / 32)

stmia   sp, {r0-r7}             @ backup

onenand_copy_to_ram:
ldmia   r8!, {r0-r7}
stmia   r9!, {r0-r7}
subs    r10, r10, #0x1
bne     onenand_copy_to_ram

ldmia   sp, {r0-r7}             @ restore

add     r5, r5, #0x4            @ next FPA
cmp     r5, #0x100              @ last FPA?
bne     onenand_bl2_load

/* next block */
mov     r5, #0x0                @ reset FPA
add     r3, r3, #0x1            @ next FBA
cmp     r3, #0x2                @ last FBA?
bne     onenand_bl2_load
b       after_copy
#endif

#ifdef CONFIG_BOOT_ONENAND_IROM
ldr     sp, _TEXT_PHY_BASE
bl      onenand_bl2_copy
b       after_copy
#endif

after_copy:
ldr     r0, =ELFIN_GPIO_BASE
ldr     r1, =0xC00
str     r1, [r0, #GPPDAT_OFFSET]
ldr     r1, [r0, #GPFPUD_OFFSET]
bic     r1, r1, #0xc0000000
orr     r1, r1, #0x80000000
str     r1, [r0, #GPFPUD_OFFSET]
ldr     r1, [r0, #GPFDAT_OFFSET]
orr     r1, r1, #0x8000
str     r1, [r0, #GPFDAT_OFFSET]
ldr     r1, [r0, #GPFCON_OFFSET]
bic     r1, r1, #0xc0000000
orr     r1, r1, #0x40000000
str     r1, [r0, #GPFCON_OFFSET]

#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldr     r5, =0x0000ffff
mcr     p15, 0, r5, c3, c0, 0           @ load domain access register

/* Set the TTB register */
ldr     r0, _mmu_table_base
ldr     r1, =CFG_PHY_UBOOT_BASE
ldr     r2, =0xfff00000
bic     r0, r0, r2
orr     r1, r0, r1
mcr     p15, 0, r1, c2, c0, 0

/* Enable the MMU */
mmu_on:
mrc     p15, 0, r0, c1, c0, 0
orr     r0, r0, #1                      /* Set CR_M to enable MMU */
mcr     p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif

skip_hw_init:
/* Set up the stack                                                 */
stack_setup:
#ifdef CONFIG_MEMORY_UPPER_CODE
ldr     sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
#else
ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
sub     r0, r0, #CFG_MALLOC_LEN /* malloc area                      */
sub     r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
#ifdef CONFIG_USE_IRQ
sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub     sp, r0, #12             /* leave 3 words for abort-stack    */

#endif

clear_bss:
ldr     r0, _bss_start          /* find start of bss segment        */
ldr     r1, _bss_end            /* stop here                        */
mov     r2, #0x00000000         /* clear                            */

clbss_l:
str     r2, [r0]                /* clear loop...                    */
add     r0, r0, #4
cmp     r0, r1
ble     clbss_l

ldr     pc, _start_armboot

_start_armboot:
.word start_armboot   /*c运行环境已经准备好,通过直接跳转代码进入第二阶段*/

#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
.word mmu_table
#endif

/*
* copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
* r0: size to be compared
* Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
*/
.globl copy_from_nand
copy_from_nand:
mov     r10, lr         /* save return address */

mov     r9, r0
/* get ready to call C functions */
ldr     sp, _TEXT_PHY_BASE      /* setup temp stack pointer */
sub     sp, sp, #12
mov     fp, #0                  /* no previous frame, so fp=0 */
mov     r9, #0x1000
bl      copy_uboot_to_ram

3:      tst     r0, #0x0
bne     copy_failed

ldr     r0, =0x0c000000
ldr     r1, _TEXT_PHY_BASE
1:      ldr     r3, [r0], #4
ldr     r4, [r1], #4
teq     r3, r4
bne     compare_failed  /* not matched */
subs    r9, r9, #4
bne     1b

4:      mov     lr, r10         /* all is OK */
mov     pc, lr

copy_failed:
nop                     /* copy from nand failed */
b       copy_failed

compare_failed:
nop                     /* compare failed */
b       compare_failed

/*
* we assume that cache operation is done before. (eg. cleanup_before_linux())
* actually, we don't need to do anything about cache if not use d-cache in U-Boot
* So, in this function we clean only MMU. by scsuh
*
* void theLastJump(void *kernel, int arch_num, uint boot_params);
*/
#ifdef CONFIG_ENABLE_MMU
.globl theLastJump
theLastJump:
mov     r9, r0
ldr     r3, =0xfff00000
ldr     r4, _TEXT_PHY_BASE
adr     r5, phy_last_jump
bic     r5, r5, r3
orr     r5, r5, r4
mov     pc, r5
phy_last_jump:
/*
* disable MMU stuff
*/
mrc     p15, 0, r0, c1, c0, 0
bic     r0, r0, #0x00002300     /* clear bits 13, 9:8 (--V- --RS) */
bic     r0, r0, #0x00000087     /* clear bits 7, 2:0 (B--- -CAM) */
orr     r0, r0, #0x00000002     /* set bit 2 (A) Align */
orr     r0, r0, #0x00001000     /* set bit 12 (I) I-Cache */
mcr     p15, 0, r0, c1, c0, 0

mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */

mov     r0, #0
mov     pc, r9
#endif
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE    72

#define S_OLD_R0        68
#define S_PSR           64
#define S_PC            60
#define S_LR            56
#define S_SP            52

#define S_IP            48
#define S_FP            44
#define S_R10           40
#define S_R9            36
#define S_R8            32
#define S_R7            28
#define S_R6            24
#define S_R5            20
#define S_R4            16
#define S_R3            12
#define S_R2            8
#define S_R1            4
#define S_R0            0

#define MODE_SVC 0x13
#define I_BIT    0x80

/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/

.macro  bad_save_user_regs
sub     sp, sp, #S_FRAME_SIZE           @ carve out a frame on current user stack
stmia   sp, {r0 - r12}                  @ Save user registers (now in svc mode) r0-r12

ldr     r2, _armboot_start
sub     r2, r2, #(CFG_MALLOC_LEN)
sub     r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack
ldmia   r2, {r2 - r3}                   @ get values for "aborted" pc and cpsr (into parm regs)
add     r0, sp, #S_FRAME_SIZE           @ grab pointer to old stack

add     r5, sp, #S_SP
mov     r1, lr
stmia   r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr
mov     r0, sp                          @ save current stack into r0 (param register)
.endm

.macro  irq_save_user_regs
sub     sp, sp, #S_FRAME_SIZE
/*
* 将r0~r12共13个寄存器的数据都转到sp上句空出的空间里面.具体过程是:先将r0中断数据转到sp指向的地
* 址处,然后将sp调整到sp+4位置处,再将r1中的数据转过去,以此类推...
*/
stmia   sp, {r0 - r12}                  @ Calling r0-r12
add     r8, sp, #S_PC                   @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
stmdb   r8, {sp, lr}^                   @ Calling SP, LR
str     lr, [r8, #0]                    @ Save calling PC
mrs     r6, spsr
str     r6, [r8, #4]                    @ Save CPSR
str     r0, [r8, #8]                    @ Save OLD_R0
mov     r0, sp
.endm

.macro  irq_restore_user_regs
/*
* 将sp所对应的堆栈的数据送到r0~r14个寄存器中,因为lr就是r14. IA:表示先传送,再递增地址
* (4字节递增) ^:这里不涉及R15,所以只是想告诉CPU使用的是用户模式下的寄存器r0~r14
*/
ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
mov     r0, r0
ldr     lr, [sp, #S_PC]                 @ Get PC
add     sp, sp, #S_FRAME_SIZE
subs    pc, lr, #4                      @ return & move spsr_svc into cpsr
.endm

.macro get_bad_stack
ldr     r13, _armboot_start             @ setup our mode stack (enter in banked mode)
sub     r13, r13, #(CFG_MALLOC_LEN)     @ move past malloc pool
sub     r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack

str     lr, [r13]                       @ save caller lr in position 0 of saved stack
mrs     lr, spsr                        @ get the spsr
str     lr, [r13, #4]                   @ save spsr in position 1 of saved stack

mov     r13, #MODE_SVC                  @ prepare SVC-Mode
@ msr   spsr_c, r13
msr     spsr, r13                       @ switch modes, make sure moves will execute
mov     lr, pc                          @ capture return pc
movs    pc, lr                          @ jump to next instruction & switch modes.
.endm

.macro get_bad_stack_swi
sub     r13, r13, #4                    @ space on current stack for scratch reg.
str     r0, [r13]                       @ save R0's value.
ldr     r0, _armboot_start              @ get data regions start
sub     r0, r0, #(CFG_MALLOC_LEN)       @ move past malloc pool
sub     r0, r0, #(CFG_GBL_DATA_SIZE+8)  @ move past gbl and a couple spots for abort stack
str     lr, [r0]                        @ save caller lr in position 0 of saved stack
mrs     r0, spsr                        @ get the spsr
str     lr, [r0, #4]                    @ save spsr in position 1 of saved stack
ldr     r0, [r13]                       @ restore r0
add     r13, r13, #4                    @ pop stack entry
.endm

.macro get_irq_stack                    @ setup IRQ stack
ldr     sp, IRQ_STACK_START
.endm

.macro get_fiq_stack                    @ setup FIQ stack
ldr     sp, FIQ_STACK_START
.endm

/*
* exception handlers
*/
.align  5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl      do_undefined_instruction

.align  5
software_interrupt:
get_bad_stack_swi
bad_save_user_regs
bl      do_software_interrupt

.align  5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl      do_prefetch_abort

.align  5
data_abort:
get_bad_stack
bad_save_user_regs
bl      do_data_abort

.align  5
not_used:
get_bad_stack
bad_save_user_regs
bl      do_not_used

#ifdef CONFIG_USE_IRQ

.align  5
irq:
get_irq_stack
irq_save_user_regs
bl      do_irq
irq_restore_user_regs

.align  5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl      do_fiq
irq_restore_user_regs

#else

.align  5
irq:
get_bad_stack
bad_save_user_regs
bl      do_irq

.align  5
fiq:
get_bad_stack
bad_save_user_regs
bl      do_fiq

#endif
.align 5
.global arm1136_cache_flush
arm1136_cache_flush:
mcr     p15, 0, r1, c7, c5, 0   @ invalidate I cache
mov     pc, lr                  @ back to caller

#if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_CINTEGRATOR)
/* Use the IntegratorCP function from board/integratorcp/platform.S */
#elif defined(CONFIG_S3C64XX)
/* For future usage of S3C64XX*/
#else
.align  5
.globl reset_cpu
reset_cpu:
ldr     r1, rstctl      /* get addr for global reset reg */
mov     r3, #0x2        /* full reset pll+mpu */
str     r3, [r1]        /* force reset */
mov     r0, r0
_loop_forever:
b       _loop_forever
rstctl:
.word   PM_RSTCTRL_WKUP

#endif
在这一刻,我真的迷惘了,知道了江湖的成份,但是想详细了解江湖还是这么困难。但我知道我已经没有了退路,江湖我会战胜你的!

转载请注明出处:/article/8604666.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: