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,9 +56,37 @@ impl PciIoAddress {
54
56
}
55
57
}
56
58
59
+ impl From < u64 > for PciIoAddress {
60
+ fn from ( value : u64 ) -> Self {
61
+ let raw = value. to_ne_bytes ( ) ;
62
+ Self {
63
+ reg : raw[ 0 ] ,
64
+ fun : raw[ 1 ] ,
65
+ dev : raw[ 2 ] ,
66
+ bus : raw[ 3 ] ,
67
+ ext_reg : u32:: from_ne_bytes ( [ raw[ 4 ] , raw[ 5 ] , raw[ 6 ] , raw[ 7 ] ] ) ,
68
+ }
69
+ }
70
+ }
71
+
57
72
impl From < PciIoAddress > for u64 {
58
73
fn from ( value : PciIoAddress ) -> Self {
59
- unsafe { core:: mem:: transmute ( value) }
74
+ let ereg = value. ext_reg . to_ne_bytes ( ) ;
75
+ Self :: from_ne_bytes ( [
76
+ value. reg , value. fun , value. dev , value. bus , ereg[ 0 ] , ereg[ 1 ] , ereg[ 2 ] , ereg[ 3 ] ,
77
+ ] )
78
+ }
79
+ }
80
+
81
+ impl PartialOrd for PciIoAddress {
82
+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
83
+ Some ( self . cmp ( other) )
84
+ }
85
+ }
86
+
87
+ impl Ord for PciIoAddress {
88
+ fn cmp ( & self , other : & Self ) -> Ordering {
89
+ u64:: from ( * self ) . cmp ( & u64:: from ( * other) )
60
90
}
61
91
}
62
92
@@ -95,3 +125,25 @@ fn encode_io_mode_and_unit<U: PciIoUnit>(mode: PciIoMode) -> PciRootBridgeIoProt
95
125
_ => unreachable ! ( "Illegal PCI IO-Mode / Unit combination" ) ,
96
126
}
97
127
}
128
+
129
+ #[ cfg( test) ]
130
+ mod tests {
131
+ use super :: PciIoAddress ;
132
+ use core:: mem;
133
+
134
+ #[ test]
135
+ fn test_pci_ioaddr_raw_conversion ( ) {
136
+ assert_eq ! ( mem:: size_of:: <u64 >( ) , mem:: size_of:: <PciIoAddress >( ) ) ;
137
+ let srcaddr = PciIoAddress {
138
+ reg : 0x11 ,
139
+ fun : 0x33 ,
140
+ dev : 0x55 ,
141
+ bus : 0x77 ,
142
+ ext_reg : 0x99bbddff ,
143
+ } ;
144
+ let rawaddr: u64 = srcaddr. into ( ) ;
145
+ let dstaddr = PciIoAddress :: from ( rawaddr) ;
146
+ assert_eq ! ( rawaddr, 0x99_bb_dd_ff_7755_3311 ) ;
147
+ assert_eq ! ( srcaddr, dstaddr) ;
148
+ }
149
+ }
0 commit comments