S3C2440啟動代碼分析
;==;========================================= - ;NAME:2440INIT.S
- ;DESC:Cstartupcodes
- ;Configurememory,ISR,stacks
- ;InitializeC-variables
- ;完全注釋;=========================================
- ;NAME:2440INIT.S
- ;DESC:Cstartupcodes
- ;Configurememory,ISR,stacks
- ;InitializeC-variables
- ;完全注釋
- ;HISTORY:
- ;2002.02.25:kwtark:ver0.0
- ;2002.03.20:purnnamu:AddsomefunctionsfortestingSTOP,Sleepmode
- ;2003.03.14:DonGo:Modifiedfor2440.
- ;200906.24:TinkoModified
- ;=========================================
- ;匯編不能使用include包含頭文件,所有用Get
- ;匯編也不認(rèn)識*.h文件,所有只能用*.inc
- GEToption.inc;定義芯片相關(guān)的配置
- GETmemcfg.inc;定義存儲器配置
- GET2440addr.inc;定義了寄存器符號
- ;REFRESH寄存器[22]bit:0-autorefresh;1-selfrefresh
- BIT_SELFREFRESHEQU(1<<22);用于節(jié)電模式中,SDRAM自動刷新
- ;處理器模式常量:CPSR寄存器的后5位決定目前處理器模式M[4:0]
- USERMODEEQU0x10
- FIQMODEEQU0x11
- IRQMODEEQU0x12
- SVCMODEEQU0x13
- ABORTMODEEQU0x17
- UNDEFMODEEQU0x1b
- MODEMASKEQU0x1f;M[4:0]
- NOINTEQU0xc0
- ;定義處理器各模式下堆棧地址常量
- UserStackEQU(_STACK_BASEADDRESS-0x3800);0x33ff4800~_STACK_BASEADDRESS定義在option.inc中
- SVCStackEQU(_STACK_BASEADDRESS-0x2800);0x33ff5800~
- UndefStackEQU(_STACK_BASEADDRESS-0x2400);0x33ff5c00~
- AbortStackEQU(_STACK_BASEADDRESS-0x2000);0x33ff6000~
- IRQStackEQU(_STACK_BASEADDRESS-0x1000);0x33ff7000~
- FIQStackEQU(_STACK_BASEADDRESS-0x0);0x33ff8000~
- ;arm處理器有兩種工作狀態(tài)1.arm:32位這種工作狀態(tài)下執(zhí)行字對準(zhǔn)的arm指令2.Thumb:16位這種工作狀
- ;態(tài)執(zhí)行半字對準(zhǔn)的Thumb指令
- ;因?yàn)樘幚砥鞣譃?6位32位兩種工作狀態(tài)程序的編譯器也是分16位和32兩種編譯方式所以下面的程序用
- ;于根據(jù)處理器工作狀態(tài)確定編譯器編譯方式
- ;code16偽指令指示匯編編譯器后面的指令為16位的thumb指令
- ;code32偽指令指示匯編編譯器后面的指令為32位的arm指令
- ;
- ;Arm上電時處于ARM狀態(tài),故無論指令為ARM集或Thumb集,都先強(qiáng)制成ARM集,待init.s初始化完成后
- ;再根據(jù)用戶的編譯配置轉(zhuǎn)換成相應(yīng)的指令模式。為此,定義變量THUMBCODE作為指示,跳轉(zhuǎn)到main之前
- ;根據(jù)其值切換指令模式
- ;
- ;這段是為了統(tǒng)一目前的處理器工作狀態(tài)和軟件編譯方式(16位編譯環(huán)境使用tasm.exe編譯
- ;Checkiftasm.exe(armasm-16...@ADS1.0)isused.
- GBLLTHUMBCODE;定義THUMBCODE全局變量注意EQU所定義的宏與變量的區(qū)別
- [{CONFIG}=16;如果發(fā)現(xiàn)是在用16位代碼的話(編譯選項(xiàng)中指定使用thumb指令)
- THUMBCODESETL{TRUE};一方面把THUMBCODE設(shè)置為TURE
- CODE32;另一方面暫且把處理器設(shè)置成為ARM模式,以方便初始化
- |;(|表示else)如果編譯選項(xiàng)本來就指定為ARM模式
- THUMBCODESETL{FALSE};把THUMBCODE設(shè)置為FALSE就行了
- ];結(jié)束
- MACRO;一個根據(jù)THUMBCODE把PC寄存的值保存到LR的宏
- MOV_PC_LR;宏名稱
- [THUMBCODE;如果定義了THUMBCODE,則
- bxlr;在ARM模式中要使用BX指令轉(zhuǎn)跳到THUMB指令,并轉(zhuǎn)換模式.bx指令會根據(jù)PC最后1位來確定是否進(jìn)入thumb狀態(tài)
- |;否則,
- movpc,lr;如果目標(biāo)地址也是ARM指令的話就采用這種方式
- ]
- MEND;宏定義結(jié)束標(biāo)志
- MACRO;和上面的宏一樣,只是多了一個相等的條件
- MOVEQ_PC_LR
- [THUMBCODE
- bxeqlr
- |
- moveqpc,lr
- ]
- MEND
- ;=======================================================================================
- ;下面這個宏是用于第一次查表過程的實(shí)現(xiàn)中斷向量的重定向,如果你比較細(xì)心的話就是發(fā)現(xiàn)
- ;在_ISR_STARTADDRESS=0x33FF_FF00里定義的第一級中斷向量表是采用型如Handle***的方式的.
- ;而在程序的ENTRY處(程序開始處)采用的是bHandler***的方式.
- ;在這里Handler***就是通過HANDLER這個宏和Handle***建立聯(lián)系的.
- ;這種方式的優(yōu)點(diǎn)就是正真定義的向量數(shù)據(jù)在內(nèi)存空間里,而不是在ENTRY處的ROM(FLASH)空間里,
- ;這樣,我們就可以在程序里靈活的改動向量的數(shù)據(jù)了.
- ;========================================================================================
- ;;這段程序用于把中斷服務(wù)程序的首地址裝載到pc中,有人稱之為“加載程序”。
- ;本初始化程序定義了一個數(shù)據(jù)區(qū)(在文件最后),34個字空間,存放相應(yīng)中斷服務(wù)程序的首地址。每個字
- ;空間都有一個標(biāo)號,以Handle***命名。
- ;在向量中斷模式下使用“加載程序”來執(zhí)行中斷服務(wù)程序。
- ;這里就必須講一下向量中斷模式和非向量中斷模式的概念
- ;向量中斷模式是當(dāng)cpu讀取位于0x18處的IRQ中斷指令的時候,系統(tǒng)自動讀取對應(yīng)于該中斷源確定地址上的;
- ;指令取代0x18處的指令,通過跳轉(zhuǎn)指令系統(tǒng)就直接跳轉(zhuǎn)到對應(yīng)地址
- ;函數(shù)中節(jié)省了中斷處理時間提高了中斷處理速度標(biāo)例如ADC中斷的向量地址為0xC0,則在0xC0處放如下
- ;代碼:ldrPC,=HandlerADC當(dāng)ADC中斷產(chǎn)生的時候系統(tǒng)會
- ;自動跳轉(zhuǎn)到HandlerADC函數(shù)中
- ;非向量中斷模式處理方式是一種傳統(tǒng)的中斷處理方法,當(dāng)系統(tǒng)產(chǎn)生中斷的時候,系統(tǒng)將interrupt
- ;pending寄存器中對應(yīng)標(biāo)志位置位然后跳轉(zhuǎn)到位于0x18處的統(tǒng)一中斷
- ;函數(shù)中該函數(shù)通過讀取interruptpending寄存器中對應(yīng)標(biāo)志位來判斷中斷源并根據(jù)優(yōu)先級關(guān)系再跳到
- ;對應(yīng)中斷源的處理代碼中
- ;
- ;H|------|H|------|H|------|H|------|H|------|
- ;|///||///||///||///||///|
- ;|------|<----sp|------||------||------||------|<------sp
- ;L|||------|<----spL|------||-isr--||------|isr==>pc
- ;|||||--r0--|<----sp|---r0-|<----spL|------|r0==>r0
- ;(0)(1)(2)(3)(4)
- MACRO
- $HandlerLabelHANDLER$HandleLabel
- $HandlerLabel;標(biāo)號
- subsp,sp,#4;(1)減少sp(用于存放轉(zhuǎn)跳地址)
- stmfdsp!,{r0};(2)把工作寄存器壓入棧(lrdoesnotpushbecauseitreturntooriginaladdress)
- ldrr0,=$HandleLabel;將HandleXXX的址址放入r0
- ldrr0,[r0];把HandleXXX所指向的內(nèi)容(也就是中斷程序的入口)放入r0
- strr0,[sp,#4];(3)把中斷服務(wù)程序(ISR)壓入棧
- ldmfdsp!,{r0,pc};(4)用出棧的方式恢復(fù)r0的原值和為pc設(shè)定新值(也就完成了到ISR的轉(zhuǎn)跳)
- MEND
- ;=========================================================================================
- ;在這里用IMPORT偽指令(和c語言的extren一樣)引入|ImageBase|,|Image
RO Limit|...RO - ;這些變量是通過ADS的工程設(shè)置里面設(shè)定的ROBase和RWBase設(shè)定的,
- ;最終由編譯腳本和連接程序?qū)氤绦?
- ;那為什么要引入這玩意呢,最簡單的用處是可以根據(jù)它們拷貝自已
- ;==========================================================================================
- ;ImageBase等比較古怪的變量是編譯器生成的。RO,RW,ZI這三個段都保存在Flash中,但RW,ZI在Flash中
RO - ;的地址肯定不是程序運(yùn)行時變量所存儲的位置,因此我們的程序在初始化時應(yīng)該把Flash中的RW,ZI拷貝到RAM的對應(yīng)位置。
- ;一般情況下,我們可以利用編譯器替我們實(shí)現(xiàn)這個操作。比如我們跳轉(zhuǎn)到main()時,使用b__Main,編譯器就會在__Main
- ;和Main之間插入一段匯編代碼,來替我們完成RW,ZI段的初始化。如果我們使用bMain,那么初始化工作要我們自己做。
- ;編譯器會生成如下變量告訴我們RO,RW,ZI三個段應(yīng)該位于什么位置,但是它并沒有告訴我們RW,ZI在Flash中存儲在什么位置,
- ;實(shí)際上RW,ZI在Flash中的位置就緊接著RO存儲。我們知道了ImageBase,Image
RO Limit,那么ImageRO Limit就RO - ;是RW(ROMdata)的開始。
- IMPORT|ImageBase|;BaseofROMcode
RO - IMPORT|ImageLimit|;EndofROMcode(=startofROMdata)
RO - IMPORT|ImageBase|;BaseofRAMtoinitialise
RW - IMPORT|ImageBase|;Baseandlimitofarea
ZI - IMPORT|ImageLimit|;tozeroinitialise
ZI - ;這里引入一些在其它文件中實(shí)現(xiàn)在函數(shù),包括為我們所熟知的main函數(shù)
- ;IMPORTMMU_SetAsyncBusMode
- ;IMPORTMMU_SetFastBusMode;hzh
- IMPORTMain
- ;從這里開始就是正真的代碼入口了!
- AREAInit,CODE,READONLY;這表明下面的是一個名為Init的代碼段
- ENTRY;定義程序的入口(調(diào)試用)
- EXPORT__ENTRY;導(dǎo)出符號_ENTRY,但在那用到就還沒查明
- __ENTRY
- ResetEntry
- ;1)Thecode,whichconvertstoBig-endian,shouldbeinlittleendiancode.
- ;2)ThefollowinglittleendiancodewillbecompiledinBig-Endianmode.
- ;Thecodebyteordershouldbechangedasthememorybuswidth.
- ;3)Thepseudoinstruction,DCDcannotbeusedherebecausethelinkergenerateserror.
- ;條件編譯,在編譯成機(jī)器碼前就設(shè)定好
- ASSERT:DEF:ENDIAN_CHANGE;判斷ENDIAN_CHANGE是否已定義
- [ENDIAN_CHANGE;如果已經(jīng)定義了ENDIAN_CHANGE,則(在Option.inc里已經(jīng)設(shè)為FALSE)
- ASSERT:DEF:ENTRY_BUS_WIDTH;判斷ENTRY_BUS_WIDTH是否已定義
- [ENTRY_BUS_WIDTH=32;如果已經(jīng)定義了ENTRY_BUS_WIDTH,則判斷是不是為32
- bChangeBigEndian;DCD0xea000007
- ]
- ;在bigendian中,地址為A的字單元包括字節(jié)單元A,A+1,A+2,A+3,字節(jié)單元由高位到低位為A,A+1,A+2,A+3
- ;地址為A的字單元包括半字單元A,A+2,半字單元由高位到低位為A,A+2
- [ENTRY_BUS_WIDTH=16
- andeqr14,r7,r0,lsl#20;DCD0x0007ea00也是bChangeBigEndian指令,只是由于總線不一樣而取機(jī)器碼的順序不一樣
- ];先取低位->高位上述指令是通過機(jī)器碼裝換而來的
- [ENTRY_BUS_WIDTH=8
- streqr0,[r0,-r10,ror#1];DCD0x070000ea也是bChangeBigEndian指令,只是由于總線不一樣而取機(jī)器碼的順序不一樣
- ]
- |
- bResetHandler;我們的程序由于ENDIAN_CHANGE設(shè)成FALSE就到這兒了,轉(zhuǎn)跳到復(fù)位程序入口
- ]
- bHandlerUndef;handlerforUndefinedmode;0x04
- bHandlerSWI;handlerforSWIinterrupt;0x08
- bHandlerPabort;handlerforPAbort;0x0c
- bHandlerDabort;handlerforDAbort;0x10
- b.;reserved注意小圓點(diǎn);0x14
- bHandlerIRQ;handlerforIRQinterrupt;0x18
- bHandlerFIQ;handlerforFIQinterrupt;0x1c
- ;@0x20
- bEnterPWDN;Mustbe@0x20.
- ;==================================================================================
- ;下面是改變大小端的程序,這里采用直接定義機(jī)器碼的方式,至說為什么這么做就得問三星了
- ;反正我們程序里這段代碼也不會去執(zhí)行,不用去管它
- ;==================================================================================
- ;通過設(shè)置CP15的C1的位7,設(shè)置存儲格式為Bigendian,三種總線方式
- ChangeBigEndian;//hereENTRY_BUS_WIDTH=16
- ;@0x24
- [ENTRY_BUS_WIDTH=32
- DCD0xee110f10;0xee110f10=>mrcp15,0,r0,c1,c0,0
- DCD0xe3800080;0xe3800080=>orrr0,r0,#0x80;//Big-endian
- DCD0xee010f10;0xee010f10=>mcrp15,0,r0,c1,c0,0
- ;對存儲器控制寄存器操作,指定內(nèi)存模式為Big-endian
- ;因?yàn)閯傞_始CPU都是按照32位總線的指令格式運(yùn)行的,如果采用其他的話,CPU別不了,必須轉(zhuǎn)化
- ;但當(dāng)系統(tǒng)初始化好以后,則CPU能自動識別
- ]
- [ENTRY_BUS_WIDTH=16
- DCD0x0f10ee11
- DCD0x0080e380
- DCD0x0f10ee01
- ;因?yàn)椴捎肂ig-endian模式,采用16位總線時,物理地址的高位和數(shù)據(jù)的地位對應(yīng)
- ;所以指令的機(jī)器碼也相應(yīng)的高低對調(diào)
- ]
- [ENTRY_BUS_WIDTH=8
- DCD0x100f11ee
- DCD0x800080e3
- DCD0x100f01ee
- ]
- DCD0xffffffff;swinv0xffffffissimilarwithNOPandrunwellinbothendianmode.
- DCD0xffffffff
- DCD0xffffffff
- DCD0xffffffff
- DCD0xffffffff
- bResetHandler
- ;=========================================================================================
- ;Functionforenteringpowerdownmode
- ;1.SDRAMshouldbeinself-refreshmode.
- ;2.AllinterruptshouldbemakskedforSDRAM/DRAMself-refresh.
- ;3.LCDcontrollershouldbedisabledforSDRAM/DRAMself-refresh.
- ;4.TheI-cachemayhavetobeturnedon.
- ;5.Thelocationofthefollowingcodemayhavenottobechanged.
- ;voidEnterPWDN(intCLKCON);
- EnterPWDN
- movr2,r0;r2=rCLKCON保存原始數(shù)據(jù)0x4c00000c使能各模塊的時鐘輸入
- tstr0,#0x8;測試bit[3]SLEEPmode?1=>sleep
- bneENTER_SLEEP;C=0,即TST結(jié)果非0,bit[3]=1
- ;//進(jìn)入PWDN后如果不是sleep則進(jìn)入stop
- ;//進(jìn)入Stopmode
- ENTER_STOP
- ldrr0,=REFRESH;0x48000024DRAM/SDRAMrefreshconfig
- ldrr3,[r0];r3=rREFRESH
- movr1,r3
- orrr1,r1,#BIT_SELFREFRESH;EnableSDRAMself-refresh
- strr1,[r0];EnableSDRAMself-refresh
- movr1,#16;waituntilself-refreshisissued.maynotbeneeded.
- 0
- subsr1,r1,#1
- bne%B0
- ;//wait16fclksforself-refresh
- ldrr0,=CLKCON;enterSTOPmode.
- strr2,[r0]
- movr1,#32
- 0
- subsr1,r1,#1;1)waituntiltheSTOPmodeisineffect.
- bne%B0;2)OrwaithereuntiltheCPU&Peripheralswillbeturned-off
- ;EnteringSLEEPmode,onlytheresetbywake-upisavailable.
- ldrr0,=REFRESH;exitfromSDRAMselfrefreshmode.
- strr3,[r0]
- MOV_PC_LR;backtomainprocess
- ENTER_SLEEP
- ;NOTE.
- ;1)rGSTATUS3shouldhavethereturnaddressafterwake-upfromSLEEPmode.
- ldrr0,=REFRESH
- ldrr1,[r0];r1=rREFRESH
- orrr1,r1,#BIT_SELFREFRESH
- strr1,[r0];EnableSDRAMself-refresh
- ;//EnableSDRAMself-refresh
- movr1,#16;Waituntilself-refreshisissued,whichmaynotbeneeded.
- 0
- subsr1,r1,#1
- bne%B0
- ;//Waituntilself-refreshisissued,whichmaynotbeneeded
- ldrr1,=MISCCR;IOregister
- ldrr0,[r1]
- orrr0,r0,#(7<<17);SetSCLK0=1,SCLK1=1,SCKE=1.
- strr0,[r1]
- ldrr0,=CLKCON;Entersleepmode
- strr2,[r0]
- b.;CPUwilldiehere.
- ;//進(jìn)入SleepMode,1)設(shè)置SDRAM為self-refresh
- ;//2)設(shè)置MISCCRbit[17]1:sclk0=sclk0:sclk0=0
- ;//bit[18]1:sclk1=sclk0:sclk1=0
- ;//bit[19]1:Selfrefreshretainenable
- ;//0:Selfrefreshretaindisable
- ;//When1,Afterwake-upfromsleep,Theself-refreshwillberetained.
- WAKEUP_SLEEP
- ;ReleaseSCLKnafterwake-upfromtheSLEEPmode.
- ldrr1,=MISCCR
- ldrr0,[r1]
- bicr0,r0,#(7<<17);SCLK0:0->SCLK,SCLK1:0->SCLK,SCKE:0->=SCKE.
- strr0,[r1]
- ;//設(shè)置MISCCR
- ;Setmemorycontrolregisters
- ;ldrr0,=SMRDATA
- adrlr0,SMRDATA
- ldrr1,=BWSCON;BWSCONAddress;//總線寬度和等待控制寄存器
- addr2,r0,#52;EndaddressofSMRDATA
- 0
- ldrr3,[r0],#4;數(shù)據(jù)處理后R0自加4,[R0]->R3,R0+4->R0
- strr3,[r1],#4
- cmpr2,r0
- bne%B0
- ;//設(shè)置所有的memorycontrolregister,他的初始地址為BWSCON,初始化
- ;//數(shù)據(jù)在以SMRDATA為起始的存儲區(qū)
- movr1,#256
- 0
- subsr1,r1,#1;1)waituntiltheSelfRefreshisreleased.
- bne%B0
- ;//1)waituntiltheSelfRefreshisreleased.
- ldrr1,=GSTATUS3;GSTATUS3hasthestartaddressjustafterSLEEPwake-up
- ldrr0,[r1]
- movpc,r0
- ;//跳出SleepMode,進(jìn)入Sleep狀態(tài)前的PC
- ;============================================================================================
- ;如上所說,這里采用HANDLER宏去建立Hander***和Handle***之間的聯(lián)系
- LTORG;聲明文字池,因?yàn)槲覀冇昧薼dr偽指令
- HandlerFIQHANDLERHandleFIQ
- HandlerIRQHANDLERHandleIRQ
- HandlerUndefHANDLERHandleUndef
- HandlerSWIHANDLERHandleSWI
- HandlerDabortHANDLERHandleDabort
- HandlerPabortHANDLERHandlePabort
- ;===================================================================================
- ;呵呵,來了來了.好戲來了,這一段程序就是用來進(jìn)行第二次查表的過程了.
- ;如果說第一次查表是由硬件來完成的,那這一次查表就是由軟件來實(shí)現(xiàn)的了.
- ;為什么要查兩次表??
- ;沒有辦法,ARM把所有的中斷都?xì)w納成一個IRQ中斷異常和一個FIRQ中斷異常
- ;第一次查表主要是查出是什么異常,可我們總要知道是這個中斷異常中的什么中斷呀!
- ;沒辦法了,再查一次表唄!
- ;===================================================================================
- ;//外部中斷號判斷,通過中斷服務(wù)程序入口地址存儲器的地址偏移確定
- ;//PC=[HandleEINT0+[INTOFFSET]]
- ;H|------|
- ;|///|
- ;|--isr-|====>pc
- ;L|--r8--|
- ;|--r9--|<----sp
- IsrIRQ
- subsp,sp,#4;給PC寄存器保留reservedforPC
- stmfdsp!,{r8-r9};把r8-r9壓入棧
- ldrr9,=INTOFFSET;把INTOFFSET的地址裝入r9INTOFFSET是一個內(nèi)部的寄存器,存著中斷的偏移
- ldrr9,[r9];I_ISR
- ldrr8,=HandleEINT0;這就是我們第二個中斷向量表的入口的,先裝入r8
- ;===================================================================================
- ;哈哈,這查表方法夠好了吧,r8(入口)+index*4(別望了一條指令是4bytes的喔),
- ;這不就是我們要找的那一項(xiàng)了嗎.找到了表項(xiàng),下一步做什么?肯定先裝入了!
- ;==================================================================================
- addr8,r8,r9,lsl#2;地址對齊,因?yàn)槊總€中斷向量占4個字節(jié),即isr=IvectTable+Offeset*4
- ldrr8,[r8];裝入中斷服務(wù)程序的入口
- strr8,[sp,#8];把入口也入棧,準(zhǔn)備用舊招
- ldmfdsp!,{r8-r9,pc};施招,彈出棧,哈哈,順便把r8彈出到PC了,跳轉(zhuǎn)成功!
- LTORG
- ;==============================================================================
- ;ENTRY(好了,我們的CPU要在這復(fù)位了.)
- ;==============================================================================
- ResetHandler
- ldrr0,=WTCON;1.關(guān)看門狗
- ldrr1,=0x0;bit[5]:0-disable;1-enable(reset默認(rèn))
- strr1,[r0]
- ldrr0,=INTMSK
- ldrr1,=0xffffffff;2.關(guān)中斷
- strr1,[r0]
- ldrr0,=INTSUBMSK
- ldrr1,=0x7fff;3.關(guān)子中斷
- strr1,[r0]
- [{FALSE};4.得有些表示了,該點(diǎn)點(diǎn)LED燈了,不過被FALSE掉了.
- ;rGPFDAT=(rGPFDAT&~(0xf<<4))|((~data&0xf)<<4);
- ;Led_Display
- ldrr0,=GPFCON
- ldrr1,=0x5500
- strr1,[r0]
- ldrr0,=GPFDAT
- ldrr1,=0x10
- strr1,[r0]
- ]
- ;5.為了減少PLL的locktime,調(diào)整LOCKTIME寄存器.
- ;ToreducePLLlocktime,adjusttheLOCKTIMEregister.
- ldrr0,=LOCKTIME
- ldrr1,=0xffffff;reset的默認(rèn)值
- strr1,[r0]
- ;6.下面就來設(shè)置PLL了,你的板快不快就看這了!!
- ;這里介紹一下計(jì)算公式
- ;//Fpllo=(m*Fin)/(p*2^s)
- ;//m=MDIV+8,p=PDIV+2,s=SDIV
- ;TheproperrangeofPandM:1<=P<=62,1<=M<=248
- ;Fpllo必須大于200Mhz小于600Mhz
- ;Fpllo*2^s必須小于1.2GHz
- ;如下面的PLLCON設(shè)定中的M_DIVP_DIVS_DIV是取自option.h中
- ;#elif(MCLK==40000000)
- ;#definePLL_M(0x48)
- ;#definePLL_P(0x3)
- ;#definePLL_S(0x2)
- ;所以m=MDIV+8=80,p=PDIV+2=5,s=SDIV=2
- ;硬件使用晶振為10Mhz,即Fin=10Mhz
- ;Fpllo=80*10/5*2^2=40Mhz
- [PLL_ON_START
- ;Addedforconfirmclockdivide.for2440.
- ;SettingvalueFclk:Hclk:Pclk
- ldrr0,=CLKDIVN
- ldrr1,=CLKDIV_VAL;0=1:1:1,1=1:1:2,2=1:2:2,3=1:2:4,4=1:4:4,5=1:4:8,6=1:3:3,7=1:3:6.option.inc中定義CLKDIV_VAL=7
- strr1,[r0];//數(shù)據(jù)表示分頻數(shù)
- ;===============================================================================
- ;MMU_SetAsyncBusMode和MMU_SetFastBusMode都在4K代碼以上,
- ;如果你想你編譯出來的程序能在NAND上運(yùn)行的話,就不要在這調(diào)用這兩函數(shù)了.
- ;如果你不要求的話,你就用把.啥事沒有.
- ;為什么是4K,問三星吧,就提供4K的內(nèi)部SRAM,要是提供400K多好呀.
- ;好了,好了,4K就4K吧,不能用這兩函數(shù),自己寫還不行嗎,下面的代碼這這么來了,
- ;實(shí)現(xiàn)和上面兩函數(shù)一樣的功能.
- ;===============================================================================
- ;[CLKDIV_VAL>1;意思是Fclk:Hclk不是1:1.
- ;blMMU_SetAsyncBusMode
- ;|
- ;blMMU_SetFastBusMode;defaultvalue.
- ;]
- ;==手冊第243頁==
- ;IfHDIVNisnot0,theCPUbusmodehastobechangedfromthefastbusmodetotheasynchronous
- ;busmodeusingfollowinginstructions
- ;MMU_SetAsyncBusMode
- ;mrcp15,0,r0,c1,c0,0
- ;orrr0,r0,#R1_nF:OR:R1_iA
- ;mcrp15,0,r0,c1,c0,0
- [CLKDIV_VAL>1;意思是Fclk:Hclk不是1:1.
- mrcp15,0,r0,c1,c0,0
- orrr0,r0,#0xc0000000;R1_nF:OR:R1_iA
- mcrp15,0,r0,c1,c0,0
- |
- mrcp15,0,r0,c1,c0,0
- bicr0,r0,#0xc0000000;R1_iA:OR:R1_nF
- mcrp15,0,r0,c1,c0,0
- ]
- ;配置UPLL
- ;//ConfigureUPLLFin=12.0MHzUFout=48MHz
- ldrr0,=UPLLCON
- ldrr1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV);//USBPLLCONFIG56,2,2===>48MHz
- strr1,[r0]
- ;7個nop必不可少??!
- nop;//Caution:AfterUPLLsetting,atleast7-clocksdelaymustbeinsertedforsettinghardwarebecompleted.
- nop
- nop
- nop
- nop
- nop
- nop
- ;配置MPLL
- ;//ConfigureMPLLFin=12.0MHzMFout=304.8MHz
- ldrr0,=MPLLCON
- ldrr1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV);68,1,1==>304MHz
- strr1,[r0]
- ]
- ;檢查是否從SLEEP模式中恢復(fù)
- ;//Checkifthebootiscausedbythewake-upfromSLEEPmode.
- ldrr1,=GSTATUS2
- ldrr0,[r1]
- tstr0,#0x2;testifbit[1]is1or00->C=1
- ;1->C=0
- ;Incaseofthewake-upfromSLEEPmode,gotoSLEEP_WAKEUPhandler.
- bneWAKEUP_SLEEP;C=0,jump
- EXPORTStartPointAfterSleepWakeUp
- StartPointAfterSleepWakeUp
- ;===============================================================================
- ;設(shè)置內(nèi)存控制器等寄存器的值,因?yàn)檫@些寄存器是連續(xù)排列的,所以采用如下辦法對這些
- ;寄存器進(jìn)行連續(xù)設(shè)置.其中用到了SMRDATA的數(shù)據(jù),這在代碼后面有定義
- ;===============================================================================
- ;這是設(shè)置SDRAM,flashROM存儲器連接和工作時序的程序,片選定義的程序
- ;SMRDATAmap在下面的程序中定義
- ;SMRDATA中涉及的值請參考memcfg.inc程序
- ;Setmemorycontrolregisters
- ;ldrr0,=SMRDATA;dangerous!!!
- adrlr0,SMRDATA;becareful!,tinko
- ldrr1,=BWSCON;BWSCONAddress
- addr2,r0,#52;EndaddressofSMRDATA;SMRDATA數(shù)據(jù)的結(jié)束地址,共有52字節(jié)的數(shù)據(jù)
- 0
- ldrr3,[r0],#4
- strr3,[r1],#4
- cmpr2,r0
- bne%B0;%表示搜索,B表示反向-back(F表示向前-forward),0為局部標(biāo)號(0~99)
- ;================================================================================
- ;如果EINT0產(chǎn)生(這中斷就是我們按鍵產(chǎn)生的),就清除SDRAM,不過好像沒人會在這個時候按
- ;================================================================================
- ;checkifEIN0buttonispressed
- ldrr0,=GPFCON
- ldrr1,=0x0;00=Input
- strr1,[r0]
- ldrr0,=GPFUP
- ldrr1,=0xff;1-Thepullupfunctionisdisabled.
- strr1,[r0]
- ldrr1,=GPFDAT
- ldrr0,[r1]
- bicr0,r0,#(0x1e<<1);bitclear
- tstr0,#0x1
- bne%F1;如果沒有按,就跳到后面的1標(biāo)號處=>Initializestacks
- ;這就是清零內(nèi)存的代碼
- ldrr0,=GPFCON
- ldrr1,=0x55aa
- strr1,[r0]
- ;ldrr0,=GPFUP
- ;ldrr1,=0xff
- ;strr1,[r0]
- ldrr0,=GPFDAT
- ldrr1,=0x0
- strr1,[r0];LED=****
- movr1,#0
- movr2,#0
- movr3,#0
- movr4,#0
- movr5,#0
- movr6,#0
- movr7,#0
- movr8,#0
- ldrr9,=0x4000000;64MB
- ldrr0,=0x30000000
- 0
- stmiar0!,{r1-r8}
- subsr9,r9,#32
- bne%B0
- ;到這就結(jié)束了.
- ;//4.初始化各模式下的棧指針
- ;Initializestacks
- 1
- blInitStacks
- ;=======================================================================
- ;哈哈,下面又有看頭了,這個初始化程序好像被名曰hzh的高手改過
- ;能在NORNAND還有內(nèi)存中運(yùn)行,當(dāng)然了,在內(nèi)存中運(yùn)行最簡單了.
- ;在NORNAND中運(yùn)行的話都要先把自己拷到內(nèi)存中.
- ;此外,還記得上面提到的|ImageBase|,|Image
RO Limit|...嗎?RO - ;這就是拷貝的依據(jù)了!!!
- ;=========================================================================
- ;BWSCON的[2:1]反映了外部引腳OM[1:0]:若OM[1:0]!=00,從NORFLash啟動或直接在內(nèi)存運(yùn)行;若OM[1:0]==00,則為NandFlashMode
- ldrr0,=BWSCON
- ldrr0,[r0]
- andsr0,r0,#6;#6==0110-->BWSCON[2:1]
- bnecopy_proc_beg;OM[1:0]!=00,NORFLashboot,不讀取NANDFLASH
- adrr0,ResetEntry;否則,OM[1:0]==0,為從NANDFLash啟動
- cmpr0,#0;再比較入口是否為0地址處
- ;如果是0才是真正從NAND啟動,因?yàn)槠?k被復(fù)制到0地址開始的stepingstone內(nèi)部sram中
- ;注意adr得到的是相對地址,非絕對地址==ifuseMulti-ice,
- bnecopy_proc_beg;如果!=0,說明在usingice,這種情況也不讀取NANDFLASH.dontreadnandflashforboot
- ;nop
- ;==============這一段代碼完成從NANDFlash讀代碼到RAM=====================
- nand_boot_beg;
- movr5,#NFCONF;首先設(shè)定NAND的一些控制寄存器
- ;settimingvalue
- ldrr0,=(7<<12)|(7<<8)|(7<<4)
- strr0,[r5]
- ;enablecontrol
- ldrr0,=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
- strr0,[r5,#4]
- blReadNandID;按著讀取NAND的ID號,結(jié)果保存在r5里
- movr6,#0;r6設(shè)初值0.
- ldrr0,=0xec73;期望的NANDID號
- cmpr5,r0;這里進(jìn)行比較
- beq%F1;相等的話就跳到下一個1標(biāo)號處
- ldrr0,=0xec75;這是另一個期望值
- cmpr5,r0
- beq%F1;相等的話就跳到下一個1標(biāo)號處
- movr6,#1;不相等,設(shè)置r6=1.
- 1
- blReadNandStatus;讀取NAND狀態(tài),結(jié)果放在r1里
- movr8,#0;r8設(shè)初值0,意義為頁號
- ldrr9,=ResetEntry;r9設(shè)初值為初始化程序入口地址
- ;注意,在這里使用的是ldr偽指令,而不是上面用的adr偽指令,它加載的是ResetEntry
- ;的絕對地址,也就是我們期望的RAM中的地址,在這里,它和|ImageBase|一樣
RO - ;也就是說,我如我們編譯程序時RObase指定的地址在RAM里,而把生成的文件拷到
- ;NAND里運(yùn)行,由ldr加載的r9的值還是定位在內(nèi)存.???
- 2
- andsr0,r8,#0x1f;凡r8為0x1f(32)的整數(shù)倍-1,eq有效,ne無效
- bne%F3;這句的意思是對每個塊(32頁)進(jìn)行檢錯--在每個塊的開始頁進(jìn)行
- movr0,r8;r8->r0
- blCheckBadBlk;檢查NAND的壞區(qū)
- cmpr0,#0;比較r0和0
- addner8,r8,#32;存在壞塊的話就跳過這個壞塊:+32得到下一塊.故:r8=blockpageaddr,因?yàn)樽x寫是按頁進(jìn)行的(每頁512Byte)
- bne%F4;然后跳到4進(jìn)行循環(huán)條件判斷。沒有的話就跳到標(biāo)號3處copy當(dāng)前頁
- 3
- movr0,r8;當(dāng)前頁號->r0
- movr1,r9;當(dāng)前目標(biāo)地址->r1
- blReadNandPage;讀取該頁的NAND數(shù)據(jù)到RAM
- addr9,r9,#512;每一頁的大小是512Bytes
- addr8,r8,#1;r8指向下一頁
- 4
- cmpr8,#256;比較是否讀完256頁即128KBytes
- ;注意:這說明此程序默認(rèn)拷貝128KByte的代碼(byTinko)
- bcc%B2;如果r8小于256(沒讀完),就返回前面的標(biāo)號2處
- ;nowcopycompleted
- movr5,#NFCONF;DisableNandFlash
- ldrr0,[r5,#4]
- bicr0,r0,#1
- strr0,[r5,#4]
- ldrpc,=copy_proc_beg;調(diào)用copy_proc_beg
- ;個人認(rèn)為應(yīng)該為InitRam?????????????????????????????
- ;===========================================================
- copy_proc_beg
- adrlr0,ResetEntry;ResetEntry值->r0
- ;這里應(yīng)該注意,使用的是adr,而不是ldr。使用ldr說明ResetEntry是個絕對地址,這個地址是在程序鏈接的時候
- ;確定的。而使用adr則說明ResetEntry的地址和當(dāng)前代碼的執(zhí)行位置有關(guān),它是一個相對的地址。比如這段代碼
- ;在stepingstone里面執(zhí)行,那么ResetEntry的地址就是零。如果在RAM里執(zhí)行,那么ResetEntry就應(yīng)是RAM的一個
- ;地址,應(yīng)該等于RObase。
- ldrr2,BaseOfROM;BaseOfROM值(后面有定義)->r2
- cmpr0,r2;比較ResetEntry和BaseOfROM
- ldreqr0,TopOfROM;如果相等的話(在內(nèi)存運(yùn)行---ice--無需復(fù)制code區(qū)中的ro段,但需要復(fù)制code區(qū)中的rw段),TopOfROM->r0
- beqInitRam;同時跳到InitRam
- ;否則,下面開始復(fù)制code的RO段
- ;=========================================================
- ;下面這個是針對代碼在NORFLASH時的拷貝方法
- ;功能為把從ResetEntry起,TopOfROM-BaseOfROM大小的數(shù)據(jù)拷到BaseOfROM
- ;TopOfROM和BaseOfROM為|ImageLimit|和|Image
RO Base|RO - ;|ImageLimit|和|Image
RO Base|由連接器生成RO - ;為生成的代碼的代碼段運(yùn)行時的起啟和終止地址
- ;BaseOfBSS和BaseOfZero為|ImageBase|和|Image
RW Base|ZI - ;|ImageBase|和|Image
RW Base|也是由連接器生成ZI - ;兩者之間就是初始化數(shù)據(jù)的存放地
- ;--在加載階段,不存在ZI區(qū)域--
- ;=======================================================
- ldrr3,TopOfROM
- 0
- ldmiar0!,{r4-r7};開始時,r0=ResetEntry---source
- stmiar2!,{r4-r7};開始時,r2=BaseOfROM---destination
- cmpr2,r3;終止條件:復(fù)制了TopOfROM-BaseOfROM大小
- bcc%B0
- ;---------------------------------------------------------------
- ;下面2行,根據(jù)理解,由tinko添加
- ;猜測上面的代碼不應(yīng)該用"!",以至于地址被修改。這里重新賦值
- ;---------------------------------------------------------------
- adrlr0,ResetEntry;dontuseadr,causeoutofrangeerroroccures
- ldrr2,BaseOfROM
- ;旨在計(jì)算出正確的RW區(qū)起始位置
- ;下面2行目的是為了計(jì)算正確的r0(必須使之指向code區(qū)中的rw域開始處)
- subr2,r2,r3;r2=BaseOfROM-TopOfROM=(-)代碼長度
- subr0,r0,r2;r0=ResetEntry-(-)代碼長度=ResetEntry+代碼長度
- InitRam
- ;復(fù)制代碼加載位置中的RM區(qū)到|ImageBase|
RW - ldrr2,BaseOfBSS;BaseOfBSS->r2,BaseOfBSS=|ImageBase|
RW - ldrr3,BaseOfZero;BaseOfZero->r3,BaseOfZero=|ImageBase|
ZI - 0
- cmpr2,r3;比較BaseOfBSS和BaseOfZero
- ldrccr1,[r0],#4;當(dāng)代碼在內(nèi)存中運(yùn)行時,r0(初始值)=TopOfROM.這之后的BaseOfZero-BaseOfBSS仍屬于code,需拷貝到BaseOfBSS
- strccr1,[r2],#4
- bcc%B0
- ;用0初始化ZI區(qū)
- movr0,#0
- ldrr3,EndOfBSS;EndOfBSS=|ImageLimit|
ZI - 1
- cmpr2,r3
- strccr0,[r2],#4
- bcc%B1
- ;要是r21;meansFclk:Hclkisnot1:1.
- ;blMMU_SetAsyncBusMode
- ;|
- ;blMMU_SetFastBusMode;defaultvalue.
- ;]
- ;blLed_Test
- ;===========================================================
- ;進(jìn)入C語言前的最后一步了,就是把我們用說查二級向量表
- ;的中斷例程安裝到一級向量表(異常向量表)里.
- ;//5.設(shè)置缺省中斷處理函數(shù)
- ;SetupIRQhandler
- ldrr0,=HandleIRQ;Thisroutineisneeded
- ldrr1,=IsrIRQ;ifthereisntsubspc,lr,#4at0x18,0x1c
- strr1,[r0]
- ;//initializetheIRQ將普通中斷判斷程序的入口地址給HandleIRQ
- ;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ;注意,以下這段可能不需要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;//6.將數(shù)據(jù)段拷貝到ram中將零初始化數(shù)據(jù)段清零跳入C語言的main函數(shù)執(zhí)行到這步結(jié)束bootloader初步引導(dǎo)結(jié)束
- ;Ifmain()isused,thevariableinitializationwillbedonein__main().
- [{FALSE};bytinko--最外面的條件由tinko添加,實(shí)際上不再執(zhí)行這段
- [:LNOT:USE_MAIN;initialized{FALSE}
- ;CopyandpasteRWdata/zeroinitializeddata
- LDRr0,=|ImageLimit|;GetpointertoROMdata
RO - LDRr1,=|ImageBase|;andRAMcopy
RW - LDRr3,=|ImageBase|
ZI - ;Zeroinitbase=>topofinitialiseddata
- CMPr0,r1;Checkthattheyaredifferentjustfordebug??????????????????????????
- BEQ%F2
- 1
- CMPr1,r3;Copyinitdata
- LDRCCr2,[r0],#4;-->LDRCCr2,[r0]+ADDr0,r0,#4
- STRCCr2,[r1],#4;-->STRCCr2,[r1]+ADDr1,r1,#4
- BCC%B1
- 2
- LDRr1,=|ImageLimit|;Topofzeroinitsegment
ZI - MOVr2,#0
- 3
- CMPr3,r1;Zeroinit
- STRCCr2,[r3],#4
- BCC%B3
- ]
- ]
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;***************************************
- ;bytinko
- [{TRUE};得有些表示了,該點(diǎn)點(diǎn)LED燈了
- ;rGPFDAT=(rGPFDAT&~(0xf<<4))|((~data&0xf)<<4);
- ;Led_Display
- ldrr0,=GPFCON
- ldrr1,=0x5500
- strr1,[r0]
- ldrr0,=GPFDAT
- ldrr1,=0xe0
- strr1,[r0]
- ldrr2,=0xffffffff;
- 1
- subr2,r2,#1
- bne%b1
- ldrr0,=GPFDAT
- ldrr1,=0xe0
- ;b.;diehere
- ]
- ;*****************************************
- ;*****************************************************************************
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;媽呀,終說見到艷陽天了!!!!!!!!!!
- ;跳到C語言的main函數(shù)處了.
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;*****************************************************************************
- [:LNOT:THUMBCODE;ifthumbcode={false}blmainL代表logic變量
- blMain;Dontusemain()because......
- b.;注意小圓點(diǎn)
- ]
- ;//ifthumbcod={ture}
- [THUMBCODE;forstart-upcodeforThumbmode
- orrlr,pc,#1
- bxlr
- CODE16
- blMain;Dontusemain()because......
- b.;注意小圓點(diǎn)
- CODE32
- ]
- ;functioninitializingstacks
- InitStacks
- ;DontuseDRAM,suchasstmfd,ldmfd......
- ;SVCstackisinitializedbefore
- ;Undertoolkitver2.5,msrcpsr,r1canbeusedinsteadofmsrcpsr_cxsf,r1
- mrsr0,cpsr
- bicr0,r0,#MODEMASK
- orrr1,r0,#UNDEFMODE|NOINT
- msrcpsr_cxsf,r1;UndefMode
- ldrsp,=UndefStack;UndefStack=0x33FF_5C00
- orrr1,r0,#ABORTMODE|NOINT
- msrcpsr_cxsf,r1;AbortMode
- ldrsp,=AbortStack;AbortStack=0x33FF_6000
- orrr1,r0,#IRQMODE|NOINT
- msrcpsr_cxsf,r1;IRQMode
- ldrsp,=IRQStack;IRQStack=0x33FF_7000
- orrr1,r0,#FIQMODE|NOINT
- msrcpsr_cxsf,r1;FIQMode
- ldrsp,=FIQStack;FIQStack=0x33FF_8000
- bicr0,r0,#MODEMASK|NOINT
- orrr1,r0,#SVCMODE
- msrcpsr_cxsf,r1;SVCMode
- ldrsp,=SVCStack;SVCStack=0x33FF_5800
- ;USERmodehasnotbeinitialized.
- ;//為什么不用初始化user的stacks,系統(tǒng)剛啟動的時候運(yùn)行在哪個模式下?
- movpc,lr
- ;TheLRregisterwontbevalidifthecurrentmodeisnotSVCmode.?
- ;//系統(tǒng)一開始運(yùn)行就是SVCmode?
- ;===========================================================
- ReadNandID
- movr7,#NFCONF
- ldrr0,[r7,#4];NFChipEn();
- bicr0,r0,#2
- strr0,[r7,#4]
- movr0,#0x90;WrNFCmd(RdIDCMD);
- strbr0,[r7,#8]
- movr4,#0;WrNFAddr(0);
- strbr4,[r7,#0xc]
- 1;while(NFIsBusy());
- ldrr0,[r7,#0x20]
- tstr0,#1
- beq%B1
- ldrbr0,[r7,#0x10];id=RdNFDat()<<8;
- movr0,r0,lsl#8
- ldrbr1,[r7,#0x10];id|=RdNFDat();
- orrr5,r1,r0
- ldrr0,[r7,#4];NFChipDs();
- orrr0,r0,#2
- strr0,[r7,#4]
- movpc,lr
- ReadNandStatus
- movr7,#NFCONF
- ldrr0,[r7,#4];NFChipEn();
- bicr0,r0,#2
- strr0,[r7,#4]
- movr0,#0x70;WrNFCmd(QUERYCMD);
- strbr0,[r7,#8]
- ldrbr1,[r7,#0x10];r1=RdNFDat();
- ldrr0,[r7,#4];NFChipDs();
- orrr0,r0,#2
- strr0,[r7,#4]
- movpc,lr
- WaitNandBusy
- movr0,#0x70;WrNFCmd(QUERYCMD);
- movr1,#NFCONF
- strbr0,[r1,#8]
- 1;while(!(RdNFDat()&0x40));
- ldrbr0,[r1,#0x10]
- tstr0,#0x40
- beq%B1
- movr0,#0;WrNFCmd(READCMD0);
- strbr0,[r1,#8]
- movpc,lr
- CheckBadBlk
- movr7,lr
- movr5,#NFCONF
- bicr0,r0,#0x1f;addr&=~0x1f;
- ldrr1,[r5,#4];NFChipEn()
- bicr1,r1,#2
- strr1,[r5,#4]
- movr1,#0x50;WrNFCmd(READCMD2)
- strbr1,[r5,#8]
- movr1,#5;6;6->5
- strbr1,[r5,#0xc];WrNFAddr(5);(6)6->5
- strbr0,[r5,#0xc];WrNFAddr(addr)
- movr1,r0,lsr#8;WrNFAddr(addr>>8)
- strbr1,[r5,#0xc]
- cmpr6,#0;if(NandAddr)
- movner0,r0,lsr#16;WrNFAddr(addr>>16)
- strnebr0,[r5,#0xc]
- ;blWaitNandBusy;WaitNFBusy()
- ;donotuseWaitNandBusy,afterWaitNandBusywillreadpartA!
- movr0,#100
- 1
- subsr0,r0,#1
- bne%B1
- 2
- ldrr0,[r5,#0x20]
- tstr0,#1
- beq%B2
- ldrbr0,[r5,#0x10];RdNFDat()
- subr0,r0,#0xff
- movr1,#0;WrNFCmd(READCMD0)
- strbr1,[r5,#8]
- ldrr1,[r5,#4];NFChipDs()
- orrr1,r1,#2
- strr1,[r5,#4]
- movpc,r7
- ReadNandPage
- movr7,lr
- movr4,r1
- movr5,#NFCONF
- ldrr1,[r5,#4];NFChipEn()
- bicr1,r1,#2
- strr1,[r5,#4]
- movr1,#0;WrNFCmd(READCMD0)
- strbr1,[r5,#8]
- strbr1,[r5,#0xc];WrNFAddr(0)
- strbr0,[r5,#0xc];WrNFAddr(addr)
- movr1,r0,lsr#8;WrNFAddr(addr>>8)
- strbr1,[r5,#0xc]
- cmpr6,#0;if(NandAddr)
- movner0,r0,lsr#16;WrNFAddr(addr>>16)
- strnebr0,[r5,#0xc]
- ldrr0,[r5,#4];InitEcc()
- orrr0,r0,#0x10
- strr0,[r5,#4]
- blWaitNandBusy;WaitNFBusy()
- movr0,#0;for(i=0;i<512;i++)
- 1
- ldrbr1,[r5,#0x10];buf[i]=RdNFDat()
- strbr1,[r4,r0]
- addr0,r0,#1
- bicr0,r0,#0x10000
- cmpr0,#0x200
- bcc%B1
- ldrr0,[r5,#4];NFChipDs()
- orrr0,r0,#2
- strr0,[r5,#4]
- movpc,r7
- ;--------------------LEDtest
- EXPORTLed_Test
- Led_Test
- movr0,#0x56000000
- movr1,#0x5500
- strr1,[r0,#0x50]
- 0
- movr1,#0x50
- strr1,[r0,#0x54]
- movr2,#0x100000
- 1
- subsr2,r2,#1
- bne%B1
- movr1,#0xa0
- strr1,[r0,#0x54]
- movr2,#0x100000
- 2
- subsr2,r2,#1
- bne%B2
- b%B0
- movpc,lr
- ;===========================================================
- ;=====================================================================
- ;Clockdivisiontest
- ;Assemblecode,becauseVSYNCtimeisveryshort
- ;=====================================================================
- EXPORTCLKDIV124
- EXPORTCLKDIV144
- CLKDIV124
- ldrr0,=CLKDIVN
- ldrr1,=0x3;0x3=1:2:4
- strr1,[r0]
- ;waituntilclockisstable
- nop
- nop
- nop
- nop
- nop
- ldrr0,=REFRESH
- ldrr1,[r0]
- bicr1,r1,#0xff
- bicr1,r1,#(0x7<<8)
- orrr1,r1,#0x470;REFCNT135
- strr1,[r0]
- nop
- nop
- nop
- nop
- nop
- movpc,lr
- CLKDIV144
- ldrr0,=CLKDIVN
- ldrr1,=0x4;0x4=1:4:4
- strr1,[r0]
- ;waituntilclockisstable
- nop
- nop
- nop
- nop
- nop
- ldrr0,=REFRESH
- ldrr1,[r0]
- bicr1,r1,#0xff
- bicr1,r1,#(0x7<<8)
- orrr1,r1,#0x630;REFCNT675-1520
- strr1,[r0]
- nop
- nop
- nop
- nop
- nop
- movpc,lr
- ;存儲器控制寄存器的定義區(qū)
- LTORG
- SMRDATADATA
- ;Memoryconfigurationshouldbeoptimizedforbestperformance
- ;Thefollowingparameterisnotoptimized.
- ;Memoryaccesscycleparameterstrategy
- ;1)ThememorysettingsissafeparametersevenatHCLK=75Mhz.
- ;2)SDRAMrefreshperiodisforHCLK<=75Mhz.
- DCD(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28));各bank的buswidth;沒有B0,因?yàn)橛蒓M[1:0]pins確定
- DCD((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC));GCS0
- DCD((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC));GCS1
- DCD((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC));GCS2
- DCD((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC));GCS3
- DCD((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC));GCS4
- DCD((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC));GCS5
- DCD((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN));GCS6B6_MT定義在memcfg.inc中,11-->SDRAM;B6_SCAN-非reset默認(rèn)值
- DCD((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN));GCS7
- DCD((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT);Tchr-notused
- ;DCD0x32;SCLKpowersavingmode,BANKSIZE128M/128M
- DCD0x31;SCLKpowersavingmode,BANKSIZE64M/64M
- DCD0x30;MRSR6CL=3clk
- DCD0x30;MRSR7CL=3clk
- BaseOfROMDCD|ImageBase|
RO - TopOfROMDCD|ImageLimit|
RO - BaseOfBSSDCD|ImageBase|
RW - BaseOfZeroDCD|ImageBase|
ZI - EndOfBSSDCD|ImageLimit|
ZI - ALIGN
- AREARamData,DATA,READWRITE
- ^_ISR_STARTADDRESS;_ISR_STARTADDRESS=0x33FF_FF00
- HandleReset#4
- HandleUndef#4
- HandleSWI#4
- HandlePabort#4
- HandleDabort#4
- HandleReserved#4
- HandleIRQ#4
- HandleFIQ#4
- ;DontusethelabelIntVectorTable,
- ;ThevalueofIntVectorTableisdifferentwiththeaddressyouthinkitmaybe.
- ;IntVectorTable
- ;@0x33FF_FF20
- HandleEINT0#4
- HandleEINT1#4
- HandleEINT2#4
- HandleEINT3#4
- HandleEINT4_7#4
- HandleEINT8_23#4
- HandleCAM#4;Addedfor2440.
- HandleBATFLT#4
- HandleTICK#4
- HandleWDT#4
- HandleTIMER0#4
- HandleTIMER1#4
- HandleTIMER2#4
- HandleTIMER3#4
- HandleTIMER4#4
- HandleUART2#4
- ;@0x33FF_FF60
- HandleLCD#4
- HandleDMA0#4
- HandleDMA1#4
- HandleDMA2#4
- HandleDMA3#4
- HandleMMC#4
- HandleSPI0#4
- HandleUART1#4
- HandleNFCON#4;Addedfor2440.
- HandleUSBD#4
- HandleUSBH#4
- HandleIIC#4
- HandleUART0#4
- HandleSPI1#4
- HandleRTC#4
- HandleADC#4
- ;@0x33FF_FFA0
- END
評論