;/*************************************************************************************
;* Copyright (c) 2007 by National ASIC System Engineering Research Center.
;* PROPRIETARY RIGHTS of ASIC are involved in the subject matter of this
;* material. All manufacturing, reproduction, use, and sales rights
;* pertaining to this subject matter are governed by the license agreement.
;* The recipient of this software implicitly accepts the terms of the license.
;*
;* File Name: startup.s
;*
;* File Description:
;* 系统启动的初始化文件
;*
;* Version Date Author
;*------------------------------------------------------------------------------------
;* 1.0 2009.3.4 007LWM
;**************************************************************************************/
INCLUDE include/kxarm.inc
INCLUDE include/SEP0718addr.inc
;***********************************************************************************
; 要求保持堆栈8字节对齐。
; 告诉编译器不检查堆栈对齐问题, 或告诉linker "--diag_suppress 6238"
;***********************************************************************************
PRESERVE8
AREA INITARM1136, CODE, READONLY ; name this block of code
;***********************************************************************************
; Pre-defined constants.
; CPU 各模式在CPSR低5位(M[4:0])的定义
;***********************************************************************************
USER_MODE EQU 0x10
FIQ_MODE EQU 0x11
IRQ_MODE EQU 0x12
SVC_MODE EQU 0x13
ABORT_MODE EQU 0x17
UNDEF_MODE EQU 0x1b
MODE_SYS EQU 0x1F ; 系统模式
MODE_MASK EQU 0x1f
NOINT EQU 0xc0 ; M[7:6]都为1表示禁止IRQ和FIQ中断
;***********************************************************************************
; Start address of each stacks
; 此为堆栈最高地址,值不可超过SDRAM 的实际大小
;***********************************************************************************
STACK_BASEADDRESS EQU 0x30100000
;***********************************************************************************
; Start address of each stacks
;***********************************************************************************
USER_STACK EQU ( STACK_BASEADDRESS - 0x3000 ) ; 用户模式
SYS_STACK EQU ( STACK_BASEADDRESS - 0x2800 ) ; 系统模式
SVC_STACK EQU ( STACK_BASEADDRESS - 0x2000 ) ; 管理模式
IRQ_STACK EQU ( STACK_BASEADDRESS - 0x1800 ) ; 外部中断模式
FIQ_STACK EQU ( STACK_BASEADDRESS - 0x1000 ) ; 快速中断模式
UNDEF_STACK EQU ( STACK_BASEADDRESS - 0x0800 ) ; 未定义指令中止模式
ABORT_STACK EQU ( STACK_BASEADDRESS - 0x0000 ) ; 数据访问终止模式
IMPORT Main ; C entrypoint for Steppingstone loader.
STARTUPTEXT
LEAF_ENTRY StartUp
ResetHandler
;***********************************************************************************
; vector table(32字节) ,存放到Steppingstone的第一条地址
; 此中断向量表按优先级从高到低排列
;***********************************************************************************
bal RST_DO ;系统启动时最先跳转到RST_DO部分,初始化堆栈及基本配置
bal EXTENT_INSTRU
bal SWI_DO
bal ABORT_PREFETCH_DO
bal ABORT_DATA_DO
mov R1, R1 ;reserved exception
bal IRQ_DO
bal FIQ_DO
IRQ_DO
stmfd sp!, {r0,r1}
ldr r0, =IRQ_R1
str r1, [r0]
ldmfd sp!, {r0}
ldr r1, =IRQ_R0
str r0, [r1]
add r13, r13, #4 ;restore the sp_irq top to original irq top
sub r14, r14, #4
mov r0, r14
mrs r1, spsr
orr r1, r1, #0x80
msr cpsr_cxsf, r1 ;change irq mode into svc
;------------------------------------------------
bic r1, r1, #0x80 ;open the irq
stmfd sp!, {r0}
stmfd sp!, {r14}
stmfd sp!, {r1}
ldr r0, =IRQ_R1
ldr r1, [r0]
stmfd sp!, {r1}
ldr r1, =IRQ_R0
ldr r0, [r1]
stmfd sp!, {r0}
ldmfd sp!, {r0,r1}
stmfd sp!, {r0-r12} ;save the registers r0--r12
;-----------------------------;search the irq vector and jump to isr
IMPORT IrqHandler
bl IrqHandler
;-----------------------------;restore the register
ldmfd sp!, {r0-r12}
ldmfd sp!, {r14}
msr cpsr_cxsf, r14
ldmfd sp!, {r14}
ldmfd sp!, {pc}
;*******************************************************************************
; other exception handler
;*******************************************************************************
EXTENT_INSTRU
b EXTENT_INSTRU
SWI_DO
stmfd sp!, {r14}
ldmfd sp!, {pc}^
ABORT_PREFETCH_DO
b ABORT_PREFETCH_DO
ABORT_DATA_DO
b ABORT_DATA_DO
FIQ_DO
b FIQ_DO
;********************************************************************************
; Steppingstone loader entry point.
; RST_DO优先级最高
;********************************************************************************
RST_DO ;初始化最先执行这里
;Initialize stack初始化堆栈
mrs r0, cpsr ; 复制CPSR到r0中
bic r0, r0, #MODE_MASK ; 清除CPSR中的低5位M[4:0]
orr r1, r0, #FIQ_MODE|NOINT ; 设置CPSR为FIQ模式.
msr cpsr_cxsf, r1 ;全域写回cpsr
ldr sp, =FIQ_STACK ;将FIQ堆栈地址写入sp(此时为FIQ模式)
;以下同样初始化其他堆栈
mrs r0, cpsr
bic r0, r0, #MODE_MASK
orr r1, r0, #IRQ_MODE|NOINT ; IRQ模式.
msr cpsr_cxsf, r1
ldr sp, =IRQ_STACK
mrs r0, cpsr
bic r0, r0, #MODE_MASK
orr r1, r0, #ABORT_MODE|NOINT ; ABORT模式.
msr cpsr_cxsf, r1
ldr sp, =ABORT_STACK
mrs r0, cpsr
bic r0, r0, #MODE_MASK
orr r1, r0, #UNDEF_MODE|NOINT ; UNDEF模式.
msr cpsr_cxsf, r1
ldr sp, =UNDEF_STACK
mrs r0, cpsr ; 只有mrs可以直接设置cpsr或spsr.保存
bic r0, r0, #MODE_MASK|NOINT ; 位清除
orr r1, r0, #SVC_MODE ;
msr cpsr_cxsf, r1 ; 写状态寄存器,设置为SVCMode
ldr sp, =SVC_STACK ; SP指向SVCStack地址
;****************************************************************
; init the EMI, SDRAM
; 也可参照C函数配置
;****************************************************************
ldr r1, =SDRAM_CONFIG_REG ;配置SDRAM 32bit 列8bit 行12bit 4bank
ldr r2, =0x143188
str r2, [r1]
ldr r1, =CSE_ALIAS_ADDR ;这个寄存器的低16bit没有用,为什么写入20B?
ldr r2, =0x20B
str r2, [r1]
;*******************************************************************************
; Enable Icache
; 加快从NOR启动速度
;*******************************************************************************
mrc p15, 0, r0, c1, c0, 0 ;将cp15协处理的c1寄存器读入r0
orr r0, r0, #0x1000 ;打开Icache
mcr p15, 0, r0, c1, c0, 0 ;写回c1
;********************************************************************************
; enable CPSR IRQ bit
;********************************************************************************
mrs r4, cpsr
bic r4, r4, #0x80 ;set bit7 to zero, 即打开IRQ
msr cpsr_c, r4
; Jump to main C routine.
bl Main ;跳转到main函数
IRQ_R1 DCD 0X0
IRQ_R0 DCD 0X0
END