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 buffer;
@@ -10,7 +12,7 @@ pub mod root_bridge;
10
12
11
13
/// IO Address for PCI/register IO operations
12
14
#[ repr( C , packed) ]
13
- #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
15
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
14
16
pub struct PciIoAddress {
15
17
/// Register number within the PCI device.
16
18
pub reg : u8 ,
@@ -56,9 +58,37 @@ impl PciIoAddress {
56
58
}
57
59
}
58
60
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
+
59
74
impl From < PciIoAddress > for u64 {
60
75
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) )
62
92
}
63
93
}
64
94
@@ -97,3 +127,25 @@ fn encode_io_mode_and_unit<U: PciIoUnit>(mode: PciIoMode) -> PciRootBridgeIoProt
97
127
_ => unreachable ! ( "Illegal PCI IO-Mode / Unit combination" ) ,
98
128
}
99
129
}
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