第一部分: 启动代码
;==================================================================
;文件: startup.s
;
;日期: 2008/10/9
;描述: 基于ARM处理器S3C44b0X C语言启动代码
; 初始化ISP,栈,C变量
;版本历史记录 V1.0
;==================================================================
;外设和存器空间信息
;nGCS0 :ROM HY29LV160 0x0000_0000~0x001f_ffff
;nGCS1 :USB PDIUSBD12 0x0200_0000~0x03ff_ffff
;nGCS2 :ATA 0x0400_0000~0x05ff_ffff
;nGCS3 :NET RTL9019AS 0x0600_0000~0x07ff_ffff
;nGCS4 :-- 0x0800_0000~0x09ff_ffff
;nGCS5 :-- 0x0a00_0000~0x0bff_ffff
;nGCS6 :RAM HY57V641620 0x0c00_0000~0x0dff_ffff
;nGCS7 :-- 0x0c80_0000~0x0fff_ffff
;APP RAM=0xc000000~0xc7effff
;44BMON RAM=0xc7f0000~0xc7fffff
;STACK RAM=0xc7ffa00
;==================================================================
_ISR_STARTADDRESS EQU 0xc7fff00
GBLA BUSWIDTH
BUSWIDTH SETA 16
GBLL PLLONSTART
PLLONSTART SETL {TRUE}
GBLA PLLCLK
PLLCLK SETA 64000000
[ PLLCLK = 64000000
M_DIV EQU 8
P_DIV EQU 2
S_DIV EQU 1
]
;==================================================================
;看门狗定时器预定义
WTCON EQU 0x01d30000
;系统时钟预定义
PLLCON EQU 0x01d80000
CLKCON EQU 0x01d80004
LOCKTIME EQU 0x01d8000c
;存储器控制预定义
REFRESH EQU 0x01c80024
;BDMA目的寄存器
BDIDES0 EQU 0x1f80008
BDIDES1 EQU 0x1f80028
;==================================================================
;中断控制预定义
INTPND EQU 0x01e00004
INTMOD EQU 0x01e00008
INTMSK EQU 0x01e0000c
I_ISPR EQU 0x01e00020
I_CMST EQU 0x01e0001c
;预定义常数(常量)
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
I_BIT EQU 0x80
F_BIT EQU 0x40
T_BIT EQU 0x20
;==================================================================
GBLL THUMBCODE ;定义指定状态逻辑变量
[ {CONFIG} = 16 ;判定汇编器在Thumb汇编
THUMBCODE SETL {TRUE}
CODE32 ;指示代码为ARM指令
|
THUMBCODE SETL {FALSE}
]
[ THUMBCODE ;启动在Thumb时转向RAM
CODE32
]
;------------------------------------------------------------------
MACRO ;中断向量宏定义
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;减SP指针为存跳转地址
stmfd sp!,{r0} ;将ro入栈
ldr r0,=$HandleLabel ;装载处理地址到ro
ldr r0,[r0] ;装载处理地址内容到r0
str r0,[sp,#4] ;存储r0到栈中
ldmfd sp!,{r0,pc} ;出栈并跳到r0指向的地址
MEND
;------------------------------------------------------------------
AREA Init,CODE,READONLY ;初始人代码段
ENTRY ;程序入口
ResetEntry
b ResetHandler ;复位处理
b HandlerUndef ;未定义处理
b HandlerSWI ;SWI中断处理
b HandlerPabort ;指令中止处理
b HandlerDabort ;数据中止处理
b . ;保留
b HandlerIRQ ;中断处理
b HandlerFIQ ;快速中断处理
;------------------------------------------------------------------
VECTOR_BRANCH ;中断向量表
ldr pc,=HandlerEINT0 ;mGA 0x20
ldr pc,=HandlerEINT1 ;
ldr pc,=HandlerEINT2 ;
ldr pc,=HandlerEINT3 ;
ldr pc,=HandlerEINT4567 ;
ldr pc,=HandlerTICK ;mGA 0x34
b .
b .
ldr pc,=HandlerZDMA0 ;mGB 0x40
ldr pc,=HandlerZDMA1 ;
ldr pc,=HandlerBDMA0 ;
ldr pc,=HandlerBDMA1 ;
ldr pc,=HandlerWDT ;
ldr pc,=HandlerUERR01 ;mGB 0x54
b .
b .
ldr pc,=HandlerTIMER0 ;mGC 0x60
ldr pc,=HandlerTIMER1 ;
ldr pc,=HandlerTIMER2 ;
ldr pc,=HandlerTIMER3 ;
ldr pc,=HandlerTIMER4 ;
ldr pc,=HandlerTIMER5 ;mGC 0x74
b .
b .
ldr pc,=HandlerURXD0 ;mGD 0x80
ldr pc,=HandlerURXD1 ;
ldr pc,=HandlerIIC ;
ldr pc,=HandlerSIO ;
ldr pc,=HandlerUTXD0 ;
ldr pc,=HandlerUTXD1 ;mGD 0x94
b .
b .
ldr pc,=HandlerRTC ;mGKA 0xa0
b .
b .
b .
b .
b . ;mGKA
b .
b .
ldr pc,=HandlerADC ;mGKB 0xc0
b . ;
b . ;
b . ;
b . ;
b . ;mGKB
b .
b .
ldr pc,=EnterPWDN ;0xe0=EnterPWDN
;------------------------------------------------------------------
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
ldr r1,=((M_DIV<<12)+(P_DIV<<4)+S_DIV)
str r1,[r0]
;]
ldr r0,=CLKCON ;所有功能单元块时钟使能
ldr r1,=0x7ff8
str r1,[r0]
;------------------------------------------------------------------
ldr r0,=BDIDES0 ;修正BDMACON值
ldr r1,=0x40000000 ;BDIDESn 复位值: 0x40000000
str r1,[r0]
ldr r0,=BDIDES1
ldr r1,=0x40000000 ;BDIDESn 复位值: 0x40000000
str r1,[r0]
;-----------------------------------------------------------------
adr r0, ResetHandler ;设定存储器控制寄存器
ldr r1, =ResetHandler
sub r0, r1, r0
ldr r1, =SMRDATA
sub r0, r1, r0
ldmia r0, {r1-r13}
ldr r0, =0x01c80000 ;BWSCON 地址
stmia r0, {r1-r13}
;------------------------------------------------------------------
ldr sp, =SVCStack ;初始化堆栈,复位后位SVC模式
bl InitStacks
;------------------------------------------------------------------
ldr r0,=HandleIRQ ;设置中断处理
ldr r1,=IsrIRQ
str r1,[r0]
;------------------------------------------------------------------
adr r0, ResetEntry
ldr r2, BaseOfROM
cmp r0, r2 ;判定是否将程序拷贝到RAM
ldreq r0, TopOfROM
beq InitRam
ldr r3, TopOfROM
0 ;将程序拷贝到RAM中
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
sub r2, r2, r3
sub r0, r0, r2
InitRam ;初始化RW段
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0 ;初始化ZI段
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
;------------------------------------------------------------------
_main ;跳到主程序
__main
EXPORT _main
EXPORT __main
ldr lr, GotoMain
mov pc, lr
GBLS MainEntry
MainEntry SETS "Main"
IMPORT $MainEntry
GotoMain DCD $MainEntry
;------------------------------------------------------------------
InitStacks ;初始化栈
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
mov pc,lr
;------------------------------------------------------------------
IsrIRQ ;中断服务程序入口
sub sp,sp,#4 ;留出中断地址空间
stmfd sp!,{r8-r9} ;寄存器入栈
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 ;装载中断基址
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
;------------------------------------------------------------------
;void EnterPWDN(int CLKCON); ;进入掉电模式
EnterPWDN ;r0=CLKCON
mov r2,r0
ldr r0,=REFRESH
ldr r3,[r0]
mov r1, r3
orr r1, r1, #0x400000 ;使能自刷新模式
str r1, [r0]
nop ;等待自刷新被使用
nop
nop
nop
nop
nop
nop
;进入掉电模式
ldr r0,=CLKCON ;设定系统时钟
str r2,[r0]
mov r0,#0xff ;在掉电模式等待唤醒
0 subs r0,r0,#1
bne %B0
ldr r0,=REFRESH ;退出SRAM自刷新模式
str r3,[r0]
mov pc,lr
LTORG
;-----------------------------------------------------------------
EXPORT DisableInt ;禁止中断函数
DisableInt
mrs r0, cpsr
orr r0, r0, #NOINT
msr cpsr_cf, r0
mov pc, lr
EXPORT EnableInt ;使能中断函数
EnableInt
mrs r0, cpsr
bic r0, r0, #NOINT
msr cpsr_cf, r0
mov pc, lr
EXPORT EnterCritical ;进入临界状态函数
EnterCritical
mrs r1, cpsr
str r1, [r0]
orr r1, r1, #NOINT
msr cpsr_cxsf, r1
mov pc, lr
EXPORT ExitCritical ;退出临界状态函数
ExitCritical
ldr r1, [r0]
msr cpsr_cxsf, r1
mov pc, lr
EXPORT outportb ;指定地址附值(字节)
outportb
strb r0, [r1]
mov pc, lr
EXPORT outportw ;指定地址附值(半字)
outportw
strh r0, [r1]
mov pc, lr
EXPORT outportl ;指定地址附值(字)
outportl
str r0, [r1]
mov pc, lr
EXPORT inportb ;得到指定地址内容(字节)
inportb
ldrb r0, [r0]
mov pc, lr
EXPORT inportw ;得到指定地址内容(半字)
inportw
ldrh r0, [r0]
mov pc, lr
EXPORT inportl ;得到指定地址内容(字节)
inportl
ldr r0, [r0]
mov pc, lr
EXPORT GetBaseOfROM ;得到代码段基地址
GetBaseOfROM
ldr r0, BaseOfROM
mov pc, lr
EXPORT GetEndOfROM ;得到代码段结束地址
GetEndOfROM
ldr r0, TopOfROM
mov pc, lr
EXPORT GetBaseOfBSS ;得到数据段基地址
GetBaseOfBSS
ldr r0, BaseOfBSS
mov pc, lr
EXPORT GetBaseOfZero ;得到初始化零段基地址
GetBaseOfZero
ldr r0, BaseOfZero
mov pc, lr
EXPORT GetEndOfBSS ;得到初始零段结束地址
GetEndOfBSS
ldr r0, EndOfBSS
mov pc, lr
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
;------------------------------------------------------------------
SMRDATA DATA
[ BUSWIDTH=16
DCD 0x01001102
|;BUSWIDTH=32
DCD 0x22222220
]
DCD ((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(1<<2)+(0)) ;nGCS0 ROM
DCD ((0<<13)+(2<<11)+(4<<8)+(2<<6)+(0<<4)+(0<<2)+(0)) ;nGCS1 USB
DCD ((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(1<<2)+(0)) ;nGCS2 ATA
DCD ((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(3<<2)+(0)) ;nGCS3 NET
DCD ((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(3<<2)+(0)) ;nGCS0 ---
DCD ((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(3<<2)+(0)) ;nGCS0 ---
DCD ((3<<15)+(1<<2)+(0)) ;GCS6 RAM
DCD ((3<<15)+(1<<2)+(0)) ;GCS7 ---
DCD ((1<<23)+(0<<22)+(0<<20)+(1<<18)+(2<<16)+1550)
DCD 0x10
DCD 0x20
DCD 0x20
;------------------------------------------------------------------
IMPORT |Image$$RO$$Base|
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
BaseOfROM DCD |Image$$RO$$Base|
TopOfROM DCD |Image$$RO$$Limit|
BaseOfBSS DCD |Image$$RW$$Base|
BaseOfZero DCD |Image$$ZI$$Base|
EndOfBSS DCD |Image$$ZI$$Limit|
ALIGN
;------------------------------------------------------------------
AREA RamData, DATA, READWRITE
^ (_ISR_STARTADDRESS-0x500)
UserStack # 256 ;c1(c7)ffa00
SVCStack # 256 ;c1(c7)ffb00
UndefStack # 256 ;c1(c7)ffc00
AbortStack # 256 ;c1(c7)ffd00
IRQStack # 256 ;c1(c7)ffe00
FIQStack # 0 ;c1(c7)fff00
^ _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
;==================================================================
end