在嵌入式系统中,cache位于CPU与DDR之间,是一段SRAM,读写性能远高于DDR,利用cache line提供了预取功能,平衡CPU与DDR之间的性能差异,提高系统的性能。
据我了解,ARM/PPC/MIPS三款主流嵌入式处理器都是软件管理cache,即有专门的指令来进行cache操作,如PPC的iccci icbi,ARM的CP15协处理器也提供对cache的操作。
cache的操作有2种:写回和无效。写回操作是将cache中数据写回到DDR中,无效操作是无效掉cache中原有数据,下次读取cache中数据时,需要从DDR中重新读取。这两种操作其实都是为了保证cache数据一致性。在kernel平台汇编代码中也封装了cache操作函数,这里以ARM v7处理器
3.4.55内核为例,在arch/arm/mm/cache-v7.S中就封装了cache的操作函数,其中v7_dma_flush_range刷新函数是完成了写回和无效2种操作。
其他平台(ARM MIPS)中cache操作函数也类似。
对cache敏感是因为在cache问题上被坑过2次。。。,其中一次在移植uboot时,没有注意cache,网卡dma始终不能工作,表面上dma描述符该配置的我都已经配置了,但是dma就是不能运行,在将uboot整个启动代码都过了一遍后我才考虑到是cache的问题,我写入的描述符数据并没有完全写入DDR中,而是cache住了,uboot对系统运行性能要求不高,索性将cache关掉,发现dma果然正常了。这个问题前后折腾了我半个多月,cache的问题实在不好查,读取写入DDR中的数据是完全正确的(因为读到的其实是cache中的数据),只能靠猜测推断这个问题原因。导致我现在一看到cache操作就紧张。
不扯题外话了,正因为嵌入式处理器软件管理cache,就需要我们代码主动去操作cache,但在内核开发中却很少会直接进行cache操作,那么kernel是在什么时候进行的cache操作。
首先想明白一点,为什么要进行cache操作,只能说cache是天使也是魔鬼。
cache在提高了系统性能同时却导致了数据的不一致性。嵌入式处理器软件管理cache的初衷就是保证数据一致性。
那什么地方需要保证数据一致性呢?