pci_core/capabilities/
read_only.rs1use super::PciCapability;
7use inspect::Inspect;
8use std::fmt::Debug;
9use zerocopy::Immutable;
10use zerocopy::IntoBytes;
11use zerocopy::KnownLayout;
12
13#[derive(Debug)]
15pub struct ReadOnlyCapability<T> {
16 label: String,
17 data: T,
18}
19
20impl<T: IntoBytes + Immutable + KnownLayout> ReadOnlyCapability<T> {
21 pub fn new(label: impl Into<String>, data: T) -> Self {
23 Self {
24 label: label.into(),
25 data,
26 }
27 }
28}
29
30impl<T: Debug> Inspect for ReadOnlyCapability<T> {
31 fn inspect(&self, req: inspect::Request<'_>) {
32 req.respond()
33 .field("label", &self.label)
34 .display_debug("data", &self.data);
35 }
36}
37
38impl<T> PciCapability for ReadOnlyCapability<T>
39where
40 T: IntoBytes + Send + Sync + Debug + Immutable + KnownLayout,
41{
42 fn label(&self) -> &str {
43 &self.label
44 }
45
46 fn len(&self) -> usize {
47 size_of::<T>()
48 }
49
50 fn read_u32(&self, offset: u16) -> u32 {
51 if offset as usize + 4 <= self.len() {
52 let offset = offset.into();
53 u32::from_ne_bytes(self.data.as_bytes()[offset..offset + 4].try_into().unwrap())
54 } else {
55 !0
56 }
57 }
58
59 fn write_u32(&mut self, offset: u16, val: u32) {
60 tracelimit::warn_ratelimited!(
61 label = ?self.label,
62 ?offset,
63 ?val,
64 "write to read-only capability"
65 );
66 }
67
68 fn reset(&mut self) {}
69}
70
71mod save_restore {
72 use super::*;
73 use vmcore::save_restore::NoSavedState;
74 use vmcore::save_restore::RestoreError;
75 use vmcore::save_restore::SaveError;
76 use vmcore::save_restore::SaveRestore;
77
78 impl<T> SaveRestore for ReadOnlyCapability<T> {
80 type SavedState = NoSavedState;
81
82 fn save(&mut self) -> Result<Self::SavedState, SaveError> {
83 Ok(NoSavedState)
84 }
85
86 fn restore(&mut self, NoSavedState: Self::SavedState) -> Result<(), RestoreError> {
87 Ok(())
88 }
89 }
90}