Struct pci::PciDevice

source ·
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

source

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 between 0 and 5 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.

source

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 between 0 and 5 inclusively, as each PCI device can only have 6 BARs at the most.
source

pub fn modern_interrupt_support(&self) -> ModernInterruptSupport

Queries and returns whether this PCI device supports MSI and MSI-X interrupts.

source

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 to
  • int_num: interrupt number to assign to the MSI vector
Panics

This function panics if the MSI capability isn’t aligned to 4 bytes

source

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.

source

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
source

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
source

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).

source

pub fn pci_enable_intx(&self, enable: bool)

Enables/Disables legacy (INTx) interrupts for this device

source

pub fn pci_intx_enabled(&self) -> bool

Checks that legacy interrupts are enabled in the command register.

source

pub fn pci_get_intx_status(&self, check_enabled: bool) -> bool

Reads and returns this PCI device’s legacy interrupt status flag.

source

pub fn set_intx_waker( &'static self, waker: Waker ) -> Result<Option<Waker>, &'static str>

Sets up the given waker to be woken when this PCI device triggers a legacy interrupt (INTx).

Returns the previous interrupt waker for this device, if there was one.

Methods from Deref<Target = PciLocation>§

source

pub fn bus(&self) -> u8

source

pub fn slot(&self) -> u8

source

pub fn function(&self) -> u8

source

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 (??)

source

pub fn pci_set_intx_disable_bit(&self, bit: bool)

Sets the PCI device’s command bit 10 to disable legacy interrupts

Trait Implementations§

source§

impl Debug for PciDevice

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for PciDevice

§

type Target = PciLocation

The resulting type after dereferencing.
source§

fn deref(&self) -> &PciLocation

Dereferences the value.
source§

impl DerefMut for PciDevice

source§

fn deref_mut(&mut self) -> &mut PciLocation

Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.