/* ?*??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后面“:”標號,類似C中g(shù)oto后面標號 ?*?_start的值就是代碼的最起始,相對0的位置;跳轉(zhuǎn)到reset這個標號執(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),因為啟動代碼有可能還運行在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: @?這填寫的只是一個初始值,填充4字節(jié) .word?0x12345678?/*?now?16*4=64?*/ .global?_end_vect??@?異常向量結(jié)束標號 _end_vect: @?表示接下來的代碼使用16字節(jié)對齊,不足的使用0xdeadbeef填充(壞牛肉) @?類似的還有一個0xbadc0de??壞代碼(哈哈),十六進制沒有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、保護系統(tǒng)、配置時鐘模式(在bootloader時鐘初始化用到) ????????@?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?緩沖頁表(虛擬機地址轉(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語言部分做準備 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個位 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