-
-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port of the pci
crate
#1019
Port of the pci
crate
#1019
Conversation
Not sure if you're ready for me to re-review it or if you're still in the process of making changes. Once you're done, click the re-request review button at the top right under "Reviewers" so I know for sure. |
I merged in #972, please update this PR to incorporate those changes. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one small comment; most other changes look great!
How much have you tested this, e.g., does it fully work with all existing supported devices on aarch64 and x86_64?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haven't yet tested it on my machine, but i did leave a few more suggestions.
Disk I/O works correctly with your changes 👍 |
I just noticed something weird that is also present in the original implementation. In |
That's true, I think that's intentional though, as it's a "raw" inner function that is designed to be used by other public PCI functions. I suppose the idea is that if you wanted to preserve those bits, you would have read the existing value right before that and then passed in the updated value to that write function. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still waiting on the PciAddress
-related fixes, some pending comments there. After that we can merge.
@kevinaboos I replaced the previous pci read/writers with this: impl PciLocation {
/// Read a 4-bytes register from the PCI Configuration Space.
///
/// Panics if the register isn't a [`FullDword`]
fn pci_read_32(&self, register: PciRegister) -> u32
/// Read a 2-bytes register from the PCI Configuration Space.
///
/// Panics if the register isn't a [`Word0`] / [`Word1`]
fn pci_read_16(&self, register: PciRegister) -> u16
/// Read a one-byte register from the PCI Configuration Space.
///
/// Panics if the register isn't a [`Byte0`] / [`Byte1`] / [`Byte2`] / [`Byte3`]
fn pci_read_8(&self, register: PciRegister) -> u8;
/// Write a 4-bytes register from the PCI Configuration Space.
///
/// Panics if the register isn't a [`FullDword`]
fn pci_write_32(&self, register: PciRegister, value: u32);
/// Write a 2-bytes register from the PCI Configuration Space.
///
/// Panics if the register isn't a [`Word0`] / [`Word1`]
fn pci_write_16(&self, register: PciRegister, value: u16);
/// Write a one-byte register from the PCI Configuration Space.
///
/// Panics if the register isn't a [`Byte0`] / [`Byte1`] / [`Byte2`] / [`Byte3`]
fn pci_write_8(&self, register: PciRegister, value: u8);
}
/// (PCI Config Space Dword Index, Register Span)
type PciRegister = (u8, RegisterSpan);
enum RegisterSpan {
/// Bits [0:31]
FullDword,
/// Bits [0:15]
Word0,
/// Bits [16:31]
Word1,
/// Bits [0:7]
Byte0,
/// Bits [8:15]
Byte1,
/// Bits [16:23]
Byte2,
/// Bits [24:31]
Byte3,
}
const PCI_VENDOR_ID: PciRegister = (0x0, Word0);
const PCI_DEVICE_ID: PciRegister = (0x0, Word1);
const PCI_COMMAND: PciRegister = (0x1, Word0);
const PCI_STATUS: PciRegister = (0x1, Word1);
const PCI_REVISION_ID: PciRegister = (0x2, Byte0);
const PCI_PROG_IF: PciRegister = (0x2, Byte1);
// ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some changes to clean things up a bit. I like the introduction of all the new types, but we can actually go further to use traits and trait bounds to move all of the assertions into compile time type errors. We'll save that for the next PR.
* Support PCI on aarch64 via MMIO access mechanisms. * Redesign the PCI addressing code to be very clear and use more types. Currently some checks are done at runtime with assertions, but these could easily be moved to compile time by introducing traits about register sizes that can be implemented by each `RegisterSpan` within the `PciRegister` type. * Note: PCI currently uses Port I/O on x86 and MMIO on aarch64 to read/write, but x86_64 may also use MMIO-based access in the future, because Port I/O is the legacy method to access the PCI configuration space. * The `device_manager` now initializes and scans the PCI bus on both the aarch64 and x86_64 platforms. * Scanning the PCI bus for the first time also maps the memory behind the configuration space. Co-authored-by: Kevin Boos <[email protected]> e979b80
…eus-os#1019) * Support PCI on aarch64 via MMIO access mechanisms. * Redesign the PCI addressing code to be very clear and use more types. Currently some checks are done at runtime with assertions, but these could easily be moved to compile time by introducing traits about register sizes that can be implemented by each `RegisterSpan` within the `PciRegister` type. * Note: PCI currently uses Port I/O on x86 and MMIO on aarch64 to read/write, but x86_64 may also use MMIO-based access in the future, because Port I/O is the legacy method to access the PCI configuration space. * The `device_manager` now initializes and scans the PCI bus on both the aarch64 and x86_64 platforms. * Scanning the PCI bus for the first time also maps the memory behind the configuration space. Co-authored-by: Kevin Boos <[email protected]>
This brings the following changes:
pci::scan_pci
maps the pci config space on aarch64, in addition to what it used to do.pci::PciLocation
was modified so that it uses the mapping on aarch64device_manager
calls it (via pci_device_iter) on both platformsconst
offsets to an enum but the capability "linked-list" fromfind_pci_capability
needs the offset to be a raw u8, and I might also need custom offsets for USB support so I dropped this.QEMU_FLAGS
starts the virt machine with new options:highmem=on
&highmem-mmio=on
because without them, the PCI configuration space lies in "low memory" but its base address points to a bunch of zeros for some reason.Note: while
pci
currently uses port-io on x86 and mmio on aarch64, x86 may also support memory-based PCI configuration in the future; port-io is the legacy way to access the config space.