/*
* __flush_dcache_all()
* Flush the wholeD-cache.
* Corrupted registers: x0-x7, x9-x11
*/
ENTRY(__flush_dcache_all)
//保证之前的访存指令的顺序
dsb sy
//读cache level id register
mrs x0, clidr_el1 // read clidr
//取bits[26:24](Level of Coherency for the cache hierarchy.)
//需要遵循cache一致性的cache层级(例如有3级cache,但2级需要做一致性)
and x3, x0, #0x7000000 // extract loc from clidr
//逻辑右移23位,把bits[26:24]放到bits[2:0]
lsr x3, x3, #23 // left align loc bit field
//如果需要做cache一致性的层级为0,则不需要flush,跳转到finished标记处。
cbz x3, finished // if loc is 0, then no need toclean
//x10存放cache级,从level0 cache开始做flush
//以下三个循环loop3是set/way(x9),
//loop2是index(x7),loop1是cache level(x10)
mov x10, #0 // start clean at cache level 0
loop1:
//x10+2后右移一位正好等于1,再加上x10本身正好等于3
//每执行一次loop1,x2+3*执行次数,目的在于把x0(clidr_el1)右移3位,
//取下一个cache的ctype type fields字段,clidr_el1的格式见《ARMv8 ARM》
add x2, x10, x10, lsr #1 /
//x0逻辑右移x2位,给x1,提取cache类型放到x1中,x0中存放:clidr_el1
lsr x1, x0, x2
//掩掉高位,只取当前cache类型
and x1, x1, #7
/* 判断当前cache是什么类型:
* 000 No cache.
* 001 Instruction cache only.
* 010 Data cache only.
* 011 Separate instruction and data caches.
* 100 Unified cache.
*/
//小于2说明data cache不存在或者只有icache,
//跳转skip执行,大于等于2继续执行
cmp x1, #2
b.lt skip
/*
* Save/disableand restore interrupts.
* .macro save_and_disable_irqs, olddaif
* mrs \olddaif,daif
* disable_irq
* .endm
*/
//保存daif到x9寄存器中,关闭中断
save_and_disable_irqs x9 // make CSSELR and CCSIDR access atomic
//选择当前cache级进行操作,csselr_el1寄存器bit[3:1]选择要操作的cache级
//第一次执行时x10=0,选择level 0级cache
msr csselr_el1,x10
//isb用于同步新的cs-s-r和csidr寄存器
isb
//因为执行了“msr csselr_el1,x10”,所以要重新读取ccsidr_el1
mrs x1, ccsidr_el1 // read the new ccsidr
/*