Skip to main content

xen/
macros.rs

1#[inline(always)]
2pub fn wmb() {
3    #[cfg(target_arch = "x86_64")]
4    unsafe {
5        core::arch::x86_64::_mm_sfence();
6    }
7
8    #[cfg(target_arch = "x86")]
9    unsafe {
10        core::arch::x86::_mm_sfence();
11    }
12
13    #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
14    {
15        core::sync::atomic::fence(core::sync::atomic::Ordering::Release);
16    }
17
18    core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::Release);
19}
20
21#[macro_export]
22macro_rules! xc_check_error {
23    ($handle:expr, $rc:expr) => {
24        if $rc < 0 {
25            let handle = $handle;
26            let rc = $rc;
27
28            unsafe {
29                let err = ::xen_sys::xc_get_last_error(handle);
30                let desc = ::xen_sys::xc_error_code_to_desc((*err).code as _);
31                return Err($crate::error::XenError::Xen($crate::error::XcError {
32                    rc,
33                    code: (*err).code as _,
34                    desc: ::std::ffi::CStr::from_ptr(desc).to_str().unwrap(),
35                    backtrace: ::std::backtrace::Backtrace::capture(),
36                }));
37            }
38        }
39    };
40}
41
42#[macro_export]
43macro_rules! __RD2 {
44    ($x:expr) => {
45        if $x as u32 & 0x00000002 != 0 {
46            0x2
47        }
48        else {
49            $x as u32 & 0x1
50        }
51    };
52}
53
54#[macro_export]
55macro_rules! __RD4 {
56    ($x:expr) => {
57        if $x as u32 & 0x0000000c != 0 {
58            $crate::__RD2!(($x) >> 2) << 2
59        }
60        else {
61            $crate::__RD2!($x)
62        }
63    };
64}
65
66#[macro_export]
67macro_rules! __RD8 {
68    ($x:expr) => {
69        if $x as u32 & 0x000000f0 != 0 {
70            $crate::__RD4!(($x) >> 4) << 4
71        }
72        else {
73            $crate::__RD4!($x)
74        }
75    };
76}
77
78#[macro_export]
79macro_rules! __RD16 {
80    ($x:expr) => {
81        if $x as u32 & 0x0000ff00 != 0 {
82            $crate::__RD8!(($x) >> 8) << 8
83        }
84        else {
85            $crate::__RD8!($x)
86        }
87    };
88}
89
90#[macro_export]
91macro_rules! __RD32 {
92    ($x:expr) => {
93        if $x as u32 & 0xffff0000 != 0 {
94            $crate::__RD16!(($x) >> 16) << 16
95        }
96        else {
97            $crate::__RD16!($x)
98        }
99    };
100}
101
102#[macro_export]
103macro_rules! __RING_SIZE {
104    ($s:expr, $sz:ident) => {{
105        let s = $s;
106        let sz = $sz;
107
108        unsafe {
109            $crate::__RD32!(
110                ((sz as usize + s as usize - (*s).ring.as_mut_ptr() as *const _ as usize)
111                    / ::std::mem::size_of_val(&*(*s).ring.as_ptr())) as u32
112            )
113        }
114    }};
115}
116
117#[macro_export]
118macro_rules! SHARED_RING_INIT {
119    ($s:expr) => {{
120        let s = $s as *mut ::xen_sys::vm_event_sring;
121
122        unsafe {
123            (*s).req_prod = 0;
124            (*s).rsp_prod = 0;
125            (*s).req_event = 1;
126            (*s).rsp_event = 1;
127            (*s).pvt.pvt_pad = std::mem::zeroed();
128            (*s).__pad = std::mem::zeroed();
129        }
130    }};
131}
132
133#[macro_export]
134macro_rules! BACK_RING_ATTACH {
135    ($r:ident, $s:ident, $i:expr, $size:ident) => {
136        let _s = $s as *mut ::xen_sys::vm_event_sring;
137
138        $r.rsp_prod_pvt = $i;
139        $r.req_cons = $i;
140        $r.nr_ents = $crate::__RING_SIZE!(_s, $size);
141        $r.sring = $s as _;
142    };
143}
144
145#[macro_export]
146macro_rules! BACK_RING_INIT {
147    ($r:ident, $s:ident, $size:ident) => {
148        $crate::BACK_RING_ATTACH!($r, $s, 0, $size);
149    };
150}
151
152#[macro_export]
153macro_rules! RING_SIZE {
154    ($r:expr) => {
155        $r.nr_ents
156    };
157}
158
159#[macro_export]
160macro_rules! RING_HAS_UNCONSUMED_REQUESTS {
161    ($r:expr) => {{
162        let r = $r;
163        let req = unsafe { (*(r.sring)).req_prod - r.req_cons };
164        let rsp = $crate::RING_SIZE!(r) - (r.req_cons - r.rsp_prod_pvt);
165        if req < rsp { req } else { rsp }
166    }};
167}
168
169#[macro_export]
170macro_rules! RING_GET_REQUEST {
171    ($r:expr, $idx:ident) => {{
172        let r = $r;
173
174        unsafe {
175            let ring_slice = (*r.sring).ring.as_slice(r.nr_ents as usize);
176            ring_slice[($idx & (r.nr_ents - 1)) as usize].req
177        }
178    }};
179}
180
181#[macro_export]
182macro_rules! RING_PUT_RESPONSE {
183    ($r:expr, $idx:expr, $value:expr) => {{
184        let r = $r;
185        let idx = $idx;
186        let value = $value;
187
188        unsafe {
189            let ring_slice = (*r.sring).ring.as_mut_slice(r.nr_ents as usize);
190            ring_slice[(idx & (r.nr_ents - 1)) as usize].rsp = value;
191        }
192    }};
193}
194
195#[macro_export]
196macro_rules! RING_PUSH_RESPONSES {
197    ($name1:expr) => {{
198        let name1 = $name1;
199
200        unsafe {
201            $crate::macros::wmb();
202            ::std::ptr::write_volatile(&mut (*(name1.sring)).rsp_prod, name1.rsp_prod_pvt);
203        }
204    }};
205}