?? 2410init.s
字號:
#=========================================
# NAME: 2410INIT.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,POWER_OFF mode
#=========================================
.include "option.a"
.include "memcfg.a"
.include "2410addr.s"
.EQU BIT_SELFREFRESH,(1<<22)
.EQU REFRESH, 0x48000024
#Pre-defined constants
.equ USERMODE, 0x10
.equ FIQMODE, 0x11
.equ IRQMODE, 0x12
.equ SVCMODE, 0x13
.equ ABORTMODE, 0x17
.equ UNDEFMODE, 0x1b
.equ MODEMASK, 0x1f
.equ NOINT, 0xc0
#The location of stacks
/*.equ UserStack, (_STACK_BASEADDRESS-0x3800) /*0x33ff4800 ~*/
/*.equ SVCStack (_STACK_BASEADDRESS-0x2800) /*0x33ff5800 ~*/
/*.equ UndefStack (_STACK_BASEADDRESS-0x2400) /*0x33ff5c00 ~*/
/*.equ AbortStack (_STACK_BASEADDRESS-0x2000) /*0x33ff6000 ~*/
/*.equ IRQStack (_STACK_BASEADDRESS-0x1000) /*0x33ff7000 ~*/
/*.equ FIQStack (_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 HANDLER HandleLabel
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)*/
.endm
.extern Image_RO_Base
.extern Image_RO_Limit /* End of ROM code (=start of ROM data) */
.extern Image_RW_Base /* Base of RAM to initialise */
.extern Image_ZI_Base /* Base and limit of area */
.extern Image_ZI_Limit /* to zero initialise */
.extern Main /* The main entry of mon program */
.text
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,.long can't be used here because the linker generates error.
.ifeq ENDIAN_CHANGE-1
.ifdef ENTRY_BUS_WIDTH
.ifeq ENTRY_BUS_WIDTH-32
b ChangeBigEndian @ .long 0xea000007
.elseif ENTRY_BUS_WIDTH-16
andeq r14,r7,r0,lsl #20 @ .long 0x0007ea00
.elseif ENTRY_BUS_WIDTH-8
streq r0,[r0,-r10,ror #1] @ .long 0x070000ea
.endif
.endif
.else
b ResetHandler
.endif
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
ChangeBigEndian:
#@ 0x24
.ifeq ENTRY_BUS_WIDTH-32
.long 0xee110f10 @ 0xee110f10 => mrc p15,0,r0,c1,c0,0
.long 0xe3800080 @ 0xe3800080 => orr r0,r0,#0x80# //Big-endian
.long 0xee010f10 @ 0xee010f10 => mcr p15,0,r0,c1,c0,0
.endif
.ifeq ENTRY_BUS_WIDTH-16
.long 0x0f10ee11
.long 0x0080e380
.long 0x0f10ee01
.endif
.ifeq ENTRY_BUS_WIDTH-8
.long 0x100f11ee
.long 0x800080e3
.long 0x100f01ee
.endif
.long 0xffffffff @ swinv 0xffffff is similar with NOP and run well in both endian mode.
.long 0xffffffff
.long 0xffffffff
.long 0xffffffff
.long 0xffffffff
b ResetHandler
#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:
mov r2,r0 @r2=rCLKCON
tst r0,#0x8 @POWER_OFF mode?
bne ENTER_POWER_OFF
ENTER_STOP:
ldr r0,=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.
B0: subs r1,r1,#1
bne B0
ldr r0,=CLKCON @enter STOP mode.
str r2,[r0]
mov r1,#32
F0: 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 POWER_OFF 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_POWER_OFF:
#NOTE.
#1) rGSTATUS3 should have the return address after wake-up from POWER_OFF 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.
B1: subs r1,r1,#1
bne B1
ldr r1,=MISCCR
ldr r0,[r1]
orr r0,r0,#(7<<17) @;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up
str r0,[r1]
ldr r0,=CLKCON
str r2,[r0]
b . @;CPU will die here.
WAKEUP_POWER_OFF:
#;Release SCLKn after wake-up from the POWER_OFF mode.
ldr r1,=MISCCR
ldr r0,[r1]
bic r0,r0,#(7<<17) @;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
str r0,[r1]
#;Set memory control registers
ldr r0,=SMRDATA
ldr r1,=BWSCON @;BWSCON Address
add r2, r0, #52 @;End address of SMRDATA
B2:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne B2
mov r1,#256
B3: subs r1,r1,#1 @;1) wait until the SelfRefresh is released.
bne B3
ldr r1,=GSTATUS3 @;GSTATUS3 has the start address just after POWER_OFF wake-up
ldr r0,[r1]
mov pc,r0
.LTORG
HandlerFIQ: HANDLER HandleFIQ
HandlerIRQ: HANDLER HandleIRQ
HandlerUndef: HANDLER HandleUndef
#;HandlerUndef
#; sub sp, sp, #4 ;decrement sp(to store jump address)
#; stmfd sp!, {r14} ;PUSH the work register to stack(lr does't push because it return to original address)
#; ldr r0, =HandleUndef ;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}
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}
#=======
# 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,=0x7ff @all sub interrupt disable
str r1,[r0]
.ifdef LED_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]
.endif
ldr r0,=GPBCON @蜂鳴器靜止
ldr r1,=0x15555a
str r1,[r0]
ldr r0,=GPBDAT
ldr r1,=0x7f8
str r1,[r0]
ldr r0,=GPGCON @顯示器黑皮
ldr r1,=0xff85ff02
str r1,[r0]
ldr r0,=GPGDAT
ldr r1,=0x0
str r1,[r0]
#To reduce PLL lock time, adjust the LOCKTIME register.
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
.ifdef PLL_ON_START
# Configure MPLL
ldr r0,=CLKDIVN
ldr r1,=0x3
str r1,[r0]
ldr r0,=MPLLCON
ldr r1,=0xa1031
str r1,[r0]
.endif
#Check if the boot is caused by the wake-up from POWER_OFF mode.
ldr r1,=GSTATUS2
ldr r0,[r1]
tst r0,#0x2
#In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler.
bne WAKEUP_POWER_OFF
.global StartPointAfterPowerOffWakeUp
StartPointAfterPowerOffWakeUp:
#Set memory control registers
adr r0, SMRDATA @can't use ldr r0, =xxxx important!!!
ldr r1, =BWSCON @BWSCON Address
add r2, r0, #52 @End address of SMRDATA
B4:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne B4
#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]
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
Ldr r0, =ResetEntry @OM[1:0] == 0, NAND FLash boot , 是不是判斷resetentry地址在0x0還是0x30000000????
@ cmp r0, #0 @if use Multi-ice, , 是不是“若是0x0,則表明是nandflash啟動”
cmp r0, #0x30000000
bne copy_proc_beg @don't read nand flash for boot , 若是“0x30000000,則程序已經通過仿真器下載到sdram,
#=========================================================== resetentry從0x30000000開始執行,不需要在搬運nandflash里面的代碼
nand_boot_beg:
ldr r5, =NFCONF
ldr r0, =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7)
str r0, [r5]
bl ReadNandID
mov r6, #0
ldr r0, =0xec73
cmp r5, r0
beq G1
ldr r0, =0xec75 @我們做的板讀出來是0xec76
cmp r5, r0
beq G1
mov r6, #1
G1:
bl ReadNandStatus
mov r8, #0
# ldr r9, =ResetEntry @從nandflash啟動時,resetentry地址是0x0還是0x30000000????
ldr r9, =0x30000000 @修改后的,自己添加的
G2:
ands r0, r8, #0x1f @判斷一塊block是否拷貝完
bne G3
mov r0, r8
bl CheckBadBlk
cmp r0, #0
addne r8, r8, #32 @若是壞塊,跳到下一塊
bne G4
G3:
mov r0, r8
mov r1, r9
bl ReadNandPage
add r9, r9, #512
add r8, r8, #1
G4:
cmp r8, #4096 @總共要拷貝256頁,128kbytes,為什么是這個數目,是不是由程序大小決定的?????
@ cmp r8, #1
bcc G2
G5:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -