1.CP14调试通信通道协处理器
调试通信通道协处理器DCC(the Debug Communications Channel)提供了两个32bits寄存器用于传送数据,还提供了6bits通信数据控制寄存器控制寄存器中的两个位提供目标和主机调试器之间的同步握手。
通信数据控制寄存器
以下指令在 Rd 中返回控制寄存器的值:
MRC p14, 0, Rd, c0, c0
此控制寄存器中的两个位提供目标和主机调试器之间的同步握手:
位 1(W 位) 从目标的角度表示通信数据写入寄存器是否空闲:
W = 0 目标应用程序可以写入新数据。
W = 1 主机调试器可以从写入寄存器中扫描出新数据。
位 0(R 位) 从目标的角度表示通信数据读取寄存器中是否有新数据:
R = 1 有新数据,目标应用程序可以读取。
R = 0 主机调试器可以将新数据扫描到读取寄存器中。
注意:
调试器不能利用协处理器 14 直接访问调试通信通道,因为这对调试器无意义。 但调试器可使用扫描链读写 DCC 寄存器。 DCC 数据和控制寄存器可映射到 EmbeddedICE 逻辑单元中的地址。 若要查看 EmbeddedICE 逻辑寄存器,请参阅您的调试器和调试目标的相关文档。
通信数据读取寄存器
用于接收来自调试器的数据的 32 位宽寄存器。 以下指令在 Rd 中返
回读取寄存器的值:
MRC p14, 0, Rd, c1, c0
通信数据写入寄存器
用于向调试器发送数据的 32 位宽寄存器。 以下指令将 Rn 中的值写
到写入寄存器中:
MCR p14, 0, Rn, c1, c0
注意:
有关访问 ARM10 和 ARM11 内核 DCC 寄存器的信息,请参阅相应的技术参考手册。 ARM9 之后的各处理器中,所用指令、状态位位置以及对状态位的解释都有所不同。
目标到调试器的通信
这是运行于 ARM 内核上的应用程序与运行于主机上的调试器之间的通信事件
顺序:
1. 目标应用程序检查 DCC 写入寄存器是否空闲可用。 为此,目标应用程序使用 MRC 指令读取调试通信通道控制寄存器,以检查 W 位是否已清除。
2. 如果 W 位已清除,则通信数据写入寄存器已清空,应用程序对协处理器 14 使用 MCR 指令将字写入通信数据写入寄存器。 写入寄存器操作会自动设置W 位。如果 W 位已设置,则表明调试器尚未清空通信数据写入寄存器。此时,如果应用程序需要发送另一个字,它必须轮询 W 位,直到它已清除。
3. 调试器通过扫描链 2 轮询通信数据控制寄存器。 如果调试器发现 W 位已设置,则它可以读 DCC 数据寄存器,以读取应用程序发送的信息。 读取数据的进程会自动清除通信数据控制寄存器中的 W 位。
以下代码显示了这一过程
AREA OutChannel, CODE, READONLY
ENTRY
MOV r1,#3 ; Number of words to send
ADR r2, outdata ; Address of data to send
pollout
MRC p14,0,r0,c0,c0 ; Read control register
TST r0, #2
BNE pollout ; if W set, register still full
write
LDR r3,[r2],#4 ; Read word from outdata
; into r3 and update the pointer
MCR p14,0,r3,c1,c0 ; Write word from r3
SUBS r1,r1,#1 ; Update counter
BNE pollout ; Loop if more words to be written
MOV r0, #0x18 ; Angel_SWIreason_ReportException
LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
SVC 0x123456 ; ARM semihosting (formerly SWI)
outdata
DCB "Hello there!"
END
调试器到目标的通信
这是运行于主机上的调试器向运行于内核上的应用程序传输消息的事件顺序:
1. 调试器轮询通信数据控制寄存器的 R 位。 如果 R 位已清除,则通信数据读取寄存器已清空,可将数据写入此寄存器,以供目标应用程序读取。
2. 调试器通过扫描链 2 将数据扫描到通信数据读取寄存器中。 此操作会自动设置通信数据控制寄存器中的 R 位。
3. 目标应用程序轮询通信数据控制寄存器中的 R 位。 如果该位已经设置,则通信数据读取寄存器中已经有数据,应用程序可使用 MRC 指令从协处理器
14 读取该数据。 同时,读取指令还会清除 R 位。
以下显示的目标应用程序代码演示了这一过程
AREA InChannel, CODE, READONLY
ENTRY
MOV r1,#3 ; Number of words to read
LDR r2, =indata ; Address to store data read
pollin
MRC p14,0,r0,c0,c0 ; Read control register
TST r0, #1
BEQ pollin ; If R bit clear then loop
read
MRC p14,0,r3,c1,c0 ; read word into r3
STR r3,[r2],#4 ; Store to memory and
; update pointer
SUBS r1,r1,#1 ; Update counter
BNE pollin ; Loop if more words to read
MOV r0, #0x18 ; Angel_SWIreason_ReportException
LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
SVC 0x123456 ; ARM semihosting (formerly SWI)
AREA Storage, DATA, READWRITE
indata
DCB "Duffmessage#"
END
2.CP15系统控制协处理器
CP15 —系统控制协处理器 (the system control coprocessor)他通过协处理器指令MCR和MRC提供具体的寄存器来配置和控制caches、MMU、保护系统、配置时钟模式(在bootloader时钟初始化用到)
CP15的寄存器只能被MRC和MCR(Move to Coprocessor from ARM Register )指令访问
ARM处理器中CP15协处理器的寄存器
寄存器编号 | 基本作用 | 在MMU中的作用 | 在PU中的作用 |
0 | ID编码(只读) | ID编码和cache类型 |
|
1 | 控制位(可读写) | 各种控制位 |
|
2 | 存储保护和控制 | 地址转换表基地址 | Cachability的控制位 |
3 | 存储保护和控制 | 域访问控制位 | Bufferablity控制位 |
4 | 存储保护和控制 | 保留 | 保留 |
5 | 存储保护和控制 | 内存失效状态 | 访问权限控制位 |
6 | 存储保护和控制 | 内存失效地址 | 保护区域控制 |
7 | 高速缓存和写缓存 | 高速缓存和写缓存控制 |
|
8 | 存储保护和控制 | TLB控制 | 保留 |
9 | 高速缓存和写缓存 | 高速缓存锁定 |
|
10 | 存储保护和控制 | TLB锁定 | 保留 |
11 | 保留 |
|
|
12 | 保留 |
|
|
13 | 进程标识符 | 进程标识符 |
|
14 | 保留 |
|
|
15 | 因不同设计而异 | 因不同设计而异 | 因不同设计而异 |
MCR{cond} p15,<Opcode_1>,<Rd>,<CRn>,<CRm>,<Opcode_2>
MRC{cond} p15,<Opcode_1>,<Rd>,<CRn>,<CRm>,<Opcode_2>
其中L位用来区分MCR(L=1)和MRC(L=0)操作. CP15包括15个具体的寄存器如下:
-R0:ID号寄存器
-R0:缓存类型寄存器
-R1:控制寄存器
-R2:转换表基址寄存器(Translation Table Base --TTB)
-R3:域访问控制寄存器(Domain access control )
-R4:保留
-R5:异常状态寄存器(fault status -FSR)
-R6:异常地址寄存器(fault address -FAR)
-R7:缓存操作寄存器
-R8:TLB操作寄存器
-R9:缓存锁定寄存器
-R10:TLB 锁定寄存器
-R11-12&14:保留
-R13:处理器ID
-R15:测试配置寄存器 2-24
要注意有2个R0,根据MCR操作数的不同传送不同的值,这也一个只读寄存器
-R0:ID号寄存器 这是一个只读寄存器,返回一个32位的设备ID号,具体功能参考ARM各个系列型号的的CP15 Register 0说明.
MRC p15, 0, <Rd>, c0, c0, {0, 3-7} ;returns ID
以下为ID Code详细描叙(ARM926EJ-S); ARM920T Part Number为0x920,Architecture (ARMv4T) 为0x2具体可参照ARM各型号.
-R0:缓存类型寄存器(CACHE TYPE REGISTER),包含了caches的信息。读这个寄存器的方式是通过设置协处理操作码为1.
MRC p15, 0, <Rd>, c0, c0, 1; returns cache details
- CP15的寄存器C0
CP15中寄存器C0对应两个标识符寄存器,由访问CP15中的寄存器指令中的<opcode_2>指定要访问哪个具体物理寄存器,<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位即位[15:12]可能的取值为0~7但不能是0或7 |
位[19: 16] | ARM体系的版本号,可能的取值如下: 0x1 ARM体系版本4 0x2 ARM体系版本4T 0x3 ARM体系版本5 0x4 ARM体系版本5T 0x5 ARM体系版本5TE 其他 由ARM公司保留将来使用 |
位[23: 20] | 生产商定义的产品子编号,当产品主编号相同时,使用子编号来区分不同的产品子类,如产品中不同的高速缓存的大小等 |
位[31: 24] | 生产厂商的编号,现在已经定义的有以下值: 0x41 =A ARM公司 0x44 =D Digital Equipment公司 0x69 =I intel公司 |
ARM7处理器的主标识符寄存器编码格式如下所示:
31 24 23 22 16 15 4 3 0 | ||||
由生产商确定 | A | 产品子编号 | 产品主编号 | 处理器版本号 |
位 | 说 明 |
位[3: 0] | 生产商定义的处理器版本号 |
位[15: 4] | 生产商定义的产品主编号,其中最高4位即位[15:12]的值为0x7 |
位[22: 16] | 生产商定义的产品子编号,当产品主编号相同时,使用子编号来区分不同的产品子类,如产品中不同的高速缓存的大小等 |
续表
位 | 说 明 |
位[23] | ARM7支持下面两种ARM体系的版本号: 0x0 ARM体系版本3 0x1 ARM体系版本4T |
位[31: 24] | 生产厂商的编号,现在已经定义的有以下值: 0x41 =A ARM公司 0x44 =D Digital Equipment公司 0x69 =I Intel公司 |
ARM7之前处理器的主标识符寄存器编码格式如下所示:
31 24 23 22 16 15 4 3 0 | ||||
由生产商确定 | A | 产品子编号 | 产品主编号 | 处理器版本号 |
位 | 说 明 |
位[3: 0] | 生产商定义的处理器版本号 |
位[15: 4] | 生产商定义的产品主编号,其中最高4位即为[15:12]的值为0x7 |
位[22: 16] | 生产商定义的产品子编号,当产品主编号相同时,使用子编号来区分不同的产品子类,如产品中不同的高速缓存的大小等 |
位[23] | ARM7支持下面两种ARM体系的版本号: 0x0 ARM体系版本3 0x1 ARM体系版本4T |
位[31: 24] | 生产厂商的编号,现在已经定义的有以下值: 0x41 =A ARM公司 0x44 =D Digital Equipment公司 0x69 =I intel公司 |
2)cache类型标识符寄存器
访问cache类型标识符寄存器的指令格式如下所示:
mrc p15, 0, r0, c0, c0, 1 ;将cache类型标识符寄存器C0,1的值读到r0中
ARM处理器中cache类型标识符寄存器的编码格式如下所示:
31 29 28 25 24 23 12 11 0 | ||||
0 0 0 | 属性字段 | S | 数据cache相关属性 | 指令cache相关属性 |
位 | 说明 |
位[28: 25] | 指定控制字段位[24: 0]指定的属性之外的cache的其他属性,详见表4-2 |
位[24] | 定义系统中的数据cache和指令cache是分开的还是统一的: 0 系统的数据cache和指令cache是统一的; 1 系统的数据cache和指令cache是分开的 |
位[23: 12] | 定义数据cache的相关属性,如果位[24]为0,本字段定义整个cache的属性 |
位[31: 24] | 定义指令cache的相关属性,如果位[24]为0,本字段定义整个cache的属性 |
其中控制字段位[28:25]的含义说明如下:
表4-2 cache类型标识符寄存器的控制字段位[28:25]
编 码 | cache类型 | cache内容清除方法 | cache内容锁定方法 |
0b0000 | 写通类型 | 不需要内容清除 | 不支持内容锁定 |
0b0001 | 写回类型 | 数据块读取 | 不支持内容锁定 |
0b0010 | 写回类型 | 由寄存器C7定义 | 不支持内容锁定 |
0b0110 | 写回类型 | 由寄存器C7定义 | 支持格式A |
0b0111 | 写回类型 | 由寄存器C7定义 | 支持格式B |
控制字段位[23:12]和控制字段位[11:0]的编码格式相同,含义如下所示:
11 9 8 6 5 3 2 1 0 | ||||
0 0 0 | cache容量 | cache相联特性 | M | 块大小 |
cache容量字段bits[8: 6]的含义如下所示:
编 码 | M=0时含义(单位KB) | M=1时含义(单位KB) |
0b000 | 0.5 | 0.75 |
0b001 | 1 | 1.5 |
0b010 | 2 | 3 |
0b011 | 4 | 6 |
0b100 | 8 | 12 |
0b101 | 16 | 24 |
0b110 | 32 | 48 |
0b111 | 64 | 96 |
cache相联特性字段bits[5: 3]的含义如下所示:
编 码 | M=0时含义 | M=1时含义 |
0b000 | 1路相联(直接映射) | 没有cache |
0b001 | 2路相联 | 3路相联 |
0b010 | 4路相联 | 6路相联 |
0b011 | 8路相联 | 12路相联 |
0b100 | 16路相联 | 24路相联 |
0b101 | 32路相联 | 48路相联 |
0b110 | 64路相联 | 96路相联 |
0b111 | 128路相联 | 192路相联 |
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的编码格式及含义说明如下:
31 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
附加 | L4 | RR | V | I | Z | F | R | S | B | L | D | P | W | C | A | M |
位 | 说 明 |
M | 0:禁止MMU或者PU;1:使能MMU或者PU |
A | 0:禁止地址对齐检查;1:使能地址对齐检查 |
C | 0:禁止数据/整个cache;1:使能数据/整个cache |
W | 0:禁止写缓冲;1:使能写缓冲 |
P | 0:异常中断处理程序进入32位地址模式;1:异常中断处理程序进入26位地址模式 |
D | 0:禁止26位地址异常检查;1:使能26位地址异常检查 |
L | 0:选择早期中止模型;1:选择后期中止模型 |
B | 0:little endian;1:big endian |
S | 在基于MMU的存储系统中,本位用作系统保护 |
R | 在基于MMU的存储系统中,本位用作ROM保护 |
F | 0:由生产商定义 |
Z | 0:禁止跳转预测功能;1:使能跳转预测指令 |
I | 0:禁止指令cache;1:使能指令cache |
V | 0:选择低端异常中断向量0x0~0x1c;1:选择高端异常中断向量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中的寄存器C2保存的是页表的基地址,即一级映射描述符表的基地址。其编码格如下所示:
31 0 |
一级映射描述符表的基地址(物理地址) |
- CP15的寄存器C3
CP15中的寄存器C3定义了ARM处理器的16个域的访问权限。
31 0 | |||||||||||||||
D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
- CP15的寄存器C5
CP15中的寄存器C5是失效状态寄存器,编码格式如下所示:
31 9 8 7 4 3 0 | |||
UNP/SBZP | 0 | 域标识 | 状态标识 |
其中,域标识bit[7:4]表示存放引起存储访问失效的存储访问所属的域。
状态标识bit[3:0]表示放引起存储访问失效的存储访问类型,该字段含义如表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
CP15的C7寄存器用来控制cache和写缓存,它是一个只写寄存器,读操作将产生不可预知的后果。
访问CP15的C7寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c7>, crm, <opcode_2> ;<rd>、<crm>和<opcode_2>的不同取值组合 实现不同功能
- CP15中的寄存器C8
CP15的C8寄存器用来控制清除TLB的内容,是只写寄存器,读操作将产生不可预知的后果。
访问CP15的C8寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c8>, crm, <opcode_2> ;<rd>、<crm>和<opcode_2>的不同取值组合实现不同功能,见第4.2节
- CP15中的寄存器C9
CP15的C9寄存器用于控制cache内容锁定。
访问CP15的C9寄存器的指令格式如下所示:
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的内容锁定寄存器。
CP15的C9寄存器有A、B两种编码格式。编码格式A如下所示:
31 32-W 31-W 0 | |
cache组内块序号index | 0 |
其中index表示当下一次发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为index的cache块中。此时序号为0~index-1的cache块被锁定,当发生cache替换时,从序号为index到ASSOCIATIVITY的块中选择被替换的块。
编码格式B如下所示:
31 30 W W-1 0 | ||
L | 0 | cache组内块序号index |
位 | 说 明 |
L=0 | 当发生cache未命中时,将预取的存储块存入cache中该块对应的组中序号为index的cache块中 |
续表
位 | 说 明 |
L=1 | 如果本次写操作之前L=0,并且index值小于本次写入的index,本次写操作执行的结果不可预知;否则,这时被锁定的cache块包括序号为0~index-1的块,当发生cache替换时,从序号为index到ASSOCIATIVITY的块中选择被替换的块 |
- CP15的寄存器C10
CP15的C10寄存器用于控制TLB内容锁定。
访问CP15的C10寄存器的指令格式如下所示:
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。
访问CP15的C13寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c13>, c0, 0
mrc p15, 0, <rd>, <c13>, c0, 0
C13寄存器的编码格式如下所示:
31 25 24 0 | |
PID | 0 |
其中,PID表示当前进程的所在的进程空间块的编号,即当前进程的进程标识符,取值为0~127。
0:MVA(变换后的虚拟地址)= VA(虚拟地址),禁止FCSE(快速上下文切换技术),系统复位后PID=0;
非0:使能FCSE。
以下为CP15的一些应用示例
U32 ARM_CP15_DeviceIDRead(void)
{
U32 id;
__asm { MRC P15, 0, id, c0, c0; }
return id;
}
void ARM_CP15_SetPageTableBase(P_U32 TableAddress)
{
__asm { MCR P15, 0, TableAddress, c2, c0, 0; }
}
void ARM_CP15_SetDomainAccessControl(U32 flags)
{
__asm { MCR P15, 0, flags, c3, c0, 0; }
}
void ARM_CP15_ICacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c5, 0; }
}
void ARM_CP15_DCacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c6, 0; }
}
void ARM_CP15_CacheFlush()
{
unsigned long dummy;
__asm { MCR p15, 0, dummy, c7, c7, 0; }
}
void ARM_CP15_TLBFlush(void)
{
unsigned long dummy;
__asm { MCR P15, 0, dummy, c8, c7, 0; }
}
void ARM_CP15_ControlRegisterWrite(U32 flags)
{
__asm { MCR P15, 0, flags, c1, c0; }
}
void ARM_CP15_ControlRegisterOR(U32 flag)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2,flag
orr r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
void ARM_CP15_ControlRegisterAND(U32 flag)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2,flag
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
}
void ARM_MMU_Init(P_U32 TableAddress)
{
ARM_CP15_TLBFlush();
ARM_CP15_CacheFlush();
ARM_CP15_SetDomainAccessControl(0xFFFFFFFF);
ARM_CP15_SetPageTableBase(TableAddress);
}
void Enable_MMU (void)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2, #0x00000001
orr r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
printf("MMU enabled\n");
}
void Disable_MMU (void)
{
__asm {
mrc p15,0,r0,c1,c0,0
mov r2, #0xFFFFFFFE
and r0,r2,r0
mcr p15,0,r0,c1,c0,0
}
printf("MMU disabled\n");
}