chipset_device/pci.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! PCI configuration space access
5
6use crate::ChipsetDevice;
7use crate::io::IoResult;
8
9/// Implemented by devices which have a PCI config space.
10pub trait PciConfigSpace: ChipsetDevice {
11 /// Dispatch a PCI config space read to the device with the given address.
12 fn pci_cfg_read(&mut self, offset: u16, value: &mut u32) -> IoResult;
13 /// Dispatch a PCI config space write to the device with the given address.
14 fn pci_cfg_write(&mut self, offset: u16, value: u32) -> IoResult;
15
16 /// Check if the device has a suggested (bus, device, function) it expects
17 /// to be located at.
18 ///
19 /// The term "suggested" is important here, as it's important to note that
20 /// one of the major selling points of PCI was that PCI devices _shouldn't_
21 /// need to care about about what PCI address they are initialized at. i.e:
22 /// on a physical machine, it shouldn't matter that your fancy GTX 4090 is
23 /// plugged into the first vs. second PCI slot.
24 ///
25 /// ..that said, there are some instances where it makes sense for an
26 /// emulated device to declare its suggested PCI address:
27 ///
28 /// 1. Devices that emulate bespoke PCI devices part of a particular
29 /// system's chipset.
30 /// - e.g: the PIIX4 chipset includes several bespoke PCI devices that are
31 /// required to have specific PCI addresses. While it _would_ be
32 /// possible to relocate them to a different address, it may break OSes
33 /// that assume they exist at those spec-declared addresses.
34 /// 2. Multi-function PCI devices
35 /// - In an unfortunate case of inverted responsibilities, there is a
36 /// single bit in the PCI configuration space's `Header` register that
37 /// denotes if a particular PCI card includes multiple functions.
38 /// - Since multi-function devices are pretty rare, `ChipsetDevice` opted
39 /// to model each function as its own device, which in turn implies that
40 /// in order to correctly init a multi-function PCI card, the
41 /// `ChipsetDevice` with function 0 _must_ report if there are other
42 /// functions at the same bus and device.
43 fn suggested_bdf(&mut self) -> Option<(u8, u8, u8)> {
44 None
45 }
46}