基于ARM板s3c2440---MMU和Cache

Cache—高速缓存存储器

高速缓冲存储器(Cache)其原始意义是指存取速度比一般随机存取记忆体(RAM)来得快的一种RAM,一般而言它不像系统主记忆体那样使用DRAM技术,而使用昂贵但较快速的SRAM技术,也有快取记忆体的名称。

高速缓冲存储器是存在于主存与CPU之间的一级存储器, 由静态存储芯片(SRAM)组成,容量比较小但速度比主存高得多, 接近于CPU的速度。在计算机存储系统的层次结构中,是介于中央处理器和主存储器之间的高速小容量存储器。它和主存储器一起构成一级的存储器。高速缓冲存储器和主存储器之间信息的调度和传送是由硬件自动进行的。

高速缓冲存储器最重要的技术指标是它的命中率。

为什么需要引入cache

在这里插入图片描述
需要了解第一点,CPU与sdram相应时间并非一致,在访问sdram时,需要等待几个机械周期,这个几可能上千个机械周期,对于不断访问同一块的地址,这就需要浪费一定的时间。
在这里插入图片描述
在这里插入图片描述
引入cache的原因就在于我能够将重复使用的数据以及指令,放入cache,然后之后取数据和指令就能直接在cache里面取。

cache运行过程

在这里插入图片描述
在这里插入图片描述
cache miss:缓冲器中没有这个数据
在这里插入图片描述
cache fill:向cache填入该数据以及之后一个line的数据,这里需要注意一个line是8个字,这里的字不一定是两个字节,对于32位的sdram,一个字是4个字节,8个字就是32字节。
注意:这里fill第一次数据会返回给CPU,也就是这里会操作两步,一步是cache fill 一步是返回数据。

cache hit:CPU在cache中找到这个数据或指令。

协处理器

在这里插入图片描述
cp15就是s3c2440里面的协处理器,一共有16个。具体意思不用详细学习。
instruction cache :ICache指令缓冲
data cache :DCache指令缓冲

这里补充一个概念,还有write buffer,对于写操作,并不是直接写入sdram中,首先我们写到cahce里面,然后机器把数据刷到write buffer里面,write buffer在写进sdram里面去。所以对于一些我们需要即时操作的硬件,我们不能开通write buffer,cache两个功能,例如IO口的操作,需要马上传出或者马上传入;显存需要电子枪马上打上屏幕;sdram可以开通。
在这里插入图片描述

协处理器指令

在这里插入图片描述
r:register
c:co-process
在这里插入图片描述

使能cpu中的icache

