pci_core/test_helpers/
mod.rs1use crate::capabilities::PciCapability;
7use crate::capabilities::extended::PciExtendedCapability;
8use crate::cfg_space_emu::ConfigSpaceType0Emulator;
9use crate::cfg_space_emu::ConfigSpaceType1Emulator;
10use crate::msi::SignalMsi;
11use chipset_device::pci::ByteEnabledDwordRead;
12use chipset_device::pci::ByteEnabledDwordWrite;
13use chipset_device::pci::PciConfigAddress;
14use parking_lot::Mutex;
15use std::collections::VecDeque;
16use std::sync::Arc;
17
18#[derive(Debug, Clone)]
21pub struct TestPciInterruptController {
22 inner: Arc<TestPciInterruptControllerInner>,
23}
24
25#[derive(Debug)]
26struct TestPciInterruptControllerInner {
27 msi_requests: Mutex<VecDeque<(u64, u32)>>, }
30
31impl TestPciInterruptController {
32 pub fn new() -> Self {
34 Self {
35 inner: Arc::new(TestPciInterruptControllerInner {
36 msi_requests: Mutex::new(VecDeque::new()),
37 }),
38 }
39 }
40
41 pub fn get_next_interrupt(&self) -> Option<(u64, u32)> {
43 self.inner.msi_requests.lock().pop_front()
44 }
45
46 pub fn signal_msi(&self) -> Arc<dyn SignalMsi> {
48 self.inner.clone()
49 }
50}
51
52impl SignalMsi for TestPciInterruptControllerInner {
53 fn signal_msi(&self, _devid: Option<u32>, address: u64, data: u32) {
54 self.msi_requests.lock().push_back((address, data));
55 }
56}
57
58pub trait TestCfgAccess {
60 fn read_u32(&self, offset: u16) -> u32;
62
63 fn write_u32(&mut self, offset: u16, value: u32);
65}
66
67impl TestCfgAccess for ConfigSpaceType0Emulator {
68 fn read_u32(&self, offset: u16) -> u32 {
69 assert!(offset.is_multiple_of(4));
70 let mut val = 0;
71 self.read(
72 PciConfigAddress::new(0, 0, offset / 4).unwrap(),
73 ByteEnabledDwordRead::with_all_bytes_enabled(&mut val),
74 )
75 .unwrap();
76 val
77 }
78
79 fn write_u32(&mut self, offset: u16, value: u32) {
80 assert!(offset.is_multiple_of(4));
81 self.write(
82 PciConfigAddress::new(0, 0, offset / 4).unwrap(),
83 ByteEnabledDwordWrite::with_all_bytes_enabled(value),
84 )
85 .unwrap();
86 }
87}
88
89impl TestCfgAccess for ConfigSpaceType1Emulator {
90 fn read_u32(&self, offset: u16) -> u32 {
91 assert!(offset.is_multiple_of(4));
92 let mut val = 0;
93 self.read(
94 PciConfigAddress::new(0, 0, offset / 4).unwrap(),
95 ByteEnabledDwordRead::with_all_bytes_enabled(&mut val),
96 )
97 .unwrap();
98 val
99 }
100
101 fn write_u32(&mut self, offset: u16, value: u32) {
102 assert!(offset.is_multiple_of(4));
103 self.write(
104 PciConfigAddress::new(0, 0, offset / 4).unwrap(),
105 ByteEnabledDwordWrite::with_all_bytes_enabled(value),
106 )
107 .unwrap();
108 }
109}
110
111pub fn read_cap_u32(cap: &impl PciCapability, offset: u16) -> u32 {
113 let mut value = 0;
114 cap.read(
115 offset,
116 ByteEnabledDwordRead::with_all_bytes_enabled(&mut value),
117 );
118 value
119}
120
121pub fn write_cap_u32(cap: &mut impl PciCapability, offset: u16, val: u32) {
123 cap.write(offset, ByteEnabledDwordWrite::with_all_bytes_enabled(val))
124}
125
126pub fn read_extended_cap_u32(cap: &impl PciExtendedCapability, offset: u16) -> u32 {
128 let mut value = 0;
129 cap.read(
130 offset,
131 ByteEnabledDwordRead::with_all_bytes_enabled(&mut value),
132 );
133 value
134}
135
136pub fn write_extended_cap_u32(cap: &mut impl PciExtendedCapability, offset: u16, val: u32) {
138 cap.write(offset, ByteEnabledDwordWrite::with_all_bytes_enabled(val))
139}