<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x
    查看: 3177|回復: 5
    打印 上一主題 下一主題

    開貼分析FL2440的bootloader

    [復制鏈接]
    跳轉到指定樓層
    樓主
    發表于 2010-9-11 12:32:54 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    關鍵詞: bootloader
    本文轉引自 飛凌嵌入式FL2440技術交流版 www.witech.com.cn
    感謝作者:jsacer2008的無私奉獻
    首先申明本人學習ARM不過數月,根基尚淺。以下分析如有謬誤,還請大家之爭。本著探討和共同進步的目的,我把我花了幾個星期看完的
    bootloader并做得分析貼出。首先,bootloader中最重要的就是2440init.s引導代碼,現將其貼出,整個文檔太大,附件中沒法上傳,需要的
    朋友可以去FL群空間里下載
    ;=========================================
    ; NAME: 2440INIT.S
    ; DESC: C start up codes
    ;       Configure memory, ISR ,stacks
    ;        Initialize C-variables
    ; HISTORY:
    ; 2002.02.25:kwtark: ver 0.0
    ; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
    ; 2003.03.14onGo: Modified for 2440.
    ;2010.09.02:jinzhenjun analysed
    ;=========================================
            GET option.inc
            GET memcfg.inc
            GET 2440addr.inc
    BIT_SELFREFRESH EQU        (1<<22)
    re-defined constants                                                                                                         
                                                          ;系統的工作模式設定,宏定義
    ;對應的是各工作模式在CPSR中的位
    ;                                                        7                6                5                4               
    3                2                1                0
    ;                                                        I         F         T         M4        M3        M2        M1      
    M0
    ;USERMODE            0                0                0                1                0                0                0  
                  0               
    ;FIQMODE             0                0                0                1                0                0                0  
                  1
    ;IRQMODE             0                0                0                1                0                0                1  
                  0
    ;SVCMODE             0                0                0                1                0                0                1  
                  1
    ;ABORTMODE           0                0                0                1                0                1                1  
                  1               
    ;UNDEFMODE           0                0                0                1                1                0                1  
                  1
    ;MODEMASK            0                0                0                1                1                1                1  
                  1        
    ;NOINT                                1                1                0                0                0                0  
                  0                0
    USERMODE    EQU         0x10               
    FIQMODE     EQU         0x11
    IRQMODE     EQU         0x12
    SVCMODE     EQU         0x13
    ABORTMODE   EQU         0x17
    UNDEFMODE   EQU         0x1b
    MODEMASK    EQU         0x1f
    NOINT       EQU         0xc0
    ;The location of stacks                                                                                                      
                                                              ;各種工作模式的堆棧首地址定義
    ;_STACK_BASEADDRESS        EQU        0x33ff8000                                                                              
                                ;在內存中的堆棧表首地址
    UserStack        EQU        (_STACK_BASEADDRESS-0x3800)        ;0x33ff4800 ~
    SVCStack        EQU        (_STACK_BASEADDRESS-0x2800)        ;0x33ff5800 ~
    UndefStack        EQU        (_STACK_BASEADDRESS-0x2400)        ;0x33ff5c00 ~
    AbortStack        EQU        (_STACK_BASEADDRESS-0x2000)        ;0x33ff6000 ~
    IRQStack        EQU        (_STACK_BASEADDRESS-0x1000)        ;0x33ff7000 ~
    FIQStack        EQU        (_STACK_BASEADDRESS-0x0)        ;0x33ff8000 ~
    ;=============================================================================================;
    ;        arm處理器有兩種工作狀態 1.arm:32位 這種工作狀態下執行字對準的arm指令 2.Thumb:16位這種工作狀        ;
    ;        態執行半字對準的Thumb指令因為處理器分為16位 32位兩種工作狀態 程序的編譯器也是分16位和32兩種        ;
    ;        編譯方式 所以下面的程序用于根據處理器工作狀態確定編譯器編譯方式code16偽指令指示匯編編譯器后        ;
    ;        面的指令為16位的thumb指令code32偽指令指示匯編編譯器后面的指令為32位的arm指令這段是為了統一        ;
    ;        目前的處理器工作狀態和軟件編譯方式(16位編譯環境使用tasm.exe編譯)                                                   
                                                                ;
    ;=============================================================================================;
    ;Check if tasm.exe(armasm -16 [email=...@ADS]...@ADS[/email] 1.0) is used.
            GBLL    THUMBCODE                                                                                                     
                                                                         ;定義一個全局變量
            [ {CONFIG} = 16                                                                                                      
                                                                                      ;if config==16 這里表示你的目前處于領先地16
    位編譯方式
    THUMBCODE SETL  {TRUE}                                                                                                        
                                                             ;設置THUMBCODE 為 true表示告訴系統當前想用thumb,但實際啟動時不行,
    只能啟動后再跳
                CODE32                                                                                                            
                                                                                                 ;啟動時強制使用32位編譯模式
                    |                                                                                                            
                                                                                                                                ;
    [ | ]表示if else endif
    THUMBCODE SETL  {FALSE}                                                                                                      
                                                              ;如果系統要求是ARM指令,則直接設置THUMBCODE 為 false 說明當前的是32
    位編譯模式
        ]
                    MACRO                                                                                                         
                                                                                                                    ;宏定義
            MOV_PC_LR                                                                                                            
                                                                                                        ;程序跳轉,當CODE16時編譯
    器切換成Tumb模式
                    [ THUMBCODE
                bx lr
                    |
                mov        pc,lr
                    ]
            MEND
                    MACRO                                                                                                         
                   
            MOVEQ_PC_LR                                                                                                           
                                                                                                  ;條件相等則程序跳轉,當CODE16時
    編譯器切換成Tumb模式
                    [ THUMBCODE
            bxeq lr                                                                                                               
                                                                                      ;相等Z=1,則跳轉
                    |
                moveq pc,lr
                    ]
            MEND
    ;===============================================================================================;
    沙發
     樓主| 發表于 2010-9-11 12:33:26 | 只看該作者
    ;        注意下面這段程序是個宏定義 很多人對這段程序不理解 我再次強調這是一個宏定義 所以大家要注意了下        ;
    ;        面包含的HandlerXXX HANDLER HandleXXX將都被下面這段程序展開這段程序用于把中斷服務程序的首地址         ;
    ;        裝載到pc中,有人稱之為“加載程序”。本初始化程序定義了一個數據區(在文件最后),34個字空間,存         ;
    ;        放相應中斷服務程序的首地址。每個字空間都有一個標號,以Handle***命名。在向量中斷模式下使用“加         ;
    ;        載程序”來執行中斷服務程序。這里就必須講一下向量中斷模式和非向量中斷模式的概念向量中斷模式是當        ;
    ;        cpu讀取位于0x18處的IRQ中斷指令的時候,系統自動讀取對應于該中斷源確定地址上的;指令取代0x18處的        ;
    ;        指令,通過跳轉指令系統就直接跳轉到對應地址函數中 節省了中斷處理時間提高了中斷處理速度標 例如         ;
    ;        ADC中斷的向量地址為0xC0,則在0xC0處放如下代碼:ldr PC,=HandlerADC 當ADC中斷產生的時候系統會自         ;
    ;        動跳轉到HandlerADC函數中非向量中斷模式處理方式是一種傳統的中斷處理方法,當系統產生中斷的時候         ;
    ;        系統將interrupt pending寄存器中對應標志位置位 然后跳轉到位于0x18處的統一中斷函數中 該函數通過        ;
    ;        讀取interrupt pending寄存器中對應標志位 來判斷中斷源 并根據優先級關系再跳到對應中斷源的處理代        ;
    ;        碼中                                                                                                                 

                                                                                                                                  

                                                                                                                             ;
    ;===============================================================================================;

                    MACRO
    $HandlerLabel HANDLER $HandleLabel

    $HandlerLabel
            sub        sp,sp,#4        ;decrement sp(to store jump address)
            stmfd        sp!,{r0}        USH the work register to stack(lr does t push because it return to original address)
            ldr     r0,=$HandleLabel;load the address of HandleXXX to r0
            ldr     r0,[r0]         ;load the contents(service routine start address) of HandleXXX
            str     r0,[sp,#4]      ;store the contents(ISR) of HandleXXX to stack
            ldmfd   sp!,{r0,pc}     OP the work register and pc(jump to ISR)
            MEND
            
    ;從ADS的段設置中導入字符常量

            IMPORT  |Image$$RO$$Base|        ; Base of ROM code
            IMPORT  |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
            IMPORT  |Image$$RW$$Base|   ; Base of RAM to initialise
            IMPORT  |Image$$ZI$$Base|   ; Base and limit of area
            IMPORT  |Image$$ZI$$Limit|  ; to zero initialise

    ;從后續的C語言中導入函數地址
            IMPORT        MMU_SetAsyncBusMode
            IMPORT        MMU_SetFastBusMode        

            IMPORT  Main    ; The main entry of mon program


            AREA    Init,CODE,READONLY

            ENTRY
            
            EXPORT        __ENTRY
    __ENTRY
    ;========
    ;復位
    ;========
    ResetEntry
            ;1)The code, which converts to Big-endian, should be in little endian code.
            ;2)The following little endian code will be compiled in Big-Endian mode.
            ;  The code byte order should be changed as the memory bus width.
            ;3)The pseudo instruction,DCD can t be used here because the linker generates error.
            ASSERT        EF:ENDIAN_CHANGE                                                                                       

            ;條件編譯,在編譯成機器碼前就設定好,判斷ENDIAN_CHANGE是否已定義,在Option.inc中GBLL ENDIAN_CHANGE
            [ ENDIAN_CHANGE                                                                                                      

                                             ;如果已經定義了ENDIAN_CHANGE,則判斷,Option.inc中賦值ENDIAN_CHANGE        SETL      

    {FALSE}
                ASSERT  EF:ENTRY_BUS_WIDTH                                                                        ;判斷

    ENTRY_BUS_WIDTH是否已定義
                [ ENTRY_BUS_WIDTH=32                                                                                             

              ;Option.inc中賦值ENTRY_BUS_WIDTH        SETA        16
                    b        ChangeBigEndian            ;DCD 0xea000007
                ]

                [ ENTRY_BUS_WIDTH=16
                    andeq        r14,r7,r0,lsl #20   ;DCD 0x0007ea00
                ]

                [ ENTRY_BUS_WIDTH=8
                    streq        r0,[r0,-r10,ror #1] ;DCD 0x070000ea
                ]
            |
                b        ResetHandler
        ]                                                                                                                        

                                                                           ;此段代碼沒有可讀性,待有時間查閱相關資料,芯片手冊貌

    似沒有記錄
       
    ;===============================================================================================;

    ; 異常中斷矢量表(每個表項占4個字節)首地址在Option.inc中定義 _ISR_STARTADDRESS        EQU 0x33ffff00  ;
    ; 下面是中斷向量表 一旦系統運行時中斷發生 即使移植了操作系統 如linux 處理器已經把控制權交給了操 ;
    ; 作系統一旦發生中斷 處理器還是會跳轉到從0x0開始從中斷向量表中某個中斷表項(依據中斷類型)開始  ;
    ; 執行具體中斷向量布局請參考s3c44b0 spec 例如 adc中斷向量為0x000000c0下面對應表中第49項位置向量 ;
    ; 地址0x0+4*(49-1)=0x000000c0                                                                                                

                                                                                                                                  

                                                     ;

    ;===============================================================================================;
       
            b        HandlerUndef        ;handler for Undefined mode
            b        HandlerSWI        ;handler for SWI interrupt
            b        HandlerPabort        ;handler for PAbort
            b        HandlerDabort        ;handler for DAbort
            b        .                ;reserved
            b        HandlerIRQ        ;handler for IRQ interrupt
            b        HandlerFIQ        ;handler for FIQ interrupt

    ;@0x20
            b        EnterPWDN        ; Must be @0x20.                                                                           

                                                        ;這個可不是中斷哦,個人認為這一代碼在機器正常運轉的時候不會執行,放在這兒

    應該是
                                                                                                                                  

                                                                                                                              ;當

    程序異常走到這兒的時候,可以執行類似睡眠這類處理,屬異常操作。另一個重要原因
                                                                                                                                  

                                                                                                                              ;是

    可以避免下面過程的執行        
                                                                                                                                  

                                                                                                                                  

                                                                                                       
    ChangeBigEndian                                                                                                               

                                                                                     ;該段代碼生澀難懂,屬機器碼。不加深入研究,

    同時該段代碼根本就沒有被執行過                                                                                
    ;@0x24                                                                                                                        

                                                                                                            ;主要用途:改變大小端

    存儲的方式,而這種改變又與總線寬度有關
            [ ENTRY_BUS_WIDTH=32
                DCD        0xee110f10        ;0xee110f10 =>  p15,0,r0,c1,c0,0
                DCD        0xe3800080        ;0xe3800080 => orr r0,r0,#0x80;  //Big-endian
                DCD        0xee010f10        ;0xee010f10 => mcr p15,0,r0,c1,c0,0
            ]
            [ ENTRY_BUS_WIDTH=16
                DCD 0x0f10ee11
                DCD 0x0080e380
                DCD 0x0f10ee01
            ]
            [ ENTRY_BUS_WIDTH=8
                DCD 0x100f11ee
                DCD 0x800080e3
                DCD 0x100f01ee
        ]
            DCD 0xffffffff  ;swinv 0xffffff is similar with NOP and run well in both endian mode.
            DCD 0xffffffff
            DCD 0xffffffff
            DCD 0xffffffff
            DCD 0xffffffff
            b ResetHandler
            
    HandlerFIQ      HANDLER HandleFIQ
    HandlerIRQ      HANDLER HandleIRQ
    HandlerUndef    HANDLER HandleUndef
    HandlerSWI      HANDLER HandleSWI
    HandlerDabort   HANDLER HandleDabort
    HandlerPabort   HANDLER HandlePabort

    IsrIRQ                                                                                                                        

                                                                                                            ;下面有中斷向量表跳轉

    的具體分析
            sub        sp,sp,#4       ;reserved for PC
            stmfd        sp!,{r8-r9}

            ldr        r9,=INTOFFSET
            ldr        r9,[r9]
            ldr        r8,=HandleEINT0
            add        r8,r8,r9,lsl #2
            ldr        r8,[r8]
            str        r8,[sp,#8]
            ldmfd        sp!,{r8-r9,pc}


            LTORG

    ;=======
    板凳
     樓主| 發表于 2010-9-11 12:36:08 | 只看該作者
    ; ENTRY
    ;=======
    ResetHandler                                                                                                                  

                                                                                          ;開機或者
    ldr        r0,=WTCON       ;watch dog disable                                                                                 

           ;關看門狗
            ldr        r1,=0x0
            str        r1,[r0]

            ldr        r0,=INTMSK                                                                                                

                                                                                           ;禁全部中斷
            ldr        r1,=0xffffffff  ;all interrupt disable
            str        r1,[r0]

            ldr        r0,=INTSUBMSK                                                                                             

                                                                                      ;禁全部子中斷
            ldr        r1,=0x7fff                ;all sub interrupt disable
            str        r1,[r0]

            ;led顯示
            [ {FALSE}                                                                                                            

                                                                                                       ;因為FALSE值,所以這段代碼

    無效
            ; rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
            ; Led_Display
            ldr        r0,=GPFCON
            ldr        r1,=0x5500
            str        r1,[r0]
            ldr        r0,=GPFDAT
            ldr        r1,=0x10
            str        r1,[r0]
            ]

            ;To reduce PLL lock time, adjust the LOCKTIME register.
            ldr        r0,=LOCKTIME                                                                                               

                                                                                     ;設置時鐘穩定等待的時間
            ldr        r1,=0xffffff
            str        r1,[r0]

        [ PLL_ON_START                                                                                                            

                                                                        ;配置時鐘分頻寄存器,確定系統各總線時鐘的分頻系數
            ; Added for confirm clock divide. for 2440.
            ; Setting value Fclk:Hclkclk
            ldr        r0,=CLKDIVN
            ldr        r1,=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.
            str        r1,[r0]
            
    ;===============================================================================================;

    ; MCR 指令用于將ARM 處理器寄存器中的數據傳送到協處理器寄存器中,若協處理器不能成功完成操作,則產 ;
    ; 生未定義指令異常。其中協處理器操作碼1 和協處理器操作碼2 為協處理器將要執行的操作,源寄存器為  ;
    ; ARM 處理器的寄存器,目的寄存器1 和目的寄存器2 均為協處理器的寄存器。                                                        

                                                    ;

    ;===============================================================================================;        
            [ CLKDIV_VAL>1                 ; means Fclk:Hclk is not 1:1.
            mrc p15,0,r0,c1,c0,0                                                                                                  

                                                                  ;讀MMU控制命令
            orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA                                                                                 

                  ;功能如下:31位(iA bit)Function:Asynchronous clock select (選擇異步時鐘)30位(nF bit)Function: notFastBus

    select
            mcr p15,0,r0,c1,c0,0
            |
            mrc p15,0,r0,c1,c0,0
            bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
            mcr p15,0,r0,c1,c0,0
            ]

            ;Configure UPLL                                                                                                      

                                                                                     ;配置USB時鐘鎖相環
            ldr        r0,=UPLLCON
            ldr        r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)  
            str        r1,[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
            ldr        r0,=MPLLCON                                                                                                

                                                                                            ;配置系統時鐘鎖相環
            ldr        r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ;Fin=16.9344MHz
            str        r1,[r0]
        ]
       
            ;Check if the boot is caused by the wake-up from SLEEP mode.
            ldr        r1,=GSTATUS2                                                                                               

                                                                                     ;判斷系統是否是被喚醒的,是的話轉入喚醒中斷

    函數
            ldr        r0,[r1]
            tst        r0,#0x2
            ;In case of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
            bne        WAKEUP_SLEEP

    ;        EXPORT StartPointAfterSleepWakeUp
    ;StartPointAfterSleepWakeUp

            ;Set memory control registers
            ;ldr        r0,=SMRDATA
            adrl        r0, SMRDATA                                                                                               

                                                                                     ;配置SDRAM各組控制寄存器,配置信息在SMRDATA

    數據區中
            ldr        r1,=BWSCON        ;BWSCON Address
            add        r2, r0, #52        ;End address of SMRDATA

    0
            ldr        r3, [r0], #4
            str        r3, [r1], #4
            cmp        r2, r0
            bne        %B0
            
            ;delay
            mov        r0, #&1000                                                                                                

                                                                                           ;等待SDRAM穩定運行
    1
            subs        r0, r0, #1
            bne        %B1
            ;===

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;       When EINT0 is pressed,  Clear SDRAM
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; check if EIN0 button is pressed

    ;        ldr        r0,=GPFCON
    ;        ldr        r1,=0x0
    ;        str        r1,[r0]
    ;        ldr        r0,=GPFUP
    ;        ldr        r1,=0xff
    ;        str        r1,[r0]
    ;
    ;        ldr        r1,=GPFDAT
    ;        ldr        r0,[r1]
    ;        bic        r0,r0,#(0x1e<<1)  ; bit clear
    ;        tst        r0,#0x1
    ;        bne %F1

    ; Clear SDRAM Start
      
    ;        ldr        r0,=GPFCON
    ;        ldr        r1,=0x55aa
    ;        str        r1,[r0]
    ;        ldr        r0,=GPFUP
    ;        ldr        r1,=0xff
    ;        str        r1,[r0]
    ;        ldr        r0,=GPFDAT
    ;        ldr        r1,=0x0
    ;        str        r1,[r0]        ;LED=****


    ;Clear SDRAM End

    1

            ;Initialize stacks
            bl        InitStacks                                                                                                  

                                                                                          ;初始化堆棧

    ;==========================================================
              ; Setup IRQ handler                                                                                                

                                                                   ;建立中斷表
            ldr        r0,=HandleIRQ       ;This routine is needed
            ldr        r1,=IsrIRQ          ;if there isn t 'subs pc,lr,#4' at 0x18, 0x1c
            str        r1,[r0]
    ;===========================================================
    ;// 判斷是從nor啟動還是從nand啟動
    ;===========================================================
            ;bl        Led_Test
            
            ldr        r0, =BWSCON
            ldr        r0, [r0]
            ands        r0, r0, #6                ;OM[1:0] != 0, NOR FLash boot
            bne        NORRoCopy                ;don t read nand flash
            adr        r0, ResetEntry                ;OM[1:0] == 0, NAND FLash boot // ADR ;裝載參照的地址=sub r0,pc,#0x268;
            cmp        r0, #0                                ;if use Multi-ice,//                                                

                                           ;JTAG調試時是直接下載到內存中運行,不需要再從nand拷貝
            bne        InitRamZero                ;don t read nand flash for boot
            ;nop
            

            
    ;===========================================================
    ;//將程序從nandflash拷貝到sdram
    ;===========================================================
    地板
     樓主| 發表于 2010-9-11 12:37:55 | 只看該作者
    nand_boot_beg
            bl        ClearSdram
            mov        r5, #NFCONF                                                                                                

                                                                                            ;配置NandFlash的配置寄存器
            ;set timing value
            ldr        r0,        =(7<<12)|(7<<8)|(7<<4)
            str        r0,        [r5]
            ;enable control
            ldr        r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
            str        r0, [r5, #4]                                                                                               

                                                                                     ;配置控制寄存器
            
            bl        ReadNandID                                                                                                  

                                                                                          ;跳轉到讀取芯片ID函數,芯片ID存在R5中
            mov        r6, #0
            ldr        r0, =0xecF1
            cmp        r5,        r0
            beq        %F1
    ;        ldr        r0, =0xecda
    ;        cmp        r5, r0
            mov        r6, #1                        ;Nandaddr(尋址周期 0:4  1:5)
    1        
            bl        ReadNandStatus

    ;===============================================================================================;

    ; ldr取得是ResetEntry的絕對地址                                                                                               

                                                                                                                                  

                                               ;
    ; 這里ResetEntry的絕對地址是0x30100000,由ADS連接器中指定                                                                     

                                                                                               ;
    ; 這里不用adr,adr只適合短地址讀取                                                                                             

                                                                                                                                  

                                         ;

    ;===============================================================================================;         
            mov        r8, #0
            ldr        r9, =ResetEntry
            mov r10,#32                        ;+081010 feiling
            
    ;===============================================================================================;

    ; 這個的意思是看 r8 是不是一個block的第一個扇區的地址就看作為頁計數的r8是不是64的整數倍,如果是 ;
    ; 整數倍那么就是block的第一個扇區了,那么在3段代碼執行后下一步執行什么,3段是讀一頁的操作吧。如 ;
    ; 果是的話,后多少位會是0 如果是一個block的第一個扇區就執行CheckBadBlk 如果不是的話就直接讀數據  ;

    ;===============================================================================================;

    2        
            ands        r0, r8, #0x3f                                                                                             

                                                                               ;如果是第一頁,則檢測壞塊。這里0x3f代表一塊是64頁
            bne                %F3
            mov                r0, r8
            bl                CheckBadBlk
            cmp                r0, #0                                                                                             

                                                                                                       ;該處的r0是壞快標志,是0的

    時候不是壞快,否則就是壞快
            addne        r8, r8, #64                                                                                             

                                                                                      ;每塊的頁數  此處有BUG r8同時也做計數用。。
            addne        r10,r10,#64 ;+081010 feiling                                                                             

                               ;當是壞快的時候跳過該壞快
            bne                %F4
    3        
            mov        r0, r8
            mov        r1, r9
            bl        ReadNandPage                                                                                                

                                                                                    ;跳轉到的函數的功能是把nandflash中的程序數據

    搬運到SDRAM中
            add        r9, r9, #2048                                                                                             

                                                                                      ;每頁的字節數
            add        r8, r8, #1                                                                                                

                                                                                           ;頁數+1
            
    ; 步驟4將前32頁全部搬運一遍,這前32頁應該已經包含了bootload在nandflash中固化了的RO段和RW段

    4        
            cmp        r8, r10                                                                                                   

                                                                                           ;要拷貝的頁數 081010 pht:#32->r10
            bcc        %B2                                                                                                        

                                                                                                                    ;CC 無符號小


            
            mov        r5, #NFCONF                        ;DsNandFlash
            ldr        r0, [r5, #4]
            bic r0, r0, #1
            str        r0, [r5, #4]
            ldr        pc, =InitRamZero                                                                                          

                                                                         ;此處跳轉到內存空間 LDR 裝載數據,尋址靈活。 但不改變PSR
                                                                                                                                  

                                                                                                                        ;要裝載一

    個被存儲的‘狀態’并正確的恢復它 可以這樣寫:ldr r0, [base] 換行  moves pc, r0
                                                                                                                                  

                                                                                                                        ;注意,程

    序不能在Nandflash中運行,NORFlash可以理解為類似SRAM的存儲器,NandFlash可被理解為IO設備
    ;=============================================================================================
    ;若是從NAND啟動,則拷貝工作已經在nand_boot_beg中完成,所以直接跳轉到main
    ;若是從NOR啟動,則將RO和RW部分都拷貝到內存,然后跳轉到內存運行(也可在NOR中運行,只是速度稍慢)
    ;
    ;注:若在NOR中直接運行,需把RO/BASE改為0并定義RW/BASE 會跳過RO拷貝
    ;=============================================================================================
    NORRoCopy                        ;copy_proc_beg  by pht
            bl        ClearSdram

            adr        r0, ResetEntry                                                                                             

                                                                               ;判斷是否在ROM中運行,ROM即RO指定的地址 從NOR啟動

    時ResetEntry為0
            ldr        r2, BaseOfROM                                                                                             

                                                                                      ;如果相等,進行RW段的拷貝;不相等的話還需進

    行RO段,也就是程序段的拷貝
            cmp        r0, r2
            beq        NORRwCopy                                
            ldr r3, TopOfROM                ;
    0                                                                                                                             

                                                                                                                               ;

    程序段拷貝工作
            ldmia        r0!, {r4-r7}
            stmia        r2!, {r4-r7}
            cmp        r2, r3
            bcc        %B0
            
                   
    NORRwCopy                                                                                                                     

                                                                                                       ;數據段的拷貝工作
            ldr        r0, TopOfROM
            ldr r1, BaseOfROM
            sub r0, r0, r1                                                                                                        

                                                                                    ;TopOfROM-BaseOfROM得到從0開始RW的偏移地址
            ldr        r2, BaseOfBSS                                                                                             

                                                                                      ;將RW部分的數據從ROM拷貝到RAM
            ldr        r3, BaseOfZero        
    0                                                                                                                             

                                                                                                                               

    ;BSS段的拷貝工作
            cmp        r2, r3
            ldrcc        r1, [r0], #4
            strcc        r1, [r2], #4
            bcc        %B0        
            
    InitRamZero                                                                                                                  

                                                                                                 ;此段代碼不管在NOR還是Nand中都將

    搬運
            mov        r0,        #0
            ldr r2, BaseOfZero
            ldr        r3,        EndOfBSS
    1                                                                                                                             

                                                                                                                               

    ;ZERO段的初始化工作
            cmp        r2,        r3                                                                                             

                                                                                                              ;初始化Zero部分 不

    管從哪里啟動,這部分都需要執行
            strcc        r0, [r2], #4
            bcc        %B1
            
            ldr        pc, =CEntry                ;goto compiler address

            
    ;        [ CLKDIV_VAL>1                 ; means Fclk:Hclk is not 1:1.
    ;        bl        MMU_SetAsyncBusMode
    ;        |
    ;        bl MMU_SetFastBusMode        ; default value.
    ;        ]
            


    CEntry
            bl        Main        ;Don t use main() because ......
            b        .


    ;=========================================================
    地下室
     樓主| 發表于 2010-9-11 12:41:42 | 只看該作者
    ClearSdram
            mov r1,#0
            mov r2,#0
            mov r3,#0
            mov r4,#0
            mov r5,#0
            mov r6,#0
            mov r7,#0
            mov r8,#0
            
            ldr        r9,=0x00700000   ;for wince
            ldr        r0,=0x30000000
    0        
            stmia        r0!,{r1-r8}
            subs        r9,r9,#32
            bne        %B0
            mov        pc,lr
            
    ;===========================================================        
    ;function initializing stacks
    InitStacks                                                                                                                    

                                                                                                ;進入各種模式,分別配置各種模式的

    堆棧地址
            ;Don t 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'
            mrs        r0,cpsr
            bic        r0,r0,#MODEMASK
            orr        r1,r0,#UNDEFMODE|NOINT
            msr        cpsr_cxsf,r1                ;UndefMode
            ldr        sp,=UndefStack                ; UndefStack=0x33FF_5C00

            orr        r1,r0,#ABORTMODE|NOINT
            msr        cpsr_cxsf,r1                ;AbortMode
            ldr        sp,=AbortStack                ; AbortStack=0x33FF_6000

            orr        r1,r0,#IRQMODE|NOINT
            msr        cpsr_cxsf,r1                ;IRQMode
            ldr        sp,=IRQStack                ; IRQStack=0x33FF_7000

            orr        r1,r0,#FIQMODE|NOINT
            msr        cpsr_cxsf,r1                ;FIQMode
            ldr        sp,=FIQStack                ; FIQStack=0x33FF_8000

            bic        r0,r0,#MODEMASK|NOINT
            orr        r1,r0,#SVCMODE
            msr        cpsr_cxsf,r1                ;SVCMode
            ldr        sp,=SVCStack                ; SVCStack=0x33FF_5800

            ;USER mode has not be initialized.

            mov        pc,lr
            ;The LR register won t be valid if the current mode is not SVC mode.
            
    ;===========================================================
    ReadNandID
            mov      r7,#NFCONF
            ldr      r0,[r7,#4]                ;NFChipEn();                                                                       

                                     ;使能NandFlash芯片
            bic      r0,r0,#2
            str      r0,[r7,#4]                                                                                                   

                                                                         
            mov      r0,#0x90                ;WrNFCmd(RdIDCMD);
            strb     r0,[r7,#8]                                                                                                   

                                                                         ;命令寄存器,寫90h,讀ID
            mov      r4,#0                        ;WrNFAddr(0);
            strb     r4,[r7,#0xc]                                                                                                

                                                                   ;讀命令第二步,地址寫0
    1                                                        ;while(NFIsBusy());
            ldr      r0,[r7,#0x20]                                                                                                

                                                            ;判斷是否忙,狀態寄存器
            tst      r0,#1
            beq      %B1
            ldrb     r0,[r7,#0x10]        ;id  = RdNFDat()<<8;                                                                ;從

    讀數據ID,讀取ID,前兩個周期即可分辨芯片
            mov      r0,r0,lsl #8
            ldrb     r1,[r7,#0x10]        ;id |= RdNFDat();                                                                       

             
            orr      r5,r1,r0
            ldr      r0,[r7,#4]                ;NFChipDs();                                                                       

                                     ;禁止NandFlash芯片
            orr      r0,r0,#2
            str      r0,[r7,#4]
            mov                 pc,lr        
            
    ReadNandStatus
            mov                 r7,#NFCONF
            ldr      r0,[r7,#4]                ;NFChipEn();
            bic      r0,r0,#2
            str      r0,[r7,#4]
            mov      r0,#0x70                ;WrNFCmd(QUERYCMD);                                                                  

                          ;命令為讀狀態寄存器
            strb     r0,[r7,#8]        
            ldrb     r1,[r7,#0x10]        ;r1 = RdNFDat();                                                                        

            ;狀態數據存在R1中
            ldr      r0,[r7,#4]                ;NFChipDs();
            orr      r0,r0,#2
            str      r0,[r7,#4]
            mov                 pc,lr

    WaitNandBusy
            mov      r0,#0x70                ;WrNFCmd(QUERYCMD);
            mov      r1,#NFCONF
            strb     r0,[r1,#8]
    1                                                        ;while(!(RdNFDat()&0x40));        
            ldrb     r0,[r1,#0x10]
            tst      r0,#0x40
            beq                 %B1
            mov      r0,#0                        ;WrNFCmd(READCMD0);                                                            

                               ;00h 老操作的結束,新操作的開始
            strb     r0,[r1,#8]
            mov      pc,lr

    ;===============================================================================================;

    ; Samsung makes sure that either the 1st or 2nd page of every                                                                 

                                                                                   ;
    ; 壞快標志的檢測步驟                                                                                                         

                                                                                                                                  

                                                                            ;
    ; 1.Set Block Address = 0                                                                                                     

                                                                                                                                  

                                                                 ;
    ; 2.Check "FFh" at the column address 2048,of the 1st and 2nd page in the block                                               

                             ;
    ; 3.Check "FFh"                ?                                Y->繼續        N->記錄壞快進入壞塊表                          

                                                                                                                                  

                    ;                                                                                                            

                               
    ; 4.判斷Last Block ?                                        Y->檢測完成        N->塊數加1,跳轉到地2歩                        

                                                                                                            ;

    ;===============================================================================================;                             

                                                                                                                                  

                                                                                        

    ;initial invalid block has non-FFh data at the column address of 2048
    CheckBadBlk
            mov                r7, lr
            mov                r5, #NFCONF
            
            bic      r0,r0,#0x3f        ;addr &= ~0x3f;                                                                           

                         ;r0中存放的是頁數
            ldr      r1,[r5,#4]                ;NFChipEn()
            bic      r1,r1,#2
            str      r1,[r5,#4]

            mov      r1,#0x00                ;WrNFCmd(READCMD)
            strb     r1,[r5,#8]
            mov      r1, #0                        ;2048&0xff
            strb     r1,[r5,#0xc]        ;WrNFAddr(2048&0xff);
            mov      r1, #8                        ;(2048>>8)&0xf                                                                 

                                           ;這里的壞快檢測操作就是獲取每頁1K地址處的值,看看是不是為0xff
            strb     r1,[r5,#0xc]
            
            strb     r0,[r5,#0xc]        ;WrNFAddr(addr)
            mov      r1,r0,lsr #8        ;WrNFAddr(addr>>8)
            strb     r1,[r5,#0xc]
            cmp      r6,#0                        ;if(NandAddr)
            movne    r1,r0,lsr #16        ;WrNFAddr(addr>>16)
            strb     r1,[r5,#0xc]
            
            mov      r1,#0x30                        ;WrNFCmd(0x30)
            strb     r1,[r5,#8]
                   
    ;        cmp      r6,#0                        ;if(NandAddr)               
    ;        movne    r0,r0,lsr #16        ;WrNFAddr(addr>>16)
    ;        strneb   r0,[r5,#0xc]
            
    ;        bl                WaitNandBusy        ;WaitNFBusy()
            ;don t use WaitNandBusy, after WaitNandBusy will read part A!
            mov        r0, #100
    1
            subs        r0, r0, #1
            bne        %B1
    2
            ldr        r0, [r5, #0x20]                                                                                            

                                                                                ;1歩與2歩都在等待
            tst        r0, #1
            beq        %B2        

            ldrb        r0, [r5,#0x10]        ;RdNFDat()
            sub                r0, r0, #0xff                                                                                      

                                                                                      ;r0中的數據為nandflash中該地址數據減去0xff

    ,因為非壞塊時該處值為0xff
            
    ;        mov      r1,#0                        ;WrNFCmd(READCMD0)
    ;        strb     r1,[r5,#8]
            
            ldr      r1,[r5,#4]                ;NFChipDs()
            orr      r1,r1,#2
            str      r1,[r5,#4]
            
            mov                pc, r7
            
    ReadNandPage
            mov                 r7,lr
            mov      r4,r1
            mov      r5,#NFCONF

            ldr      r1,[r5,#4]                ;NFChipEn()
            bic      r1,r1,#2
            str      r1,[r5,#4]        

    ;===============================================================================================;








    ; K9F2G08UXA的地址傳送方式如下                                                                  ;
    ;                         I/O0                I/O1                I/O2                I/O3                I/O4               

    I/O5                I/O6                I/O7                                                                                 

                                  ;
    ;        1st                        0                                1                                2                       

             3                                4                                5                                6                 

                   7                                                                                                              

              ;
    ;        2st                        8                                9                                10                     

      11                        L                                L                                L                              

    L                                                        L(Low)                                        ;
    ; 3st                        12                        13                        14                        15                 

           16                        17                        18                        19                                       

                                                                             ;
    ;        4st                        20                        21                        22                        23         

                  24                        25                        26                        27                                

                                                                                    ;
    ;        5st                        28                        L                                L                              

      L                                L                                L                                L                        

            L                                                                                                                     

       ;

    ; K9F2G08UXA的讀地址中數據的流程為:(一下程序段即此過程展示)                                                                  

                                                                                  ;
    ; 1. Write 00h                                                                                                               

                                                                                                                                  

                                                                                              ;
    ; 2. Write Address                                                                                                            

                                                                                                                                  

                                                                                  ;
    ; 3. Write 30h                                                                                                               

                                                                                                                                  

                                                                                              ;
    ; 4. Read Data                                                                                                               

                                                                                                                                  

                                                                                              ;
    ; 5. ECC Generation                                                                                                           

                                                                                                                                  

                                                                                   ;
    ; 6. Verify ECC并判斷是否正確(硬件自動實現)                                                                                   

                                                                                                                                  

           ;
    ; 7. 完成                                                                                                                     

                                                                                                                                  

                                                                                                                 ;

    ;===============================================================================================;

            mov      r1,#0                        ;WrNFCmd(READCMD0)
            strb     r1,[r5,#8]                                                                                                   

                                                                                                                                  

                                                                                   ;Waiting for next command
            strb     r1,[r5,#0xc]        ;WrNFAddr(0)                                                                             

                                                                                                                                  

                                         ;輸入地址,地址從小地址開始寫
            strb     r1,[r5,#0xc]        ;WrNFAddr(0)                                                                             

                                                                                                                                  

                                        
            strb     r0,[r5,#0xc]        ;WrNFAddr(addr)                                                                          

                                                                                                                                  

                                    ;R8-》R0中保存的是當前檢測的頁面數
            mov      r1,r0,lsr #8        ;WrNFAddr(addr>>8)
            strb     r1,[r5,#0xc]        
            cmp      r6,#0                        ;if(NandAddr)                                                                  

                                                                                                                                  

                                                           ;提供一個判斷條件,判斷是否是增強型的Flash 是的一頁2K字節
            movne    r1,r0,lsr #16        ;WrNFAddr(addr>>16)                                                                     

                                                                                                                                  

                 ;K9F2G08UXA所以頁均可以這種方式讀出。
            strb     r1,[r5,#0xc]        

            mov      r1,#0x30                        ;WrNFCmd(0x30)
            strb     r1,[r5,#8]
                   
            
            ldr      r0,[r5,#4]                ;InitEcc()
            orr      r0,r0,#0x10
            str      r0,[r5,#4]
            
            bl       WaitNandBusy        ;WaitNFBusy()
            
            mov      r0,#0                        ;for(i=0; i<2048; i++)
    1
            ldrb     r1,[r5,#0x10]        ;buf[i] = RdNFDat()
            strb     r1,[r4,r0]                                                                                                   

                                                                                                                                  

                                                                                   ;r4中存放的是RO中程序段對應復制頁的地址
            add      r0,r0,#1
            bic      r0,r0,#0x10000        ;?                                                                                    

                                                                                                                                  

                                                                 ;最大1G
            cmp      r0,#0x800                                                                                                   

                                                                                                                                  

                                                                                  ;一頁有2048個字節,全部放入執行段中去
            bcc      %B1
            
            ldr      r0,[r5,#4]                ;NFChipDs()
            orr      r0,r0,#2
            str      r0,[r5,#4]
                   
            mov                 pc,r7

    ;--------------------LED test------------------------------
            EXPORT        Led_Test                                                                                                

                                                                                                                                  

                                                                                              ;LED測試代碼,沒有太多分析價值
    Led_Test
            mov        r0, #0x56000000
            mov        r1, #0x5500
            str        r1, [r0, #0x50]
            
    0        
            mov        r1, #0x50
            str        r1, [r0, #0x54]
            mov        r2, #0x100000
    1
            subs        r2, r2, #1
            bne        %B1
            
            mov        r1, #0xa0
            str        r1, [r0, #0x54]
            mov        r2, #0x100000
    2
            subs        r2, r2, #1
            bne        %B2
            b        %B0
            mov        pc, lr

    ;===========================================================

            LTORG

    ;GCS0->SST39VF1601
    ;GCS1->16c550
    ;GCS2->IDE
    ;GCS3->CS8900
    ;GCS4->DM9000
    ;GCS5->CF Card
    ;GCS6->SDRAM
    ;GCS7->unused

    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)+(Tsrc<<18)+(Tchr<<16)+REFCNT)

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

            DCD 0x20            ;MRSR6 CL=2clk
            DCD 0x20            ;MRSR7 CL=2clk
            
    BaseOfROM        DCD        |Image$$RO$$Base|
    TopOfROM        DCD        |Image$$RO$$Limit|
    BaseOfBSS        DCD        |Image$$RW$$Base|
    BaseOfZero        DCD        |Image$$ZI$$Base|
    EndOfBSS        DCD        |Image$$ZI$$Limit|

            ALIGN
            
    ;Function for entering power down mode
    ; 1. SDRAM should be in self-refresh mode.
    ; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.
    ; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.
    ; 4. The I-cache may have to be turned on.
    ; 5. The location of the following code may have not to be changed.

    ;void EnterPWDN(int CLKCON);
    EnterPWDN                                                                                                                     

                                                                                                       ;其實bootload根本不會執行

    到下面的代碼,下面關于EnterPWDN的代碼純屬廢碼
            mov r2,r0                ;r2=rCLKCON
            tst r0,#0x8                ;SLEEP mode?
            bne ENTER_SLEEP

    ENTER_STOP
            ldr r0,=REFRESH                                                                                                      

                                                                                     ;2440addr.inc中定義REFRESH         EQU  

    0x48000024     ;DRAM/SDRAM refresh
            ldr r3,[r0]                ;r3=rREFRESH
            mov r1, r3
            orr r1, r1, #BIT_SELFREFRESH
            str r1, [r0]                ;Enable SDRAM self-refresh

            mov r1,#16                        ;wait until self-refresh is issued. may not be needed.
    0        subs r1,r1,#1
            bne %B0

            ldr r0,=CLKCON                ;enter STOP mode.
            str r2,[r0]

            mov r1,#32
    0        subs r1,r1,#1        ;1) wait until the STOP mode is in effect.
            bne %B0                ;2) Or wait here until the CPU&Peripherals will be turned-off
                            ;   Entering SLEEP mode, only the reset by wake-up is available.

            ldr r0,=REFRESH ;exit from SDRAM self refresh mode.
            str r3,[r0]

            MOV_PC_LR

    ENTER_SLEEP
            ;NOTE.
            ;1) rGSTATUS3 should have the return address after wake-up from SLEEP mode.

            ldr r0,=REFRESH
            ldr r1,[r0]                ;r1=rREFRESH
            orr r1, r1, #BIT_SELFREFRESH
            str r1, [r0]                ;Enable SDRAM self-refresh

            mov r1,#16                        ;Wait until self-refresh is issued,which may not be needed.
    0        subs r1,r1,#1
            bne %B0
    6
     樓主| 發表于 2010-9-11 12:42:32 | 只看該作者
    ldr        r1,=MISCCR
            ldr        r0,[r1]
            orr        r0,r0,#(7<<17)  ;Set SCLK0=0, SCLK1=0, SCKE=0.
            str        r0,[r1]

            ldr r0,=CLKCON                ; Enter sleep mode
            str r2,[r0]

            b .                        ;CPU will die here.

    WAKEUP_SLEEP
            ;Release SCLKn after wake-up from the SLEEP mode.
            ldr        r1,=MISCCR
            ldr        r0,[r1]
            bic        r0,r0,#(7<<17)  ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:0->=SCKE.
            str        r0,[r1]

            ;Set memory control registers
            ldr        r0,=SMRDATA        
            ldr        r1,=BWSCON        ;BWSCON Address
            add        r2, r0, #52        ;End address of SMRDATA
    0
            ldr        r3, [r0], #4
            str        r3, [r1], #4
            cmp        r2, r0
            bne        %B0

            mov r1,#256
    0        subs r1,r1,#1        ;1) wait until the SelfRefresh is released.
            bne %B0

            ldr r1,=GSTATUS3         ;GSTATUS3 has the start address just after SLEEP wake-up
            ldr r0,[r1]

            mov pc,r0
            
    ;=====================================================================
    ; 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]
            bic                r1, r1, #0xff
            bic                r1, r1, #(0x7<<8)
            orr                r1, 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]
            bic                r1, r1, #0xff
            bic                r1, r1, #(0x7<<8)
            orr                r1, r1, #0x630        ; REFCNT675 - 1520
            str     r1, [r0]
            nop
            nop
            nop
            nop
            nop
            mov     pc, lr


            ALIGN

            AREA RamData, DATA, READWRITE
    ;================================================================================================;

    ; 按照我的分析,IRQ或者FIQ中斷操作的時候一共跳了三次。一次當中斷產生時進入絕對跳轉地址,也就是硬 ;
    ; 件中斷地址0x018或0x1c。然后跳轉到HandleXXX函數,HandleXXX函數就是下面的中斷向量表的HandleIRQ或 ;
    ; HandleFIQ。其中HandleIRQ存放IsrIRQ的地址,而ISRIRQ這個函數就是跳轉到中斷源對應的中斷向量入口, ;
    ; 其中斷向量在下面這張中斷向量表的后大半部分。向量偏移由寄存器INTOFFSET指定,而INTOFFSET也是中斷 ;
    ; 源硬件設置的。然后,在從次中斷向量入口跳轉到用戶定義的中斷處理函數,通過這一方法實現了中斷跳轉 ;

    ;=============================================================================================== ;
            
            ^   _ISR_STARTADDRESS                ; _ISR_STARTADDRESS=0x33FF_FF00
    HandleReset         #   4
    HandleUndef         #   4
    HandleSWI                #   4
    HandlePabort    #   4
    HandleDabort    #   4
    HandleReserved  #   4
    HandleIRQ                #   4
    HandleFIQ                #   4

    ;Don t 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
    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規則

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