根据完全手册上写的MMU汇编代码

本文详细阐述了如何将代码烧入Nand启动,并通过设置内存控制器、复制代码到SDRAM、创建页面表和初始化MMU来实现SDRAM启动的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RO设为0xB0004000 烧入Nand启动


MEM_CTL_BASE   EQU       0x48000000

SDRAM_BASE EQU         0x30004000
SDRAM_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

     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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值