启动代码

第一部分: 启动代码

;==================================================================
;文件: 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

 

你可能感兴趣的:(启动代码)