📄 2440init.s
字号:
;=========================================
; 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.14:DonGo: Modified for 2440.
;=========================================
GET option.inc
GET memcfg.inc
GET 2440addr.inc
BIT_SELFREFRESH EQU (1<<22)
;Pre-defined constants
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
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 ~
;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE}
CODE32
|
THUMBCODE SETL {FALSE}
]
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
MACRO
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH 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} ;POP the work register and pc(jump to ISR)
MEND
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
;IMPORT MMU_SetAsyncBusMode
;IMPORT MMU_SetFastBusMode ;hzh
IMPORT Main ; The main entry of mon program
AREA Init,CODE,READONLY
ENTRY
EXPORT __ENTRY
__ENTRY ;在image map 里面 __ENTRY=0x30100000 Image$$RO$$Base=0x30100000
;但是,2440开机的时候,会复制nand的前4K到0x00000000 ~0x00001000,所以__ENTRY的地址为0x00000000,
;Image$$RO$Base是编译器给程序的定值,所以还是Image$$RO$Base==0x30100000
;至于这些地址的作用是告诉2440的USBD下载,应该下载到0x30100000开始的SDRAM,
;而Bin文件每条命令是没有绝对地址的,都是相对于第一条指令的地址而言而已。
;反正说了这么多,要说的是
;1.0x30100000改为多少没什么所谓
;2.后面的copy_proc_beg是有用的,把0x00000000 ~0x00001000复制回0x30100000以后的位置。
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 :DEF:ENDIAN_CHANGE
[ ENDIAN_CHANGE
ASSERT :DEF:ENTRY_BUS_WIDTH
[ ENTRY_BUS_WIDTH=32
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
]
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 => mrc 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
;=======
; 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]
[ {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: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 dont' call here
; call it after copy, hzh
; [ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
; bl MMU_SetAsyncBusMode
; |
; bl MMU_SetFastBusMode ; default value.
; ]
;program has not been copied, so use these directly, hzh
[ 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
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 ;be careful!, hzh
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, hzh
mov r0, #&1000
1
subs r0, r0, #1
bne %B1
;===
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; When EINT0 is pressed, Clear SDRAM
;;;;;;;;;;;;; 这段没什么必要,mini2440 eint0外接上拉电阻,所以一定 Clear SDRAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed
ldr r0,=GPFCON
ldr r1,=0x0;GPF 全部输入
str r1,[r0]
ldr r0,=GPFUP
ldr r1,=0xff;GPF 取消内部上拉
str r1,[r0]
ldr r1,=GPFDAT
ldr r0,[r1]
bic r0,r0,#(0x1e<<1) ; bit clear;不判断 GPF2,3,4,5.GPF2,3,4,5清0
tst r0,#0x1 ;如果GPF0=1,则Clear SDRAM
;问题是,mini2440,eint0接了上拉电阻,也就是GPF0=1,所以,一定Clear SDRAM
bne %F1
; Clear SDRAM Start
;完全没有,mini2440的灯不是这样
ldr r0,=GPFCON
ldr r1,=0x55aa
;01 01 01 01 10 10 10 10
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
ldr r9,=0x4000000 ;64MB
ldr r0,=0x30000000
0
stmia r0!,{r1-r8}
subs r9,r9,#32
bne %B0
;Clear SDRAM End
1
;Initialize stacks
bl InitStacks
;===========================================================
;bl Led_Test
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
cmp r0, #0 ;if use Multi-ice,
bne copy_proc_beg ;don't read nand flash for boot
;完全不懂,不是应该跳到copy_proc_beg 才对吗?
;解释:adr r0, ResetEntry不是ldr r0, =ResetEntry
;adr r0, ResetEntry 是ResetEntry这个地址的值传到r0
;ldr r0, =ResetEntry是ResetEntry这个值传到r0
;adr r0, ResetEntry
;也许是用Multi-ice调试的时候,[ResetEntry]会被为0
;但resetEntry=0x30100000
;
;nop
;没用的,可以删了
;ldr r0, =ResetEntry
;ldr r2, =0x30100000
;cmp r0, r2
;bleq LT_RE
;===========================================================
;这段才是内存复制。。。。。。。。。。。。。
;===========================================================
nand_boot_beg
mov r5, #NFCONF
;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
mov r6, #0
ldr r0, =0xec73
cmp r5, r0
beq %F1
ldr r0, =0xec75
cmp r5, r0
beq %F1
mov r6, #1
1
bl ReadNandStatus
mov r8, #0
ldr r9, =ResetEntry
2
ands r0, r8, #0x1f ;r0=#0x1f
bne %F3
mov r0, r8
bl CheckBadBlk
cmp r0, #0
addne r8, r8, #32
bne %F4
3
mov r0, r8
mov r1, r9
bl ReadNandPage
add r9, r9, #512
add r8, r8, #1
4
;cmp r8, #256
cmp r8,#512 ;add by Simon at 2009.09.28
;改大的目的是为了下载大的图片
;不懂为什么可以下载这么大,ResetEntry=0;
;512*512=0x40000,0x40000没有相对应的空间
;究竟下载去哪里。
;还是说ResetEntry=0x30100000
;编译器编译的时候已经把ResetEntry代换为0x30100000
;它不是代表开始的代码,它现在是一个#DEFINE,代换而已
bcc %B2
;从nand复制0x20000个数据到ResetEntry开始 131k
;有可能是因为这里,使图片弄大点,就会有问题
mov r5, #NFCONF ;DsNandFlash
ldr r0, [r5, #4]
bic r0, r0, #1
str r0, [r5, #4]
ldr pc, =copy_proc_beg;这个非常有必要,实现BootSRAM(4KB)跳到SDRAM(bank6)
;===========================================================
;关于这段有个问题,PC正在指向这里,但是,这段代码是要改变0x30100000~EndOfBSS的
;code,一边执行,一边改变自己,不是很矛盾吗?
copy_proc_beg
adr r0, ResetEntry
ldr r2, BaseOfROM
cmp r0, r2 ;ResetEntry=__Entry=0x30100000=Image$$RO$$Base=BaseOfROM=0x30100000
ldreq r0, TopOfROM ;这个一定执行,但是不懂为什么这样写 TopOfROM=Image$$RO$$Limit=0x3011ec7c (一个很后的地址,与图片大小有关)
beq InitRam
ldr r3, 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 ;BaseOfBSS=Image$$RW$$Base=Image$$RO$$Limit=TopOfROM=0x3011ec7c
ldr r3, BaseOfZero ;BaseOfZero=Image$$ZI$$Base=0x3011ef04
; Image$$RW$$Base与Image$$ZI$$Base之间夹着
;Symbol Name Value Ov Type Size Object(Section)
;-----------------------------------------------------------------------------------------------
;Image$$RW$$Base 0x3011ec7c Number 0 anon$$obj.o ABSOLUTE
;Selfpwr 0x3011ec7c Data 1 usbsetup.o(.data)
;mallocPt 0x3011ec80 Data 4 2440lib.o(.data)
;boot_params 0x3011ec88 Data 368 nand.o(.data)
;vend_params 0x3011ee34 Data 208 nand.o(.data)
;Image$$ZI$$Base 0x3011ef04 Number 0 anon$$obj.o ABSOLUTE
0
cmp r2, r3
ldrcc r1, [r0], #4 ;cc 小于
strcc r1, [r2], #4 ;很有问题,r0=Image$$RO$$Limit,r2=Image$$RW$$Base,r0=r2,所以根本就没复制过。
bcc %B0
mov r0, #0
ldr r3, EndOfBSS ;Symbol Name Value Ov Type Size Object(Section)
;-----------------------------------------------------------------------------------------------
;frameBuffer16BitTft 0x3012000c Data 4 lcdinit.o(.bss)
;Image$$RW$$Limit 0x30120070 Number 0 anon$$obj.o ABSOLUTE
;Image$$ZI$$Limit 0x30120070 Number 0 anon$$obj.o ABSOLUTE
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
ldr pc, =%F2 ;goto compiler address
2
; [ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
; bl MMU_SetAsyncBusMode
; |
; bl MMU_SetFastBusMode ; default value.
; ]
;bl Led_Test
;===========================================================
; 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]
; ;Copy and paste RW data/zero initialized data
; ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
; ldr r1, =|Image$$RW$$Base| ; and RAM copy
; ldr r3, =|Image$$ZI$$Base|
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -