决心入门者:S3C2410bootloader 之2410Init.s详解二

来源:互联网 发布:北京师范大学 知乎 编辑:程序博客网 时间:2024/05/20 22:37

;=======================================================================
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
; 哈哈,下面又有看头了,这个初始化程序好像被名曰hzh的高手改过
; 能在NOR NAND 还有内存中运行,当然了,在内存中运行最简单了.
; 在NOR NAND中运行的话都要先把自己拷到内存中.
; 此外,还记得上面提到的|Image$$RO$$Base|,|Image$$RO$$Limit|...吗?
; 这就是拷贝的依据了!!!
;BWSCON的[2:1]反映了外部引脚OM[1:0]:若OM[1:0] != 00, 从NOR FLash启动或直接在内存运行;
;若OM[1:0]==00,则为Nand Flash Mode
;=========================================================================
 ldr r0, =BWSCON   ;总线和等待状态控制寄存器
 ldr r0, [r0]
 ands r0, r0, #6  ;OM[1:0] != 0, NOR FLash boot
 bne copy_proc_beg  ;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,    ;TAG调试时是直接下载到内存中运行,不需要再从nand拷贝
 bne copy_proc_beg  ;don't read nand flash for boot
 

 
;===========================================================
;6.将数据段拷贝到RAM中,将零初始化数据段清零
;将程序从nandflash拷贝到sdram
;===========================================================
nand_boot_beg
 mov r5, #NFCONF
 ldr r0, =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7) ;Nand Flash 配置寄存器,看手册
 str r0, [r5]
 
 bl ReadNandID          ;读取Nand的ID号,在nandflash手册上可以查到     
 mov r6, #0
 ldr r0, =0xec73          ;k9f1208u0m的ID不是0xec76么???不知道这里是怎么匹配的
 cmp r5, r0
 beq %F1
 ldr r0, =0xec75
 cmp r5, r0
 beq %F1            ;向前跳转到标号1 读nand状态
 mov r6, #1

 bl ReadNandStatus
 
 mov r8, #0
 ldr r9, =ResetEntry

 ands r0, r8, #0x1f
 bne  %F3
 mov  r0, r8
 bl  CheckBadBlk
 cmp  r0, #0
 addne r8, r8, #32
 bne  %F4

 mov r0, r8
 mov r1, r9
 bl ReadNandPage
 add r9, r9, #512
 add r8, r8, #1

 cmp r8, #256
 bcc %B2
 
 mov r5, #NFCONF   ;DsNandFlash
 ldr r0, [r5]
 and r0, r0, #~0x8000
 str r0, [r5]
 ldr pc, =copy_proc_beg
 
 
;===========================================================;==================================
;若是从NAND启动,则拷贝工作已经在nand_boot_beg中完成,所以直接跳转到main
;若是从NOR启动,则将RO和RW部分都拷贝到内存,然后跳转到内存运行(也可在NOR中运行,只是速度稍慢)
;注:若在NOR中直接运行,需把RO/BASE改为0并定义RW/BASE 会跳过RO拷贝
;=============================================================================================
copy_proc_beg
 adr r0, ResetEntry   ;判断是否在ROM中运行,ROM即RO指定的地址 从NOR启动时ResetEntry为0
 ldr r2, BaseOfROM   ;如果是则跳转到RwCopy 否则的话,将程序拷贝到ROM地址
 cmp r0, r1
 ldreq r0, TopOfROM
 beq InitRam 
 ldr r3, TopOfROM

 ldmia r0!, {r4-r7}
 stmia r2!, {r4-r7}
 cmp r2, r3
 bcc %B0
 
 sub r2, r2, r3
 sub r0, r0, r2    
  
InitRam 
 ldr r2, BaseOfBSS
 ldr r3, BaseOfZero 
0
 cmp r2, r3
 ldrcc r1, [r0], #4
 strcc r1, [r2], #4
 bcc %B0 

 mov r0, #0
 ldr r3, EndOfBSS

 cmp r2, r3   ;初始化Zero部分 不管从哪里启动,这部分都需要执行
 strcc r0, [r2], #4
 bcc %B1 

 ;send reset status to main function
 ldr r1, =GSTATUS2
 ldr r0, [r1]
 str r0, [r1] ;clear reset status

    [ :LNOT:THUMBCODE
     ldr pc, GotoMain ;bl Main        ;Don't use main() because ......
     b .                      
    ]

    [ THUMBCODE         ;for start-up code for Thumb mode
     orr lr,pc,#1
     bx lr
     CODE16
     bl Main        ;Don't use main() because ......
     b .
     CODE32
    ]

;===========================================================
 EXPORT disable_irq
disable_irq
 mrs r0, cpsr    ;enter svc mode and disable irq,fiq
 orr r0, r0, #0xc0
 msr cpsr_c, r0
 mov pc, lr
 
ReadNandID                  ;读取Nand的ID号,在nandflash手册上可以查到
 mov   r7,#NFCONF 
 ldr      r0,[r7,#0]  ;NFChipEn();
 bic      r0,r0,#0x800
 str      r0,[r7,#0] 
 mov      r0,#0x90  ;WrNFCmd(RdIDCMD);
 strb     r0,[r7,#4] 
 mov      r4,#0   ;WrNFAddr(0);
 strb     r4,[r7,#8] 
1       ;while(NFIsBusy());
 ldr      r0,[r7,#0x10] 
 tst      r0,#1
 beq      %B1
 ldrb     r0,[r7,#0xc] ;id  = RdNFDat()<<8;
 mov      r0,r0,lsl #8 
 ldrb     r1,[r7,#0xc] ;id |= RdNFDat();
 orr      r5,r1,r0 
 ldr      r0,[r7,#0]  ;NFChipDs();
 orr      r0,r0,#0x800
 str      r0,[r7,#0] 
 mov   pc,lr 
 
ReadNandStatus
 mov   r7,#NFCONF
 ldr      r0,[r7,#0]  ;NFChipEn();
 bic      r0,r0,#0x800
 str      r0,[r7,#0]
 mov      r0,#0x70  ;WrNFCmd(QUERYCMD);
 strb     r0,[r7,#4] 
 ldrb     r1,[r7,#0xc] ;r1 = RdNFDat();
 ldr      r0,[r7,#0]  ;NFChipDs();
 orr      r0,r0,#0x800
 str      r0,[r7,#0]
 mov   pc,lr

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

CheckBadBlk
 mov  r7, lr
 mov  r5, #NFCONF
 
 bic  r0, r0, #0x1f ;addr &= ~0x1f;
 ldr      r1,[r5,#0]  ;NFChipEn()
 bic      r1,r1,#0x800
 str      r1,[r5,#0] 

 mov      r1,#0x50  ;WrNFCmd(READCMD2)
 strb     r1,[r5,#4] 
 mov      r1, #5
 strb     r1,[r5,#8]  ;WrNFAddr(5)
 strb     r0,[r5,#8]  ;WrNFAddr(addr)
 mov      r1,r0,lsr #8 ;WrNFAddr(addr>>8)
 strb     r1,[r5,#8] 
 cmp      r6,#0   ;if(NandAddr)  
 movne    r0,r0,lsr #16 ;WrNFAddr(addr>>16)
 strneb   r0,[r5,#8]
 
 bl  WaitNandBusy ;WaitNFBusy()

 ldrb r0, [r5,#0xc] ;RdNFDat()
 sub  r0, r0, #0xff
 
 mov      r1,#0   ;WrNFCmd(READCMD0)
 strb     r1,[r5,#4] 
 
 ldr      r1,[r5,#0]  ;NFChipDs()
 orr      r1,r1,#0x800
 str      r1,[r5,#0]
 
 mov  pc, r7
 
ReadNandPage
 mov   r7,lr
 mov      r4,r1
 mov      r5,#NFCONF

 ldr      r1,[r5,#0]  ;NFChipEn()
 bic      r1,r1,#0x800
 str      r1,[r5,#0] 

 mov      r1,#0   ;WrNFCmd(READCMD0)
 strb     r1,[r5,#4] 
 strb     r1,[r5,#8]  ;WrNFAddr(0)
 strb     r0,[r5,#8]  ;WrNFAddr(addr)
 mov      r1,r0,lsr #8 ;WrNFAddr(addr>>8)
 strb     r1,[r5,#8] 
 cmp      r6,#0   ;if(NandAddr)  
 movne    r0,r0,lsr #16 ;WrNFAddr(addr>>16)
 strneb   r0,[r5,#8]
 
 ldr      r0,[r5,#0]  ;InitEcc()
 orr      r0,r0,#0x1000
 str      r0,[r5,#0] 
 
 bl       WaitNandBusy ;WaitNFBusy()
 
 mov      r0,#0   ;for(i=0; i<512; i++)
1
 ldrb     r1,[r5,#0xc] ;buf[i] = RdNFDat()
 strb     r1,[r4,r0]
 add      r0,r0,#1
 bic      r0,r0,#0x10000
 cmp      r0,#0x200
 bcc      %B1
 
 ldr      r0,[r5,#0]  ;NFChipDs()
 orr      r0,r0,#0x800
 str      r0,[r5,#0]
  
 mov   pc,r7


;====================================================================
4.初始化各模式下的栈指针
;终于要干完在2410sram中要干的活了,接下来的工作将要去sdram中执行Main了.
;=====================================================================
;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
 
 orr r1,r0,#ABORTMODE|NOINT
 msr cpsr_cxsf,r1  ;AbortMode
 ldr sp,=AbortStack

 orr r1,r0,#IRQMODE|NOINT
 msr cpsr_cxsf,r1  ;IRQMode
 ldr sp,=IRQStack
   
 orr r1,r0,#FIQMODE|NOINT
 msr cpsr_cxsf,r1  ;FIQMode
 ldr sp,=FIQStack

 bic r0,r0,#MODEMASK|NOINT
 orr r1,r0,#SVCMODE
 msr cpsr_cxsf,r1  ;SVCMode
 ldr sp,=SVCStack
 
 ;USER mode has not be initialized.
 
 mov pc,lr
 ;The LR register won't be valid if the current mode is not SVC mode.
 

 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 0x1f7c;((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
;     DCD 0x20            ;MRSR6 CL=2clk
;     DCD 0x20            ;MRSR7

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|


;====================================================================
;7.跳转到C语言Main入口函数中
;=====================================================================
 GBLS main_entry         
main_entry SETS "Main" 
 IMPORT $main_entry
GotoMain DCD $main_entry  

     ALIGN


     AREA RamData, DATA, READWRITE
;这里将中断异常向量建立在sdram中

        ^   _ISR_STARTADDRESS
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
HandleEINT0    #   4
HandleEINT1    #   4
HandleEINT2    #   4
HandleEINT3    #   4
HandleEINT4_7 #   4
HandleEINT8_23 #   4
HandleRSV6 #   4
HandleBATFLT    #   4
HandleTICK    #   4
HandleWDT #   4
HandleTIMER0  #   4
HandleTIMER1  #   4
HandleTIMER2  #   4
HandleTIMER3  #   4
HandleTIMER4  #   4
HandleUART2   #   4
HandleLCD  #   4
HandleDMA0 #   4
HandleDMA1 #   4
HandleDMA2 #   4
HandleDMA3 #   4
HandleMMC #   4
HandleSPI0 #   4
HandleUART1 #   4
HandleRSV24 #   4
HandleUSBD #   4
HandleUSBH #   4
HandleIIC    #   4
HandleUART0  #   4
HandleSPI1  #   4
HandleRTC  #   4
HandleADC  #   4

        END

原创粉丝点击