📄 44b0init.s
字号:
;* change BDMACON reset value for BDMA *
;****************************************
ldr r0,=BDIDES0
ldr r1,=0x40000000 ;BDIDESn reset value should be 0x40000000
str r1,[r0]
ldr r0,=BDIDES1
ldr r1,=0x40000000 ;BDIDESn reset value should be 0x40000000
str r1,[r0]
;****************************************************
;* Set memory control registers *
;****************************************************
ldr r0,=SMRDATA
ldmia r0,{r1-r13}
ldr r0,=0x01c80000 ;BWSCON Address
stmia r0,{r1-r13}
;****************************************************
;* Initialize stacks *
;****************************************************
ldr sp, =SVCStack ;
bl InitStacks
;****************************************************
;* Setup IRQ handler *
;****************************************************
;Setup IRQ handler 主体就是将0x0处的异常表搬运到_IRQ_BASEADDRESS,并设置irq服务(none vector mode)
;为什么要这么做?中断发生时不是自动转到0x0处的中断异常表吗?
;莫非日后,再修改此表使他指向_IRQ_BASEADDRESS处?这样都在ram中,加快速度???
;————不是的!!!看一下分析即可知道。
;下面这段代码看似将_IRQ_BASEADDRESS + 0x100之后的0x100全部初始化为_IRQ_BASEADDRESS
;事实上,结合44b.h中的isr部分就清楚了,那里是安装isr的地方,而起始地址正是_IRQ_BASEADDRESS + 0x100!
;当irq到来时,无论是非vector mode还是vector mode,都要跳转到HandleXXX处,
;而HandleXXX的首地址正是(_IRQ_BASEADDRESS+0x100)!
;再回顾一下中断或异常到来后的行为:
; 1,异常发生
; 2,转到0x0为首地址的异常表
; 3,根据异常类型,转入某个项,比如SWI
; ldr pc, =(_IRQ_BASEADDRESS + 0x08) ; HandlerSWI
; 4,那么(_IRQ_BASEADDRESS + 0x08)处放的是什么呢?
; 见下表
; ^ (_IRQ_BASEADDRESS)
; HandleReset # 4
; HandleUndef # 4
; HandleSWI # 4
; ...
; 由此可知HandleSWI是位于_IRQ_BASEADDRESS + 0x08处的,而44b.h中定义:
; #define pISR_SWI (*(unsigned *)(_IRQ_BASEADDRESS+0x8))
; 我们可以安装这个异常处理函数!
; irq到来时,情况差不多。
; A) 如果是vector mode
; 那么直接载入0x20开始的指令,比如ldr pc,=HandlerEINT4567 ;
; HandlerEINT4567的定义可知:
; ^ (_IRQ_BASEADDRESS+0x100)
; HandleADC # 4
; HandleRTC # 4
; ...
; HandleEINT4567 # 4
; 他位于_IRQ_BASEADDRESS+0x154处,而44b.h中定义:
; #define pISR_EINT4567 (*(unsigned *)(_IRQ_BASEADDRESS+0x154))//0x74))
; 于是我们可以安装处理函数。
;
; B) 如果是none vector mode
; 那么仅在装入HandlerEINT4567时方法不同,它是通过判断程序来完成的,剩下的步骤还是相同的。
ldr r0,=(_IRQ_BASEADDRESS + 0x100)
ldr r2,=_IRQ_BASEADDRESS
add r3,r0, #0x100 ;r3指向_IRQ_BASEADDRESS+0x200处
0
CMP r0, r3 ;do what? <- 哈哈,我知道了,居然你们立宇泰的人不知道!!!
STRCC r2, [r0], #4;cc:Carry clear;save R2 to R0 address, R0 + 4=R0。
BCC %B0
;----------------------------------------------------------------------------------------
;将0x0处的vector table 拷贝到 _IRQ_BASEADDRESS(0xc000000)
ldr r1,=_IRQ_BASEADDRESS
ldr r0,=ExceptionHanlderBegin ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
ldr r3,=ExceptionHanlderEnd
0
CMP r0, r3 ;put the vector table at _IRQ_BASEADDRESS(0xc000000)
LDRCC r2, [r0], #4
STRCC r2, [r1], #4
BCC %B0
;----------------------------------------------------------------------------------------
;下面代码将非向量模式下的中断判断处理函数拷贝到_IRQ_BASEADDRESS+0x80(0xc000080)
ldr r1,=DIsrIRQ ;put the IRQ judge program at _IRQ_BASEADDRESS+0x80(0xc000080)
ldr r0,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
ldr r3,=IsrIRQEnd
0
CMP r0, r3
LDRCC r2, [r0], #4
STRCC r2, [r1], #4
BCC %B0
;----------------------------------------------------------------------------------------
;将非向量模式的中断处理函数装入_IRQ_BASEADDRESS处的HandleIRQ
ldr r1, =MyHandleIRQ ;MyHandleIRQ point to DIsrIRQ
ldr r0, =ExceptionHanlderBegin
ldr r4, =_IRQ_BASEADDRESS;////
sub r0, r1, r0 ;计算MyHandleIRQ在ExceptionHanlderBegin这个中断表中的偏移
;add r0, r0, #_IRQ_BASEADDRESS
add r0, r0,r4 ;r0指向_IRQ_BASEADDRESS+(MyHandleIRQ的偏移),即0xc000000处的HandleIRQ
ldr r1, =DIsrIRQ ;将非向量模式的中断处理函数装入0xc000000处的HandleIRQ
str r1, [r0]
; ldr r0,=HandleIRQ ;This routine is needed
; ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
; str r1,[r0]
;-----------------------------------------------------------------------------------------
; --- Initialise memory required by C code
;********************************************************
;* 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 %F1
0
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 %B0
1
LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment
MOV r2, #0
2
CMP r3, r1 ; Zero init 初始化bss段
STRCC r2, [r3], #4
BCC %B2
;--------Now we enter the C code
[ :LNOT:THUMBCODE ;if(!thumbcode) arm state;
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
]
;****************************************************
;* The function for initializing stack *
;****************************************************
;4.初始化各模式下的栈指针
InitStacks
;Don't use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.50, '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 is not initialized.
mov pc,lr ;The LR register may be not valid for the mode changes.
;****************************************************
;* The function for entering power down mode *
;****************************************************
;void EnterPWDN(int CLKCON);
EnterPWDN
mov r2,r0 ;r0=CLKCON
ldr r0,=REFRESH
ldr r3,[r0]
mov r1, r3
orr r1, r1, #0x400000 ;self-refresh enable
str r1, [r0]
nop ;Wait until self-refresh is issued. May not be needed.
nop ;If the other bus master holds the bus, ...
nop ; mov r0, r0
nop
nop
nop
nop
;enter POWERDN mode
ldr r0,=CLKCON
str r2,[r0]
;wait until enter SL_IDLE,STOP mode and until wake-up
ldr r0,=0x10
0 subs r0,r0,#1
bne %B0
;exit from DRAM/SDRAM self refresh mode.
ldr r0,=REFRESH
str r3,[r0]
mov pc,lr
;LTORG
SMRDATA DATA
;*****************************************************************
;* Memory configuration has to be optimized for best performance *
;* The following parameter is not optimized. *
;*****************************************************************
;*** memory access cycle parameter strategy ***
; 1) Even FP-DRAM, EDO setting has more late fetch point by half-clock
; 2) The memory settings,here, are made the safe parameters even at 66Mhz.
; 3) FP-DRAM Parameters:tRCD=3 for tRAC, tcas=2 for pad delay, tcp=2 for bus load.
; 4) DRAM refresh rate is for 40Mhz.
;bank0 16bit BOOT ROM
;bank1 8bit NandFlash
;bank2 16bit IDE
;bank3 8bit UDB
;bank4 rtl8019
;bank5 8bit usb host
;bank6 16bit SDRAM
;bank7 16bit SDRAM
[ BUSWIDTH=16
DCD 0x11010101 ;Bank0=16bit BootRom(AT29C010A*2) :0x0 8bit usb host![20:23]=0
| ;BUSWIDTH=32
DCD 0x22222220 ;Bank0=OM[1:0], Bank1~Bank7=32bit
]
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
[ BDRAMTYPE="DRAM"
DCD ((B6_MT<<15)+(B6_Trcd<<4)+(B6_Tcas<<3)+(B6_Tcp<<2)+(B6_CAN)) ;GCS6 check the MT value in parameter.a
DCD ((B7_MT<<15)+(B7_Trcd<<4)+(B7_Tcas<<3)+(B7_Tcp<<2)+(B7_CAN)) ;GCS7
| ;"SDRAM"
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) ;REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019
DCD 0x10 ;SCLK power down mode, BANKSIZE 32M/32M
DCD 0x20 ;MRSR6 CL=2clk
DCD 0x20 ;MRSR7
ALIGN ;?
;==========================================================================================================================================
;以下的数据段充分的说明了中断处理程序的存储结构
;分为3个区域
; 1,异常向量表(_IRQ_BASEADDRESS ~ _IRQ_BASEADDRESS+0x4*8)
; 2,none vector mode的判断程序(_IRQ_BASEADDRESS+0x80~...)
; 3,isr表(中断处理服务表)(_IRQ_BASEADDRESS+0x100~...)
;最后还有堆栈区域
AREA RamData, DATA, READWRITE
^ (_IRQ_BASEADDRESS)
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
^ (_IRQ_BASEADDRESS+0x80)
DIsrIRQ # 4
;Don't use the label 'IntVectorTable',
;because armasm.exe cann't recognize this label correctly.
;the value is different with an address you think it may be.
;IntVectorTable
^ (_IRQ_BASEADDRESS+0x100)
HandleADC # 4
HandleRTC # 4
HandleUTXD1 # 4
HandleUTXD0 # 4
HandleSIO # 4
HandleIIC # 4
HandleURXD1 # 4
HandleURXD0 # 4
HandleTIMER5 # 4
HandleTIMER4 # 4
HandleTIMER3 # 4
HandleTIMER2 # 4
HandleTIMER1 # 4
HandleTIMER0 # 4
HandleUERR01 # 4
HandleWDT # 4
HandleBDMA1 # 4
HandleBDMA0 # 4
HandleZDMA1 # 4
HandleZDMA0 # 4
HandleTICK # 4
HandleEINT4567 # 4
HandleEINT3 # 4
HandleEINT2 # 4
HandleEINT1 # 4
HandleEINT0 # 4
^ (_ISR_STARTADDRESS-0x1400)
UserStack # 1024 ;c1(c7)fe600
SVCStack # 1024 ;c1(c7)feb00
UndefStack # 1024 ;c1(c7)ff000
AbortStack # 1024 ;c1(c7)ff500
IRQStack # 1024 ;c1(c7)ffa00
FIQStack # 0 ;c1(c7)fff00
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -