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) -> Option<u32> {
48        let res = self
49            .mem32
50            .as_mut()?
51            .allocate(size as _, size as _, AllocPolicy::FirstMatch)
52            .ok()?;
53        Some(res.start() as _)
54    }
55
56    pub fn alloc_memory64(&mut self, size: u64) -> Option<u64> {
57        let res = self
58            .mem64
59            .as_mut()?
60            .allocate(size as _, size as _, AllocPolicy::FirstMatch)
61            .ok()?;
62        Some(res.start() as _)
63    }
64
65    /// Allocate from 32-bit windows considering prefetchable flag.
66    pub fn alloc_memory32_with_pref(&mut self, size: u32, prefetchable: bool) -> Option<u32> {
67        if prefetchable && let Some(alloc) = self.mem32_pref.as_mut() {
68            let res = alloc
69                .allocate(size as _, size as _, AllocPolicy::FirstMatch)
70                .ok()?;
71            return Some(res.start() as _);
72        }
73        // fallback to non-prefetchable window
74        self.alloc_memory32(size)
75    }
76
77    /// Allocate from 64-bit windows considering prefetchable flag.
78    pub fn alloc_memory64_with_pref(&mut self, size: u64, prefetchable: bool) -> Option<u64> {
79        if prefetchable && let Some(alloc) = self.mem64_pref.as_mut() {
80            let res = alloc
81                .allocate(size as _, size as _, AllocPolicy::FirstMatch)
82                .ok()?;
83            return Some(res.start() as _);
84        }
85        // fallback to non-prefetchable window
86        self.alloc_memory64(size)
87    }
88}