基本概念
飞腾CPU采用的弱顺序模型,因此程序执行的结果可能不正确,特别是涉及到多处理器编程或设备驱动编程的情况。
飞腾CPU提供ISB、DMB和DSB三种顺序保证指令,很多时候,顺序保证指令又称为屏障指令。
- ISB指令,主要是保证ISB指令之后的所有程序代码指令是在ISB指令执行完成后才从指令缓冲或内存中取指。一般说来,缓冲和TLB的操作之后,或者在访问系统寄存器之后,插入ISB指令,确保在ISB指令之后,前面的操作全部有效。
- DMB指令,主要是保证DBM指令前后的某种类型访存指令的执行必须遵守顺序。DMB指令并不保证前后访存指令完成的顺序。
- DSB指令,主要是保证DSB指令之前的某种类型访存指令必须在DSB指令完成之前完成。
顺序保证指令DMB和DSB,一般有两方面因素需要考虑:
- 范围,即在定义的范围内保证顺序性。armv8定义了四种范围,最大是全系统范围,依次是外部共享范围、内部共享范围和非共享范围。
- 访存指令类型,即哪些访存指令需要保证顺序性。
范围 | 约束的访存类型 | |
sy | 全系统范围 | 读、写 |
st | 全系统范围 | 写 |
ld | 全系统范围 | 读 |
osh | 外部共享范围 | 读、写 |
oshst | 外部共享范围 | 写 |
oshld | 外部共享范围 | 读 |
ish | 内部共享范围 | 读、写 |
ishst | 内部共享范围 | 写 |
ishld | 内部共享范围 | 读 |
nsh | 非共享范围 | 读、写 |
nshst | 非共享范围 | 写 |
nshld | 非共享范围 | 读 |
ISB
#define isb() asm volatile("isb" : : : "memory")
DMB
#define dmb(opt) asm volatile("dmb " #opt : : : "memory")
#define __smp_mb() dmb(ish)
#define __smp_rmb() dmb(ishld)
#define __smp_wmb() dmb(ishst)
#define dma_mb() dmb(osh)
#define dma_rmb() dmb(oshld)
#define dma_wmb() dmb(oshst)
DSB
#define dsb(opt) asm volatile("dsb " #opt : : : "memory")
#define mb() dsb(sy)
#define rmb() dsb(ld)
#define wmb() dsb(st)