ADS1.2下2416的启动文件

ADS1.2环境下2416的初始化代码
CPU S3C2416
DDR K4T51163DJ
这几句话相当于调用头文件,#include<…>
GET option.s
GET memcfg.s
GET 2416addr.s

这个相当于C语言上的#define,这是切换成对应模式的数据
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0

//定义各个模式的栈的地址
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~

GBLL    THUMBCODE   定义一个全局变量,如果总线是16位宽度,就会置1,是32位就置0
[ {CONFIG} = 16   ---- 这个参数是通过软件上面设置的

THUMBCODE SETL {TRUE}
CODE32
|
THUMBCODE SETL {FALSE}
]

// MACRO … MEND 定义红变量
在这里定义 MOV_PC_LR 和 MOVEQ_PC_LR

	MACRO
MOV_PC_LR
	[ THUMBCODE
    bx lr
	|
    mov	pc,lr
	]
MEND

	MACRO
MOVEQ_PC_LR
	[ THUMBCODE
    bxeq lr
	|
    moveq pc,lr
	]
MEND

定义中断函数
MACRO
$HandlerLabel HANDLER $HandleLabel

KaTeX parse error: Expected 'EOF', got '#' at position 25: …bel sub sp,sp,#̲4 ;将栈指针-4 stmf…HandleLabel;把要跳转的地址存到R0
ldr r0,[r0] ;把地址里面的数据存到R0
str r0,[sp,#4] ;把R0里的数据存到栈里面sp+4的地址上
ldmfd sp!,{r0,pc} ;还原数据到R0,并渎职数据到PC上面
MEND

//代码段,数据段,未初始化的全局变量段(BBS)
//IMPORT是汇编里面引用外部变量与函数
IMPORT |Image|RAM_EXEC|Base| ; 代码段首地址
IMPORT |Image|RO|Limit| ; 代码段的结束地址
IMPORT |Image|RAM|Base| ; 数据段首地址
IMPORT |Image|ZI|Base| ; BBS首地址
IMPORT |Image|ZI|Limit| ; BBS结束地址
(注:实际上面的|是$$的代码,排版太难看我就用|代替)
IMPORT __main

AREA    Init,CODE,READONLY
IMPORT __use_no_semihosting_swi
ENTRY

ResetEntry

ASSERT	:DEF:ENDIAN_CHANGE //判断是否有定义变量 **ENDIAN_CHANGE**
[ ENDIAN_CHANGE
    ASSERT  :DEF:ENTRY_BUS_WIDTH  //判断是否有定义变量 **ENDIAN_CHANGE**
    [ ENTRY_BUS_WIDTH=32
	b	ChangeBigEndian	    ;DCD 0xea000007
    ]

    [ ENTRY_BUS_WIDTH=16
	andeq	r14,r7,r0,lsl #20   ;DCD 0x0007ea00
    ]

    [ ENTRY_BUS_WIDTH=8
	streq	r0,[r0,-r10,ror #1] ;DCD 0x070000ea
    ]
|
    b	ResetHandler
]

ChangeBigEndian — 设置对应的总线
[ ENTRY_BUS_WIDTH=32
DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian
DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
]
[ ENTRY_BUS_WIDTH=16
DCD 0x0f10ee11
DCD 0x0080e380
DCD 0x0f10ee01
]
[ ENTRY_BUS_WIDTH=8
DCD 0x100f11ee
DCD 0x800080e3
DCD 0x100f01ee
]
DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode.
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
b ResetHandler
/
ResetHandler
ldr r0,=WTCON ;关开门狗
ldr r1,=0x0
str r1,[r0]

ldr	r0,=INTMSK
ldr	r1,=0xffffffff  ;关中断
str	r1,[r0]

ldr	r0,=INTSUBMSK
ldr	r1,=0x7fff		;关中断
str	r1,[r0]

ldr	r0,=LOCKTIME
ldr	r1,=0xffffff
str	r1,[r0]	

;//时钟初始化///
LDR R0, =CLOCK_BASE
LDR R1, =3600
;// MPLL锁定时间大于300us,以外部晶振12M计
STR R1, [R0, #LOCKCON0_OFS]
LDR R1, =3600
;// EPLL锁定时间大于300us
STR R1, [R0, #LOCKCON1_OFS]

LDR R1, =(0x1<<0)+(1<<2)+(1<<3)+(0x1<<4)+(0x0<<9)
STR R1, [R0, #CLKDIV0_OFS]
			
LDR R1, =(0x0<<4)+(0x3<<6)+(0x0<<8)+(0x0<<12)+ \
						(0x0<<16)+(0x0<<24)
STR R1, [R0, #CLKDIV1_OFS]

LDR R1, =(0x0<<0)+(0x3<<6)
STR R1, [R0, #CLKDIV2_OFS]

;// 设置EPLL输出96M,
LDR R1, =(2<<0)+(1<<8)+(32<<16)+(0x0<<24)+(0x0<<25)
STR R1, [R0, #EPLLCON_OFS]

;// 外部晶振12M,设置MPLL输出为400M
LDR R1, =(1<<0)+(3<<5)+(267<<14)+(0x0<<24)+(0x0<<25)
STR R1, [R0, #MPLLCON_OFS]

LDR R1, =(1<<4)+(1<<6) 
STR R1, [R0, #CLKSRC_OFS]

;// 初始化动态变量///

LDR R0, =DRAM_BASE
LDR R1, =(2<<17)+(2<<14)+(2<<11)+(2<<8)+(1<<6)+(1<<4)+(1<<1)+(1<<0)
STR R1, [R0, #BANKCFG_OFS]

;// DQS delay 3,Write buffer,Auto pre-charge,bank address 在高位
LDR R1, =(3<<28)+(1<<26)+(1<<8)+(0<<7)+
(1<<6)+(0<<5)+(1<<4)
STR R1, [R0, #BANKCON1_OFS]

LDR R1, =(5<<20)+(13<<16)+(3<<4)+(1<<2)+(1<<0)
STR R1, [R0, #BANKCON2_OFS] 

;// issue a PALL(pre-charge all) command
LDR R1, [R0, #BANKCON1_OFS]
BIC R1, R1, #0x03
ORR R1, R1, #0x01
STR R1, [R0, #BANKCON1_OFS]

;// issue an EMRS(extern mode register) command to EMR(2)
LDR R1, [R0, #BANKCON3_OFS]
LDR R2, =0xFFFF0000
BIC R1, R1, R2
ORR R1, R1, #(2<<30)
STR R1, [R0, #BANKCON3_OFS]

LDR R1, [R0, #BANKCON1_OFS]
ORR R1, R1, #0x03				
STR R1, [R0, #BANKCON1_OFS]

;// issue an EMRS(extern mode register) command to EMR(3)
LDR R1, [R0, #BANKCON3_OFS]
LDR R2, =0xFFFF0000
BIC R1, R1, R2
ORR R1, R1, #(3<<30)
STR R1, [R0, #BANKCON3_OFS]

LDR R1, [R0, #BANKCON1_OFS]
ORR R1, R1, #0x03				
STR R1, [R0, #BANKCON1_OFS]

;// issue an EMRS to enable DLL and RDQS, nDQS, ODT disable
LDR R1, =0xFFFF0000
LDR R2, [R0, #BANKCON3_OFS]
BIC R2, R2, R1
LDR R1, =(0x1<<30)+(0<<27)+(1<<26)+
(0<<23)+(0<<16)
ORR R1, R1, R2
STR R1, [R0, #BANKCON3_OFS]
LDR R1, [R0, #BANKCON1_OFS]
ORR R1, R1, #0x03
STR R1, [R0, #BANKCON1_OFS]
;// issue a mode register set command for DLL reset
LDR R1, =0x0000FFFF
LDR R2, [R0, #BANKCON3_OFS]
BIC R2, R2, R1
LDR R1, =(1<<8)+(0<<7)+(3<<4)
ORR R1, R1, R2
STR R1, [R0, #BANKCON3_OFS]
LDR R1, [R0, #BANKCON1_OFS]
BIC R1, R1, #0x03
ORR R1, R1, #0x02
STR R1, [R0, #BANKCON1_OFS]
;// Issue 2 or more auto-refresh commands
LDR R1, =0x20
STR R1, [R0, #REFRESH_OFS]
;// Issue a MRS command with LOW to A8 to initialize device operation
LDR R1, =0x0000FFFF
LDR R2, [R0, #BANKCON3_OFS]
BIC R2, R2, R1
LDR R1, =(0<<8)+(0<<7)+(3<<4)
ORR R1, R1, R2
STR R1, [R0, #BANKCON3_OFS]
LDR R1, [R0, #BANKCON1_OFS]
BIC R1, R1, #0x03
ORR R1, R1, #0x02
STR R1, [R0, #BANKCON1_OFS]

;// Wait 200 clock, execute OCD Calibration
LDR R1, =200
0 SUBS R1, R1, #1
BNE %B0
;// Issue a EMRS1 command to over OCD Mode Calibration
LDR R1, =0xFFFF0000
LDR R2, [R0, #BANKCON3_OFS]
BIC R2, R2, R1
LDR R1, =(0x1<<30)+(0<<27)+(1<<26)+
(0<<23)+(0<<19)+(0<<22)+(0<<18)+
(0x0<<17)+(0<<16)
ORR R1, R1, R2
STR R1, [R0, #BANKCON3_OFS]
LDR R1, [R0, #BANKCON1_OFS]
ORR R1, R1, #0x03
STR R1, [R0, #BANKCON1_OFS]

;// Refresh period is 7.8us, HCLK=133M, REFCYC=1037
LDR R1, =1037
STR R1, [R0, #REFRESH_OFS]

;// issue a Normal mode
LDR R1, [R0, #BANKCON1_OFS]
BIC R1, R1, #0x03
STR R1, [R0, #BANKCON1_OFS]
//到这里就吧内存设置好了

	[ {TRUE} //将BBS段清零

clean_bss
ldr r0, BaseOfZero
ldr r1, EndOfBSS
mov r3, #0
cmp r0, r1
beq on_ddr
clean_loop
str r3, [r0], #4
cmp r0, r1
bne clean_loop
]

on_ddr

bl InitStacks  //初始化栈区
BL	NandBoot_Init ;// Nand初始化
MOV R0,#0
LDR R1, BaseOfROM
LDR R2, =0x300000	
BL	NandBoot_ReadSkipBad ;// 调用Nand读函数,检查坏块
MOVS	R0, R0 ;// 返回值确定函数成功还是失败

Nand_Boot_Loop

BNE Nand_Boot_Loop ;// 返回非0说明拷贝失败

ldr	r0,=HandleIRQ       ;This routine is needed
ldr	r1,=IsrIRQ	  ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c'
str	r1,[r0]

ldr pc,=__main  --开始执行main

halt
b halt

//栈的初始化
InitStacks
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack ; UndefStack=0x31FF_5C00

orr	r1,r0,#ABORTMODE|NOINT
msr	cpsr_cxsf,r1		;AbortMode
ldr	sp,=AbortStack		; AbortStack=0x31FF_6000

orr	r1,r0,#IRQMODE|NOINT
msr	cpsr_cxsf,r1		;IRQMode
ldr	sp,=IRQStack		; IRQStack=0x31FF_7000

orr	r1,r0,#FIQMODE|NOINT
msr	cpsr_cxsf,r1		;FIQMode
ldr	sp,=FIQStack		; FIQStack=0x31FF_8000

bic	r0,r0,#MODEMASK|NOINT
orr	r1,r0,#SVCMODE
msr	cpsr_cxsf,r1		;SVCMode
ldr	sp,=SVCStack		; SVCStack=0x31FF_5800

;USER mode has not be initialized.

mov	pc,lr

;The LR register won't be valid if the current mode is not SVC mode.'


LTORG  

LDR R0,(某地址)的指令来解决. 这就是一般的解决之道.

呵呵, 但是我们必须再度想一下,LDR指令能寻址多远呢? LDR指令最多处理4K的偏移!!! 也是因为CPU指令集的问题. 我们的CODE SECTION如果很大, 导致0X12345678放置的地方超过了LDR指令寻址能力, 将再度出现错误! OK, 了解了这点, 我们就应该能够预防这里问题的出现. 我们需要的是让编译器尽可能近地处理这个常量. 查看一下编译器手册, 请使用LTORG巴. LTORG将立刻在当前计数器上放置所有的那些已经出现,并且需要解决的常量. 这样,我们在那些FUNC的尾部加上LTORG指令, 就可以处理调那些加载常量导致的麻烦.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值