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