PCI Bus Operations
Relevant source files
This document covers the PCI (Peripheral Component Interconnect) bus operations provided by the axdriver_pci
crate. This crate serves as a bridge between the ArceOS driver framework and PCI device discovery and management functionality. It provides the foundational infrastructure for PCI device enumeration, configuration space access, and memory-mapped I/O (MMIO) region allocation needed by hardware device drivers.
For information about specific device driver implementations that use PCI operations, see Network Drivers and Block Storage Drivers. For VirtIO device integration over PCI transport, see VirtIO Integration.
Architecture Overview
The PCI bus operations layer sits between the hardware abstraction and device-specific drivers, providing standardized access to PCI configuration and memory management.
PCI Integration Architecture
flowchart TD subgraph subGraph3["Device Drivers"] NETDRIVERS["Network Drivers(ixgbe, VirtIO-Net)"] BLOCKDRIVERS["Block Drivers(VirtIO-Block)"] DISPLAYDRIVERS["Display Drivers(VirtIO-GPU)"] end subgraph subGraph2["virtio-drivers Foundation"] VIRTIOPCI["virtio_drivers::transport::pci::bus"] PCITYPES["PCI Types & Operations"] end subgraph subGraph1["axdriver_pci Layer"] PCIROOT["PciRootBus enumeration"] DEVICEFUNC["DeviceFunctionDevice access"] ALLOCATOR["PciRangeAllocatorMMIO allocation"] BARINFO["BarInfoMemory region info"] end subgraph subGraph0["Hardware Layer"] PCIHW["PCI Hardware Bus"] DEVICES["PCI Devices(Network, Storage, Display)"] end ALLOCATOR --> BLOCKDRIVERS ALLOCATOR --> DISPLAYDRIVERS ALLOCATOR --> NETDRIVERS DEVICEFUNC --> BLOCKDRIVERS DEVICEFUNC --> DISPLAYDRIVERS DEVICEFUNC --> NETDRIVERS DEVICES --> VIRTIOPCI PCIHW --> VIRTIOPCI PCIROOT --> BLOCKDRIVERS PCIROOT --> DISPLAYDRIVERS PCIROOT --> NETDRIVERS PCITYPES --> ALLOCATOR VIRTIOPCI --> BARINFO VIRTIOPCI --> DEVICEFUNC VIRTIOPCI --> PCIROOT
Sources: axdriver_pci/src/lib.rs(L1 - L14) axdriver_pci/Cargo.toml(L14 - L15)
Core PCI Types and Operations
The axdriver_pci
crate primarily re-exports essential PCI types from the virtio-drivers
crate, providing a consistent interface for PCI device management across the ArceOS ecosystem.
Device Discovery and Access
Type | Purpose | Key Operations |
---|---|---|
PciRoot | Root PCI bus controller | Device enumeration and scanning |
DeviceFunction | Individual PCI device/function | Configuration space access |
DeviceFunctionInfo | Device metadata | Vendor ID, device ID, class codes |
CapabilityInfo | PCI capabilities | Extended feature discovery |
Memory and I/O Management
Type | Purpose | Usage |
---|---|---|
BarInfo | Base Address Register info | Memory region mapping |
MemoryBarType | Memory BAR classification | 32-bit vs 64-bit addressing |
Command | PCI command register | Bus mastering, memory enable |
Status | PCI status register | Capability support, error status |
PCI Type Relationships
flowchart TD subgraph Configuration["Configuration"] COMMAND["Command"] STATUS["Status"] CAPINFO["CapabilityInfo"] end subgraph subGraph1["Memory Management"] BARINFO["BarInfo"] MEMBARTYPE["MemoryBarType"] ALLOCATOR["PciRangeAllocator"] end subgraph subGraph0["Device Discovery"] PCIROOT["PciRoot"] DEVICEFUNC["DeviceFunction"] DEVINFO["DeviceFunctionInfo"] end BARINFO --> ALLOCATOR BARINFO --> MEMBARTYPE DEVICEFUNC --> BARINFO DEVICEFUNC --> CAPINFO DEVICEFUNC --> COMMAND DEVICEFUNC --> DEVINFO DEVICEFUNC --> STATUS PCIROOT --> DEVICEFUNC
Sources: axdriver_pci/src/lib.rs(L11 - L14)
MMIO Range Allocation
The PciRangeAllocator
provides a custom memory allocation system specifically designed for PCI Base Address Register (BAR) allocation. This allocator ensures proper alignment and prevents memory region conflicts.
Allocator Structure
The PciRangeAllocator
maintains a simple linear allocation strategy:
pub struct PciRangeAllocator {
_start: u64, // Base address of allocatable region
end: u64, // End boundary of allocatable region
current: u64, // Current allocation pointer
}
Allocation Algorithm
The allocator implements power-of-2 aligned allocation with the following constraints:
Property | Requirement | Rationale |
---|---|---|
Size alignment | Must be power of 2 | PCI BAR size requirements |
Address alignment | Multiple of size | Hardware addressing constraints |
Boundary checking | Within allocated range | Memory safety |
MMIO Allocation Flow
flowchart TD START["alloc(size: u64)"] CHECK_POW2["size.is_power_of_two()"] ALIGN["ret = align_up(current, size)"] CHECK_BOUNDS["ret + size > end?"] UPDATE["current = ret + size"] RETURN_ADDR["return Some(ret)"] RETURN_NONE["return None"] ALIGN --> CHECK_BOUNDS CHECK_BOUNDS --> RETURN_NONE CHECK_BOUNDS --> UPDATE CHECK_POW2 --> ALIGN CHECK_POW2 --> RETURN_NONE START --> CHECK_POW2 UPDATE --> RETURN_ADDR
Usage Example
The typical allocation pattern for PCI BARs:
- Create allocator with memory range:
PciRangeAllocator::new(base, size)
- Request aligned memory:
allocator.alloc(bar_size)
- Map returned address to device BAR
Sources: axdriver_pci/src/lib.rs(L17 - L53)
Integration with Device Drivers
The PCI operations integrate with device drivers through standardized patterns for device discovery, configuration, and memory mapping.
Typical Driver Integration Pattern
sequenceDiagram participant DeviceDriver as "Device Driver" participant PciRoot as "PciRoot" participant DeviceFunction as "DeviceFunction" participant PciRangeAllocator as "PciRangeAllocator" DeviceDriver ->> PciRoot: Enumerate devices PciRoot ->> DeviceDriver: Found matching device DeviceDriver ->> DeviceFunction: Read configuration DeviceFunction ->> DeviceDriver: Device info & BARs DeviceDriver ->> PciRangeAllocator: Request MMIO region PciRangeAllocator ->> DeviceDriver: Allocated address DeviceDriver ->> DeviceFunction: Configure BAR mapping DeviceFunction ->> DeviceDriver: Device ready
Error Handling
PCI operations use the PciError
type for consistent error reporting across device initialization and configuration operations.
Sources: axdriver_pci/src/lib.rs(L11)
Dependencies and External Integration
The axdriver_pci
crate builds upon the virtio-drivers
crate version 0.7.4, specifically leveraging its PCI transport layer. This dependency provides:
- Low-level PCI configuration space access
- Standard PCI type definitions
- Cross-platform PCI hardware abstraction
The integration allows ArceOS drivers to benefit from the mature PCI implementation in virtio-drivers
while maintaining the consistent ArceOS driver interface patterns.
Sources: axdriver_pci/Cargo.toml(L15) axdriver_pci/src/lib.rs(L3 - L7)