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}