RO设为0xB0004000 烧入Nand启动
MEM_CTL_BASE EQU 0x48000000
SDRAM_BASE EQU 0x30004000SDRAM_CODE_BASE EQU 0xB0004000 ;//MVA
DELAYTIME equ 0x10
IMPORT create_page_table
AREA MMU,CODE,READONLY
ENTRY
CODE32
;IMPORT mmu_init
START bl disable_watch_dog ;//关闭WATCHDOG,否则CPU会不断重启
bl memsetup ;//设置存储控制器
bl copy_steppingstone_to_sdram ;//复制代码到SDRAM中
bl create_page_table
bl mmu_init
;LDR R2,=ON_SDRAM ;//RO=0x00000000
;LDR R3,=SDRAM_CODE_BASE
;ADD R1,R2,R3
;MOV PC,R1
LDR PC,=ON_SDRAM ;//跳到SDRAM中继续执行,RO=0x30004000
ON_SDRAM
ldr sp, =0xB4000000 ;//设置堆栈
bl Main
halt_loop
b halt_loop
Main
LDR r1,=0xA0000010
MOV r2,#0x15400
STR r2,[r1]
LDR r1,=0xA0000014
MOV r3,#0x1d0
STR r3,[r1]
Main_loop
LDR r1,=0xA0000014
STR r3,[r1]
CMP r3,#0x00000000 ;//判断R3是否为0,是则重新赋值
MOVEQ r3,#0x000001F0
SUB r3,r3,#0x20
LDR r0,=DELAYTIME
BL Delay ;//调用延迟子程序
b Main_loop
mmu_init
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 ;/* 使无效ICaches和DCaches */
mcr p15, 0, r0, c7, c10, 4 ;/* drain write buffer on v4 */
mcr p15, 0, r0, c8, c7, 0 ;/* 使无效指令、数据TLB */
mov r4, #0x30000000 ;/* r4 = 页表基址 */
mcr p15, 0, r4, c2, c0, 0 ;/* 设置页表基址寄存器 */
mvn r0, #0
mcr p15, 0, r0, c3, c0, 0 ;/* 域访问控制寄存器设为0xFFFFFFFF,不进行权限检查 */
;/*
; * 对于控制寄存器,先读出其值,在这基础上修改感兴趣的位,
; * 然后再写入
; */
mrc p15, 0, r0, c1, c0, 0 ;/* 读出控制寄存器的值 */
;/* 控制寄存器的低16位含义为:.RVI ..RS B... .CAM
; * R : 表示换出Cache中的条目时使用的算法,
; * 0 = Random replacement;1 = Round robin replacement
; * V : 表示异常向量表所在的位置,
; * 0 = Low addresses = 0x00000000;1 = High addresses = 0xFFFF0000
; * I : 0 = 关闭ICaches;1 = 开启ICaches
; * R、S : 用来与页表中的描述符一起确定内存的访问权限
; * B : 0 = CPU为小字节序;1 = CPU为大字节序
; * C : 0 = 关闭DCaches;1 = 开启DCaches
; * A : 0 = 数据访问时不进行地址对齐检查;1 = 数据访问时进行地址对齐检查
; * M : 0 = 关闭MMU;1 = 开启MMU
; */
;/*
; * 先清除不需要的位,往下若需要则重新设置它们
; */
; /* .RVI ..RS B... .CAM */
bic r0, r0, #0x3000 ; /* ..11 .... .... .... 清除V、I位 */
bic r0, r0, #0x0300 ; /* .... ..11 .... .... 清除R、S位 */
bic r0, r0, #0x0087 ; /* .... .... 1... .111 清除B/C/A/M */
;/*
; * 设置需要的位
; */
orr r0, r0, #0x0002 ; /* .... .... .... ..1. 开启对齐检查 */
orr r0, r0, #0x0004 ; /* .... .... .... .1.. 开启DCaches */
orr r0, r0, #0x1000 ; /* ...1 .... .... .... 开启ICaches */
orr r0, r0, #0x0001 ; /* .... .... .... ...1 使能MMU */
mcr p15, 0, r0, c1, c0, 0 ;/* 将修改的值写入控制寄存器 */
MOV PC, lr ;返回
Delay
ldr r2,=0x1fff
delay_1
SUB r2,r2,#1
CMP r2,#0x0
BNE delay_1
SUB r0,r0,#1
CMP r0,#0x0
BNE Delay
MOV PC, lr ;返回
disable_watch_dog
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
mov pc, lr
copy_steppingstone_to_sdram
;//将Steppingstone的4K数据全部复制到SDRAM中去
;//Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
mov r1, #0
ldr r2, =SDRAM_BASE
mov r3, #4*1024
1
ldr r4, [r1],#4 ;//从Steppingstone读取4字节的数据,并让源地址加4
str r4, [r2],#4 ;//将此4字节的数据复制到SDRAM中,并让目地地址加4
cmp r1, r3 ;//判断是否完成:源地址等于Steppingstone的未地址?
bne %B1 ;//若没有复制完,继续
mov pc, lr ;//返回
memsetup
;//设置存储控制器以便使用SDRAM等外设
mov r1, #MEM_CTL_BASE ;//存储控制器的13个寄存器的开始地址
adrl r2, mem_cfg_val ;//这13个值的起始存储地址
add r3, r1, #52 ;//13*4 = 52
1
ldr r4, [r2], #4 ;//读取设置值,并让r2加4
str r4, [r1], #4 ;//将此值写入寄存器,并让r1加4
cmp r1, r3 ;//判断是否设置完所有13个寄存器
bne %B1 ;//若没有写成,继续
mov pc, lr ;//返回
mem_cfg_val
DCD 0x22111120
DCD 0x00002F50
DCD 0x00000700
DCD 0x00000700
DCD 0x00000700
DCD 0x00000700
DCD 0x0007FFFC
DCD 0x00018005
DCD 0x00018005
DCD 0x008E0459
DCD 0x00000032
DCD 0x00000030
DCD 0x00000030
END