/*
?*??armboot?-?Startup?Code?for?S5PC110/ARM-Cortex?CPU-core
?*
?*??Copyright?(c)?2009 Samsung?Electronics
?*
?*
?*?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
?*
?*?Base?codes?by?scsuh?(sc.suh)
?*/
/*
?*??mod?by?lhh
?*
?*??Our?U-Boot?Memory?Map?with?static?mmu_table
?*??????????????????????????????????????(offset)
?*???????--------------------------?????
?*???????|?????Stack?????(512KB)??|
?*???????--------------------------?????
?*???????|?????Heap???????(1MB+envsize)???|
?*???????--------------------------????
?*???????|?????IRQ?Stack??(KB)???|?<------------------------?if?exists
?*???????--------------------------?????
?*???????|?????FIQ?Stack??(KB)???|?<------------------------?if?exists
?*???????--------------------------?????
?*???????|?????GBL???????(B)???|
?*???????--------------------------?????0x03exxxxx
?*???????|?????BSS?and?Reserved???|
?*???????--------------------------?????0x03e60000
?*???????|?????U-Boot????(512KB)??|
?*???????--------------------------?????0x03e00000
?*/
#include#include#if?defined(CONFIG_ENABLE_MMU)
#include#endif
#include#ifndef?CONFIG_ENABLE_MMU
#ifndef?CFG_PHY_UBOOT_BASE
#define?CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE
#endif?/*?CFG_PHY_UBOOT_BASE?*/
#endif?/*?CONFIG_ENABLE_MMU?*/
/*
?*************************************************************************
?*
?*?Jump?vector?table?as?in?table?3.1?in?[1]
?*
?*************************************************************************
?*/
#if?defined(CONFIG_EVT1)?&&?!defined(CONFIG_FUSED)
.word?0x2000
.word?0x0
.word?0x0
.word?0x0
#endif
?/******************************************************************************
?*?.global關(guān)鍵字,相當(dāng)于C語言extern,全局變量,外部可訪問
?*?_start程序入口,即uboot代碼的開始。_start后面“:”標(biāo)號,類似C中g(shù)oto后面標(biāo)號
?*?_start的值就是代碼的最起始,相對0的位置;跳轉(zhuǎn)到reset這個(gè)標(biāo)號執(zhí)行,即復(fù)位向量
?*?ARM上電復(fù)位后,從0x00000000執(zhí)行,跳轉(zhuǎn)到reset,不會執(zhí)行異常向量表這部分。
?*
?*?異常向量表:未定義指令異常、軟中斷異常、預(yù)處理指令異常、未使用、數(shù)據(jù)異常、
?*?中斷異常、快速中斷異常;每條占一字節(jié),地址范圍為0x0000?0000~0x0000?0020
?*?設(shè)置異常向量表的作用是識別bootloader。以后系統(tǒng)每當(dāng)有異常出現(xiàn),
?*?則CPU會根據(jù)異常號,從內(nèi)存的0x00000000處開始查表做相應(yīng)的處理
*******************************************************************************/
.globl?_start
_start:?b reset???@相對跳轉(zhuǎn),不能用絕對跳轉(zhuǎn),因?yàn)閱哟a有可能還運(yùn)行在IRAM(s5pv210內(nèi)部的SRAM)
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
@?.word偽操作,為分配一段字(4字節(jié))內(nèi)存單元
@?用C表示:pc?=?*(_x)?=?x??x=異常向量
_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:
@?這填寫的只是一個(gè)初始值,填充4字節(jié)
.word?0x12345678?/*?now?16*4=64?*/
.global?_end_vect??@?異常向量結(jié)束標(biāo)號
_end_vect:
@?表示接下來的代碼使用16字節(jié)對齊,不足的使用0xdeadbeef填充(壞牛肉)
@?類似的還有一個(gè)0xbadc0de??壞代碼(哈哈),十六進(jìn)制沒有o,是數(shù)字0
.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
?*
?*************************************************************************
?*/
@?代碼段基地址,boardsamsungTQ210config.mk中定義,TEXT_BASE=0x23e00000
_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
@?*(_armboot_start)?=?_start
.globl?_armboot_start
_armboot_start:
.word?_start
/*
?*?These?are?defined?in?the?board-specific?linker?script.
?*/
?@?棧頭和棧尾定義在鏈接腳本里:boardsamsungTQ210u-boot.lds
.globl?_bss_start
_bss_start:
.word?__bss_start
.globl?_bss_end
_bss_end:
.word?_end
@?中斷的堆棧設(shè)置,在cpu_init中用到
#if?defined(CONFIG_USE_IRQ)
/*?IRQ?stack?memory?(calculated?at?run-time)?*/
.globl?IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/*?IRQ?stack?memory?(calculated?at?run-time)?*/
.globl?FIQ_STACK_START
FIQ_STACK_START:
.word?0x0badc0de
#endif?/*?CONFIG_USE_IRQ?*/
/*
?*?the?actual?reset?code
?*/
?@?ARM復(fù)位執(zhí)行就是這里的程序,上面那部分異常只有在異常發(fā)生才會執(zhí)行
reset:
/*
?*?set?the?cpu?to?SVC32?mode?and?IRQ?&?FIQ?disable
?*/
@;mrs r0,cpsr
@;bic r0,r0,#0x1f
@;orr r0,r0,#0xd3
@;msr cpsr,r0
@?置cpu到svc32模式,關(guān)閉中斷;msr將0xd3寫到cpsr_c
31 30 29 28 --- 7 6 - 4 3 2 1 0 說明
????????N Z C V ?I F ? M4 M3 M2 M1 M0 ?
? ?????????????????????????????????0 0 0 0 0 User模式
? ?????????????????????????????????0 0 0 0 1 FIQ模式
? ?????????????????????????????????0 0 0 1 0 IRQ模式
? ?????????????????????????????????0 0 0 1 1 SVC模式
? ?????????????????????????????????1 0 0 0 0 User模式
? ?????????????????????????????????1 0 0 0 1 FIQ模式
? ?????????????????????????????????1 0 0 1 0 IRQ模式
? ?????????????????????????????????1 0 0 1 1 SVC模式
? ?????????????????????????????????1 0 1 1 1 ABT模式
? ?????????????????????????????????1 1 0 1 1 UND模式
msr cpsr_c,?#0xd3 @?I?&?F?disable,?Mode:?0x13?-?SVC???1101?0011
/*
?*************************************************************************
?*
?*?CPU_init_critical?registers
?*
?*?setup?important?registers
?*?setup?memory?timing
?*
?*************************************************************************
?*/
?????????/*
?????????*?we?do?sys-critical?inits?only?at?reboot,
?????????*?not?when?booting?from?ram!
?????????*/
@?cpu初始化
cpu_init_crit:
@?CONFIG_EVT1定義了,這段不執(zhí)行
#ifndef?CONFIG_EVT1
#if?0
bl v7_flush_dcache_all
#else
bl disable_l2cache??
mov r0,?#0x0 @?
mov r1,?#0x0 @?i
mov r3,?#0x0
mov r4,?#0x0
lp1:
mov r2,?#0x0 @?j
lp2:
mov r3,?r1,?LSL?#29 @?r3?=?r1(i)?<<29
mov r4,?r2,?LSL?#6 @?r4?=?r2(j)?<<6
orr r4,?r4,?#0x2 @?r3?=?(i<<29)|(j<<6)|(1<<1)
orr r3,?r3,?r4
mov r0,?r3 @?r0?=?r3
bl CoInvalidateDCacheIndex
add r2,?#0x1 @?r2(j)++
cmp r2,?#1024 @?r2?<?1024
bne lp2 @?jump?to?lp2
add r1,?#0x1 @?r1(i)++
cmp r1,?#8 @?r1(i)?<?8
bne lp1 @?jump?to?lp1
bl set_l2cache_auxctrl
bl enable_l2cache
#endif
#endif
bl disable_l2cache???@?關(guān)閉I/D-cache
bl set_l2cache_auxctrl_cycle
bl enable_l2cache????@?使能I/D-cache
???????/*
????????*?Invalidate?L1?I/D
????????*/
@?ARM?Architecture?Reference?Manual.pdf的745頁有例子,可以搜索CP15
@?CP15?—系統(tǒng)控制協(xié)處理器?(the?system?control?coprocessor)
@?通過協(xié)處理器指令MCR和MRC提供具體的寄存器來配置和控制caches、MMU、保護(hù)系統(tǒng)、配置時(shí)鐘模式(在bootloader時(shí)鐘初始化用到)
????????@?Register?7?-?Cache?control???Register?8?-?TLB?operations
mov r0,?#0??????????????????@?set?up?for?MCR
????????mcr p15,?0,?r0,?c8,?c7,?0???@?invalidate?TLBs??關(guān)閉TLB?緩沖頁表(虛擬機(jī)地址轉(zhuǎn)物理地址的表)的cache
????????mcr p15,?0,?r0,?c7,?c5,?0???@?invalidate?icache?icache?緩沖指令的I-cache
???????/*
????????*?disable?MMU?stuff?and?caches
????????*/
@?關(guān)閉MMU和cache?---?分析cp15的寄存器1
????????mrc p15,?0,?r0,?c1,?c0,?0??
????????bic r0,?r0,?#0x00002000?????@?clear?bits?13?(--V-)
????????bic r0,?r0,?#0x00000007?????@?clear?bits?2:0?(-CAM)
????????orr r0,?r0,?#0x00000002?????@?set?bit?1?(--A-)?Align
????????orr r0,?r0,?#0x00000800?????@?set?bit?12?(Z---)?BTB
????????mcr? p15,?0,?r0,?c1,?c0,?0??
????????/*?Read?booting?information?*/
????????ldr r0,?=PRO_ID_BASE
????????ldr r1,?[r0,#OMR_OFFSET]
????????bic r2,?r1,?#0xffffffc1
/*電源管理,保持供電*/
#ifdef?CONFIG_TQ210_IIC_PM_CHIP
/*?PS_HOLD(GPJ2_5)?set?to?output?high?*/
ldr r0,?=ELFIN_GPIO_BASE
ldr r1,?=0x00100000
str r1,?[r0,?#GPJ2CON_OFFSET]
ldr r1,?=0x0400
str r1,?[r0,?#GPJ2PUD_OFFSET]
ldr r1,?=0x20
str r1,?[r0,?#GPJ2DAT_OFFSET]
#endif?/*?CONFIG_TQ210_IIC_PM_CHIP?*/
#ifdef?CONFIG_VOGUES
/*?PS_HOLD(GPH0_0)?set?to?output?high?*/
ldr r0,?=ELFIN_GPIO_BASE
ldr r1,?=0x00000001
str r1,?[r0,?#GPH0CON_OFFSET]
ldr r1,?=0x5500
str r1,?[r0,?#GPH0PUD_OFFSET]
ldr r1,?=0x01
str r1,?[r0,?#GPH0DAT_OFFSET]
#endif
????@?啟動方式nand,SD,nor
/*?NAND?BOOT?*/
cmp r2,?#0x0 @?512B?4-cycle
moveq r3,?#BOOT_NAND
cmp r2,?#0x2 @?2KB?5-cycle
moveq r3,?#BOOT_NAND
cmp r2,?#0x4 @?4KB?5-cycle 8-bit?ECC
moveq r3,?#BOOT_NAND
cmp r2,?#0x6 @?4KB?5-cycle 16-bit?ECC
moveq r3,?#BOOT_NAND
cmp r2,?#0x8 @?OneNAND?Mux
moveq r3,?#BOOT_ONENAND
/*?SD/MMC?BOOT?*/
cmp?????r2,?#0xc
moveq???r3,?#BOOT_MMCSD
/*?NOR?BOOT?*/
cmp?????r2,?#0x14
moveq???r3,?#BOOT_NOR
#if?0 /*?Android?C110?BSP?uses?OneNAND?booting!?*/
/*?For?second?device?booting?*/
/*?OneNAND?BOOTONG?failed?*/
cmp?????r2,?#0x8
moveq???r3,?#BOOT_SEC_DEV
#endif
/*?Uart?BOOTONG?failed?*/
cmp?????r2,?#(0x1<<4)
moveq???r3,?#BOOT_SEC_DEV
ldr r0,?=INF_REG_BASE
str r3,?[r0,?#INF_REG3_OFFSET]?????
/*
?*?Go?setup?Memory?and?board?specific?bits?prior?to?relocation.
?*/
ldr sp,?=0xd0036000?/*?end?of?sram?dedicated?to?u-boot?*/
sub sp,?sp,?#12 /*?set?stack?*/
mov fp,?#0
????@?跳到底層硬件初始化,這部分代碼在自己建立的開發(fā)板目錄下的lowlevel_init.S中
@?會返回
bl lowlevel_init /*?go?setup?pll,mux,memory?*/
/*?To?hold?max8698?output?before?releasing?power?on?switch,
?*?set?PS_HOLD?signal?to?high
?*/
ldr r0,?=0xE010E81C??/*?PS_HOLD_CONTROL?register?*/
ldr r1,?=0x00005301 ?/*?PS_HOLD?output?high */
str r1,?[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?*/
/*?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.
?*/
?@?比較r1和r2,拷貝到sram
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?boot?device?is?nand?*/
beq nand_boot
cmp r1,?#BOOT_ONENAND /*?0x1?=>?boot?device?is?onenand?*/
beq onenand_boot
cmp r1,?#BOOT_MMCSD
beq mmcsd_boot
cmp r1,?#BOOT_NOR
beq nor_boot
cmp r1,?#BOOT_SEC_DEV
beq mmcsd_boot
nand_boot:
mov r0,?#0x1000
bl copy_from_nand
b after_copy
onenand_boot:
bl onenand_bl2_copy
b after_copy
mmcsd_boot:
#if?DELETE
ldr sp,?_TEXT_PHY_BASE??????
sub sp,?sp,?#12
mov fp,?#0
#endif
bl movi_bl2_copy
b after_copy
nor_boot:
bl read_hword
b after_copy
after_copy:
#if?defined(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
mcr p15,?0,?r0,?c1,?c0,?0
nop
nop
nop
nop
#endif
skip_hw_init:
/*?Set?up?the?stack ????*/
@?初始化棧,為第二階段的C語言部分做準(zhǔn)備
stack_setup:
#if?defined(CONFIG_MEMORY_UPPER_CODE)
ldr sp,?=(CFG_UBOOT_BASE?+?CFG_UBOOT_SIZE?-?0x1000)
#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????????????????????????*/
#if?defined(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????????????????????????????*/
@?初始化直接使用雙字,一次就是64個(gè)位
clbss_l:
str r2,?[r0] /*?clear?loop...????????????????????*/
add r0,?r0,?#4
cmp r0,?r1
ble clbss_l
ldr pc,?_start_armboot?@?跳轉(zhuǎn)到stage2
_start_armboot:
.word?start_armboot
#if?defined(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:
push {lr} /*?save?return?address?*/
mov r9,?r0
mov r9,?#0x100 /*?Compare?about?8KB?*/
bl copy_uboot_to_ram
tst? r0,?#0x0
bne copy_failed
#if?defined(CONFIG_EVT1)
ldr r0,?=0xd0020000
#else
ldr r0,?=0xd0030000
#endif
ldr r1,?_TEXT_PHY_BASE /*?0x23e00000?*/
#if?!defined(CONFIG_SECURE_BOOT)
1: ldr r3,?[r0],?#4
ldr r4,?[r1],?#4
teq r3,?r4
bne compare_failed /*?not?matched?*/
subs r9,?r9,?#4
bne 1b
#endif
pop {pc} /*?all?is?OK?*/
copy_failed:
/**************lhh?add?start******************/
ldr?r0,=?0xE0200080
ldr r1,?=(0x11<<12)
str r1,?[r0,?#0]
ldr r1,?=(0x2<<3)
str r1,?[r0,?#4]
/**************lhh?add?end?*******************/
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);
?*/
#if?defined(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
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
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???????????????????????@32字節(jié)對齊
undefined_instruction:
get_bad_stack???????????????????@宏,保存現(xiàn)場棧
bad_save_user_regs??????????????@宏,保存現(xiàn)場
bl do_undefined_instruction????@宏,答應(yīng)現(xiàn)場
.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
#if?defined(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?arm_cache_flush
arm_cache_flush:
???????mcr?????p15,?0,?r1,?c7,?c5,?0???????????@?invalidate?I?cache
???????mov?????pc,?lr??????????????????????????@?back?to?caller
/*
?*?????v7_flush_dcache_all()
?*
?*?????Flush?the?whole?D-cache.
?*
?*?????Corrupted?registers:?r0-r5,?r7,?r9-r11
?*
?*?????-?mm????-?mm_struct?describing?address?space
?*/
???????.align?5
.global?v7_flush_dcache_all
v7_flush_dcache_all:
ldr r0,?=0xffffffff
mrc p15,?1,?r0,?c0,?c0,?1? @?Read?CLIDR
ands r3,?r0,?#0x7000000
mov r3,?r3,?LSR?#23??????? @?Cache?level?value?(naturally?aligned)
beq? Finished
mov r10,?#0
Loop1:?????????
add r2,?r10,?r10,?LSR?#1?? @?Work?out?3xcachelevel
mov r1,?r0,?LSR?r2???????? @?bottom?3?bits?are?the?Ctype?for?this?level
and r1,?r1,?#7???????????? @?get?those?3?bits?alone
cmp r1,?#2
blt Skip??????????????????? @?no?cache?or?only?instruction?cache?at?this?level
mcr p15,?2,?r10,?c0,?c0,?0? @?write?the?Cache?Size?selection?register
mov r1,?#0
mcr p15,?0,?r1,?c7,?c5,?4? @?PrefetchFlush?to?sync?the?change?to?the?CacheSizeID?reg
mrc p15,?1,?r1,?c0,?c0,?0? @?reads?current?Cache?Size?ID?register
and r2,?r1,?#0x7??????????? @?extract?the?line?length?field
add r2,?r2,?#4???????????? @?add?4?for?the?line?length?offset?(log2?16?bytes)
ldr r4,?=0x3FF
ands r4,?r4,?r1,?LSR?#3??? @?R4?is?the?max?number?on?the?way?size?(right?aligned)
clz r5,?r4???????????????? @?R5?is?the?bit?position?of?the?way?size?increment
ldr r7,?=0x00007FFF
ands r7,?r7,?r1,?LSR?#13?? @?R7?is?the?max?number?of?the?index?size?(right?aligned)
Loop2:?????????
mov r9,?r4?????????????????????? @?R9?working?copy?of?the?max?way?size?(right?aligned)
Loop3:?????????
orr r11,?r10,?r9,?LSL?r5???????? @?factor?in?the?way?number?and?cache?number?into?R11
orr r11,?r11,?r7,?LSL?r2???????? @?factor?in?the?index?number
mcr p15,?0,?r11,?c7,?c6,?2? @?invalidate?by?set/way
subs r9,?r9,?#1????????????????? @?decrement?the?way?number
bge Loop3
subs r7,?r7,?#1????????????????? @?decrement?the?index
bge Loop2
Skip:??????????
add r10,?r10,?#2???????????????? @?increment?the?cache?number
cmp r3,?r10
bgt Loop1
Finished:
mov pc,?lr
???????.align??5
.global?disable_l2cache
disable_l2cache:
mrc?????p15,?0,?r0,?c1,?c0,?1
bic?????r0,?r0,?#(1<<1)
mcr?????p15,?0,?r0,?c1,?c0,?1
mov pc,?lr
???????.align??5
.global?enable_l2cache
enable_l2cache:
mrc?????p15,?0,?r0,?c1,?c0,?1
orr?????r0,?r0,?#(1<<1)
mcr?????p15,?0,?r0,?c1,?c0,?1
mov?????pc,?lr
???????.align??5
.global?set_l2cache_auxctrl
set_l2cache_auxctrl:
mov r0,?#0x0
mcr?????p15,?1,?r0,?c9,?c0,?2
mov?????pc,?lr
???????.align??5
.global?set_l2cache_auxctrl_cycle
set_l2cache_auxctrl_cycle:
mrc? p15,?1,?r0,?c9,?c0,?2
bic? r0,?r0,?#(0x1<<29)
bic? r0,?r0,?#(0x1<<21)
bic? r0,?r0,?#(0x7<<6)
bic? r0,?r0,?#(0x7<<0)
mcr? p15,?1,?r0,?c9,?c0,?2
mov?????pc,lr
.align?5
CoInvalidateDCacheIndex:
;/*?r0?=?index?*/
mcr?????p15,?0,?r0,?c7,?c6,?2
mov?????pc,lr
#if?defined(CONFIG_INTEGRATOR)?&&?defined(CONFIG_ARCH_CINTEGRATOR)
/*?Use?the?IntegratorCP?function?from?board/integratorcp/platform.S?*/
#elif?defined(CONFIG_S5PC11X)
/*?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