工作中遇到多个master之间的数据传递,牵扯到cache的操作,这里做一个总结。有什么问题,欢迎评论区指点和交流。
这里主要关注的是ACPU的cache,以ACPU和CE(Crypto Engine)之间的数据传递为例。下面分别介绍正确的cache操作流程,以及错误的操作如何导致数据不一致。
1. ACPU和CE之间的通信
1.1. ACPU 向 CE传递加密数据
- ACPU prepares the data to a DDR memory
- ACPU do the cache operation of clean
- CE get the data from physical address
1.2. ACPU从 CE获取解密数据
- ACPU allocates a buffer from DDR
- ACPU invalidates the cache of the buffer
- CE receives the command and decrypt data to the buffer
- ACPU invalidates the buffer again and fetch the data from the buffer
2. CacheLine对齐
在做cache操作,建议做到start address和size与cacheline对齐。
通常ARM处理的cacheline size是64Bytes。下面介绍cacheline不对齐可能导致的问题。
2.1. Invalidate
假设有两个buffer,buf1[32] 和buf2[32] 在同一个cacheline里。
uint8_t buf1[32];
uint8_t buf2[32];
将两个buffer都初始化成0.
memset(buf1, 0, 32);
memset(buf2, 0, 32);
先把buf2的数据设置成0x5a
memset(buf2, 0x5a, 32);
然后invalidate buf1。
invdalidate(buf1, 32);
在invalidate buf1的数据时,buf2的数据有可能还在cache里,没有回写到DDR。invalidate buf1这个操作将作用于整个cacheline,会导致丢失buf2的数据。
2.2. Clean
同样假设两个buffer,buf1[32] and buf2[32] 在同一个cacheline里。
uint8_t buf1[32];
uint8_t buf2[32];
将两个buffer都初始化成0.
memset(buf1, 0, 32);
memset(buf2, 0, 32);
然后ACPU从buf1读数据,这样整个cacheline的数据都会读到cache里。CE 向buf2中写数据. 例如将整个buf2 32bytes都设置成0x5a.
memset(buf2, 0x5a, 32);
然后clean buf1.
clean(buf1, 32);
在clean buf1的数据时,clean操作将作用于整个cacheline ,而cacheline中所有的数据都是0,这样buf2的数据将会被回写全0.