今天在看power项目的嵌入式代码的时候发现在源代码中有这么一行引起了注意,之前有了解过cpu屏障,但是还真没有实操和应用于项目中,了解一下即可,如图:

【genius_platform软件平台开发】第七十三讲:linux系统驱动开发之-中断处理之DSB指令_DMB


【genius_platform软件平台开发】第七十三讲:linux系统驱动开发之-中断处理之DSB指令_数据同步_02

1. 概述

  • 这里涉及到了一些汇编的知识,对于一些结构比较复杂的存储器系统而言,特别是带流水线和写缓冲的系统,在 这类系统中,如果没有必要的隔离指令,会导致系统发生紊乱危象(race condition)。
  • 举个例子:当我们在程序运行时修改某个存储器的值或者其映射关系时,最好在更改之后立即补上一条 DSB 指令(数据同步指令)。因为我们刚才的写操作很可能会被放到一个写缓冲中。为了提高存储器的访问效率而设计的,它也有副作用,就是会导致写内存的指令被延迟几个周期执行,因此对存储器的设置有可能不能即刻生效,这就导致紧接着的下一 条指令仍然使用旧的存储器的值。

2. 隔离指令

指令名

功能描述

DMB

数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。

DSB

数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访 问操作——译者注)

ISB

指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。

  • DMB 在双口 RAM 以及多核架构的操作中很有用。如果 RAM 的访问是带缓冲的,并且写完之后马上读,就必须让它“喘口气”——用 DMB 指令来隔离,以保证缓冲中的数据已经落实到 RAM 中。
  • DSB 比 DMB 更保险(当然也是有执行代价的),它是宁可错杀也不漏网——清空了写缓冲,使得任何它后面的指令,不管要不要使用先前的存储器访问结果,通通等待访问完成。大虾们可以在有绝对信心时使用DMB,新手还是使用DSB比较保险。
  • 同 DMB/DSB 相比,ISB 指令看起来似乎最强悍,但是却一身都是“愣劲”,不由分说就“动粗”。不过它还有其它的用场——对于高级底层技巧:“自我更新”(self-mofifying)代码,非常有用。举例来说,如果某个程序从下一条要执行的指令处更新了自己,但是先前的旧指令已经被预取到流水线中去了,此时就必须清洗流水线,把旧版本的指令洗出去,再预取新版本的指令。因此,必须在被更新代码段的前面使用 ISB,以保证旧的代码从流水线中被清洗出去,不再有机会执行(现实编程中应该极少会用到,因此读者不必太钻它)。