ARM MMU简介

一. CP15寄存器

mcr

ARM处理器的寄存器中的数据写到CP15中的寄存器中

mrc

CP15中的寄存器中的数据读到ARM处理器的寄存器中

4.1.2 CP15寄存器介绍

寄存器编号

基本作用

MMU中的作用

PU中的作用

0

ID编码(只读)

ID编码和cache类型

1

控制位(可读写)

各种控制位

2

存储保护和控制

地址转换表基地址

Cachability的控制位

3

存储保护和控制

域访问控制位

Bufferablity控制位

5

存储保护和控制

内存失效状态

访问权限控制位

6

存储保护和控制

内存失效地址

保护区域控制

7

高速缓存和写缓存

高速缓存和写缓存控制

8

存储保护和控制

TLB控制

保留

9

高速缓存和写缓存

高速缓存锁定

10

存储保护和控制

TLB锁定

保留

13

进程标识符

进程标识符

CP15的寄存器C0

CP15中寄存器C0对应两个标识符寄存器,由访问CP15中的寄存器指令中的<opcode_2>指定要访问哪个具体物理寄存器,<opcode_2>与两个标识符寄存器的对应关系如下所示:

0b000

主标识符寄存器

0b001

cache类型标识符寄存器

1)主标识符寄存器

访问主标识符寄存器的指令格式如下所示:

mrc p15, 0, r0, c0, c0, 0 ;将主标识符寄存器C0,0的值读到r0

ARM不同版本体系处理器中主标识符寄存器的编码格式说明如下。

ARM7之后处理器的主标识符寄存器编码格式如下所示:

31 24 23 20 19 16 15 4 3 0

由生产商确定

产品子编号

ARM体系版本号

产品主编号

处理器版本号

说 明

[3: 0]

生产商定义的处理器版本号

[15: 4]

生产商定义的产品主编号,最高4位可能的取值为0~7但不能是07

[19: 16]

0x1 ARM体系版本4

[23: 20]

生产商的产品子编号使用子编号来区分不同的产品子类,如产品中不同的高速缓存的大小等

[31: 24]

生产厂商的编号0x41 =A ARM公司0x69 =I intel公司

2cache类型标识符寄存器

访问cache类型标识符寄存器的指令格式如下所示:

mrc p15, 0, r0, c0, c0, 1 ;将cache类型标识符寄存器C0,1的值读到r0

ARM处理器中cache类型标识符寄存器的编码格式如下所示:

[28: 25]

指定控制字段位[24: 0]指定的属性之外的cache的其他属性

[24]

定义系统中的数据cache和指令cache是分开的还是统一的:

系统的数据cache和指令cache是统一的;

系统的数据cache和指令cache是分开的

[23: 12]

定义数据cache的相关属性,如果位[24]0,本字段定义整个cache的属性

[31: 24]

定义指令cache的相关属性,如果位[24]0,本字段定义整个cache的属性

其中控制字段位[2825]的含义说明如下:

编 码

cache类型

cache内容清除方法

cache内容锁定方法

0b0000

写通类型

不需要内容清除

不支持内容锁定

0b0001

写回类型

数据块读取

不支持内容锁定

0b0010

写回类型

由寄存器C7定义

不支持内容锁定

0b0110

写回类型

由寄存器C7定义

支持格式A

0b0111

写回类型

由寄存器C7定义

支持格式B

cache块大小字段bits[1: 0]的含义如下所示:

编 码

cache块大小

0b00

2个字(8字节)

0b01

4个字(16字节)

0b10

8个字(32字节)

0b11

16个字(64字节)

CP15的寄存器C1

访问主标识符寄存器的指令格式如下所示:

mrc p15, 0, r0, c1, c0{, 0} ;将CP15的寄存器C1的值读到r0

mcr p15, 0, r0, c1, c0{, 0} ;将r0的值写到CP15的寄存器C1

CP15中的寄存器C1的编码格式及含义说明如下:

M

0:禁止MMU或者PU1:使能MMU或者PU

A

0:禁止地址对齐检查;1:使能地址对齐检查

C

0:禁止数据/整个cache1:使能数据/整个cache

W

0:禁止写缓冲;1:使能写缓冲

P

0:异常中断处理程序进入32位地址模式;1:异常中断处理程序进入26位地址模式

D

0:禁止26位地址异常检查;1:使能26位地址异常检查

L

0:选择早期中止模型;1:选择后期中止模型

