22
33//! PCI Bus specific protocols.
44
5+ use core:: cmp:: Ordering ;
6+
57use uefi_raw:: protocol:: pci:: root_bridge:: PciRootBridgeIoProtocolWidth ;
68
79pub mod buffer;
@@ -10,7 +12,7 @@ pub mod root_bridge;
1012
1113/// IO Address for PCI/register IO operations
1214#[ repr( C , packed) ]
13- #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
15+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
1416pub struct PciIoAddress {
1517 /// Register number within the PCI device.
1618 pub reg : u8 ,
@@ -56,9 +58,37 @@ impl PciIoAddress {
5658 }
5759}
5860
61+ impl From < u64 > for PciIoAddress {
62+ fn from ( value : u64 ) -> Self {
63+ let raw = value. to_ne_bytes ( ) ;
64+ Self {
65+ reg : raw[ 0 ] ,
66+ fun : raw[ 1 ] ,
67+ dev : raw[ 2 ] ,
68+ bus : raw[ 3 ] ,
69+ ext_reg : u32:: from_ne_bytes ( [ raw[ 4 ] , raw[ 5 ] , raw[ 6 ] , raw[ 7 ] ] ) ,
70+ }
71+ }
72+ }
73+
5974impl From < PciIoAddress > for u64 {
6075 fn from ( value : PciIoAddress ) -> Self {
61- unsafe { core:: mem:: transmute ( value) }
76+ let ereg = value. ext_reg . to_ne_bytes ( ) ;
77+ Self :: from_ne_bytes ( [
78+ value. reg , value. fun , value. dev , value. bus , ereg[ 0 ] , ereg[ 1 ] , ereg[ 2 ] , ereg[ 3 ] ,
79+ ] )
80+ }
81+ }
82+
83+ impl PartialOrd for PciIoAddress {
84+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
85+ Some ( self . cmp ( other) )
86+ }
87+ }
88+
89+ impl Ord for PciIoAddress {
90+ fn cmp ( & self , other : & Self ) -> Ordering {
91+ u64:: from ( * self ) . cmp ( & u64:: from ( * other) )
6292 }
6393}
6494
@@ -97,3 +127,25 @@ fn encode_io_mode_and_unit<U: PciIoUnit>(mode: PciIoMode) -> PciRootBridgeIoProt
97127 _ => unreachable ! ( "Illegal PCI IO-Mode / Unit combination" ) ,
98128 }
99129}
130+
131+ #[ cfg( test) ]
132+ mod tests {
133+ use super :: PciIoAddress ;
134+ use core:: mem;
135+
136+ #[ test]
137+ fn test_pci_ioaddr_raw_conversion ( ) {
138+ assert_eq ! ( mem:: size_of:: <u64 >( ) , mem:: size_of:: <PciIoAddress >( ) ) ;
139+ let srcaddr = PciIoAddress {
140+ reg : 0x11 ,
141+ fun : 0x33 ,
142+ dev : 0x55 ,
143+ bus : 0x77 ,
144+ ext_reg : 0x99bbddff ,
145+ } ;
146+ let rawaddr: u64 = srcaddr. into ( ) ;
147+ let dstaddr = PciIoAddress :: from ( rawaddr) ;
148+ assert_eq ! ( rawaddr, 0x99_bb_dd_ff_7755_3311 ) ;
149+ assert_eq ! ( srcaddr, dstaddr) ;
150+ }
151+ }
0 commit comments