2440init .s解讀(三)

 

;=======

; ENTRYCPU復位的入口)

;=======

ResetHandler

       ldr   r0,=WTCON       ;關看門狗

       ldr   r1,=0x0

       str   r1,[r0]

 

       ldr   r0,=INTMSK

       ldr   r1,=0xffffffff  ;關中斷

       str   r1,[r0]

 

       ldr   r0,=INTSUBMSK

       ldr   r1,=0x7fff           ;關子中斷

       str   r1,[r0]

 

       [ {TRUE}

       ;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);

       ;led

       ldr   r0,=GPBCON

       ldr   r1,=0x00555555

       str   r1,[r0]

       ldr   r0,=GPBDAT

       ldr   r1,=0x07fe

       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:Hclk:Pclk

       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]

;      MMU_SetAsyncBusMode and MMU_SetFastBusMode over 4K, so do not call here

;      call it after copy

;      [ CLKDIV_VAL>1         ; means Fclk:Hclk is not 1:1.

;      bl MMU_SetAsyncBusMode

;      |

;      bl MMU_SetFastBusMode     ; default value.

;      ]

;===============================================================
;MMU_SetAsyncBusMode
MMU_SetFastBusMode 都在4K代碼以上(三星就提供4K的內部SRAM,
;
如果你想你編譯出來的程序能在NAND上運行的話,就不能在這調用這兩函數了.
;
如果你不要求的話,你就可以直接調用

;下面的代碼就是實現和上面兩函數一樣的功能.

;利用的協處理器的命令實現了對總線模式的設置
;===============================================================

       ;program has not been copied, so use these directly

       [ CLKDIV_VAL>1         ; means Fclk:Hclk is not 1:1.

       mrc p15,0,r0,c1,c0,0

       orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA

       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.配置 MPLL 一定要使最後的頻率爲16.9344MHz,不然你甭想用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           ; Check GSTATUS2[2] in order to know whether or not

;the power-up is caused by the wake-up from SLEEP mode.

       bne WAKEUP_SLEEP            ;如果是,則跳轉到WAKEUP_SLEEP

 

       EXPORT StartPointAfterSleepWakeUp  ;定義外部的StartPointAfterSleepWakeUp

StartPointAfterSleepWakeUp            

 

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

 ;設置存儲器控制寄存器,此段代碼把13個存儲控制器的內容批量的讀取到了對應的特殊功能寄存器中

 ;首先是有一個數據區SMRDATA,在程序的後面有定義,這個數據區給13個寄存器分配52字節的地址空間。在下面

;的代碼中,r0是這個數據區的起始地址,r2是數據區的結束地址,r1是寄存器的起始地址。這樣,用一個判斷語句  

; cmp       r2, r0

 ; bne %B0,就可以把內存中的數據賦給這13個存儲控制寄存器了。

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

      ;ldr  r0,=SMRDATA

      adrl r0, SMRDATA    ;be careful!

       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

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;       When EINT0 is pressed,  Clear SDRAM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; check if EIN0 button is pressed

 

   ldr    r0,=GPFCON

       ldr   r1,=0x0

       str   r1,[r0]           ;F(0:15)input

       ldr   r0,=GPFUP

       ldr   r1,=0xff

       str   r1,[r0]            ;不使用上拉電阻

 

       ldr   r1,=GPFDAT          ; GPFDAT=0xff

       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=****

 

       mov r1,#0

       mov r2,#0

       mov r3,#0

       mov r4,#0

       mov r5,#0

       mov r6,#0

       mov r7,#0

       mov r8,#0

      

;64MBSDRAM0x300000000x34000000

 

       ldr   r9,=0x4000000 

       ldr   r0,=0x30000000

0    

       stmia      r0!,{r1-r8}

       subs       r9,r9,#32

       bne %B0

 

;Clear SDRAM End

 

1

 

             ;Initialize stacks

       bl    InitStacks                 初始化堆棧

 

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

       這段程序能在nor  nand flash 運行,也可以在內存中運行。在nor nand flash運行,需要拷貝數據;

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

 

       ldr   r0, =BWSCON

       ldr   r0, [r0]

       ands       r0, r0, #6              ;OM[1:0] != 0, NOR FLash 或者內存啓動

       bne copy_proc_beg         ;不要讀取 nand flash

       adr  r0, ResetEntry          ;OM[1:0] == 0, NAND FLash 啓動

       cmp      r0, #0                   ;再比較入口是否爲0地址處,如果不是則用了仿真器

       bne copy_proc_beg           ;用仿真器的情況也不要用 nand flash啓動

       ;nop

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

nand_boot_beg                      ;這一段代碼完成從NAND讀代碼到RAM

       mov       r5, #NFCONF             ;設置NAND FLASH的控制寄存器

       ;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]                         ;設置NFCONT,使能NAND FLASH

;控制;禁止片選;初始化ECC等,具體查看手冊

 

 

       bl    ReadNandID       ;按着讀取NANDID,結果保存在r5

       mov       r6, #0          ;r6設初值0.

       ldr   r0, =0xec73         ;期望的NAND ID

       cmp       r5,   r0             ;這裏進行比較

       beq %F1              ;相等的話就跳到下一個1標號處

       ldr   r0, =0xec75         ;這是另一個期望值

       cmp       r5, r0              ;再進行比較

       beq %F1               ;相等的話就跳到下一個1標號處

       mov       r6, #1           ;不相等了,設置r6=1.

1    

       bl    ReadNandStatus      ;讀取NAND狀態,結果放在r1

      

       mov       r8, #0            ;r8設初值0,意義爲頁號

       ldr   r9, =ResetEntry

;===============================================================
;
注意,在這裏使用的是ldr僞指令,而不是上面用的adr僞指令,它加載的是ResetEntry
;
的絕對地址,也就是我們期望的RAM中的地址,在這裏,它和|Image$$RO$$Base|

;一樣 也就是說,我如我們編譯程序時RO BASE指定的地址在RAM,而把生成的

;文件拷到 NAND裏運行,ldr加載的r9的值還是定位在內存.

;LdrADR的區別http://blog.163.com/ncx995/blog/static/28003127200851085043536/
;===============================================================

2    

       ands       r0, r8, #0x1f          ;r80x1f(32)的整數倍,eq有效,ne無效

       bne        %F3                ;這句的意思是對每個塊(32)進行檢錯

       mov              r0, r8            ;r8->r0

       bl           CheckBadBlk         ;檢查NAND的壞區

       cmp              r0, #0                ;比較r00

       addne    r8, r8, #32            ;存在壞塊的話就跳過這個壞塊

       bne        %F4                 ;沒有的話就跳到標號4

3    

       mov       r0, r8                 ;當前頁號->r0    

       mov       r1, r9                 ;當前目標地址->r1

       bl    ReadNandPage            ;讀取該頁的NAND數據到RAM

       add r9, r9, #512                ;每一頁的大小是512Bytes

       add r8, r8, #1                 ; r8指向下一頁

4    

       cmp       r8, #8192              ;比較是否讀完8192

       bcc  %B2                  ;如果r8小於8192(沒讀完),就返回前面的標號2

      

       mov       r5, #NFCONF                   ;設置NAND FLASH 控制寄存器

       ldr   r0, [r5, #4]

       bic r0, r0, #1

       str   r0, [r5, #4]                    ; NAND flash controller enable

       ldr   pc, =copy_proc_beg             ;copy nand flash ram

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

copy_proc_beg

       adr  r0, ResetEntry           ;ResetEntry->r0

       ldr   r2,                     ;BaseOfROM BaseOfROM(後面有定義)->r2

       cmp       r0, r2                   ;比較r0r2

       ldreq      r0, TopOfROM       ;如果相等的話(在內存運行),TopOfROM->r0

       beq InitRam                 ;同時跳到InitRam

發佈了31 篇原創文章 · 獲贊 4 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章