rdif_pcie/
bar_alloc.rs

1use crate::{
2    PciMem32, PciMem64,
3    addr_alloc::{self, AddressAllocator, AllocPolicy},
4};
5
6#[derive(Default)]
7pub struct SimpleBarAllocator {
8    // Non-prefetchable windows
9    mem32: Option<AddressAllocator>,
10    mem64: Option<AddressAllocator>,
11    // Prefetchable windows
12    mem32_pref: Option<AddressAllocator>,
13    mem64_pref: Option<AddressAllocator>,
14}
15
16impl SimpleBarAllocator {
17    /// Convenience: add a 32-bit window with prefetchable attribute.
18    pub fn set_mem32(
19        &mut self,
20        space: PciMem32,
21        prefetchable: bool,
22    ) -> Result<(), addr_alloc::Error> {
23        let a = AddressAllocator::new(space.address as _, space.size as _)?;
24        if prefetchable {
25            self.mem32_pref = Some(a);
26        } else {
27            self.mem32 = Some(a);
28        }
29        Ok(())
30    }
31
32    /// Convenience: add a 64-bit window with prefetchable attribute.
33    pub fn set_mem64(
34        &mut self,
35        space: PciMem64,
36        prefetchable: bool,
37    ) -> Result<(), addr_alloc::Error> {
38        let a = AddressAllocator::new(space.address as _, space.size as _)?;
39        if prefetchable {
40            self.mem64_pref = Some(a);
41        } else {
42            self.mem64 = Some(a);
43        }
44        Ok(())
45    }
46
47    pub fn alloc_memory32(&mut self, size: u32, prefetchable: bool) -> Option<u32> {
48        if prefetchable
49            && let Some(set) = self.mem32_pref.as_mut()
50            && let Ok(addr) = set.allocate(size as _, size as _, AllocPolicy::FirstMatch)
51        {
52            return Some(addr.start() as _);
53        }
54
55        let res = self
56            .mem32
57            .as_mut()?
58            .allocate(size as _, size as _, AllocPolicy::FirstMatch)
59            .ok()?;
60        Some(res.start() as _)
61    }
62
63    pub fn alloc_memory64(&mut self, size: u64, prefetchable: bool) -> Option<u64> {
64        if prefetchable
65            && let Some(set) = self.mem64_pref.as_mut()
66            && let Ok(addr) = set.allocate(size as _, size as _, AllocPolicy::FirstMatch)
67        {
68            return Some(addr.start() as _);
69        }
70
71        let res = self
72            .mem64
73            .as_mut()?
74            .allocate(size as _, size as _, AllocPolicy::FirstMatch)
75            .ok()?;
76        Some(res.start() as _)
77    }
78}