描述
在特定于Cortex-A9微体系结构的某些时序环境下,对Uncacheable,可共享正常内存区域的写入请求可能会执行两次,导致写入请求在AXI总线上发送两次。
解
当写入请求之后是另一次写入相同的自然对齐的双字存储区域,而在两次写入之间没有DMB时,可能会发生这种情况。不能将第二个写请求执行到与第一个存储完全相同的字节。除非重复写入用于同步目的,否则重复写入通常不会影响系统的整体行为。
在以下情况下,对正常内存区域的写入请求将被视为Uncacheable:
- 禁用数据高速缓存时发生写入请求。
- 写请求的目标是标记为正常内存不可缓存或可缓存写入的内存区域。
- 写请求的目标是标记为正常内存可缓存回写和可共享的内存区域,并且CPU处于AMP模式。
此行为可能会影响多主系统,其中控制信息使用通信变量(例如信号量)在内存中的多个处理元件之间传递。在这样的系统中,通常使用加载专用/存储专用来声明通信变量,但是使用非专用存储来清除通信变量。由于此故障,清除此类通信变量可能会发生两次。这可能导致两个主人显然声称通信变量,因此可能导致共享数据的数据损坏。
可能发生这种情况的情况是:
MOV r1,#0x40;地址是双字对齐,映射
;在普通不可缓存的共享内存中
循环:LDREX r5,[r1,#0x0];阅读通信变量
CMP r5,#0;检查是否为0
STREXEQ r5,r0,[r1];试图存储新的价值
CMPEQ r5,#0;测试存储是否成功
BNE Loop;如果没有重试
DMB;确保所有后续访问
;获得的时候会被观察到
;已观察到通信变量
;现在可以执行关键区域中的加载和存储
MOV r2,#0
MOV r0,#0
DMB;确保遵守以前的所有访问
;在通信变量被清除之前
STR r0,[r1];用正常存储清除通信变量
STR r2,[r1,#0x4]
;之前的STR可能会合并并再次发送,这可能会
;导致不希望的通信变量释放。
当通信变量是字节,半字或单词时,此方案有效。
详细的解决方法:
有几种可能的解决方法:
1)清除通信变量后添加DMB:
STR r0,[r1];清除通讯变量
DMB;确保之前的STR已完成
此外,任何IRQ或FIQ处理程序必须在开始时执行DMB,以确保完成任何通信变量的清除。
2)确保没有其他数据使用与通信变量相同的自然对齐的64位内存位置:
ALIGN 64
communication_variable DCD 0
unused_data DCD 0
LDR r1,= communication_variable
3)使用Store-Exclusive来清除通信变量,而不是非独占商店。
影响: | 次要。 |
解决方法: | 有几个,请参阅详细的解决方法。 |
受影响的配置: | 使用CPU的系统。 |
受影响的器件版本: | 所有。没有计划修复。请参阅(Xilinx答复47916) – Zynq-7000 SoC芯片版本差异。 |
修订记录
05/16/2013 – 初始版本
没有回复内容