📄 44binit.s
字号:
; *******************************************************
; * NAME : 44BINIT.S *
; * Version : 1.1 24.April.2002 *
; * 描述:
; * *
; * C 启动代码 *
; * 配置存储器, 初始化 ISR 中断 ,各种CPU Mode下的堆栈 *
; * 初始化C变量 *
; * 对 zero-initialized C-变量清零 *
; * For HaiMai Hm701Esp(Nep)Board *
; *******************************************************
GET option.s ;汇编包含文件: 包含几个系统宏定义
GET memcfg.s ;汇编包含文件: 外部存储器控制参数
;SDRAM存储器区域 (详情参考\datasheet\s3c44b0x)
;BANK6 16bit宽度 (8MB) SDRAM(0xc000000-0xc7fffff)
;应用程序 0xc000000~0xc7effff
;STACK =0xc7ffa00
;中断控制寄存器
INTPND EQU 0x01e00004
INTMOD EQU 0x01e00008
INTMSK EQU 0x01e0000c
I_ISPR EQU 0x01e00020
I_CMST EQU 0x01e0001c
;看门狗定时器
WTCON EQU 0x01d30000
;时钟控制器
PLLCON EQU 0x01d80000
CLKCON EQU 0x01d80004
LOCKTIME EQU 0x01d8000c
;存储器控制器
REFRESH EQU 0x01c80024
;BDMA 目标控制器
BDIDES0 EQU 0x1f80008
BDIDES1 EQU 0x1f80028
;预定义的CPU模式、中断等常量
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;ARM和THUMB
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE}
CODE32
|
THUMBCODE SETL {FALSE}
]
[ THUMBCODE
CODE32 ; Thumb mode 的启动代码
]
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;为返回PC值保留
stmfd sp!,{r0} ;保存工作寄存器
ldr r0,=$HandleLabel ;装载HandleXXX 到 r0
ldr r0,[r0] ;
str r0,[sp,#4] ;
ldmfd sp!,{r0,pc} ;恢复工作寄存器,并跳转到中断处理程序
MEND
IMPORT |Image$$RO$$Limit| ; ROM 代码的末
IMPORT |Image$$RW$$Base| ; RW 数据区
IMPORT |Image$$ZI$$Base| ; ZI 需初始化为0的数据区头
IMPORT |Image$$ZI$$Limit| ; 需初始化为0的数据区尾
; 这几个符号是由 ARM连接器产生的符号
; 细节请参照《ARM的体系结构与编程》
IMPORT Main ; 主C-代码的入口
AREA Init,CODE,READONLY ;段声明,为保证下面的代码为起始在ARM连接器中layout选项中指明44Binit.o(Init)
ENTRY
b ResetHandler ;加电、复位入口
b HandlerUndef ;为定义指令异常
b HandlerSWI ;SWI 软中断
b HandlerPabort ;指令预取异常
b HandlerDabort ;数据访问异常
b . ;保留
b HandlerIRQ ;外部中断处理入口
b HandlerFIQ ;快速中断处理入口
;***特别注意***
;三星s3c44b0x有一种自有的中断模式:H/W矢量模式,上面两条指令应改为
; b HandlerIRQ -> subs pc,lr,#4
; b HandlerIRQ -> subs pc,lr,#4
VECTOR_BRANCH
ldr pc,=HandlerEINT0 ;mGA H/W 模式中断矢量表
ldr pc,=HandlerEINT1 ; 由S3C44B0X内部直接产生各个具体中断到此的跳转
ldr pc,=HandlerEINT2 ; 这种方式不是标准的ARM体系所规定
ldr pc,=HandlerEINT3 ;
ldr pc,=HandlerEINT4567 ;
ldr pc,=HandlerTICK ;mGA
b .
b .
ldr pc,=HandlerZDMA0 ;mGB
ldr pc,=HandlerZDMA1 ;
ldr pc,=HandlerBDMA0 ;
ldr pc,=HandlerBDMA1 ;
ldr pc,=HandlerWDT ;
ldr pc,=HandlerUERR01 ;mGB
b .
b .
ldr pc,=HandlerTIMER0 ;mGC
ldr pc,=HandlerTIMER1 ;
ldr pc,=HandlerTIMER2 ;
ldr pc,=HandlerTIMER3 ;
ldr pc,=HandlerTIMER4 ;
ldr pc,=HandlerTIMER5 ;mGC
b .
b .
ldr pc,=HandlerURXD0 ;mGD
ldr pc,=HandlerURXD1 ;
ldr pc,=HandlerIIC ;
ldr pc,=HandlerSIO ;
ldr pc,=HandlerUTXD0 ;
ldr pc,=HandlerUTXD1 ;mGD
b .
b .
ldr pc,=HandlerRTC ;mGKA
b . ;
b . ;
b . ;
b . ;
b . ;mGKA
b .
b .
ldr pc,=HandlerADC ;mGKB
b . ;
b . ;
b . ;
b . ;
b . ;mGKB
b .
b .
;0xe0=EnterPWDN
ldr pc,=EnterPWDN
LTORG
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
HandlerADC HANDLER HandleADC
HandlerRTC HANDLER HandleRTC
HandlerUTXD1 HANDLER HandleUTXD1
HandlerUTXD0 HANDLER HandleUTXD0
HandlerSIO HANDLER HandleSIO
HandlerIIC HANDLER HandleIIC
HandlerURXD1 HANDLER HandleURXD1
HandlerURXD0 HANDLER HandleURXD0
HandlerTIMER5 HANDLER HandleTIMER5
HandlerTIMER4 HANDLER HandleTIMER4
HandlerTIMER3 HANDLER HandleTIMER3
HandlerTIMER2 HANDLER HandleTIMER2
HandlerTIMER1 HANDLER HandleTIMER1
HandlerTIMER0 HANDLER HandleTIMER0
HandlerUERR01 HANDLER HandleUERR01
HandlerWDT HANDLER HandleWDT
HandlerBDMA1 HANDLER HandleBDMA1
HandlerBDMA0 HANDLER HandleBDMA0
HandlerZDMA1 HANDLER HandleZDMA1
HandlerZDMA0 HANDLER HandleZDMA0
HandlerTICK HANDLER HandleTICK
HandlerEINT4567 HANDLER HandleEINT4567
HandlerEINT3 HANDLER HandleEINT3
HandlerEINT2 HANDLER HandleEINT2
HandlerEINT1 HANDLER HandleEINT1
HandlerEINT0 HANDLER HandleEINT0
;
;下面子程序用于非矢量中断模式
IsrIRQ ;使用 I_ISPR 中断未决寄存器,下面是中断分拣.
sub sp,sp,#4 ;为PC保留空间
stmfd sp!,{r8-r9}
;
;如果没有正确使用中断位清除寄存器I_ISPC(如清除了另外的位), I_ISPR 可能变为0。
ldr r9,=I_ISPR
ldr r9,[r9]
cmp r9, #0x0 ;
;
beq %F2
mov r8,#0x0
0
movs r9,r9,lsr #1
bcs %F1
add r8,r8,#4
b %B0
1
ldr r9,=HandleADC ;ADC中断在I_ISPR中为第[0]位
add r9,r9,r8
ldr r9,[r9]
str r9,[sp,#8]
ldmfd sp!,{r8-r9,pc}
2
ldmfd sp!,{r8-r9}
add sp,sp,#4
subs pc,lr,#4
;****************************************************
;* 加电、复位的起始执行入口 *
;****************************************************
ResetHandler
ldr r0,=WTCON ;关闭看门狗
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0x07ffffff ;屏蔽所有的中断
str r1,[r0]
;****************************************************
;* 设置时钟控制寄存器 *
;****************************************************
ldr r0,=LOCKTIME
ldr r1,=0xfff
str r1,[r0]
[ PLLONSTART
ldr r0,=PLLCON ; PLL 控制
ldr r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV) ;Fin=12MHz,Fout=64MHz
str r1,[r0]
]
ldr r0,=CLKCON
ldr r1,=0x7ff8 ;所有部件的CLOCK打开
str r1,[r0]
;****************************************
;* 改变BDMA的控制BDMACON *
;****************************************
ldr r0,=BDIDES0
ldr r1,=0x40000000 ;BDIDESn 0x40000000
str r1,[r0]
ldr r0,=BDIDES1
ldr r1,=0x40000000 ;BDIDESn 0x40000000
str r1,[r0]
;****************************************************
;* 设置存储器控制 BANK1~BANK7的工作参数 *
;****************************************************
ldr r0,=SMRDATA
ldmia r0,{r1-r13}
ldr r0,=0x01c80000 ;BWSCON寄存器的地址
stmia r0,{r1-r13}
;****************************************************
;* 初始化SVC模式下的堆栈 *
;****************************************************
ldr sp, =SVCStack ;加电复位后CPU进入SVC模式,所以SVC堆栈必须先设置,不然无法调用下面的子程序
bl InitStacks
;****************************************************
;* 设置 IRQ 中断处理总入口点 *
;****************************************************
ldr r0,=HandleIRQ ;
ldr r1,=IsrIRQ ;
str r1,[r0]
;********************************************************
;* 拷贝 RW 数据区/清零 ZI 数据区 *
;********************************************************
LDR r0, =|Image$$RO$$Limit| ; 看上面的解释
LDR r1, =|Image$$RW$$Base| ;
LDR r3, =|Image$$ZI$$Base|
;
CMP r0, r1 ;
BEQ %F1
0
CMP r1, r3 ; 拷贝初始化数据
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
STRCC r2, [r3], #4
BCC %B2
[ :LNOT:THUMBCODE
BL Main ;不要使用小写的 main() 因为不想让编译器产生初始化调用__main()
B .
]
[ THUMBCODE ;Thumb 模式的启动代码
orr lr,pc,#1
bx lr
CODE16
bl Main ;不使用main()因为......
b .
CODE32
]
;****************************************************
;* 初始化各个模式下的堆栈指针 *
;****************************************************
InitStacks
;加电、复位后cpu进入SVC模式
;SVCstack 已在前面初始化
;
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 不能初始化,因为无法返回到SVC Mode.
mov pc,lr ;
;****************************************************
;* 进入掉电处理子程序 *
;****************************************************
;void EnterPWDN(int CLKCON);
EnterPWDN
mov r2,r0 ;r0=CLKCON
ldr r0,=REFRESH
ldr r3,[r0]
mov r1, r3
orr r1, r1, #0x400000 ;
str r1, [r0]
nop ;
nop ;
nop ;
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
;*****************************************************************
;* 存储器配置十分重要,配置不好会影响整个系统的运转稳定和性能 *
;* 参数的优化应根据使用的器件参数 *
;*****************************************************************
;*** Hm701Esp(Nep)的存储空间分配 *****
;Bank0 16bit SST39VF160
;Bank1 8Bit NandFlash
;Bank2 NIC 8019as 16bit
;Bank3 IDE
;bank4 8Bit USB
;Bank5 8Bit nGCSEXT
;Bank6 16Bit SDRAM
;Bank7 Expand
DCD 0x11001000 ;Bank0=16bit 1M BootRom(INTEL E320)
; ||||||-- Bank1=8bit NandFlash :0x2000000
; |||||--- Bank2=16bit NIC :0x4000000
; ||||---- Bank3=16bit IDE :0x6000000
; |||----- Bank4=8bit USB :0x8000000
; ||------ Bank5=8bit EXT :0xA000000
; |------- Bank6=16bit SDRAM(16M) :0xc000000
; -------- Bank7=16bit Expand
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)+(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
AREA RamData, DATA, READWRITE
^ (_ISR_STARTADDRESS-0x2000)
AddedStack # 1024
UserStack # 1024 ;预留的各个CPU模式堆栈
SVCStack # 1024 ;
UndefStack # 1024 ;
AbortStack # 1024 ;
IRQStack # 1024 ;
FIQStack # 0 ;
^ _ISR_STARTADDRESS
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;
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 + 0x84
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -