6
6
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
7
7
8
8
//! Implements pci devices and busses.
9
- #[ macro_use]
10
- extern crate log;
11
9
12
- mod bus;
13
- mod configuration;
14
- mod device;
15
- mod msix;
10
+ extern crate log;
16
11
17
12
use std:: fmt:: { self , Debug , Display } ;
18
13
use std:: num:: ParseIntError ;
19
14
use std:: str:: FromStr ;
20
15
21
16
use serde:: de:: Visitor ;
22
-
23
- pub use self :: bus:: { PciBus , PciConfigIo , PciConfigMmio , PciRoot , PciRootError } ;
24
- pub use self :: configuration:: {
25
- PciBarPrefetchable , PciBarRegionType , PciCapability , PciCapabilityId , PciClassCode ,
26
- PciConfiguration , PciConfigurationState , PciExpressCapabilityId , PciHeaderType ,
27
- PciMassStorageSubclass , PciNetworkControllerSubclass , PciSerialBusSubClass , PciSubclass ,
28
- PCI_CONFIGURATION_ID ,
29
- } ;
30
- pub use self :: device:: {
31
- BarReprogrammingParams , DeviceRelocation , Error as PciDeviceError , PciDevice ,
32
- } ;
33
- pub use self :: msix:: { Error as MsixError , MsixCap , MsixConfig , MsixConfigState , MsixTableEntry } ;
17
+ use serde:: { Deserialize , Serialize } ;
34
18
35
19
/// PCI has four interrupt pins A->D.
36
20
#[ derive( Copy , Clone ) ]
@@ -47,11 +31,6 @@ impl PciInterruptPin {
47
31
}
48
32
}
49
33
50
- #[ cfg( target_arch = "x86_64" ) ]
51
- pub const PCI_CONFIG_IO_PORT : u64 = 0xcf8 ;
52
- #[ cfg( target_arch = "x86_64" ) ]
53
- pub const PCI_CONFIG_IO_PORT_SIZE : u64 = 0x8 ;
54
-
55
34
#[ derive( Clone , Copy , PartialEq , Eq , PartialOrd ) ]
56
35
pub struct PciBdf ( u32 ) ;
57
36
@@ -202,6 +181,344 @@ impl FromStr for PciBdf {
202
181
}
203
182
}
204
183
184
+ /// Represents the types of PCI headers allowed in the configuration registers.
185
+ #[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
186
+ pub enum PciHeaderType {
187
+ Device ,
188
+ Bridge ,
189
+ }
190
+
191
+ /// Classes of PCI nodes.
192
+ #[ allow( dead_code) ]
193
+ #[ derive( Copy , Clone ) ]
194
+ pub enum PciClassCode {
195
+ TooOld ,
196
+ MassStorage ,
197
+ NetworkController ,
198
+ DisplayController ,
199
+ MultimediaController ,
200
+ MemoryController ,
201
+ BridgeDevice ,
202
+ SimpleCommunicationController ,
203
+ BaseSystemPeripheral ,
204
+ InputDevice ,
205
+ DockingStation ,
206
+ Processor ,
207
+ SerialBusController ,
208
+ WirelessController ,
209
+ IntelligentIoController ,
210
+ EncryptionController ,
211
+ DataAcquisitionSignalProcessing ,
212
+ Other = 0xff ,
213
+ }
214
+
215
+ impl PciClassCode {
216
+ pub fn get_register_value ( self ) -> u8 {
217
+ self as u8
218
+ }
219
+ }
220
+
221
+ /// A PCI subclass. Each class in `PciClassCode` can specify a unique set of subclasses. This trait
222
+ /// is implemented by each subclass. It allows use of a trait object to generate configurations.
223
+ pub trait PciSubclass {
224
+ /// Convert this subclass to the value used in the PCI specification.
225
+ fn get_register_value ( & self ) -> u8 ;
226
+ }
227
+
228
+ /// Subclasses of the MultimediaController class.
229
+ #[ allow( dead_code) ]
230
+ #[ derive( Copy , Clone ) ]
231
+ pub enum PciMultimediaSubclass {
232
+ VideoController = 0x00 ,
233
+ AudioController = 0x01 ,
234
+ TelephonyDevice = 0x02 ,
235
+ AudioDevice = 0x03 ,
236
+ Other = 0x80 ,
237
+ }
238
+
239
+ impl PciSubclass for PciMultimediaSubclass {
240
+ fn get_register_value ( & self ) -> u8 {
241
+ * self as u8
242
+ }
243
+ }
244
+
245
+ /// Subclasses of the BridgeDevice
246
+ #[ allow( dead_code) ]
247
+ #[ derive( Copy , Clone ) ]
248
+ pub enum PciBridgeSubclass {
249
+ HostBridge = 0x00 ,
250
+ IsaBridge = 0x01 ,
251
+ EisaBridge = 0x02 ,
252
+ McaBridge = 0x03 ,
253
+ PciToPciBridge = 0x04 ,
254
+ PcmciaBridge = 0x05 ,
255
+ NuBusBridge = 0x06 ,
256
+ CardBusBridge = 0x07 ,
257
+ RacEwayBridge = 0x08 ,
258
+ PciToPciSemiTransparentBridge = 0x09 ,
259
+ InfiniBrandToPciHostBridge = 0x0a ,
260
+ OtherBridgeDevice = 0x80 ,
261
+ }
262
+
263
+ impl PciSubclass for PciBridgeSubclass {
264
+ fn get_register_value ( & self ) -> u8 {
265
+ * self as u8
266
+ }
267
+ }
268
+
269
+ /// Subclass of the SerialBus
270
+ #[ allow( dead_code) ]
271
+ #[ derive( Copy , Clone ) ]
272
+ pub enum PciSerialBusSubClass {
273
+ Firewire = 0x00 ,
274
+ Accessbus = 0x01 ,
275
+ Ssa = 0x02 ,
276
+ Usb = 0x03 ,
277
+ }
278
+
279
+ impl PciSubclass for PciSerialBusSubClass {
280
+ fn get_register_value ( & self ) -> u8 {
281
+ * self as u8
282
+ }
283
+ }
284
+
285
+ /// Mass Storage Sub Classes
286
+ #[ allow( dead_code) ]
287
+ #[ derive( Copy , Clone ) ]
288
+ pub enum PciMassStorageSubclass {
289
+ ScsiStorage = 0x00 ,
290
+ IdeInterface = 0x01 ,
291
+ FloppyController = 0x02 ,
292
+ IpiController = 0x03 ,
293
+ RaidController = 0x04 ,
294
+ AtaController = 0x05 ,
295
+ SataController = 0x06 ,
296
+ SerialScsiController = 0x07 ,
297
+ NvmController = 0x08 ,
298
+ MassStorage = 0x80 ,
299
+ }
300
+
301
+ impl PciSubclass for PciMassStorageSubclass {
302
+ fn get_register_value ( & self ) -> u8 {
303
+ * self as u8
304
+ }
305
+ }
306
+
307
+ /// Network Controller Sub Classes
308
+ #[ allow( dead_code) ]
309
+ #[ derive( Copy , Clone ) ]
310
+ pub enum PciNetworkControllerSubclass {
311
+ EthernetController = 0x00 ,
312
+ TokenRingController = 0x01 ,
313
+ FddiController = 0x02 ,
314
+ AtmController = 0x03 ,
315
+ IsdnController = 0x04 ,
316
+ WorldFipController = 0x05 ,
317
+ PicmgController = 0x06 ,
318
+ InfinibandController = 0x07 ,
319
+ FabricController = 0x08 ,
320
+ NetworkController = 0x80 ,
321
+ }
322
+
323
+ impl PciSubclass for PciNetworkControllerSubclass {
324
+ fn get_register_value ( & self ) -> u8 {
325
+ * self as u8
326
+ }
327
+ }
328
+
329
+ /// Types of PCI capabilities.
330
+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
331
+ #[ allow( dead_code) ]
332
+ #[ allow( non_camel_case_types) ]
333
+ #[ repr( u8 ) ]
334
+ pub enum PciCapabilityId {
335
+ ListId = 0 ,
336
+ PowerManagement = 0x01 ,
337
+ AcceleratedGraphicsPort = 0x02 ,
338
+ VitalProductData = 0x03 ,
339
+ SlotIdentification = 0x04 ,
340
+ MessageSignalledInterrupts = 0x05 ,
341
+ CompactPciHotSwap = 0x06 ,
342
+ PciX = 0x07 ,
343
+ HyperTransport = 0x08 ,
344
+ VendorSpecific = 0x09 ,
345
+ Debugport = 0x0A ,
346
+ CompactPciCentralResourceControl = 0x0B ,
347
+ PciStandardHotPlugController = 0x0C ,
348
+ BridgeSubsystemVendorDeviceId = 0x0D ,
349
+ AgpTargetPciPcibridge = 0x0E ,
350
+ SecureDevice = 0x0F ,
351
+ PciExpress = 0x10 ,
352
+ MsiX = 0x11 ,
353
+ SataDataIndexConf = 0x12 ,
354
+ PciAdvancedFeatures = 0x13 ,
355
+ PciEnhancedAllocation = 0x14 ,
356
+ }
357
+
358
+ impl From < u8 > for PciCapabilityId {
359
+ fn from ( c : u8 ) -> Self {
360
+ match c {
361
+ 0 => PciCapabilityId :: ListId ,
362
+ 0x01 => PciCapabilityId :: PowerManagement ,
363
+ 0x02 => PciCapabilityId :: AcceleratedGraphicsPort ,
364
+ 0x03 => PciCapabilityId :: VitalProductData ,
365
+ 0x04 => PciCapabilityId :: SlotIdentification ,
366
+ 0x05 => PciCapabilityId :: MessageSignalledInterrupts ,
367
+ 0x06 => PciCapabilityId :: CompactPciHotSwap ,
368
+ 0x07 => PciCapabilityId :: PciX ,
369
+ 0x08 => PciCapabilityId :: HyperTransport ,
370
+ 0x09 => PciCapabilityId :: VendorSpecific ,
371
+ 0x0A => PciCapabilityId :: Debugport ,
372
+ 0x0B => PciCapabilityId :: CompactPciCentralResourceControl ,
373
+ 0x0C => PciCapabilityId :: PciStandardHotPlugController ,
374
+ 0x0D => PciCapabilityId :: BridgeSubsystemVendorDeviceId ,
375
+ 0x0E => PciCapabilityId :: AgpTargetPciPcibridge ,
376
+ 0x0F => PciCapabilityId :: SecureDevice ,
377
+ 0x10 => PciCapabilityId :: PciExpress ,
378
+ 0x11 => PciCapabilityId :: MsiX ,
379
+ 0x12 => PciCapabilityId :: SataDataIndexConf ,
380
+ 0x13 => PciCapabilityId :: PciAdvancedFeatures ,
381
+ 0x14 => PciCapabilityId :: PciEnhancedAllocation ,
382
+ _ => PciCapabilityId :: ListId ,
383
+ }
384
+ }
385
+ }
386
+
387
+ /// Types of PCI Express capabilities.
388
+ #[ derive( PartialEq , Eq , Copy , Clone , Debug ) ]
389
+ #[ allow( dead_code) ]
390
+ #[ repr( u16 ) ]
391
+ pub enum PciExpressCapabilityId {
392
+ NullCapability = 0x0000 ,
393
+ AdvancedErrorReporting = 0x0001 ,
394
+ VirtualChannelMultiFunctionVirtualChannelNotPresent = 0x0002 ,
395
+ DeviceSerialNumber = 0x0003 ,
396
+ PowerBudgeting = 0x0004 ,
397
+ RootComplexLinkDeclaration = 0x0005 ,
398
+ RootComplexInternalLinkControl = 0x0006 ,
399
+ RootComplexEventCollectorEndpointAssociation = 0x0007 ,
400
+ MultiFunctionVirtualChannel = 0x0008 ,
401
+ VirtualChannelMultiFunctionVirtualChannelPresent = 0x0009 ,
402
+ RootComplexRegisterBlock = 0x000a ,
403
+ VendorSpecificExtendedCapability = 0x000b ,
404
+ ConfigurationAccessCorrelation = 0x000c ,
405
+ AccessControlServices = 0x000d ,
406
+ AlternativeRoutingIdentificationInterpretation = 0x000e ,
407
+ AddressTranslationServices = 0x000f ,
408
+ SingleRootIoVirtualization = 0x0010 ,
409
+ DeprecatedMultiRootIoVirtualization = 0x0011 ,
410
+ Multicast = 0x0012 ,
411
+ PageRequestInterface = 0x0013 ,
412
+ ReservedForAmd = 0x0014 ,
413
+ ResizeableBar = 0x0015 ,
414
+ DynamicPowerAllocation = 0x0016 ,
415
+ ThpRequester = 0x0017 ,
416
+ LatencyToleranceReporting = 0x0018 ,
417
+ SecondaryPciExpress = 0x0019 ,
418
+ ProtocolMultiplexing = 0x001a ,
419
+ ProcessAddressSpaceId = 0x001b ,
420
+ LnRequester = 0x001c ,
421
+ DownstreamPortContainment = 0x001d ,
422
+ L1PmSubstates = 0x001e ,
423
+ PrecisionTimeMeasurement = 0x001f ,
424
+ PciExpressOverMphy = 0x0020 ,
425
+ FRSQueueing = 0x0021 ,
426
+ ReadinessTimeReporting = 0x0022 ,
427
+ DesignatedVendorSpecificExtendedCapability = 0x0023 ,
428
+ VfResizeableBar = 0x0024 ,
429
+ DataLinkFeature = 0x0025 ,
430
+ PhysicalLayerSixteenGts = 0x0026 ,
431
+ LaneMarginingAtTheReceiver = 0x0027 ,
432
+ HierarchyId = 0x0028 ,
433
+ NativePcieEnclosureManagement = 0x0029 ,
434
+ PhysicalLayerThirtyTwoGts = 0x002a ,
435
+ AlternateProtocol = 0x002b ,
436
+ SystemFirmwareIntermediary = 0x002c ,
437
+ ShadowFunctions = 0x002d ,
438
+ DataObjectExchange = 0x002e ,
439
+ Reserved = 0x002f ,
440
+ ExtendedCapabilitiesAbsence = 0xffff ,
441
+ }
442
+
443
+ impl From < u16 > for PciExpressCapabilityId {
444
+ fn from ( c : u16 ) -> Self {
445
+ match c {
446
+ 0x0000 => PciExpressCapabilityId :: NullCapability ,
447
+ 0x0001 => PciExpressCapabilityId :: AdvancedErrorReporting ,
448
+ 0x0002 => PciExpressCapabilityId :: VirtualChannelMultiFunctionVirtualChannelNotPresent ,
449
+ 0x0003 => PciExpressCapabilityId :: DeviceSerialNumber ,
450
+ 0x0004 => PciExpressCapabilityId :: PowerBudgeting ,
451
+ 0x0005 => PciExpressCapabilityId :: RootComplexLinkDeclaration ,
452
+ 0x0006 => PciExpressCapabilityId :: RootComplexInternalLinkControl ,
453
+ 0x0007 => PciExpressCapabilityId :: RootComplexEventCollectorEndpointAssociation ,
454
+ 0x0008 => PciExpressCapabilityId :: MultiFunctionVirtualChannel ,
455
+ 0x0009 => PciExpressCapabilityId :: VirtualChannelMultiFunctionVirtualChannelPresent ,
456
+ 0x000a => PciExpressCapabilityId :: RootComplexRegisterBlock ,
457
+ 0x000b => PciExpressCapabilityId :: VendorSpecificExtendedCapability ,
458
+ 0x000c => PciExpressCapabilityId :: ConfigurationAccessCorrelation ,
459
+ 0x000d => PciExpressCapabilityId :: AccessControlServices ,
460
+ 0x000e => PciExpressCapabilityId :: AlternativeRoutingIdentificationInterpretation ,
461
+ 0x000f => PciExpressCapabilityId :: AddressTranslationServices ,
462
+ 0x0010 => PciExpressCapabilityId :: SingleRootIoVirtualization ,
463
+ 0x0011 => PciExpressCapabilityId :: DeprecatedMultiRootIoVirtualization ,
464
+ 0x0012 => PciExpressCapabilityId :: Multicast ,
465
+ 0x0013 => PciExpressCapabilityId :: PageRequestInterface ,
466
+ 0x0014 => PciExpressCapabilityId :: ReservedForAmd ,
467
+ 0x0015 => PciExpressCapabilityId :: ResizeableBar ,
468
+ 0x0016 => PciExpressCapabilityId :: DynamicPowerAllocation ,
469
+ 0x0017 => PciExpressCapabilityId :: ThpRequester ,
470
+ 0x0018 => PciExpressCapabilityId :: LatencyToleranceReporting ,
471
+ 0x0019 => PciExpressCapabilityId :: SecondaryPciExpress ,
472
+ 0x001a => PciExpressCapabilityId :: ProtocolMultiplexing ,
473
+ 0x001b => PciExpressCapabilityId :: ProcessAddressSpaceId ,
474
+ 0x001c => PciExpressCapabilityId :: LnRequester ,
475
+ 0x001d => PciExpressCapabilityId :: DownstreamPortContainment ,
476
+ 0x001e => PciExpressCapabilityId :: L1PmSubstates ,
477
+ 0x001f => PciExpressCapabilityId :: PrecisionTimeMeasurement ,
478
+ 0x0020 => PciExpressCapabilityId :: PciExpressOverMphy ,
479
+ 0x0021 => PciExpressCapabilityId :: FRSQueueing ,
480
+ 0x0022 => PciExpressCapabilityId :: ReadinessTimeReporting ,
481
+ 0x0023 => PciExpressCapabilityId :: DesignatedVendorSpecificExtendedCapability ,
482
+ 0x0024 => PciExpressCapabilityId :: VfResizeableBar ,
483
+ 0x0025 => PciExpressCapabilityId :: DataLinkFeature ,
484
+ 0x0026 => PciExpressCapabilityId :: PhysicalLayerSixteenGts ,
485
+ 0x0027 => PciExpressCapabilityId :: LaneMarginingAtTheReceiver ,
486
+ 0x0028 => PciExpressCapabilityId :: HierarchyId ,
487
+ 0x0029 => PciExpressCapabilityId :: NativePcieEnclosureManagement ,
488
+ 0x002a => PciExpressCapabilityId :: PhysicalLayerThirtyTwoGts ,
489
+ 0x002b => PciExpressCapabilityId :: AlternateProtocol ,
490
+ 0x002c => PciExpressCapabilityId :: SystemFirmwareIntermediary ,
491
+ 0x002d => PciExpressCapabilityId :: ShadowFunctions ,
492
+ 0x002e => PciExpressCapabilityId :: DataObjectExchange ,
493
+ 0xffff => PciExpressCapabilityId :: ExtendedCapabilitiesAbsence ,
494
+ _ => PciExpressCapabilityId :: Reserved ,
495
+ }
496
+ }
497
+ }
498
+
499
+ /// See pci_regs.h in kernel
500
+ #[ derive( Copy , Clone , PartialEq , Eq , Serialize , Deserialize , Debug ) ]
501
+ pub enum PciBarRegionType {
502
+ Memory32BitRegion = 0 ,
503
+ IoRegion = 0x01 ,
504
+ Memory64BitRegion = 0x04 ,
505
+ }
506
+
507
+ #[ derive( Debug , Copy , Clone , Serialize , Deserialize ) ]
508
+ pub enum PciBarPrefetchable {
509
+ NotPrefetchable = 0 ,
510
+ Prefetchable = 0x08 ,
511
+ }
512
+
513
+ impl From < PciBarPrefetchable > for bool {
514
+ fn from ( val : PciBarPrefetchable ) -> Self {
515
+ match val {
516
+ PciBarPrefetchable :: NotPrefetchable => false ,
517
+ PciBarPrefetchable :: Prefetchable => true ,
518
+ }
519
+ }
520
+ }
521
+
205
522
#[ cfg( test) ]
206
523
mod tests {
207
524
use super :: * ;
0 commit comments