📄 startup.s
字号:
;/****************************************Copyright (c)**************************************************
** 广州致远电子有限公司
**
** http://www.21cm.com.cn
;**
;**--------------文件信息--------------------------------------------------------------------------------
;**文 件 名: startup.s
;**创 建 人: 黄绍斌
;**最后修改日期: 2005年11月11日
;**描 述: S3C2410异常向量入口及异常向量与c语言代码的接口,包括初始化堆栈、初始化PLL的代码
;**
;**--------------历史版本信息----------------------------------------------------------------------------
;** 创建人:
;** 版 本:
;** 日 期:
;** 描 述:
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
IMPORT __use_no_semihosting_swi
IMPORT __use_two_region_memory
; 定义堆栈的大小
; **** 用户可根据实际需要修改 ****
SVC_STACK_LEGTH EQU 0
FIQ_STACK_LEGTH EQU 0
IRQ_STACK_LEGTH EQU 9*20
ABT_STACK_LEGTH EQU 0
UND_STACK_LEGTH EQU 0
; 总线宽度控制定义(0表示8位,1表示16位,2表示32位)
DW8 EQU (0x0)
DW16 EQU (0x1)
DW32 EQU (0x2)
WAIT EQU (0x1<<2)
UBLB EQU (0x1<<3)
; **** 用户可根据实际需要修改 ****
B7_BWCON EQU (DW16|WAIT|UBLB)
B6_BWCON EQU (DW32|UBLB)
B5_BWCON EQU (DW16|WAIT|UBLB)
B4_BWCON EQU (DW16|WAIT|UBLB)
B3_BWCON EQU (DW16|WAIT|UBLB)
B2_BWCON EQU (DW16|WAIT|UBLB)
B1_BWCON EQU (DW16|WAIT|UBLB)
; CPU时钟设置(PLLCON控制值)
; 50.00MHz (外部晶振为12MHz时)
MDIV_50 EQU 0x5C
PDIV_50 EQU 0x4
SDIV_50 EQU 0x2
; 200.00MHz (外部晶振为12MHz时)
; 设置值为:m=100,p=6,s=0, MPLL=FCLK=12*100/6=200MHz
MDIV_200 EQU 0x5C
PDIV_200 EQU 0x4
SDIV_200 EQU 0x0
MPLLCON_200 EQU ((MDIV_200 << 12) | (PDIV_200 << 4) | (SDIV_200))
; /*************************************************************************/
; /* CPSR寄存器的位域 */
; /*************************************************************************/
; /* */
; /* 31 30 29 28 7 6 5 4 3 2 1 0 */
; /*+---+---+---+---+--ss--+---+---+---+---+---+---+---+---+ */
; /*| N | Z | C | V | | I | F | T | M4 ~ M0 | */
; /*+---+---+---+---+--ss--+---+---+---+---+---+---+---+---+ */
; /* */
; /* Processor Mode and Mask */
; /* */
; /*************************************************************************/
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_BIT EQU 0x80 ; when I bit is set (1), IRQ is disabled
F_BIT EQU 0x40 ; when F bit is set (1), FIQ is disabled
; 寄存器定义
;=================
; WATCH DOG TIMER
;=================
WTCON EQU 0x53000000 ;Watch-dog timer mode
WTDAT EQU 0x53000004 ;Watch-dog timer data
WTCNT EQU 0x53000008 ;Eatch-dog timer count
;=================
; INTERRUPT
;=================
SRCPND EQU 0x4a000000 ;Interrupt request status
INTMOD EQU 0x4a000004 ;Interrupt mode control
INTMSK EQU 0x4a000008 ;Interrupt mask control
PRIORITY EQU 0x4a00000c ;IRQ priority control
INTPND EQU 0x4a000010 ;Interrupt request status
INTOFFSET EQU 0x4a000014 ;Interruot request source offset
SUSSRCPND EQU 0x4a000018 ;Sub source pending
INTSUBMSK EQU 0x4a00001c ;Interrupt sub mask
;=================
; Memory control
;=================
BWSCON EQU 0x48000000 ;Bus width & wait status
BANKCON0 EQU 0x48000004 ;Boot ROM control
BANKCON1 EQU 0x48000008 ;BANK1 control
BANKCON2 EQU 0x4800000c ;BANK2 cControl
BANKCON3 EQU 0x48000010 ;BANK3 control
BANKCON4 EQU 0x48000014 ;BANK4 control
BANKCON5 EQU 0x48000018 ;BANK5 control
BANKCON6 EQU 0x4800001c ;BANK6 control
BANKCON7 EQU 0x48000020 ;BANK7 control
REFRESH EQU 0x48000024 ;DRAM/SDRAM refresh
BANKSIZE EQU 0x48000028 ;Flexible Bank Size
MRSRB6 EQU 0x4800002c ;Mode register set for SDRAM
MRSRB7 EQU 0x48000030 ;Mode register set for SDRAM
;==========================
; CLOCK & POWER MANAGEMENT
;==========================
LOCKTIME EQU 0x4c000000 ;PLL lock time counter
MPLLCON EQU 0x4c000004 ;MPLL Control
UPLLCON EQU 0x4c000008 ;UPLL Control
CLKCON EQU 0x4c00000c ;Clock generator control
CLKSLOW EQU 0x4c000010 ;Slow clock control
CLKDIVN EQU 0x4c000014 ;Clock divider control
B3_TACS EQU (0X3);//0:0CLOCK 1:1CLOCK 2:2CLOCK 3:4CLOCK
B3_TCOS EQU (0X3);//0:0CLOCK 1:1CLOCK 2:2CLOCK 3:4CLOCK
B3_TACC EQU (0X8);//0:1CLOCK 1:2CLOCK 2:3CLOCK 3:4CLOCK 4:6CLOCK 5:8CLOCK 6:10CLOCK 7:14CLOCK
B3_TCOH EQU (0X3);//0:0CLOCK 1:1CLOCK 2:2CLOCK 3:4CLOCK
B3_TCAH EQU (0X3);//0:0CLOCK 1:1CLOCK 2:2CLOCK 3:4CLOCK
; /************************************************************************/
; 引入的外部标号在这声明
IMPORT __main ;C语言主程序入口
IMPORT SoftwareInterrupt
; 给外部使用的标号在这声明
EXPORT Reset
EXPORT VICVectAddr
EXPORT bottom_of_heap
EXPORT StackUsr
EXPORT DisableMMU
EXPORT EnableICache
EXPORT DisableICache
EXPORT EnableDCache
EXPORT DisableDCache
EXPORT __user_initial_stackheap
; /************************************************************************/
CODE32
AREA vectors,CODE,READONLY
; 异常向量表
Reset
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD IRQ_Addr
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
; 未定义指令
Undefined
B Undefined
SwiFunction
DCD IRQDisable ;0
DCD IRQEnable ;1
DCD FIQDisable ;2
DCD FIQEnable ;3
IRQDisable
;关IRQ中断
MRS R0, SPSR
ORR R0, R0, #I_BIT
MSR SPSR_c, R0
MOVS PC, LR
IRQEnable
;开IRQ中断
MRS R0, SPSR
BIC R0, R0, #I_BIT
MSR SPSR_c, R0
MOVS PC, LR
FIQDisable
;关FIQ中断
MRS R0, SPSR
ORR R0, R0, #F_BIT
MSR SPSR_c, R0
MOVS PC, LR
FIQEnable
;开FIQ中断
MRS R0, SPSR
BIC R0, R0, #F_BIT
MSR SPSR_c, R0
MOVS PC, LR
; 取指中止
PrefetchAbort
B PrefetchAbort
; 取数据中止
DataAbort
B DataAbort
; IRQ中断
NoInt EQU 0x80
USR32Mode EQU 0x10
SVC32Mode EQU 0x13
SYS32Mode EQU 0x1f
IRQ32Mode EQU 0x12
FIQ32Mode EQU 0x11
;引入的外部标号在这声明
IMPORT OSIntCtxSw ;任务切换函数
IMPORT OSIntExit ;中断退出函数
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSIntNesting ;中断嵌套计数器
IMPORT OsEnterSum
IRQ_Handler
SUB LR, LR, #4 ; 计算返回地址
STMFD SP!, {R0-R3, R12, LR} ; 保存任务环境
MRS R3, SPSR ; 保存状态
STMFD SP, {R3, SP, LR}^ ; 保存用户状态的R3,SP,LR,注意不能回写
; 如果回写的是用户的SP,所以后面要调整SP
LDR R2, =OSIntNesting ; OSIntNesting++
LDRB R1, [R2]
ADD R1, R1, #1
STRB R1, [R2]
SUB SP, SP, #4*3
MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到系统模式
CMP R1, #1
LDREQ SP, =StackUsr
LDR R0, =INTPND
LDR R1, [R0] ; 读取INTPND的值
; 找出当前中断号(INTPND)
MOV R0, #0
FIND_NO
MOVS R1, R1, LSR #1
ADDNE R0, R0, #1
BNE FIND_NO
FIND_END
LDR R1, =VICVectAddr
MOV LR, PC ; 保存返回地址
LDR PC, [R1, R0, LSL #2] ; 跳转到相应中断服务程序
MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到系统模式
LDR R2, =OsEnterSum ; OsEnterSum,使OSIntExit退出时中断关闭
MOV R1, #1
STR R1, [R2]
BL OSIntExit
LDR R2, =OsEnterSum ; 因为中断服务程序要退出,所以OsEnterSum=0
MOV R1, #0
STR R1, [R2]
MSR CPSR_c, #(NoInt | IRQ32Mode) ; 切换回irq模式
LDMFD SP, {R3, SP, LR}^ ; 恢复用户状态的R3,SP,LR,注意不能回写
; 如果回写的是用户的SP,所以后面要调整SP
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR R1, =OSTCBCur
LDR R1, [R1]
CMP R0, R1
ADD SP, SP, #4*3 ;
MSR SPSR_cxsf, R3
LDMEQFD SP!, {R0-R3, R12, PC}^ ; 不进行任务切换
LDR PC, =OSIntCtxSw ; 进行任务切换
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -