use align_address::Align;
use thiserror::Error;
use uhyve_interface::GuestPhysAddr;
#[derive(Error, Debug)]
pub enum PagetableError {
#[error("The accessed virtual address is not mapped")]
InvalidAddress,
}
pub(crate) struct BumpAllocator<const FRAMESIZE: u64> {
start: GuestPhysAddr,
length: u64,
cnt: u64,
}
impl<const FRAMESIZE: u64> BumpAllocator<FRAMESIZE> {
pub(crate) fn new(start: GuestPhysAddr, length: u64) -> Self {
assert!(start.as_u64().is_aligned_to(FRAMESIZE));
Self {
start,
length,
cnt: 0,
}
}
pub(crate) fn allocate(&mut self) -> Option<GuestPhysAddr> {
if self.cnt < self.length {
let f = self.start + self.cnt * FRAMESIZE;
self.cnt += 1;
Some(f)
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use uhyve_interface::GuestPhysAddr;
use super::*;
#[test]
fn test_bump_frame_allocator() {
let mut ba = BumpAllocator::<0x1000>::new(GuestPhysAddr::new(0x40_0000), 4);
assert_eq!(ba.allocate(), Some(GuestPhysAddr::new(0x40_0000)));
assert_eq!(ba.allocate(), Some(GuestPhysAddr::new(0x40_1000)));
assert_eq!(ba.allocate(), Some(GuestPhysAddr::new(0x40_2000)));
assert_eq!(ba.allocate(), Some(GuestPhysAddr::new(0x40_3000)));
assert_eq!(ba.allocate(), None);
}
}