1use parking_lot::Mutex;
7use std::sync::Arc;
8use std::sync::Weak;
9use vmcore::interrupt::Interrupt;
10
11pub trait MsiInterruptTarget: Send + Sync {
13 fn new_interrupt(&self) -> Box<dyn MsiControl>;
15}
16
17pub trait MsiControl: Send {
19 fn enable(&mut self, address: u64, data: u32);
22
23 fn disable(&mut self);
26
27 fn signal(&mut self, address: u64, data: u32);
33
34 }
41
42impl<T: Send + FnMut(u64, u32)> MsiControl for T {
43 fn enable(&mut self, _address: u64, _data: u32) {}
44
45 fn disable(&mut self) {}
46
47 fn signal(&mut self, address: u64, data: u32) {
48 (*self)(address, data)
49 }
50}
51
52pub struct MsiInterruptSet {
55 interrupts: Vec<Weak<Mutex<MsiInterruptState>>>,
56}
57
58impl MsiInterruptSet {
59 pub fn new() -> Self {
61 Self {
62 interrupts: Vec::new(),
63 }
64 }
65
66 pub fn len(&self) -> usize {
68 self.interrupts.len()
69 }
70
71 pub fn connect(self, target: &dyn MsiInterruptTarget) {
74 for interrupt in self.interrupts.into_iter().filter_map(|i| i.upgrade()) {
75 let mut control = target.new_interrupt();
76 let mut state = interrupt.lock();
77 if let Some((address, data)) = state.address_data {
78 control.enable(address, data);
79 if state.pending {
80 control.signal(address, data);
81 state.pending = false;
82 }
83 }
84 state.control = Some(control);
85 }
86 }
87}
88
89pub trait RegisterMsi: Send {
91 fn new_msi(&mut self) -> MsiInterrupt;
93}
94
95impl RegisterMsi for MsiInterruptSet {
96 fn new_msi(&mut self) -> MsiInterrupt {
97 let state = Arc::new(Mutex::new(MsiInterruptState {
98 pending: false,
99 address_data: None,
100 control: None,
101 }));
102 self.interrupts.push(Arc::downgrade(&state));
103 MsiInterrupt { state }
104 }
105}
106
107pub struct MsiInterrupt {
109 state: Arc<Mutex<MsiInterruptState>>,
110}
111
112struct MsiInterruptState {
113 pending: bool,
114 address_data: Option<(u64, u32)>,
115 control: Option<Box<dyn MsiControl>>,
116}
117
118impl MsiInterrupt {
119 pub fn enable(&mut self, address: u64, data: u32, set_pending: bool) {
124 let mut state = self.state.lock();
125 let state = &mut *state;
126 state.pending |= set_pending;
127 state.address_data = Some((address, data));
128 if let Some(control) = &mut state.control {
129 control.enable(address, data);
130 if state.pending {
131 control.signal(address, data);
132 state.pending = false;
133 }
134 }
135 }
136
137 pub fn disable(&mut self) {
142 let mut state = self.state.lock();
143 state.address_data = None;
144 if let Some(control) = &mut state.control {
145 control.disable();
146 }
147 }
148
149 pub fn drain_pending(&mut self) -> bool {
151 let mut state = self.state.lock();
152 std::mem::take(&mut state.pending)
153 }
154
155 pub fn interrupt(&mut self) -> Interrupt {
157 let state = self.state.clone();
158 Interrupt::from_fn(move || {
159 let mut state = state.lock();
160 let state = &mut *state;
161 if let Some((control, (address, data))) = state.control.as_mut().zip(state.address_data)
162 {
163 control.signal(address, data);
164 } else {
165 state.pending = true;
166 }
167 })
168 }
169}