pub struct PciDevice {Show 17 fields
pub location: PciLocation,
pub intx_waker: Mutex<Option<Waker>>,
pub class: u8,
pub subclass: u8,
pub prog_if: u8,
pub bars: [u32; 6],
pub vendor_id: u16,
pub device_id: u16,
pub command: u16,
pub status: u16,
pub revision_id: u8,
pub cache_line_size: u8,
pub latency_timer: u8,
pub header_type: u8,
pub bist: u8,
pub int_pin: u8,
pub int_line: u8,
}
Expand description
Contains information common to every type of PCI Device, and offers functions for reading/writing to the PCI configuration space.
For more, see this partial table
of class
, subclass
, and prog_if
codes,
Fields§
§location: PciLocation
the bus, slot, and function number that locates this PCI device in the bus tree.
intx_waker: Mutex<Option<Waker>>
The handling task for legacy PCI interrupts
class: u8
The class code, used to determine device type.
subclass: u8
The subclass code, used to determine device type.
prog_if: u8
The programming interface of this PCI device, also used to determine device type.
bars: [u32; 6]
The six Base Address Registers (BARs)
vendor_id: u16
§device_id: u16
§command: u16
§status: u16
§revision_id: u8
§cache_line_size: u8
§latency_timer: u8
§header_type: u8
§bist: u8
§int_pin: u8
§int_line: u8
Implementations§
source§impl PciDevice
impl PciDevice
sourcepub fn determine_mem_base(
&self,
bar_index: usize
) -> Result<PhysicalAddress, &'static str>
pub fn determine_mem_base( &self, bar_index: usize ) -> Result<PhysicalAddress, &'static str>
Returns the base address of the memory region specified by the given BAR
(Base Address Register) for this PCI device.
Argument
bar_index
must be between0
and5
inclusively, as each PCI device can only have 6 BARs at the most.
Note that if the given BAR
actually indicates it is part of a 64-bit address,
it will be used together with the BAR right above it (bar + 1
), e.g., BAR1:BAR0
.
If it is a 32-bit address, then only the given BAR
will be accessed.
TODO: currently we assume the BAR represents a memory space (memory mapped I/O) rather than I/O space like Port I/O. Obviously, this is not always the case. Instead, we should return an enum specifying which kind of memory space the calculated base address is.
sourcepub fn determine_mem_size(&self, bar_index: usize) -> u32
pub fn determine_mem_size(&self, bar_index: usize) -> u32
Returns the size in bytes of the memory region specified by the given BAR
(Base Address Register) for this PCI device.
Argument
bar_index
must be between0
and5
inclusively, as each PCI device can only have 6 BARs at the most.
sourcepub fn modern_interrupt_support(&self) -> ModernInterruptSupport
pub fn modern_interrupt_support(&self) -> ModernInterruptSupport
Queries and returns whether this PCI device supports MSI and MSI-X interrupts.
sourcepub fn pci_enable_msi(
&self,
core_id: u8,
int_num: u8
) -> Result<(), &'static str>
pub fn pci_enable_msi( &self, core_id: u8, int_num: u8 ) -> Result<(), &'static str>
Enable MSI interrupts for a PCI device. We assume the device only supports one MSI vector and set the interrupt number and core id for that vector. If the MSI capability is not supported then an error message is returned.
Arguments
core_id
: core that interrupt will be routed toint_num
: interrupt number to assign to the MSI vector
Panics
This function panics if the MSI capability isn’t aligned to 4 bytes
sourcepub fn pci_enable_msix(&self) -> Result<(), &'static str>
pub fn pci_enable_msix(&self) -> Result<(), &'static str>
Enable MSI-X interrupts for a PCI device. Only the enable bit is set and the remaining initialization steps of setting the interrupt number and core id should be completed in the device driver.
sourcepub fn pci_mem_map_msix(
&self,
max_vectors: usize
) -> Result<MsixVectorTable, &'static str>
pub fn pci_mem_map_msix( &self, max_vectors: usize ) -> Result<MsixVectorTable, &'static str>
Returns the memory mapped msix vector table
- returns
Err("Device not MSI-X capable")
if the device doesn’t have the MSI-X capability - returns
Err("Invalid BAR content")
if the Base Address Register contains an invalid address
sourcepub fn pci_map_bar_mem(
&self,
bar_index: usize
) -> Result<MappedPages, &'static str>
pub fn pci_map_bar_mem( &self, bar_index: usize ) -> Result<MappedPages, &'static str>
Maps device memory specified by a Base Address Register.
Arguments
bar_index
: index of the Base Address Register to use
sourcepub fn pci_get_intx_info(
&self
) -> Result<(Option<u8>, Option<InterruptPin>), &'static str>
pub fn pci_get_intx_info( &self ) -> Result<(Option<u8>, Option<InterruptPin>), &'static str>
Reads and returns this PCI device’s INTx line and INTx pin registers.
Returns an error if this PCI device’s INTx pin value is invalid (greater than 4).
sourcepub fn pci_enable_intx(&self, enable: bool)
pub fn pci_enable_intx(&self, enable: bool)
Enables/Disables legacy (INTx) interrupts for this device
sourcepub fn pci_intx_enabled(&self) -> bool
pub fn pci_intx_enabled(&self) -> bool
Checks that legacy interrupts are enabled in the command register.
sourcepub fn pci_get_intx_status(&self, check_enabled: bool) -> bool
pub fn pci_get_intx_status(&self, check_enabled: bool) -> bool
Reads and returns this PCI device’s legacy interrupt status flag.
Methods from Deref<Target = PciLocation>§
pub fn bus(&self) -> u8
pub fn slot(&self) -> u8
pub fn function(&self) -> u8
sourcepub fn pci_set_command_bus_master_bit(&self)
pub fn pci_set_command_bus_master_bit(&self)
Sets the PCI device’s bit 3 in the command portion, which is apparently needed to activate DMA (??)
sourcepub fn pci_set_intx_disable_bit(&self, bit: bool)
pub fn pci_set_intx_disable_bit(&self, bit: bool)
Sets the PCI device’s command bit 10 to disable legacy interrupts