Skip to main content

axdriver_pci/
lib.rs

1//! Structures and functions for PCI bus operations.
2//!
3//! Currently, it just re-exports structures from the crate [virtio-drivers][1]
4//! and its module [`virtio_drivers::transport::pci::bus`][2].
5//!
6//! [1]: https://docs.rs/virtio-drivers/latest/virtio_drivers/
7//! [2]: https://docs.rs/virtio-drivers/latest/virtio_drivers/transport/pci/bus/index.html
8
9#![no_std]
10
11pub use virtio_drivers::transport::pci::bus::{
12    BarInfo, Cam, CapabilityInfo, Command, DeviceFunction, DeviceFunctionInfo, HeaderType,
13    MemoryBarType, PciError, PciRoot, Status,
14};
15
16/// Used to allocate MMIO regions for PCI BARs.
17pub struct PciRangeAllocator {
18    _start: u64,
19    end: u64,
20    current: u64,
21}
22
23impl PciRangeAllocator {
24    /// Creates a new allocator from a memory range.
25    pub const fn new(base: u64, size: u64) -> Self {
26        Self {
27            _start: base,
28            end: base + size,
29            current: base,
30        }
31    }
32
33    /// Allocates a memory region with the given size.
34    ///
35    /// The `size` should be a power of 2, and the returned value is also a
36    /// multiple of `size`.
37    pub fn alloc(&mut self, size: u64) -> Option<u64> {
38        if !size.is_power_of_two() {
39            return None;
40        }
41        let ret = align_up(self.current, size);
42        if ret + size > self.end {
43            return None;
44        }
45
46        self.current = ret + size;
47        Some(ret)
48    }
49}
50
51const fn align_up(addr: u64, align: u64) -> u64 {
52    (addr + align - 1) & !(align - 1)
53}