153行-156行
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
bl cpu_init_crit
#endif
ENTRY(cpu_init_cp15)
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
#endif
mcr p15, 0, r0, c1, c0, 0
mov pc, lr @ back to my caller
ENDPROC(cpu_init_cp15)
一、Invalidate L1 I/D 含义是:为了清除ARM中的icache,因为此时它缓存的指令不是有效的,有可能在启动过程中发生改变,所以必须先清除。
二、mov r0, #0 @ set up for MCR
将r0寄存器清零。
三、mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
将r0数据写入到协处理器寄存器c8, c7, 0中,表示使虚拟内存管理无效。
四、mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
清除icache缓存的指令。下面的手册是2011版本,将2008版本的图改成了表格形式。
手册中的Ignore表示,往此寄存器写0或者写1都是将icache中缓存清空。
本指令是将r0=0写入到此寄存器。
invalidate 含义:将icache的有效标志位置为0,读取指令的时候就不会从icache中读取了。
flush含义:是将icache中所有数据清空。
五、mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
此指令表示使Branch Predictor无效。因为icache缓存无效之后,分支预测机制也就没有意义了。
六、DSB和ISB。
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
DSB:数据同步隔离。在多核处理器中,多个核共享同一块内存,当一个核改变了内存中的数据后,别的CPU的cache中可能还缓存着内存改变之前的数据,所以需要做特别的指令处理。DSB清空了写缓冲,使得任何它后面的指令,不管要不要使用先前的存储器访问结果,通通等待访问完成。
ISB:指令同步隔离。清空数据流水线缓存,让CPU重新从cache中或者内存中取指令。
七、
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
将协处理器中 c1, c0, 0寄存器的值写入到r0寄存器。再将第13位清零。
八、
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
九、
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache