1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 引用: ACLE 的第 7.4 节 "Hints" 部分

// CP15 指令
#[cfg(not(any(
    // v8
    target_arch = "aarch64",
    // v7
    target_feature = "v7",
    // v6-M
    target_feature = "mclass"
)))]
mod cp15;

#[cfg(not(any(
    target_arch = "aarch64",
    target_feature = "v7",
    target_feature = "mclass"
)))]
pub use self::cp15::*;

// 专用指令
#[cfg(any(
    target_arch = "aarch64",
    target_feature = "v7",
    target_feature = "mclass"
))]
macro_rules! dmb_dsb {
    ($A:ident) => {
        impl super::super::sealed::Dmb for $A {
            #[inline(always)]
            unsafe fn __dmb(&self) {
                super::dmb(super::arg::$A)
            }
        }

        impl super::super::sealed::Dsb for $A {
            #[inline(always)]
            unsafe fn __dsb(&self) {
                super::dsb(super::arg::$A)
            }
        }
    };
}

#[cfg(any(
    target_arch = "aarch64",
    target_feature = "v7",
    target_feature = "mclass"
))]
mod common;

#[cfg(any(
    target_arch = "aarch64",
    target_feature = "v7",
    target_feature = "mclass"
))]
pub use self::common::*;

#[cfg(any(target_arch = "aarch64", target_feature = "v7",))]
mod not_mclass;

#[cfg(any(target_arch = "aarch64", target_feature = "v7",))]
pub use self::not_mclass::*;

#[cfg(target_arch = "aarch64")]
mod v8;

#[cfg(target_arch = "aarch64")]
pub use self::v8::*;

/// 生成 DMB (数据存储屏障) 指令或等效的 CP15 指令。
///
/// DMB 确保观察到的内存访问顺序。
/// 确保在 DMB 之后发出的内存访问之前 (指定的作用域中) 观察到 DMB 之前发出的指定类型的内存访问。
///
///
/// 例如,应在存储数据和更新标志变量之间使用 DMB,该标志变量使该数据可用于另一个内核。
///
/// __dmb() 内部函数还充当适当类型的编译器内存屏障。
///
#[inline(always)]
pub unsafe fn __dmb<A>(arg: A)
where
    A: super::sealed::Dmb,
{
    arg.__dmb()
}

/// 生成 DSB (数据同步屏障) 指令或等效的 CP15 指令。
///
/// DSB 确保完成内存访问。DSB 的行为等同于 DMB,并具有其他属性。
/// DSB 指令完成后,保证在 DSB 之前发出的所有指定类型的内存访问都已完成。
///
///
/// __dsb() 内部函数还充当适当类型的编译器内存屏障。
#[inline(always)]
pub unsafe fn __dsb<A>(arg: A)
where
    A: super::sealed::Dsb,
{
    arg.__dsb()
}

/// 生成一个 ISB (指令同步屏障) 指令或等效的 CP15 指令。
///
/// 此指令刷新处理器管道提取缓冲区,以便从高速缓存或内存中提取后续指令。
///
/// 在进行一些系统维护操作后,需要一个 ISB。
/// 在将控制权转移到已在内存中加载或修改的代码之前 (例如通过覆盖机制或即时代码生成器),还需要 ISB。
///
/// (请注意,如果指令缓存和数据缓存是分开的,则需要权限缓存维护操作来统一缓存。)
///
/// __isb() 内部函数唯一支持的参数是 15,对应于 ISB 指令的 SY (完整系统) 作用域。
///
///
///
#[inline(always)]
pub unsafe fn __isb<A>(arg: A)
where
    A: super::sealed::Isb,
{
    arg.__isb()
}

extern "unadjusted" {
    #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dmb")]
    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dmb")]
    fn dmb(_: i32);

    #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dsb")]
    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dsb")]
    fn dsb(_: i32);

    #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.isb")]
    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.isb")]
    fn isb(_: i32);
}

// 我们将它们放在一个模块中,以防止全局重导出怪异
mod arg {
    // 请参见第 7.3 节 `ACLE 的存储屏障`
    pub const SY: i32 = 15;
    pub const ST: i32 = 14;
    pub const LD: i32 = 13;
    pub const ISH: i32 = 11;
    pub const ISHST: i32 = 10;
    pub const ISHLD: i32 = 9;
    pub const NSH: i32 = 7;
    pub const NSHST: i32 = 6;
    pub const NSHLD: i32 = 5;
    pub const OSH: i32 = 3;
    pub const OSHST: i32 = 2;
    pub const OSHLD: i32 = 1;
}