Skip to content

Commit

Permalink
introduce from_pci_endian to convert data from the PCI device
Browse files Browse the repository at this point in the history
As the endianness received from the device is little endian coded
the given value must be swapped again on big endian machines. Which is done
via the u32::to_le() method as the u32::to_be() would be a no-op in big endian
machines. Resulting in no conversion.
  • Loading branch information
stlankes committed May 13, 2023
1 parent 7a2d5f6 commit 968752e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/arch/aarch64/kernel/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl ConfigRegionAccess for PciConfigRegion {
| u64::from(pci_addr.function()) << 12
| (u64::from(offset) & 0xFFF)
| self.0.as_u64();
core::ptr::read_volatile(addr as *const u32).to_le()
crate::drivers::pci::from_pci_endian(core::ptr::read_volatile(addr as *const u32))
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86_64/kernel/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl ConfigRegionAccess for PciConfigRegion {
| u32::from(register);
unsafe {
outl(PCI_CONFIG_ADDRESS_PORT, address);
inl(PCI_CONFIG_DATA_PORT).to_le()
crate::drivers::pci::from_pci_endian(inl(PCI_CONFIG_DATA_PORT))
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/drivers/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ use crate::drivers::net::NetworkInterface;
use crate::drivers::virtio::transport::pci as pci_virtio;
use crate::drivers::virtio::transport::pci::VirtioDriver;

/// Converts a given little endian coded u32 to native endian coded.
//
// INFO: As the endianness received from the device is little endian coded
// the given value must be swapped again on big endian machines. Which is done
// via the u32::to_le() method as the u32::to_be() would be a no-op in big endian
// machines. Resulting in no conversion.
#[inline]
pub(crate) fn from_pci_endian(val: u32) -> u32 {
if cfg!(target = "big_endian") {
val.to_le()
} else {
val
}
}

/// The module contains constants specific to PCI.
#[allow(dead_code)]
pub(crate) mod constants {
Expand Down
12 changes: 8 additions & 4 deletions src/drivers/virtio/transport/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,14 +1109,17 @@ fn read_caps(
/// As the device is not static, return value is not static.
fn dev_status(device: &PciDevice<PciConfigRegion>) -> u32 {
// reads register 01 from PCU Header of type 00H. WHich is the Status(16bit) and Command(16bit) register
let stat_com_reg = device.read_register(crate::drivers::pci::constants::RegisterHeader::PCI_COMMAND_REGISTER.into());
let stat_com_reg = device
.read_register(crate::drivers::pci::constants::RegisterHeader::PCI_COMMAND_REGISTER.into());
stat_com_reg >> 16
}

/// Wrapper function to get a devices capabilities list pointer, which represents
/// an offset starting from the header of the device's configuration space.
fn dev_caps_ptr(device: &PciDevice<PciConfigRegion>) -> u32 {
let cap_lst_reg = device.read_register(crate::drivers::pci::constants::RegisterHeader::PCI_CAPABILITY_LIST_REGISTER.into());
let cap_lst_reg = device.read_register(
crate::drivers::pci::constants::RegisterHeader::PCI_CAPABILITY_LIST_REGISTER.into(),
);
cap_lst_reg & u32::from(crate::drivers::pci::constants::Masks::PCI_MASK_CAPLIST_POINTER)
}

Expand All @@ -1128,7 +1131,9 @@ fn map_bars(device: &PciDevice<PciConfigRegion>) -> Result<Vec<PciBar>, PciError
/// Checks if the status of the device inidactes the device is using the
/// capabilities pointer and therefore defines a capabiites list.
fn no_cap_list(device: &PciDevice<PciConfigRegion>) -> bool {
dev_status(device) & u32::from(crate::drivers::pci::constants::Masks::PCI_MASK_STATUS_CAPABILITIES_LIST) == 0
dev_status(device)
& u32::from(crate::drivers::pci::constants::Masks::PCI_MASK_STATUS_CAPABILITIES_LIST)
== 0
}

/// Checks if minimal set of capabilities is present.
Expand Down Expand Up @@ -1300,4 +1305,3 @@ pub(crate) enum VirtioDriver {
Network(VirtioNetDriver),
FileSystem(VirtioFsDriver),
}

0 comments on commit 968752e

Please sign in to comment.