pub fn allocate_and_map_memory(
        &mut self,
        mapper: &mut (impl Mapper<Size4KiB> + Mapper<Size2MiB>),
        map_to: VirtAddr,
        size: usize,
        flags: PageTableFlags,
        parent_flags: PageTableFlags,
    ) -> Result<&'static mut [u8], AllocateError> {
        if size == 0 {
            return Err(AllocateError::ZeroSize);
        }

        if !map_to.is_aligned(align_of::<Page4KiB>() as u64) {
            return Err(AllocateError::NotAligned);
        }

        if size != align_down(size as _, Page::<Size4KiB>::SIZE) as usize {
            return Err(AllocateError::NotAligned);
        }

        let curr_size = (2usize).checked_pow(msb(size)).unwrap();

        let (first_half, first_half_size) = {
            while self.allocator.free() < curr_size {
                self.balloon();
            }
            let (chunk, chunk_size) = self.try_alloc_half(curr_size);

            if chunk.is_null() {
                self.balloon();
                self.try_alloc_half(curr_size)
            } else {
                (chunk, chunk_size)
            }
        };

        if first_half.is_null() {
            return Err(AllocateError::OutOfMemory);
        }

        let second_half_size = size.checked_sub(first_half_size).unwrap();

        if second_half_size > 0 {
            if let Err(e) = self.allocate_and_map_memory(
                mapper,
                map_to + first_half_size,
                second_half_size,
                flags,
                parent_flags,
            ) {
                unsafe {
                    self.dealloc_pages(first_half, first_half_size);
                }
                return Err(e);
            }
        }

        let phys = shim_virt_to_enc_phys(first_half);
        if let Err(e) = self.map_memory(mapper, phys, map_to, first_half_size, flags, parent_flags)
        {
            unsafe {
                self.dealloc_pages(first_half, first_half_size);
            }
            let _ = self.unmap_memory(mapper, map_to + first_half_size, second_half_size);
            return Err(e);
        }

        // transmute the whole thing to one big bytes slice
        Ok(unsafe { core::slice::from_raw_parts_mut(map_to.as_mut_ptr() as *mut u8, size) })
    }
/// Allocate memory and map it to the given virtual address
Allocate memory and map it to the given virtual address
Allocate memory and map it to the given virtual address
pub fn allocate_and_map_memory(
        &mut self,
        mapper: &mut (impl Mapper<Size4KiB> + Mapper<Size2MiB>),
        map_to: VirtAddr,
        size: usize,
        flags: PageTableFlags,
        parent_flags: PageTableFlags,
    ) -> Result<&'static mut [u8], AllocateError> {
        if size == 0 {
            return Err(AllocateError::ZeroSize);
        }
        if !map_to.is_aligned(align_of::<Page4KiB>() as u64) {
            return Err(AllocateError::NotAligned);
        }
        if size != align_down(size as _, Page::<Size4KiB>::SIZE) as usize {
            return Err(AllocateError::NotAligned);
        }
        let curr_size = (2usize).checked_pow(msb(size)).unwrap();
        let (first_half, first_half_size) = {
            while self.allocator.free() < curr_size {
                self.balloon();
            }
            let (chunk, chunk_size) = self.try_alloc_half(curr_size);
            if chunk.is_null() {
                self.balloon();
                self.try_alloc_half(curr_size)
            } else {
                (chunk, chunk_size)
            }
        };
        if first_half.is_null() {
            return Err(AllocateError::OutOfMemory);
        }
        let second_half_size = size.checked_sub(first_half_size).unwrap();
        if second_half_size > 0 {
            if let Err(e) = self.allocate_and_map_memory(
                mapper,
                map_to + first_half_size,
                second_half_size,
                flags,
                parent_flags,
            ) {
                unsafe {
                    self.dealloc_pages(first_half, first_half_size);
                }
                return Err(e);
            }
        }
        let phys = shim_virt_to_enc_phys(first_half);
        if let Err(e) = self.map_memory(mapper, phys, map_to, first_half_size, flags, parent_flags)
        {
            unsafe {
                self.dealloc_pages(first_half, first_half_size);
            }
            let _ = self.unmap_memory(mapper, map_to + first_half_size, second_half_size);
            return Err(e);
        }
        // transmute the whole thing to one big bytes slice
        Ok(unsafe { core::slice::from_raw_parts_mut(map_to.as_mut_ptr() as *mut u8, size) })
    }
pub fn allocate_and_map_memory ( & mut self , mapper : & mut ( impl Mapper < Size4KiB > + Mapper < Size2MiB > ) , map_to : VirtAddr , size : usize , flags : PageTableFlags , parent_flags : PageTableFlags , ) -> Result < & ' static mut [ u8 ] , AllocateError > { if size == 0 { return Err ( AllocateError :: ZeroSize ) ; } if ! map_to . is_aligned ( align_of :: < Page4KiB > ( ) as u64 ) { return Err ( AllocateError :: NotAligned ) ; } if size != align_down ( size as _ , Page :: < Size4KiB > :: SIZE ) as usize { return Err ( AllocateError :: NotAligned ) ; } let curr_size = ( 2usize ) . checked_pow ( msb ( size ) ) . unwrap ( ) ; let ( first_half , first_half_size ) = { while self . allocator . free ( ) < curr_size { self . balloon ( ) ; } let ( chunk , chunk_size ) = self . try_alloc_half ( curr_size ) ; if chunk . is_null ( ) { self . balloon ( ) ; self . try_alloc_half ( curr_size ) } else { ( chunk , chunk_size ) } } ; if first_half . is_null ( ) { return Err ( AllocateError :: OutOfMemory ) ; } let second_half_size = size . checked_sub ( first_half_size ) . unwrap ( ) ; if second_half_size > 0 { if let Err ( e ) = self . allocate_and_map_memory ( mapper , map_to + first_half_size , second_half_size , flags , parent_flags , ) { unsafe { self . dealloc_pages ( first_half , first_half_size ) ; } return Err ( e ) ; } } let phys = shim_virt_to_enc_phys ( first_half ) ; if let Err ( e ) = self . map_memory ( mapper , phys , map_to , first_half_size , flags , parent_flags ) { unsafe { self . dealloc_pages ( first_half , first_half_size ) ; } let _ = self . unmap_memory ( mapper , map_to + first_half_size , second_half_size ) ; return Err ( e ) ; } // transmute the whole thing to one big bytes slice Ok ( unsafe { core :: slice :: from_raw_parts_mut ( map_to . as_mut_ptr ( ) as * mut u8 , size ) } ) }
Allocate memory and map it to the given virtual address
Allocate memory and map it to the given virtual address
&mut self
mapper
&mut (impl Mapper<Size4KiB> + Mapper<Size2MiB>)
map_to
VirtAddr
size
usize
flags
PageTableFlags
parent_flags
PageTableFlags
&mut self
mapper
&mut (impl Mapper<Size4KiB> + Mapper<Size2MiB>)
map_to
VirtAddr
size
usize
flags
PageTableFlags
parent_flags
PageTableFlags