/*本段代码来自朱老师物联网大讲堂icache那一节视频*/
mrc p15,0,r0,c1,c0,0; // 读出cp15的c1到r0中
//bic r0, r0, #(1<<12) // bit12 置0 关icache
orr r0, r0, #(1<<12) // bit12 置1 开icache
mcr p15,0,r0,c1,c0,0; // 将r0写入到cp15的c1中
mrc用于读取CP15中的寄存器
mcr用于写入CP15中的寄存器
bic 是清零指令;用于清除操作数1的某些位,并把结果放置到目的寄存器中。
orr 是位置1指令;用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。
MRC{cond} p15,
MCR{cond} p15,
cond:为指令执行的条件码。当cond忽略时指令为无条件执行。
Opcode_1:协处理器的特定操作码. 对于CP15寄存器来说,opcode1=0
Rd:源寄存器的ARM寄存器,其值将被传送到协处理器寄存器中,或将协处理器寄存器的值传送到该寄存器里面 ,通常为R0
CRn:目标寄存器的协处理器寄存器,其编号是C~C15。
CRm:协处理器中附加的目标寄存器或源操作数寄存器。如果不需要设置附加信息,将CRm设置为c0,否则结果未知
Opcode_2:可选的协处理器特定操作码。(用来区分同一个编号的不同物理寄存器,当不需要提供附加信息时,指定为0)
BIC指令的格式为: BIC{条件}{S} 目的寄存器,操作数1,操作数2
ORR指令的格式为: ORR{条件}{S} 目的寄存器,操作数1,操作数2
操作数1应是一个寄存器, 操作数2可以是一个寄存器、被移位的寄存器、或一个立即数。
【关键】操作数2为32位的掩码。对于bic而言,如果在掩码中置了某一位1,则清除这一位,未设置的掩码位保持不变;对于orr而言,如果在掩码中置了某一位1,则这一位置1,未设置的掩码位保持不变;
bic r0,r0,#0x1f //其含义:清除r0的bit[4:0]位
0x1f=11111b
#define ELFIN_CLOCK_POWER_BASE 0xE0100000 // 时钟控制器基地址
#define CLK_DIV0_MASK 0x7fffffff // 掩码设置时钟的长度
#define CLK_DIV0_OFFSET 0x300 // CLK_DIV0的偏移量为0x300
ldr r0, =ELFIN_CLOCK_POWER_BASE //r0是基地址
ldr r1, [r0, #CLK_DIV0_OFFSET] //运算后寄存器r1=0xE0100300
ldr r2, =CLK_DIV0_MASK //运算后寄存器r2=0x7fffffff
bic r1, r1, r2 //把r1的bit[30-0]清零,而bit[31]保持不变,运算后r1=0x8000000
下面用图形象说明bic用法示例2命令bic r1, r1, r2 的过程:
orr r0, r0, #0xff //这个式子就是把最后的八个位置为1,主要的工作就是先把0xff与R0进行逻辑
//或,然后把这个数存进R0中。其它的位保持不变,其意义: 置r0的bit[7:0]为1
//注意:这里的r1,是bic示例1运算后得到的r1=0x1000000
ldr r2, =0x14131440
orr r1, r1, r2 //r1与r2执行完这句之后得到r1的结果如下图3所示
下面用图形象说明orr用法示例2命令orr r1, r1, r2 的过程:
十六进制数(掩码)r2=0x14131440对应的二进制数而下图所示(掩码中置了某一位1,则这一位置1):
(图1 r2=0x14131440)
因此可以知道,掩码中置了上面二进制显示为1的bit,即对应r1=0x8000000(CLK_DIV0)中对应的bit位置1:
(图2 r1=0x80000000)
上面图1和图2执行完orr r1, r1, r2 后得到r1的结果如下(图3)所示
(图3 行完orr r1, r1, r2 后得到r1)
结合上面图2,可以看出那些bit置1,然后可以知道r2=0x14131440这个值的含义分析如下:
PCLK_PSYS = HCLK_PSYS / 2
HCLK_PSYS = MOUT_PSYS / 5
PCLK_DSYS = HCLK_DSYS / 2
HCLK_DSYS = MOUT_DSYS / 4
·······
HCLK_MSYS = ARMCLK / 5
ARMCLK = MOUT_MSYS / 1