B

0little endian1big endian

S

在基于MMU的存储系统中,本位用作系统保护

R

在基于MMU的存储系统中,本位用作ROM保护

F

0:由生产商定义

Z

0:禁止跳转预测功能;1:使能跳转预测指令

I

0:禁止指令cache1:使能指令cache

V

0:选择低端异常中断向量0x0~0x1c1:选择高端异常中断向量0xffff0000~ 0xffff001c

RR

0:常规的cache淘汰算法,如随机淘汰;1:预测性淘汰算法,如round-robin淘汰算法

L4

0:保持ARMv5以上版本的正常功能;1:将ARMv5以上版本与以前版本处理器兼容,不根据跳转地址的bit[0]进行ARM指令和Thumb状态切换:bit[0]等于0表示ARM指令,等于1表示Thumb指令

CP15中的寄存器C2保存的是页表的基地址,即一级映射描述符表的基地址。

CP15中的寄存器C3定义了ARM处理器的16个域的访问权限。

CP15中的寄存器C5是失效状态寄存器,编码格式如下所示:

31 9 8 7 4 3 0

UNP/SBZP

0

域标识

状态标识

其中,域标识bit[74]表示存放引起存储访问失效的存储访问所属的域。

状态标识bit[30]表示放引起存储访问失效的存储访问类型,该字段含义如表4-3所示(优先级由上到下递减)。

4-3 状态标识字段含义

引起访问失效的原因

状态标识

域标识

C6