enable_icache:
	/*设置协处理器使能icache*/
	mrc p15, 0, r0, c1, c0, 0
	orr r0, r0, #(1<<12)		/*r0 = r0 or (1<<12)*/
	mcr p15, 0, r0, c1, c0, 0
	mov pc,lr```

在这里插入图片描述

MMU–地址映射控制器

在这里插入图片描述
首先介绍一个概念,地址映射是什么?我们用一个虚拟地址表示一个真实地址就是地址映射。
在这里插入图片描述
再者明确一个概念,多个app同时运行时我们不可能手动去分配所有app的链接地址,所以需要我们映射出app的真实地址,在程序运行时自动去找到相应的地址,执行。

引入虚拟地址的原因

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
利用同一个地址如何得到不同app的真实地址

在这里插入图片描述
根据不同进程的pid号得到不同的映射地址
在程序中我们不区分MVA和VA,一般指的是MVA。

如何使用MMU

在这里插入图片描述
首先需要创建一个页表,页表在sdram中一段没有使用的地址,需要告诉MMU这个页表的首地址。最简单就是一个表格,一一对应,里面存放虚拟地址VA和物理地址PA。但是这样就浪费空间,多了一个VA地址。
在这里插入图片描述
在这里插入图片描述
section base addre是用PA取高20位得到的。
这是1级页表的描述格式,也就说这是实际在页表中存在的东西,物理地址只是一部分。

权限管理

在这里插入图片描述
在这里插入图片描述
一共16个域,domain占4位0-15,就是16个域,0对应c3里面的第一个0域。15对应c3里面的最后一个15域。
在这里插入图片描述

创建页表


#define MMU_SECDESC_AP          (3<<10)
#define MMU_SECDESC_DOMAIN  (0<<5)
#define MMU_SECDESC_NCNB    (0<<2)
#define MMU_SECDESC_WB      (3<<2)
#define MMU_SECDESC_TYPE    ((1<<4) | (1<<1))

#define MMU_SECDESC_FOR_IO   (MMU_SECDESC_AP | MMU_SECDESC_DOMAIN | MMU_SECDESC_NCNB | MMU_SECDESC_TYPE)
#define MMU_SECDESC_FOR_MEM   (MMU_SECDESC_AP | MMU_SECDESC_DOMAIN | MMU_SECDESC_WB | MMU_SECDESC_TYPE)


#define IO  1
#define MEM 0


void create_secdesc(unsigned int *ttb, unsigned int va, unsigned int pa, int io)
{
	int index;

	index = va / 0x100000;

	if (io)
		ttb[index] = (pa & 0xfff00000) | MMU_SECDESC_FOR_IO;
	else
		ttb[index] = (pa & 0xfff00000) | MMU_SECDESC_FOR_MEM;
}

/*
     *  VA              PA                  CB
     *  0               0                   00
     *  0x40000000      0x40000000          11
     * 
     *  64M sdram:
     *  0x30000000      0x30000000          11
     *  ......
     *  0x33f00000      0x33f00000          11
     *  
     *  register: 0x48000000~0x5B00001C
     *  0x48000000      0x48000000          00
     *  .......
     *  0x5B000000      0x5B000000          00
     * 
     *  Framebuffer : 0x33c00000
     *  0x33c00000      0x33c00000          00
     * 
     *  link address:
     *  0xB0000000      0x30000000          11
     * */
void create_page_table(void)
{
    /*1.页表在哪里?0x3200 0000(16KB)只需要指向一块没有用到的地址就可以*/
    /*ttb:translation table base*/
    unsigned int *ttb = (unsigned int *)0x32000000;

	unsigned int va, pa;
	int index;

    /*2.根据va,pa设置页表条目*/
    /*2.1 for sram/nor flash*/
    /*nand启动0地址是sram的0地址,nor启动0地址是nor flash的0地址*/
    create_secdesc(ttb, 0, 0, IO);      /*这里用NCNB模式的原因是之后会通过写数据至0地址然后读出来,从而判定是nor还是nand启动*/
                                        /*如果使用cache和buffer,写数据以及读数据都会写/读到cache,这样就会导致读出的内容就是写进去的内容*/
                                        /*然后cpu就一直认为是nand启动,从而出错*/

    /* 2.2 for sram when nor boot */
    create_secdesc(ttb, 0x40000000, 0x40000000, MEM);

    /* 2.3 for 64M sdram */
	va = 0x30000000;
	pa = 0x30000000;
	for (; va < 0x34000000;)
	{
		create_secdesc(ttb, va, pa, MEM);
		va += 0x100000;
		pa += 0x100000;
	}

    /* 2.4 for register: 0x48000000~0x5B00001C */
    va = 0x48000000;
	pa = 0x48000000;
	for (; va <= 0x5B000000;)
	{
		create_secdesc(ttb, va, pa, IO);
		va += 0x100000;
		pa += 0x100000;
	}

    /* 2.5 for Framebuffer : 0x33c00000 */
    create_secdesc(ttb, 0x33c00000, 0x33c00000, IO);

    /* 2.6 for link address */
    create_secdesc(ttb, 0xB0000000, 0x30000000, MEM);
}


由于页表是以1M对齐,所以register 地址需要写成0x5B000000,

使能icache,dcache,mmu。

CP15中c2管理一级页表基址,以16KB对齐。
在这里插入图片描述
我们需要些这个协处理器,所以0–13位需要写为0,相当于是16KB对齐。

mmu_enable:
	/*把页表基地址告诉cp15*/
	ldr r0, =0x32000000
	mcr p15, 0, r0, c2, c0, 0	/*将r0的值写进协处理器cp15中的c2(c0和后面的0用区分是哪一个c2,可能有多个c2)*/

	/*设置域为0xffffffff,不进行权限检查*/
	ldr r0, =0xffffffff
	mcr p15, 0, r0, c3, c0, 0


	/*使能icache,dcache,mmu*/
	mrc p15, 0, r0, c1, c0, 0
	orr r0, r0, #(1<<12)  /* enable icache */
	orr r0, r0, #(1<<2)  /* enable dcache */
	orr r0, r0, #(1<<0)  /* enable mmu */
	mcr p15, 0, r0, c1, c0, 0	

	mov pc, lr

在这里插入图片描述
设置域的处理的方式,在页表中已经选择过0域。
本来应该只设置BIT[0,1]两个位置,这样写就是每个域都是这个权限。在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值