pci_types/capability/
msix.rs1use super::PciCapabilityAddress;
2use crate::ConfigRegionAccess;
3use bit_field::BitField;
4
5#[derive(Clone, Copy, Debug)]
6pub struct MsixCapability {
7 pub(super) address: PciCapabilityAddress,
8 table_size: u16,
9 table: u32,
11 pba: u32,
13}
14
15impl MsixCapability {
16 pub(crate) fn new(
17 address: PciCapabilityAddress,
18 control: u16,
19 access: impl ConfigRegionAccess,
20 ) -> MsixCapability {
21 let table_size = control.get_bits(0..11) + 1;
22 let table = unsafe { access.read(address.address, address.offset + 0x04) };
23 let pba = unsafe { access.read(address.address, address.offset + 0x08) };
24 MsixCapability { address, table_size, table, pba }
25 }
26
27 pub fn set_enabled(&mut self, enabled: bool, access: impl ConfigRegionAccess) {
35 let mut control = unsafe { access.read(self.address.address, self.address.offset) };
36 control.set_bit(31, enabled);
37 unsafe {
38 access.write(self.address.address, self.address.offset, control);
39 }
40 }
41
42 pub fn enabled(&self, access: impl ConfigRegionAccess) -> bool {
43 let control = unsafe { access.read(self.address.address, self.address.offset) };
44 control.get_bit(31)
45 }
46
47 pub fn set_function_mask(&mut self, mask: bool, access: impl ConfigRegionAccess) {
52 let mut control = unsafe { access.read(self.address.address, self.address.offset) };
53 control.set_bit(30, mask);
54 unsafe {
55 access.write(self.address.address, self.address.offset, control);
56 }
57 }
58
59 pub fn function_mask(&self, access: impl ConfigRegionAccess) -> bool {
60 let control = unsafe { access.read(self.address.address, self.address.offset) };
61 control.get_bit(30)
62 }
63
64 pub fn table_bar(&self) -> u8 {
66 self.table.get_bits(0..3) as u8
67 }
68
69 pub fn table_offset(&self) -> u32 {
71 self.table & !0b111
76 }
77
78 pub fn table_size(&self) -> u16 {
79 self.table_size
80 }
81
82 pub fn pba_bar(&self) -> u8 {
83 self.pba.get_bits(0..3) as u8
84 }
85
86 pub fn pba_offset(&self) -> u32 {
87 self.pba & !0b111
92 }
93}