终端异常(Terminal Exception

0b0010

无效

生产商定义

中断向量访问异常(Vector Exception

0b0000

无效

有效

地址对齐

0b00x1

无效

有效

一级页表访问失效

0b1100

无效

有效

二级页表访问失效

0b1110

有效

有效

基于段的地址变换失效

0b0101

无效

有效

基于页的地址变换失效

0b0111

有效

有效

基于段的存储访问中域控制失效

0b1001

有效

有效

基于页的存储访问中域控制失效

0b1101

有效

有效

基于段的存储访问中访问权限控制失效

0b1111

有效

有效

基于页的存储访问中访问权限控制失效

0b0100

有效

有效

基于段的cache预取时外部存储系统失效

0b0110

有效

有效

基于页的cache预取时外部存储系统失效

0b1000

有效

有效

基于段的非cache预取时外部存储系统失效

0b1010

有效

有效

CP15中的寄存器C6

CP15中的寄存器C5是失效地址寄存器,编码格式如下所示:

31 0

失效地址(虚拟地址)

CP15中的寄存器C7

CP15C7寄存器用来控制cache和写缓存,它是一个只写寄存器,读操作将产生不可预知的后果。

访问CP15C7寄存器的指令格式如下所示:

mcr p15, 0, <rd>, <c7>, crm, <opcode_2> <rd><crm><opcode_2>的不同取值组合 实现不同功能

CP15中的寄存器C8

CP15C8寄存器用来控制清除TLB的内容,是只写寄存器,读操作将产生不可预知的后果。

访问CP15C8寄存器的指令格式如下所示:

mcr p15, 0, <rd>, <c8>, crm, <opcode_2> <rd><crm><opcode_2>的不同取值组合实现不同功能,见第4.2

CP15中的寄存器C9

CP15C9寄存器用于控制cache内容锁定。

访问CP15C9寄存器的指令格式如下所示:

mcr p15, 0, <rd>, <c9>, c0, <opcode_2>

mrc p15, 0, <rd>, <c9>, c0, <opcode_2>

如果系统中包含独立的指令cache和数据cache,那么对应于数据cache和指令cache分别有一个独立的cache内容锁定寄存器,<opcode_2>用来选择其中的某个寄存器:

<opcode_2>=1选择指令cache的内容锁定寄存器;

<opcode_2>=0选择数据cache的内容锁定寄存器。

CP15C9寄存器有AB两种编码格式。编码格式A如下所示:

31 32-W 31-W 0

cache组内块序号index

0

其中index表示当下一次发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为indexcache块中。此时序号为0~index-1cache块被锁定,当发生cache替换时,从序号为indexASSOCIATIVITY的块中选择被替换的块。

编码格式B如下所示:

31 30 W W-1 0

L

0

cache组内块序号index

说 明

L=0

当发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为indexcache块中

续表

说 明

L=1

如果本次写操作之前L=0,并且index值小于本次写入的index,本次写操作执行的结果不可预知;否则,这时被锁定的cache块包括序号为0~index-1的块,当发生cache替换时,从序号为indexASSOCIATIVITY的块中选择被替换的块

CP15的寄存器C10

CP15C10寄存器用于控制TLB内容锁定。

访问CP15C10寄存器的指令格式如下所示:

mcr p15, 0, <rd>, <c10>, c0, <opcode_2>

mrc p15, 0, <rd>, <c10>, c0, <opcode_2>

如果系统中包含独立的指令TLB和数据TLB,那么对应于数据TLB和指令TLB分别有一个独立的TLB内容锁定寄存器,<opcode_2>用来选择其中的某个寄存器:

<opcode_2>=1选择指令TLB的内容锁定寄存器;

<opcode_2>=0选择数据TLB的内容锁定寄存器。

C10寄存器的编码格式如下:

31 30 32-W 31-W 32-2W 31-2W 1 0

可被替换的条目起始地址的base

下一个将被替换的条目地址victim

0

P

说 明

victim

指定下一次TLB没有命中(所需的地址变换条目没有包含在TLB中)时,从内存页表中读取所需的地址变换条目,并把该地址变换条目保存在TLB中地址victim

base

指定TLB替换时,所使用的地址范围,从(base)到(TLB中条目数-1);字段victim的值应该包含在该范围内

P

1:写入TLB的地址变换条目不会受使整个TLB无效操作的影响,一直保持有效;0:写入TLB的地址变换条目将会受到使整个TLB无效操作的影响

CP15的寄存器C13

C13寄存器用于快速上下文切换FCSE

访问CP15C13寄存器的指令格式如下所示:

mcr p15, 0, <rd>, <c13>, c0, 0

mrc p15, 0, <rd>, <c13>, c0, 0

C13寄存器的编码格式如下所示:

31 25 24 0

PID

0

其中,PID表示当前进程的所在的进程空间块的编号,即当前进程的进程标识符,取值为0~127

0MVA(变换后的虚拟地址)= VA(虚拟地址),禁止FCSE(快速上下文切换技术),系统复位后PID=0

0:使能FCSE

二.MMU原理介绍

ARM地址转换过程中涉及三个概念:virtual addr(VA),变换后的虚拟地址(不同进程使用相同虚拟地址的问题)(MVA),物理地址(PA).


三.MMU编程实例

MMU是由协处理器(cp15)控制的,最多会用到两级页表:以段(Section,1MB)的方式进行转换时只用到一级页表,以页(page)的方式进行转换时用到两级页表。页的大小有3:大页(64KB),小页(4KB),极小页(1KB)
条目也称为"描述符"(Descriptor),:段描述符,大页描述符,小页描述符,极小页描述符----它们保存段、大页、小页或极小页的起始物理地址;粗页表描述符、细页表描述符---他们保存二级页表的物理地址

TTB保存了一级页表所存放的实际物理地址,要求16KB对齐,以段的方式映射,4GB的虚拟地址空间,需要段描述符4096(每个段描述符映射1M空间),每个描述符占用4byte,所以映射一级页表占用的空间为16KB

我们假设一级页表存放在物理地址:0x30000000.

第一步:
获得虚拟地址所对应的段描述符所在的地址
addr = TTB&0xffffc000 | ((viraddr >> 20) << 2 ) = 0x30000000 & 0xfffc000 | ((0xa0004000 >> 20) << 2)= 0x30000000 | (0xa00 << 2) = 0x30002800

第二步:
0x30002800取出虚拟地址所对应的段描述符

段描述的构造我们到后面再来讲解,这里我们假设我们把0xa0004000映射到实际的物理地址0x30004000,则这里的[31:20]0x300

第三步:
组合成实际的物理地址

phyaddr = 0x300 << 20 | (0xa0004000 & 0xfffff) = 0x30004000

.实验
目标:以段的方式映射s3c2410的地址空间,一级页表存放在0x30000000

流程:
A.计算每个虚拟地址对应段描述符所在的地址(addr),方法如下:

B.构造段描述符

注意:Section base address 存放的是实际的物理地址的[31:20]

C.存放段描述符
(unsigned int *)addr = section descriptor

实例代码:
/*页表项内容*/
#define PAGE_TABLE_SECTION_AP (0x01 << 10)
#define APGE_TABLE_SECTION_DOMAIN (0x0 << 5)
#define PAGE_TABLE_SECTION_CACHE_WB (0x0 << 2)
#define PAGE_TABLE_SECTION_4BIT (1 << 4)
#define PAGE_TABLE_SECTION_TYPE (0x2)
/*段大小*/
#define SECTION_SIZE 0x100000
//根据虚拟地址和页表基地址确定页表项所在的物理地址

unsigned int get_pgtindex_addr(unsigned int viraddr,unsigned int pgtaddr)
{
unsigned int addr;
/*[31:14]页表基地地址 [13: 2]虚拟地址>>20位得到的page index   [1 : 0]总是为0,因为每一项占用4byte*/
addr = (pgtaddr & PAGE_TABLE_BASE_MASK) | (((viraddr & VIRADDR_MASK) >> 20) << 2);
return addr;
}

//获取页表项

unsigned int get_page_entry(unsigned int phyaddr)
{
unsigned int entry_value;
/*[31:20]section base address   *[19:12] *[11:10]AP *[9] *[8:5]Domain
*[4]:1 *[3]:C *[2]:B *[1:0]:Type*/
entry_value = (phyaddr & PHYADDR_MASK) | PAGE_TABLE_SECTION_AP |\
PAGE_TABLE_SECTION_CACHE_WB | PAGE_TABLE_SECTION_4BIT|\
PAGE_TABLE_SECTION_TYPE;
return entry_value;
}

/*创建一级页表:段描述符*/

void create_page_table()
{int i;
unsigned int pgt_index_addr;
unsigned int viraddr,phyaddr,pgtaddr;
/*在这里我们将0x00000000开始的1M物理空间映射到0x00000000开始的虚拟地址空间*/ 
phyaddr = SRAM_START_ADDR;
viraddr = phyaddr;
pgtaddr = PAGE_TABLE_BASE;
pgt_index_addr = get_pgtindex_addr(viraddr,pgtaddr); 
*(volatile unsigned int *)pgt_index_addr = get_page_entry(phyaddr);
/*映射64MSDRAM*/
for(phyaddr = SDRAM_ADDR_START,viraddr = VMRAM_ADDR_START;

phyaddr < SDRAM_ADDR_END;phyaddr += SECTION_SIZE,viraddr += SECTION_SIZE)
{
pgtaddr = PAGE_TABLE_BASE;
pgt_index_addr = get_pgtindex_addr(viraddr,pgtaddr);
*(volatile unsigned int *)pgt_index_addr = get_page_entry(phyaddr);
}
/*映射IO地址空间*/
phyaddr = PHIO_ADDR_START;
viraddr = VMIO_ADDR_START;
pgtaddr = PAGE_TABLE_BASE;
pgt_index_addr = get_pgtindex_addr(viraddr,pgtaddr);
*(volatile unsigned int *)pgt_index_addr = get_page_entry(phyaddr); 
return;
}

void init_mmu()
{
unsigned long mmu_table_base = PAGE_TABLE_BASE;
asm(
/*set Translation Table Base(TTB) register*/
"mrc p15,0,r0,c2,c0,0\n"
"mov r0,%0\n"
"mcr p15,0,r0,c2,c0,0\n"
/*set Domain Access Control register*/
"mrc p15,0,r0,c3,c0,0\n"
"mvn r0,#0\n"
"mcr p15,0,r0,c3,c0,0\n"
/*Enable MMU*/
"mrc p15,0,r0,c1,c0,0\n"
"orr r0, #0x1\n"
"mcr p15,0,r0,c1,c0,0\n"
"mov r0,r0\n"
"mov r0,r0\n"
"mov r0,r0\n"
:
:"r"(mmu_table_base)
:"r0"
);
return;
}
adrl r1,SMRDATA @13个寄存器值存放的地址
.ltorg @声明一个数据缓冲池的开始
SMRDATA:
.word 0x2201d110 @BWSCON 设置BANK3位宽16,使能nWait,使能UB/LB
.word 0x0700 @BANKCON0
.word 0x700 @BANKCON1
.word 0x700 @BANKCON2
.word 0x700 @BANKCON3
.word 0x700 @BANKCON4
.word 0x700 @BANKCON5
.word (3 << 15) + (1 << 0) @BANKCON6
.word 0x18001 @BANKCON7
.word (1 << 23) + (2 << 18) + (1256 << 0) @REFRESH
.word (1 << 7) + (1 << 0) @BANKSIZE
.word (3 << 4) @MRSRB6
.word (3 << 4) @MRSRB7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章