新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM啟動代碼分析(2440init.c)

        ARM啟動代碼分析(2440init.c)

        作者: 時間:2016-11-22 來源:網絡 收藏


        ;剛設置好PLL時,系統認為這是PLL還沒穩定,所有這時不用PLL的時鐘,而用外部晶振做時鐘,
        ;將PLL鎖住,過了LOCKTIME后認為PLL已經穩定了,才使用PLL給系統提供時鐘。例如S3c2410手
        ;;冊上給出鎖住時間必須大于150us,外部晶振為12M,那么(1/12M)*N>150us,其中N為U_LTIME
        或M_LTIME,N>1800,可以設置U_LTIME或和M_LTIME為0xfff,(0xfff=4096>1800),此時LOCKTIME=0xffffff.
        ;To reduce PLL lock time, adjust the LOCKTIME register.
        ldrr0,=LOCKTIME
        ldrr1,=0xffffff
        strr1,[r0]

        本文引用地址:http://www.104case.com/article/201611/320023.htm

        [ PLL_ON_START
        ; Added for confirm clock divide. for 2440.
        ; Setting value Fclk:Hclk:Pclk
        ; 這里設置的 Fclk:Hclk:Pclk = 1:3:6,因為 CLKDIV_VAL = 7
        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.
        strr1,[r0] ;數據表示分頻數

        ;UPLL和MPLL的控制參數
        ;PLLCON Bit Description Initial State
        ;MDIV [19:12] Main divider control 0x96 / 0x4d
        ;PDIV [9:4] Pre-divider control 0x03 / 0x03
        ;SDIV [1:0] Post divider control 0x0 / 0x0

        ;InputFrequency OutputFrequency MDIV PDIV SDIV
        ;12.0000MHz 48.00 MHz(Note) 56(0x38) 2 2
        ;12.0000MHz 96.00 MHz(Note) 56(0x38) 2 1
        ;12.0000MHz 271.50 MHz 173(0xad) 2 2
        ;12.0000MHz 304.00 MHz 68(0x44) 1 1
        ;12.0000MHz 405.00 MHz 127(0x7f) 2 1
        ;12.0000MHz 532.00 MHz 125(0x7d) 1 1


        ;Configure UPLL
        ; 根據手冊,要對PLL進行設置的話,就需要先設置UPLLCON,再設置MPLLCON
        ; 并且中間需要有至少七個指令周期的延時

        ldrr0,=UPLLCON
        ldrr1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)
        strr1,[r0]

        nop; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.
        nop
        nop
        nop
        nop
        nop
        nop
        ;Configure MPLL
        ldrr0,=MPLLCON
        ldrr1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
        strr1,[r0]
        ]

        ;Check if the boot is caused by the wake-up from SLEEP mode.
        ldrr1,=GSTATUS2
        ldrr0,[r1]
        tstr0,#0x2
        ;In case of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
        bneWAKEUP_SLEEP

        ;EXPORT偽指令聲明一個全局標號
        EXPORT StartPointAfterSleepWakeUp
        StartPointAfterSleepWakeUp


        ;3.置存儲相關寄存器的程序
        ;這是設置SDRAM,flash ROM 存儲器連接和工作時序的程序,片選定義的程序
        ;SMRDATA map在下面的程序中定義
        ;SMRDATA中涉及的值請參考memcfg.s程序
        ;具體寄存器各位含義請參考s3c44b0 spec
        ;Set memory control registers
        ldrr0,=SMRDATA
        ldrr1,=BWSCON;BWSCON Address
        addr2, r0, #52;End address of SMRDATA


        ; beq %F[ ]中,b為跳轉指令,eq為相等條件標識,整條語句的意思就是
        ; 如果相等,則在此條語句后面的代碼中搜索[ ]標號并跳轉。
        ; 同樣的 bcc %B[ ] 其中cc為無符號數小于,%B在此條語句前面的代碼中搜索并跳轉

        ;下面是一個循環
        ;首先把r0指向的地址單元的一個字(4字節)的內容復制到r3中,
        ;然后r0+4,這樣的話下次取的值將會是SMRDATA中的下一個個字
        ;
        ;將r3中的值寫入到r1的地址單元(BWSCON)中,并將r1+1,即
        ;下一次將會寫入到BWSCON的下一個控制器
        ;控制器以此為:BWSCON - BANKCON0 - BANKCON1 - BANKCON2 ……BANKCON7
        ;BANKSIZE - MRSRB6 - MRSRB7


        0
        ldrr3, [r0], #4
        strr3, [r1], #4
        cmpr2, r0
        bne%B0;不等于0時跳轉,也就是說一直循環直到將上面所說的控制器全部,設置了值之后才繼續執行下一步
        ;r0 是這個數據區的起始地址,r2 是數據區的結束地址,r1 是寄存器的起始地址。這樣,
        ;用一個判斷語句就可以把內存中的數據賦給這13 個存儲控制寄存器了。


        ;Initialize stacks
        ;4.初始化各模式下的棧指針
        blInitStacks


        ; Setup IRQ handler
        ;5.設置缺省中斷處理函數
        ldrr0,=HandleIRQ ;This routine is needed
        ldrr1,=IsrIRQ ;if there isnt subs pc,lr,#4 at 0x18, 0x1c
        strr1,[r0]
        ;initialize the IRQ 將普通中斷判斷程序的入口地址給HandleIRQ


        ;6.將數據段拷貝到ram中 將零初始化數據段清零 跳入C語言的main函數執行 到這步結束bootloader初步引導結束
        ;由于 ROM 和 Flash 的讀取速度相對較慢,這樣無疑會降低代碼的執行速度和系統的運行效率。
        ;為此,需要把系統的代碼復制到 RAM 中運行。
        ;If main() is used, the variable initialization will be done in __main().
        [:LNOT:USE_MAIN
        ;Copy and paste RW data/zero initialized data
        LDR r0, =|Image

        RO
        Limit| ; Get pointer to ROM data/*RO 段結束地址 */
        LDR r1, =|Image
        RW
        Base| ; and RAM copy/*RO 段起始地址 */
        LDR r3, =|Image
        ZI
        Base|

        ;Zero init base => top of initialised data
        CMP r0, r1 ; Check that they are different
        BEQ %F2
        1
        CMP r1, r3 ; Copy init data
        LDRCC r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4
        STRCC r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4
        BCC %B1
        2
        LDR r1, =|Image
        ZI
        Limit| ; Top of zero init segment
        MOV r2, #0
        3
        CMP r3, r1 ; Zero init
        STRCC r2, [r3], #4
        BCC %B3
        ]



        ;這里不能寫main,因為寫了main,系統會自動為我們完成一些初始化工作,
        ;而這些工作在這段程序中是由我們顯式地人為完成的。
        [ :LNOT:THUMBCODE
        blMain ;Dont use main() because ......
        b.
        ]

        [ THUMBCODE ;for start-up code for Thumb mode
        orrlr,pc,#1
        bxlr
        CODE16
        blMain ;Dont use main() because ......
        b.
        CODE32
        ]


        ;function initializing stacks
        InitStacks
        ;Dont use DRAM,such as stmfd,ldmfd......
        ;SVCstack is initialized before
        ;Under toolkit ver 2.5, msr cpsr,r1 can be used instead of msr cpsr_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

        ;USER mode has not be initialized.

        movpc,lr
        ;The LR register wont be valid if the current mode is not SVC mode.


        ;=====================================================================
        ; Clock division test
        ; Assemble code, because VSYNC time is very short
        ;=====================================================================
        EXPORT CLKDIV124
        EXPORT CLKDIV144

        CLKDIV124

        ldr r0, = CLKDIVN
        ldr r1, = 0x3; 0x3 = 1:2:4
        str r1, [r0]
        ;wait until clock is stable
        nop
        nop
        nop
        nop
        nop

        ldr r0, = REFRESH
        ldr r1, [r0]
        bicr1, r1, #0xff
        bicr1, r1, #(0x7<<8)
        orrr1, r1, #0x470; REFCNT135
        str r1, [r0]
        nop
        nop
        nop
        nop
        nop
        mov pc, lr

        CLKDIV144
        ldr r0, = CLKDIVN
        ldr r1, = 0x4; 0x4 = 1:4:4
        str r1, [r0]
        ;wait until clock is stable
        nop
        nop
        nop
        nop
        nop

        ldr r0, = REFRESH
        ldr r1, [r0]
        bicr1, r1, #0xff
        bicr1, r1, #(0x7<<8)
        orrr1, r1, #0x630; REFCNT675 - 1520
        str r1, [r0]
        nop
        nop
        nop
        nop
        nop
        mov pc, lr


        LTORG

        SMRDATA DATA
        ; Memory configuration should be optimized for best performance
        ; The following parameter is not optimized.
        ; Memory access cycle parameter strategy
        ; 1) The memory settings is safe parameters even at HCLK=75Mhz.
        ; 2) SDRAM refresh period is for HCLK<=75Mhz.

        DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
        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)) ;GCS6
        DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
        DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

        DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M

        DCD 0x30 ;MRSR6 CL=3clk
        DCD 0x30 ;MRSR7 CL=3clk


        ALIGN

        AREA RamData, DATA, READWRITE

        ^ _ISR_STARTADDRESS; _ISR_STARTADDRESS=0x33FF_FF00
        ;表定位在 RAM 高端,基地址為 _ISR_STARTADDRESS
        ;^是MAP的同義詞,#是FIELD的同義詞
        HandleReset # 4
        HandleUndef # 4
        HandleSWI# 4
        HandlePabort # 4
        HandleDabort # 4
        HandleReserved # 4
        HandleIRQ# 4
        HandleFIQ# 4

        ;Dont use the label IntVectorTable,
        ;The value of IntVectorTable is different with the address you think it may be.
        ;IntVectorTable
        ;@0x33FF_FF20
        HandleEINT0# 4
        HandleEINT1# 4
        HandleEINT2# 4
        HandleEINT3# 4
        HandleEINT4_7 # 4
        HandleEINT8_23 # 4
        HandleCAM# 4; Added for 2440.
        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; Added for 2440.
        HandleUSBD# 4
        HandleUSBH# 4
        HandleIIC# 4
        HandleUART0 # 4
        HandleSPI1 # 4
        HandleRTC # 4
        HandleADC # 4
        ;@0x33FF_FFA0
        END


        上一頁 1 2 下一頁

        關鍵詞: ARM啟動代碼244

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 顺昌县| 西乌珠穆沁旗| 合山市| 吴旗县| 博野县| 清新县| 沧州市| 建瓯市| 麻江县| 凤山市| 扶余县| 昌乐县| 武定县| 台东市| 阳原县| 平乡县| 新乐市| 伊宁县| 平昌县| 英德市| 四平市| 武功县| 林周县| 常山县| 洛隆县| 原阳县| 延边| 永州市| 鹿泉市| 怀化市| 海原县| 莱阳市| 天水市| 万年县| 南岸区| 石景山区| 东乡县| 延川县| 临潭县| 府谷县| 哈巴河县|