|
2 | 2 |
|
3 | 3 | //! PCI Bus specific protocols.
|
4 | 4 |
|
| 5 | +use core::cmp::Ordering; |
| 6 | + |
5 | 7 | use uefi_raw::protocol::pci::root_bridge::PciRootBridgeIoProtocolWidth;
|
6 | 8 |
|
7 | 9 | pub mod root_bridge;
|
8 | 10 |
|
9 | 11 | /// IO Address for PCI/register IO operations
|
10 | 12 | #[repr(C, packed)]
|
11 |
| -#[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 13 | +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
12 | 14 | pub struct PciIoAddress {
|
13 | 15 | /// Register number within the PCI device.
|
14 | 16 | pub reg: u8,
|
@@ -54,12 +56,30 @@ impl PciIoAddress {
|
54 | 56 | }
|
55 | 57 | }
|
56 | 58 |
|
| 59 | +impl From<u64> for PciIoAddress { |
| 60 | + fn from(value: u64) -> Self { |
| 61 | + unsafe { core::mem::transmute(value) } |
| 62 | + } |
| 63 | +} |
| 64 | + |
57 | 65 | impl From<PciIoAddress> for u64 {
|
58 | 66 | fn from(value: PciIoAddress) -> Self {
|
59 | 67 | unsafe { core::mem::transmute(value) }
|
60 | 68 | }
|
61 | 69 | }
|
62 | 70 |
|
| 71 | +impl PartialOrd for PciIoAddress { |
| 72 | + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
| 73 | + Some(self.cmp(other)) |
| 74 | + } |
| 75 | +} |
| 76 | + |
| 77 | +impl Ord for PciIoAddress { |
| 78 | + fn cmp(&self, other: &Self) -> Ordering { |
| 79 | + u64::from(*self).cmp(&u64::from(*other)) |
| 80 | + } |
| 81 | +} |
| 82 | + |
63 | 83 | /// Trait implemented by all data types that can natively be read from a PCI device.
|
64 | 84 | /// Note: Not all of them have to actually be supported by the hardware at hand.
|
65 | 85 | pub trait PciIoUnit: Sized + Default {}
|
@@ -95,3 +115,24 @@ fn encode_io_mode_and_unit<U: PciIoUnit>(mode: PciIoMode) -> PciRootBridgeIoProt
|
95 | 115 | _ => unreachable!("Illegal PCI IO-Mode / Unit combination"),
|
96 | 116 | }
|
97 | 117 | }
|
| 118 | + |
| 119 | +#[cfg(test)] |
| 120 | +mod tests { |
| 121 | + use super::PciIoAddress; |
| 122 | + use core::mem; |
| 123 | + |
| 124 | + #[test] |
| 125 | + fn test_pci_ioaddr_raw_conversion() { |
| 126 | + assert_eq!(mem::size_of::<u64>(), mem::size_of::<PciIoAddress>()); |
| 127 | + let srcaddr = PciIoAddress { |
| 128 | + reg: 0x11, |
| 129 | + fun: 0x33, |
| 130 | + dev: 0x55, |
| 131 | + bus: 0x77, |
| 132 | + ext_reg: 0x99bbddff, |
| 133 | + }; |
| 134 | + let rawaddr: u64 = srcaddr.into(); |
| 135 | + let dstaddr = PciIoAddress::from(rawaddr); |
| 136 | + assert_eq!(srcaddr, dstaddr); |
| 137 | + } |
| 138 | +} |
0 commit comments