1use super::PciCapability;
7use crate::msi::MsiInterrupt;
8use crate::msi::RegisterMsi;
9use crate::spec::caps::CapabilityId;
10use crate::spec::caps::msi::MsiCapabilityHeader;
11use inspect::Inspect;
12use inspect::InspectMut;
13use parking_lot::Mutex;
14use std::fmt::Debug;
15use std::sync::Arc;
16use vmcore::interrupt::Interrupt;
17
18#[derive(Debug, Inspect)]
20pub struct MsiCapability {
21 #[inspect(with = "|x| inspect::adhoc(|req| x.lock().inspect_mut(req))")]
22 state: Arc<Mutex<MsiCapabilityState>>,
23 addr_64bit: bool,
24 per_vector_masking: bool,
25}
26
27#[derive(Debug, InspectMut)]
28struct MsiCapabilityState {
29 enabled: bool,
30 multiple_message_enable: u8, multiple_message_capable: u8, address: u64,
33 data: u16,
34 mask_bits: u32,
35 pending_bits: u32,
36 interrupt: Option<MsiInterrupt>,
37}
38
39impl MsiCapabilityState {
40 fn new(multiple_message_capable: u8, _addr_64bit: bool, per_vector_masking: bool) -> Self {
41 Self {
42 enabled: false,
43 multiple_message_enable: 0,
44 multiple_message_capable,
45 address: 0,
46 data: 0,
47 mask_bits: if per_vector_masking { 0xFFFFFFFF } else { 0 },
48 pending_bits: 0,
49 interrupt: None,
50 }
51 }
52
53 fn control_register(&self, addr_64bit: bool, per_vector_masking: bool) -> u32 {
54 let mut control = 0u32;
55 control |= (self.multiple_message_capable as u32) << 1; control |= (self.multiple_message_enable as u32) << 4; if addr_64bit {
58 control |= 1 << 7; }
60 if per_vector_masking {
61 control |= 1 << 8; }
63 if self.enabled {
64 control |= 1 << 0; }
66 control
67 }
68}
69
70impl MsiCapability {
71 pub fn new(
79 multiple_message_capable: u8,
80 addr_64bit: bool,
81 per_vector_masking: bool,
82 register_msi: &mut dyn RegisterMsi,
83 ) -> Self {
84 assert!(multiple_message_capable <= 5, "MMC must be 0-5");
85
86 let interrupt = register_msi.new_msi();
87 let state = MsiCapabilityState {
88 interrupt: Some(interrupt),
89 ..MsiCapabilityState::new(multiple_message_capable, addr_64bit, per_vector_masking)
90 };
91
92 Self {
93 state: Arc::new(Mutex::new(state)),
94 addr_64bit,
95 per_vector_masking,
96 }
97 }
98
99 pub fn interrupt(&self) -> Option<Interrupt> {
101 self.state.lock().interrupt.as_mut().map(|i| i.interrupt())
102 }
103
104 fn len_bytes(&self) -> usize {
105 let mut len = 8; if self.addr_64bit {
107 len += 4; }
109 len += 2; if self.per_vector_masking {
111 len += 8; }
113 (len + 3) & !3
115 }
116}
117
118impl PciCapability for MsiCapability {
119 fn label(&self) -> &str {
120 "msi"
121 }
122
123 fn capability_id(&self) -> CapabilityId {
124 CapabilityId::MSI
125 }
126
127 fn len(&self) -> usize {
128 self.len_bytes()
129 }
130
131 fn read_u32(&self, offset: u16) -> u32 {
132 let state = self.state.lock();
133
134 match MsiCapabilityHeader(offset) {
135 MsiCapabilityHeader::CONTROL_CAPS => {
136 let control_reg = state.control_register(self.addr_64bit, self.per_vector_masking);
137 CapabilityId::MSI.0 as u32 | (control_reg << 16)
138 }
139 MsiCapabilityHeader::MSG_ADDR_LO => state.address as u32,
140 MsiCapabilityHeader::MSG_ADDR_HI if self.addr_64bit => (state.address >> 32) as u32,
141 MsiCapabilityHeader::MSG_DATA_32 if !self.addr_64bit => state.data as u32,
142 MsiCapabilityHeader::MSG_DATA_64 if self.addr_64bit => state.data as u32,
143 MsiCapabilityHeader::MASK_BITS if self.addr_64bit && self.per_vector_masking => {
144 state.mask_bits
145 }
146 MsiCapabilityHeader::PENDING_BITS if self.addr_64bit && self.per_vector_masking => {
147 state.pending_bits
148 }
149 _ => {
150 tracelimit::warn_ratelimited!("Unexpected MSI read offset {:#x}", offset);
151 0
152 }
153 }
154 }
155
156 fn write_u32(&mut self, offset: u16, val: u32) {
157 let mut state = self.state.lock();
158
159 match MsiCapabilityHeader(offset) {
160 MsiCapabilityHeader::CONTROL_CAPS => {
161 let control_val = (val >> 16) & 0xFFFF;
162 let old_enabled = state.enabled;
163 let new_enabled = control_val & 1 != 0;
164 let mme = ((control_val >> 4) & 0x7) as u8;
165
166 state.multiple_message_enable = mme.min(state.multiple_message_capable);
168 state.enabled = new_enabled;
169
170 let address = state.address;
172 let data = state.data as u32;
173 if let Some(ref mut interrupt) = state.interrupt {
174 if new_enabled && !old_enabled {
175 interrupt.enable(address, data, false);
177 } else if !new_enabled && old_enabled {
178 interrupt.disable();
180 }
181 }
182 }
183 MsiCapabilityHeader::MSG_ADDR_LO => {
184 state.address = (state.address & 0xFFFFFFFF00000000) | (val as u64);
185
186 if state.enabled {
188 let address = state.address;
189 let data = state.data as u32;
190 if let Some(ref mut interrupt) = state.interrupt {
191 interrupt.enable(address, data, false);
192 }
193 }
194 }
195 MsiCapabilityHeader::MSG_ADDR_HI if self.addr_64bit => {
196 state.address = (state.address & 0xFFFFFFFF) | ((val as u64) << 32);
197
198 if state.enabled {
200 let address = state.address;
201 let data = state.data as u32;
202 if let Some(ref mut interrupt) = state.interrupt {
203 interrupt.enable(address, data, false);
204 }
205 }
206 }
207 MsiCapabilityHeader::MSG_DATA_32 if !self.addr_64bit => {
208 state.data = val as u16;
209
210 if state.enabled {
212 let address = state.address;
213 let data = state.data as u32;
214 if let Some(ref mut interrupt) = state.interrupt {
215 interrupt.enable(address, data, false);
216 }
217 }
218 }
219 MsiCapabilityHeader::MSG_DATA_64 if self.addr_64bit => {
220 state.data = val as u16;
221
222 if state.enabled {
224 let address = state.address;
225 let data = state.data as u32;
226 if let Some(ref mut interrupt) = state.interrupt {
227 interrupt.enable(address, data, false);
228 }
229 }
230 }
231 MsiCapabilityHeader::MASK_BITS if self.addr_64bit && self.per_vector_masking => {
232 state.mask_bits = val;
233 }
234 MsiCapabilityHeader::PENDING_BITS if self.addr_64bit && self.per_vector_masking => {
235 tracelimit::warn_ratelimited!(
237 "Write to MSI pending bits register (typically read-only)"
238 );
239 }
240 _ => {
241 tracelimit::warn_ratelimited!("Unexpected MSI write offset {:#x}", offset);
242 }
243 }
244 }
245
246 fn reset(&mut self) {
247 let mut state = self.state.lock();
248
249 if state.enabled {
251 if let Some(ref mut interrupt) = state.interrupt {
252 interrupt.disable();
253 }
254 }
255
256 state.enabled = false;
258 state.multiple_message_enable = 0;
259 state.address = 0;
260 state.data = 0;
261 if self.per_vector_masking {
262 state.mask_bits = 0;
263 state.pending_bits = 0;
264 }
265 }
266}
267
268mod save_restore {
269 use super::*;
270 use thiserror::Error;
271 use vmcore::save_restore::RestoreError;
272 use vmcore::save_restore::SaveError;
273 use vmcore::save_restore::SaveRestore;
274
275 mod state {
276 use mesh::payload::Protobuf;
277 use vmcore::save_restore::SavedStateRoot;
278
279 #[derive(Debug, Protobuf, SavedStateRoot)]
280 #[mesh(package = "pci.caps.msi")]
281 pub struct SavedState {
282 #[mesh(1)]
283 pub enabled: bool,
284 #[mesh(2)]
285 pub multiple_message_enable: u8,
286 #[mesh(3)]
287 pub address: u64,
288 #[mesh(4)]
289 pub data: u16,
290 #[mesh(5)]
291 pub mask_bits: u32,
292 #[mesh(6)]
293 pub pending_bits: u32,
294 }
295 }
296
297 #[derive(Debug, Error)]
298 enum MsiRestoreError {
299 #[error("invalid multiple message enable value: {0}")]
300 InvalidMultipleMessageEnable(u8),
301 }
302
303 impl SaveRestore for MsiCapability {
304 type SavedState = state::SavedState;
305
306 fn save(&mut self) -> Result<Self::SavedState, SaveError> {
307 let state = self.state.lock();
308 Ok(state::SavedState {
309 enabled: state.enabled,
310 multiple_message_enable: state.multiple_message_enable,
311 address: state.address,
312 data: state.data,
313 mask_bits: state.mask_bits,
314 pending_bits: state.pending_bits,
315 })
316 }
317
318 fn restore(&mut self, saved_state: Self::SavedState) -> Result<(), RestoreError> {
319 let state::SavedState {
320 enabled,
321 multiple_message_enable,
322 address,
323 data,
324 mask_bits,
325 pending_bits,
326 } = saved_state;
327
328 if multiple_message_enable > 5 {
329 return Err(RestoreError::InvalidSavedState(
330 MsiRestoreError::InvalidMultipleMessageEnable(multiple_message_enable).into(),
331 ));
332 }
333
334 let mut state = self.state.lock();
335
336 if state.enabled {
338 if let Some(ref mut interrupt) = state.interrupt {
339 interrupt.disable();
340 }
341 }
342
343 state.enabled = enabled;
345 state.multiple_message_enable =
346 multiple_message_enable.min(state.multiple_message_capable);
347 state.address = address;
348 state.data = data;
349 state.mask_bits = mask_bits;
350 state.pending_bits = pending_bits;
351
352 if state.enabled {
354 let address = state.address;
355 let data = state.data as u32;
356 if let Some(ref mut interrupt) = state.interrupt {
357 interrupt.enable(address, data, false);
358 }
359 }
360
361 Ok(())
362 }
363 }
364}
365
366#[cfg(test)]
367mod tests {
368 use super::*;
369 use crate::msi::MsiInterruptSet;
370 use crate::test_helpers::TestPciInterruptController;
371
372 #[test]
373 fn msi_check() {
374 let mut set = MsiInterruptSet::new();
375 let mut cap = MsiCapability::new(2, true, false, &mut set); let msi_controller = TestPciInterruptController::new();
377 set.connect(&msi_controller);
378
379 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0); assert_eq!(cap.read_u32(8), 0); assert_eq!(cap.read_u32(12), 0); cap.write_u32(4, 0x12345678);
390 cap.write_u32(8, 0x9abcdef0);
391 cap.write_u32(12, 0x1234);
392
393 assert_eq!(cap.read_u32(4), 0x12345678);
394 assert_eq!(cap.read_u32(8), 0x9abcdef0);
395 assert_eq!(cap.read_u32(12), 0x1234);
396
397 cap.write_u32(0, 0x00110005); assert_eq!(cap.read_u32(0), 0x00950005); cap.reset();
403 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0);
405 assert_eq!(cap.read_u32(8), 0);
406 assert_eq!(cap.read_u32(12), 0);
407 }
408
409 #[test]
410 fn msi_32bit_check() {
411 let mut set = MsiInterruptSet::new();
412 let mut cap = MsiCapability::new(1, false, false, &mut set); let msi_controller = TestPciInterruptController::new();
414 set.connect(&msi_controller);
415
416 assert_eq!(cap.read_u32(0), 0x00020005); cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x1234); assert_eq!(cap.read_u32(4), 0x12345678);
424 assert_eq!(cap.read_u32(8), 0x1234);
425 }
426
427 #[test]
428 fn test_msi_save_restore() {
429 use vmcore::save_restore::SaveRestore;
430
431 let mut set = MsiInterruptSet::new();
432 let mut cap = MsiCapability::new(2, true, false, &mut set); let msi_controller = TestPciInterruptController::new();
434 set.connect(&msi_controller);
435
436 cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x9abcdef0); cap.write_u32(12, 0x5678); cap.write_u32(0, 0x00110001); assert_eq!(cap.read_u32(0), 0x00950005); assert_eq!(cap.read_u32(4), 0x12345678);
445 assert_eq!(cap.read_u32(8), 0x9abcdef0);
446 assert_eq!(cap.read_u32(12), 0x5678);
447
448 let saved_state = cap.save().expect("save should succeed");
450
451 cap.reset();
453 assert_eq!(cap.read_u32(0), 0x00840005); assert_eq!(cap.read_u32(4), 0);
455 assert_eq!(cap.read_u32(8), 0);
456 assert_eq!(cap.read_u32(12), 0);
457
458 cap.restore(saved_state).expect("restore should succeed");
460
461 assert_eq!(cap.read_u32(0), 0x00950005); assert_eq!(cap.read_u32(4), 0x12345678);
464 assert_eq!(cap.read_u32(8), 0x9abcdef0);
465 assert_eq!(cap.read_u32(12), 0x5678);
466 }
467
468 #[test]
469 fn test_msi_save_restore_32bit_with_masking() {
470 use vmcore::save_restore::SaveRestore;
471
472 let mut set = MsiInterruptSet::new();
473 let mut cap = MsiCapability::new(3, false, true, &mut set); let msi_controller = TestPciInterruptController::new();
475 set.connect(&msi_controller);
476
477 cap.write_u32(4, 0x87654321); cap.write_u32(8, 0x1234); cap.write_u32(12, 0xaaaabbbb); cap.write_u32(0, 0x00210001); let control_reg = cap.read_u32(0);
485 let control_val = (control_reg >> 16) & 0xFFFF;
486 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(cap.read_u32(4), 0x87654321);
489 assert_eq!(cap.read_u32(8), 0x1234);
490
491 let saved_state = cap.save().expect("save should succeed");
493
494 cap.write_u32(4, 0x11111111);
496 cap.write_u32(8, 0x9999);
497 cap.write_u32(0, 0x00000005); let control_reg = cap.read_u32(0);
501 let control_val = (control_reg >> 16) & 0xFFFF;
502 assert_eq!(control_val & 1, 0); assert_eq!(cap.read_u32(4), 0x11111111);
504 assert_eq!(cap.read_u32(8), 0x9999);
505
506 cap.restore(saved_state).expect("restore should succeed");
508
509 let control_reg = cap.read_u32(0);
511 let control_val = (control_reg >> 16) & 0xFFFF;
512 assert!(control_val & 1 != 0); assert_eq!((control_val >> 4) & 0x7, 2); assert_eq!(cap.read_u32(4), 0x87654321);
515 assert_eq!(cap.read_u32(8), 0x1234);
516 }
517
518 #[test]
519 fn test_msi_save_restore_mme_clamping() {
520 use vmcore::save_restore::SaveRestore;
521
522 let mut set = MsiInterruptSet::new();
523 let mut cap = MsiCapability::new(1, true, false, &mut set); let msi_controller = TestPciInterruptController::new();
525 set.connect(&msi_controller);
526
527 cap.write_u32(4, 0x12345678); cap.write_u32(8, 0x9abcdef0); cap.write_u32(12, 0x5678); cap.write_u32(0, 0x00310001); let control_reg = cap.read_u32(0);
535 let control_val = (control_reg >> 16) & 0xFFFF;
536 let mme = (control_val >> 4) & 0x7;
537 assert_eq!(mme, 1); let saved_state = cap.save().expect("save should succeed");
541
542 cap.reset();
544
545 cap.restore(saved_state).expect("restore should succeed");
547
548 let control_reg = cap.read_u32(0);
550 let control_val = (control_reg >> 16) & 0xFFFF;
551 let mme = (control_val >> 4) & 0x7;
552 let enabled = control_val & 1 != 0;
553 assert_eq!(mme, 1); assert!(enabled); assert_eq!(cap.read_u32(4), 0x12345678);
556 assert_eq!(cap.read_u32(8), 0x9abcdef0);
557 assert_eq!(cap.read_u32(12), 0x5678);
558 }
559}