hyperlight_common/virtq/
event.rs1use bitflags::bitflags;
11use bytemuck::{Pod, Zeroable};
12
13use super::MemOps;
14
15bitflags! {
16 #[repr(transparent)]
17 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
18 pub struct EventFlags: u16 {
19 const ENABLE = 0x0;
21 const DISABLE = 0x1;
23 const DESC = 0x2;
25 }
26}
27
28#[repr(C)]
30#[derive(Clone, Copy, Debug, Pod, Zeroable, PartialEq, Eq, Hash)]
31pub struct EventSuppression {
32 off_wrap: u16,
34 flags: u16,
36}
37
38const _: () = assert!(core::mem::size_of::<EventSuppression>() == 4);
39const _: () = assert!(EventSuppression::WRAP_OFFSET == 0);
40const _: () = assert!(EventSuppression::FLAGS_OFFSET == 2);
41
42impl EventSuppression {
43 const FLAGS_MASK: u16 = 0x3;
44 const DESC_EVENT_OFF_MASK: u16 = 0x7FFF;
45 const DESC_EVENT_WRAP: u16 = 0x8000;
46
47 pub const SIZE: usize = core::mem::size_of::<Self>();
48 pub const ALIGN: usize = core::mem::align_of::<Self>();
49 pub const WRAP_OFFSET: usize = core::mem::offset_of!(Self, off_wrap);
50 pub const FLAGS_OFFSET: usize = core::mem::offset_of!(Self, flags);
51
52 pub fn new(off_wrap: u16, flags: EventFlags) -> Self {
54 Self {
55 off_wrap,
56 flags: flags.bits(),
57 }
58 }
59
60 pub fn flags(&self) -> EventFlags {
62 EventFlags::from_bits_truncate(self.flags & Self::FLAGS_MASK)
63 }
64
65 pub fn set_flags(&mut self, flags: EventFlags) {
67 self.flags = (self.flags & !Self::FLAGS_MASK) | (flags.bits() & Self::FLAGS_MASK);
68 }
69
70 pub fn desc_event_off(&self) -> u16 {
72 self.off_wrap & Self::DESC_EVENT_OFF_MASK
73 }
74
75 pub fn desc_event_wrap(&self) -> bool {
77 (self.off_wrap & Self::DESC_EVENT_WRAP) != 0
78 }
79
80 pub fn set_desc_event(&mut self, off: u16, wrap: bool) {
82 self.off_wrap =
83 (off & Self::DESC_EVENT_OFF_MASK) | if wrap { Self::DESC_EVENT_WRAP } else { 0 };
84 }
85
86 pub fn read_flags_acquire<M: MemOps>(mem: &M, addr: u64) -> Result<EventFlags, M::Error> {
93 let flags = mem.load_acquire(addr + Self::FLAGS_OFFSET as u64)?;
95 Ok(EventFlags::from_bits_truncate(flags))
96 }
97
98 pub fn read_body<M: MemOps>(mem: &M, addr: u64, flags: EventFlags) -> Result<Self, M::Error> {
105 let off_wrap: u16 = mem.read_val(addr + Self::WRAP_OFFSET as u64)?;
106
107 Ok(Self {
108 off_wrap,
109 flags: flags.bits(),
110 })
111 }
112
113 pub fn write_release<M: MemOps>(&self, mem: &M, addr: u64) -> Result<(), M::Error> {
119 mem.write_val(addr + Self::WRAP_OFFSET as u64, self.off_wrap)?;
120 mem.store_release(addr + Self::FLAGS_OFFSET as u64, self.flags)?;
122 Ok(())
123 }
124}