2410init.s
来自「Embest S3CEB2410驱动例程源代码。」· S 代码 · 共 427 行
S
427 行
#=========================================
# 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
# 2002.04.10:SJS:sub interrupt disable 0x3ff -> 0x7ff
#=========================================
.include "option.a"
.include "memcfg.a"
.include "2410addr.a"
.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
.equ CPSR_IRQ_EN, 0x80 /* */
.equ CPSR_IRQ_MASK, 0x40 /* disable Interrupt Mode (IRQ) */
.equ CPSR_FIQ_MASK, 0x80 /* disable Fast Interrupt Mode (FIQ) */
.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:
# 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
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, 2002/04/10
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
# 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,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) @ Fin=12MHz,Fout=50MHz
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
ldr r0,=SMRDATA
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]
# 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
# Zero init base => top of initialised data
cmp r0, r1 @ Check that they are different
beq F2
F1:
cmp r1, r3 @ Copy init data
ldrcc r2, [r0], #4 @ --> LDRCC r2, [r0] + ADD r0, r0, #4
strcc r2, [r1], #4 @ --> STRCC r2, [r1] + ADD r1, r1, #4
bcc F1
F2:
ldr r1, = Image_ZI_Limit @ Top of zero init segment
mov r2, #0
B5:
cmp r3, r1 @ Zero init
strcc r2, [r3], #4
bcc B5
MRS r0, CPSR
BIC r0, r0, #0x80 /* IRQ enable */
MSR CPSR_cxsf, r0
/* jump to main() */
.ifndef THUMBCODE
bl Main @ Don't use main() because ......
b .
.endif
.ifdef THUMBCODE @ for start-up code for Thumb mode
orr lr,pc,#1
bx lr
.thumb
bl Main @ Don't use main() because ......
b .
.arm
.endif
# 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:
# 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.
.long (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.long ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) @ GCS0
.long ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) @ GCS1
.long ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) @ GCS2
.long ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) @ GCS3
.long ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) @ GCS4
.long ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) @ GCS5
.long ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) @ GCS6
.long ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) @ GCS7
.long ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.long 0x32 @ SCLK power saving mode, BANKSIZE 128M/128M
.long 0x30 @ MRSR6 CL=3clk
.long 0x30 @ MRSR7
# .long 0x20 @ MRSR6 CL=2clk
# .long 0x20 @ MRSR7
.ALIGN
.equ HandleReset, _ISR_STARTADDRESS
.equ HandleUndef, _ISR_STARTADDRESS+4
.equ HandleSWI, _ISR_STARTADDRESS+4*2
.equ HandlePabort, _ISR_STARTADDRESS+4*3
.equ HandleDabort, _ISR_STARTADDRESS+4*4
.equ HandleReserved, _ISR_STARTADDRESS+4*5
.equ HandleIRQ, _ISR_STARTADDRESS+4*6
.equ HandleFIQ, _ISR_STARTADDRESS+4*7
#Don't use the label 'IntVectorTable',
#The value of IntVectorTable is different with the address you think it may be.
#IntVectorTable
#IntVectorTable
.equ HandleEINT0, _ISR_STARTADDRESS+4*8
.equ HandleEINT1, _ISR_STARTADDRESS+4*9
.equ HandleEINT2, _ISR_STARTADDRESS+4*10
.equ HandleEINT3 , _ISR_STARTADDRESS+4*11
.equ HandleEINT4_7 , _ISR_STARTADDRESS+4*12
.equ HandleEINT8_23, _ISR_STARTADDRESS+4*13
.equ HandleRSV6 ,_ISR_STARTADDRESS+4*14
.equ HandleBATFLT ,_ISR_STARTADDRESS+4*15
.equ HandleTICK ,_ISR_STARTADDRESS+4*16
.equ HandleWDT ,_ISR_STARTADDRESS+4*17
.equ HandleTIMER0 ,_ISR_STARTADDRESS+4*18
.equ HandleTIMER1 ,_ISR_STARTADDRESS+4*19
.equ HandleTIMER2, _ISR_STARTADDRESS+4*20
.equ HandleTIMER3, _ISR_STARTADDRESS+4*21
.equ HandleTIMER4, _ISR_STARTADDRESS+4*22
.equ HandleUART2 , _ISR_STARTADDRESS+4*23
.equ HandleLCD ,_ISR_STARTADDRESS+4*24
.equ HandleDMA0 ,_ISR_STARTADDRESS+4*25
.equ HandleDMA1, _ISR_STARTADDRESS+4*26
.equ HandleDMA2, _ISR_STARTADDRESS+4*27
.equ HandleDMA3, _ISR_STARTADDRESS+4*28
.equ HandleMMC ,_ISR_STARTADDRESS+4*29
.equ HandleSPI0, _ISR_STARTADDRESS+4*30
.equ HandleUART1, _ISR_STARTADDRESS+4*31
.equ HandleRSV24, _ISR_STARTADDRESS+4*32
.equ HandleUSBD ,_ISR_STARTADDRESS+4*33
.equ HandleUSBH , _ISR_STARTADDRESS+4*34
.equ HandleIIC , _ISR_STARTADDRESS+4*35
.equ HandleUART , _ISR_STARTADDRESS+4*36
.equ HandleSPI1 , _ISR_STARTADDRESS+4*37
.equ HandleRTC, _ISR_STARTADDRESS+4*38
.equ HandleADC, _ISR_STARTADDRESS+4*39
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?