ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) ;Fin = 12.0MHz, UCLK =48MHz,对于usb来说必须是48MHz
str r1,[r0]
nop ; Caution: After UPLL setting, at least7-clocks delay must be inserted for setting hardware be completed.
nop
nop
nop
nop
nop
nop
;ConfigureMPLL
ldr r0,=MPLLCON ;计算公式是固定的,可计算得到
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin = 12.0MHz, FCLK= 400MHz
str r1,[r0]
]
;Checkif the boot is caused by the wake-up from SLEEP mode.
ldr r1,=GSTATUS2 ;这个寄存器数值表示哪个信号引起的复位动作产生
ldr r0,[r1]
tst r0,#0x2
;Incase of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
bne WAKEUP_SLEEP
EXPORTStartPointAfterSleepWakeUp
StartPointAfterSleepWakeUp
;Setmemory control registers
;ldr r0,=SMRDATA ;(等效于下边的指令)
adrl r0,SMRDATA ;be careful!中等范围的地址读取伪指令,用法类似于ldr(大范围地址读取)伪指令
ldr r1,=BWSCON ;BWSCONAddress
add r2, r0, #52 ;Endaddress of SMRDATA 共有13个寄存器地址(4字节)需要赋值,13*4=52字节
0
ldr r3, [r0], #4 ;这些都是后变址指令
str r3, [r1], #4
cmp r2, r0
bne %B0 ;当<的时候,跳转到0标号处继续执行
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; When EINT0 is pressed, Clear SDRAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed
ldr r0,=GPFCON ;input,无上拉电阻
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 ;若不相等,则向下跳到1标号,跳过下边代码
; 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=****
movr1,#0
movr2,#0
movr3,#0
movr4,#0
movr5,#0
movr6,#0
movr7,#0
movr8,#0
ldr r9,=0x4000000 ;64MB ;这几条指令目的是:擦除sdram的所有数据
ldr r0,=0x30000000
0
stmia r0!,{r1-r8}
subs r9,r9,#32
bne %B0
;Clear SDRAM End
1
;Initializestacks
bl InitStacks
;===========================================================
;OM0是flash选择开关,OM0接地时从nand 启动,悬空时(核心板上有上拉电阻)从nor启动
;OM1在核心板上,始终是接地.为0
;OM1:OM0取值:00 nandflash mode;01 16bit nor;10 32bit nor;11 test mode
;详见:s3c2440 用户手册 5.memory controller 一节
ldr r0, =BWSCON
ldr r0, [r0]
ands r0, r0, #6 ;OM[1:0]!= 0, NOR FLash boot do not read nand flash
bne copy_proc_beg
adr r0, ResetEntry ;OM[1:0] == 0, NAND FLash boot
cmp r0, #0 ;ifuse Multi-ice,
bne copy_proc_beg ;donot read nand flash for boot
;nop
;ands指令,加s表示结果影响cpsr寄存器的值
;===========================================================
;把nand中的数据,拷贝到ram中
nand_boot_beg
[{TRUE}
blRdNF2SDRAM
]
ldr pc, =copy_proc_beg
;这里的一段代码时对内存数据的初始化,涉及代码段,数据段,bss段等
;因对这里的变量设置等有异议,暂时未全面分析,但是基本原理想通,就是一个比较地址,复制数据的过程
copy_proc_beg
adr r0, ResetEntry
ldr r2, BaseOfROM
cmp r0, r2
ldreq r0, TopOfROM
beq InitRam
ldrr3, TopOfROM
0
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
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
ldr pc, =%F2 ;gotocompiler address
2
; [CLKDIV_VAL>1 ; meansFclk:Hclk is not 1:1.
; bl MMU_SetAsyncBusMode
; |
; blMMU_SetFastBusMode ; default value.
; ]
;===========================================================
; Setup IRQ handler
; 把中断服务函数的总入口地址,赋给HandleIRQ地址(文件最低端定义)
ldr r0,=HandleIRQ ;Thisroutine is needed
ldr r1,=IsrIRQ ;ifthere is not 'subs pc,lr,#4' at 0x18, 0x1c
str r1,[r0]
[:LNOT:THUMBCODE
bl Main ;Do not use main() because ......
b .
]
[THUMBCODE ;for start-up code for Thumbmode
orr lr,pc,#1
bx lr
CODE16
bl Main ;Do not use main() because ......
b .
CODE32
]
;function initializing stacks
InitStacks ; 初始化栈空间(各个模式下的),为c函数运行做准备
;Donot use DRAM,such as stmfd,ldmfd......
;SVCstackis initialized before
;Undertoolkit 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
;USERmode has not be initialized.
mov pc,lr
;TheLR register will not be valid if the current mode is not SVC mode.
LTORG
SMRDATA DATA
;配置存储器的管理方式
; Memory configuration should be optimizedfor 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 forHCLK<=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)
DCD0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD0x30 ;MRSR6 CL=3clk
DCD0x30 ;MRSR7 CL=3clk
;分配一个字的空间,并用后边的数值来初始化该空间 ,这里命名有些混乱
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 forSDRAM/DRAM self-refresh.
; 3. LCD controller should be disabled forSDRAM/DRAM self-refresh.
; 4. The I-cache may have to be turned on.
; 5. The location of the following code mayhave not to be changed.
;void EnterPWDN(int CLKCON);
EnterPWDN
movr2,r0 ;r2=rCLKCON
tstr0,#0x8 ;SLEEP mode?
bneENTER_SLEEP
ENTER_STOP
ldrr0,=REFRESH
ldrr3,[r0] ;r3=rREFRESH
movr1, r3
orrr1, r1, #BIT_SELFREFRESH
strr1, [r0] ;Enable SDRAMself-refresh
movr1,#16 ;wait untilself-refresh is issued. may not be needed.
0 subsr1,r1,#1
bne%B0
ldrr0,=CLKCON ;enter STOP mode.
strr2,[r0]
movr1,#32
0 subsr1,r1,#1 ;1) wait until the STOP mode isin effect.
bne%B0 ;2) Or wait here until theCPU&Peripherals will be turned-off
; Entering SLEEP mode, only the reset bywake-up is available.
ldrr0,=REFRESH ;exit from SDRAM self refresh mode.
strr3,[r0]
MOV_PC_LR
ENTER_SLEEP
;NOTE.
;1)rGSTATUS3 should have the return address after wake-up from SLEEP mode.
ldrr0,=REFRESH
ldrr1,[r0] ;r1=rREFRESH
orrr1, r1, #BIT_SELFREFRESH
strr1, [r0] ;Enable SDRAMself-refresh
movr1,#16 ;Wait untilself-refresh is issued,which may not be needed.
0 subsr1,r1,#1
bne%B0
ldr r1,=MISCCR
ldr r0,[r1]
orr r0,r0,#(7<<17) ;Set SCLK0=0, SCLK1=0, SCKE=0.
str r0,[r1]
ldrr0,=CLKCON ; Enter sleep mode
strr2,[r0]
b. ;CPU will die here.
WAKEUP_SLEEP
;ReleaseSCLKn 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]
;Setmemory control registers
ldr r0,=SMRDATA ;be careful!
ldr r1,=BWSCON ;BWSCONAddress
add r2, r0, #52 ;Endaddress of SMRDATA
0
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne %B0
movr1,#256
0 subsr1,r1,#1 ;1) wait until the SelfRefreshis released.
bne%B0
ldrr1,=GSTATUS3 ;GSTATUS3 has the startaddress just after SLEEP wake-up
ldrr0,[r1]
movpc,r0
;=====================================================================
; Clock division test
; Assemble code, because VSYNC time is veryshort
;=====================================================================
EXPORTCLKDIV124
EXPORTCLKDIV144
CLKDIV124
ldr r0, = CLKDIVN
ldr r1, = 0x3 ;0x3 = 1:2:4
str r1, [r0]
; waituntil 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]
; waituntil 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
;定义数据段
;^ 标志等价于MAP伪指令
;MAP用于定义一个结构化的内存表首地址,此时内存表的位置计数器值,也变成该首地址值,就相当于在这个地址处操作
;#于FIELD同义,用于定义一个结构化的内存表的数据域,后边数字表示该数据占用的字节数
;Handle*** 在此就是一个标号,为了标示数据量
;用法:把对应的终端处理函数的首地址,放到这里的对应的预留空间处,当发生中断时,就能根据宏函数,直接跳转
AREARamData, DATA, READWRITE
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Do not use the label 'IntVectorTable',
;The value of IntVectorTable is differentwith 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