Zynq-7000 SoC,APU - 对Uncacheable,可共享正常内存区域的写入请求可能会执行两次,可能导致软件同步问题

描述

在特定于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 - 初始版本

编辑 重设标签(回车键确认) 标为违禁 关闭 合并 删除

提问于 2018-07-31 13:11:09 +0800

这个帖子被标记为一个社区wiki

这个帖子是一个wiki(维基). 任何一个积分 >500的人都可以完善它