@@ -12,7 +12,7 @@ const CONFIG_ADDRESS: Port<u32> = Port::new(0xcf8);
12
12
const CONFIG_DATA : Port < u32 > = Port :: new ( 0xcfc ) ;
13
13
14
14
#[ derive( Debug , Copy , Clone ) ]
15
- struct PciConfigRegion ;
15
+ pub struct PciConfigRegion ;
16
16
17
17
impl PciConfigRegion {
18
18
pub const fn new ( ) -> Self {
@@ -30,15 +30,21 @@ pub enum PciConfigAccess {
30
30
impl ConfigRegionAccess for PciConfigAccess {
31
31
unsafe fn read ( & self , address : PciAddress , offset : u16 ) -> u32 {
32
32
match self {
33
- PciConfigAccess :: PciConfigRegion ( entry) => entry. read ( address, offset) ,
34
- PciConfigAccess :: PcieConfigRegion ( entry) => entry. read ( address, offset) ,
33
+ PciConfigAccess :: PciConfigRegion ( entry) => unsafe { entry. read ( address, offset) } ,
34
+ #[ cfg( feature = "acpi" ) ]
35
+ PciConfigAccess :: PcieConfigRegion ( entry) => unsafe { entry. read ( address, offset) } ,
35
36
}
36
37
}
37
38
38
39
unsafe fn write ( & self , address : PciAddress , offset : u16 , value : u32 ) {
39
40
match self {
40
- PciConfigAccess :: PciConfigRegion ( entry) => entry. write ( address, offset, value) ,
41
- PciConfigAccess :: PcieConfigRegion ( entry) => entry. write ( address, offset, value) ,
41
+ PciConfigAccess :: PciConfigRegion ( entry) => unsafe {
42
+ entry. write ( address, offset, value) ;
43
+ } ,
44
+ #[ cfg( feature = "acpi" ) ]
45
+ PciConfigAccess :: PcieConfigRegion ( entry) => unsafe {
46
+ entry. write ( address, offset, value) ;
47
+ } ,
42
48
}
43
49
}
44
50
}
@@ -83,9 +89,15 @@ pub(crate) fn init() {
83
89
debug ! ( "Scanning PCI Busses 0 to {}" , PCI_MAX_BUS_NUMBER - 1 ) ;
84
90
85
91
#[ cfg( feature = "acpi" ) ]
86
- if pcie:: init_pcie ( ) { return ; }
92
+ if pcie:: init_pcie ( ) {
93
+ return ;
94
+ }
87
95
88
- enumerate_devices ( 0 , PCI_MAX_BUS_NUMBER , PciConfigAccess :: PciConfigRegion ( PciConfigRegion :: new ( ) ) )
96
+ enumerate_devices (
97
+ 0 ,
98
+ PCI_MAX_BUS_NUMBER ,
99
+ PciConfigAccess :: PciConfigRegion ( PciConfigRegion :: new ( ) ) ,
100
+ ) ;
89
101
}
90
102
91
103
fn enumerate_devices ( bus_start : u8 , bus_end : u8 , access : PciConfigAccess ) {
@@ -108,26 +120,29 @@ fn enumerate_devices(bus_start: u8, bus_end: u8, access: PciConfigAccess) {
108
120
109
121
#[ cfg( feature = "acpi" ) ]
110
122
mod pcie {
111
- use core :: ptr ;
123
+ use memory_addresses :: PhysAddr ;
112
124
use pci_types:: { ConfigRegionAccess , PciAddress } ;
113
- use memory_addresses:: { PhysAddr , VirtAddr } ;
114
- use super :: { PciConfigAccess , PCI_MAX_BUS_NUMBER } ;
115
- use crate :: env;
125
+
126
+ use super :: { PCI_MAX_BUS_NUMBER , PciConfigAccess } ;
116
127
use crate :: env:: kernel:: acpi;
117
128
118
129
pub fn init_pcie ( ) -> bool {
119
- let Some ( table) = acpi:: get_mcfg_table ( ) else { return false ; } ;
130
+ let Some ( table) = acpi:: get_mcfg_table ( ) else {
131
+ return false ;
132
+ } ;
120
133
121
- let mut start_addr: * const McfgTableEntry = core:: ptr:: with_exposed_provenance ( table. table_start_address ( ) + 8 ) ;
122
- let end_addr: * const McfgTableEntry = core:: ptr:: with_exposed_provenance ( table. table_end_address ( ) + 8 ) ;
134
+ let mut start_addr: * const McfgTableEntry =
135
+ core:: ptr:: with_exposed_provenance ( table. table_start_address ( ) + 8 ) ;
136
+ let end_addr: * const McfgTableEntry =
137
+ core:: ptr:: with_exposed_provenance ( table. table_end_address ( ) + 8 ) ;
123
138
124
139
if start_addr == end_addr {
125
140
return false ;
126
141
}
127
142
128
143
while start_addr < end_addr {
129
144
unsafe {
130
- let read = ptr:: read_unaligned ( start_addr) ;
145
+ let read = core :: ptr:: read_unaligned ( start_addr) ;
131
146
init_pcie_bus ( read) ;
132
147
start_addr = start_addr. add ( 1 ) ;
133
148
}
@@ -136,58 +151,41 @@ mod pcie {
136
151
true
137
152
}
138
153
139
- #[ derive( Debug ) ]
140
- #[ repr( C ) ]
141
- struct PcieDeviceConfig {
142
- vendor_id : u16 ,
143
- device_id : u16 ,
144
- _reserved : [ u8 ; 4096 - 8 ]
145
- }
146
-
147
154
#[ derive( Debug , Copy , Clone ) ]
148
155
#[ repr( C ) ]
149
156
pub ( crate ) struct McfgTableEntry {
150
157
pub base_address : u64 ,
151
158
pub pci_segment_number : u16 ,
152
159
pub start_pci_bus : u8 ,
153
160
pub end_pci_bus : u8 ,
154
- _reserved : u32
161
+ _reserved : u32 ,
155
162
}
156
163
157
164
impl McfgTableEntry {
158
- pub fn pci_config_space_address ( & self , bus_number : u8 , device : u8 , function : u8 ) -> PhysAddr {
165
+ pub fn pci_config_space_address (
166
+ & self ,
167
+ bus_number : u8 ,
168
+ device : u8 ,
169
+ function : u8 ,
170
+ ) -> PhysAddr {
159
171
PhysAddr :: new (
160
- self . base_address +
161
- ( ( bus_number as u64 ) << 20 ) |
162
- ( ( ( device as u64 ) & 0x1f ) << 15 ) |
163
- ( ( ( function as u64 ) & 0x7 ) << 12 )
172
+ self . base_address
173
+ + ( ( u64:: from ( bus_number ) << 20 )
174
+ | ( ( u64 :: from ( device) & 0x1f ) << 15 )
175
+ | ( ( u64 :: from ( function) & 0x7 ) << 12 ) ) ,
164
176
)
165
177
}
166
178
}
167
179
168
- #[ derive( Debug ) ]
169
- #[ cfg( feature = "pci" ) ]
170
- struct McfgTable ( alloc:: vec:: Vec < McfgTableEntry > ) ;
171
-
172
- impl PcieDeviceConfig {
173
- fn get < ' a > ( physical_address : PhysAddr ) -> & ' a Self {
174
- assert ! ( env:: is_uefi( ) ) ;
175
-
176
- // For UEFI Systems, the tables are already mapped so we only need to return a proper reference to the table
177
- let allocated_virtual_address = VirtAddr :: new ( physical_address. as_u64 ( ) ) ;
178
- let ptr: * const PcieDeviceConfig = allocated_virtual_address. as_ptr ( ) ;
179
-
180
- unsafe { ptr. as_ref ( ) . unwrap ( ) }
181
- }
182
- }
183
-
184
180
impl ConfigRegionAccess for McfgTableEntry {
185
181
unsafe fn read ( & self , address : PciAddress , offset : u16 ) -> u32 {
186
182
assert_eq ! ( address. segment( ) , self . pci_segment_number) ;
187
183
assert ! ( address. bus( ) >= self . start_pci_bus) ;
188
184
assert ! ( address. bus( ) <= self . end_pci_bus) ;
189
185
190
- let ptr = self . pci_config_space_address ( address. bus ( ) , address. device ( ) , address. function ( ) ) + offset as u64 ;
186
+ let ptr =
187
+ self . pci_config_space_address ( address. bus ( ) , address. device ( ) , address. function ( ) )
188
+ + u64:: from ( offset) ;
191
189
let ptr = ptr. as_usize ( ) as * const u32 ;
192
190
193
191
unsafe { * ptr }
@@ -198,10 +196,14 @@ mod pcie {
198
196
assert ! ( address. bus( ) >= self . start_pci_bus) ;
199
197
assert ! ( address. bus( ) <= self . end_pci_bus) ;
200
198
201
- let ptr = self . pci_config_space_address ( address. bus ( ) , address. device ( ) , address. function ( ) ) + offset as u64 ;
199
+ let ptr =
200
+ self . pci_config_space_address ( address. bus ( ) , address. device ( ) , address. function ( ) )
201
+ + u64:: from ( offset) ;
202
202
let ptr = ptr. as_usize ( ) as * mut u32 ;
203
203
204
- unsafe { * ptr = value; }
204
+ unsafe {
205
+ * ptr = value;
206
+ }
205
207
}
206
208
}
207
209
@@ -210,7 +212,15 @@ mod pcie {
210
212
return ;
211
213
}
212
214
213
- let end = if bus_entry. end_pci_bus > PCI_MAX_BUS_NUMBER { PCI_MAX_BUS_NUMBER } else { bus_entry. end_pci_bus } ;
214
- super :: enumerate_devices ( bus_entry. start_pci_bus , end, PciConfigAccess :: PcieConfigRegion ( bus_entry) ) ;
215
+ let end = if bus_entry. end_pci_bus > PCI_MAX_BUS_NUMBER {
216
+ PCI_MAX_BUS_NUMBER
217
+ } else {
218
+ bus_entry. end_pci_bus
219
+ } ;
220
+ super :: enumerate_devices (
221
+ bus_entry. start_pci_bus ,
222
+ end,
223
+ PciConfigAccess :: PcieConfigRegion ( bus_entry) ,
224
+ ) ;
215
225
}
216
- }
226
+ }
0 commit comments