64 lines
1.9 KiB
C++
64 lines
1.9 KiB
C++
/*
|
|
* \brief Allocator for core-local memory
|
|
* \author Norman Feske
|
|
* \date 2009-10-12
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2009-2012 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/printf.h>
|
|
|
|
/* local includes */
|
|
#include <core_mem_alloc.h>
|
|
#include <util.h>
|
|
|
|
using namespace Genode;
|
|
|
|
static const bool verbose_core_mem_alloc = false;
|
|
|
|
|
|
bool Core_mem_allocator::Mapped_mem_allocator::alloc(size_t size, void **out_addr)
|
|
{
|
|
/* try to allocate block in cores already mapped virtual address ranges */
|
|
if (_alloc.alloc(size, out_addr))
|
|
return true;
|
|
|
|
/* there is no sufficient space in core's mapped virtual memory, expansion needed */
|
|
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
|
|
void *phys_addr = 0, *virt_addr = 0;
|
|
|
|
/* allocate physical pages */
|
|
if (!_phys_alloc->alloc(page_rounded_size, &phys_addr)) {
|
|
PERR("Could not allocate physical memory region of size %zd\n", page_rounded_size);
|
|
return false;
|
|
}
|
|
|
|
/* allocate range in core's virtual address space */
|
|
if (!_virt_alloc->alloc(page_rounded_size, &virt_addr)) {
|
|
PERR("Could not allocate virtual address range in core of size %zd\n", page_rounded_size);
|
|
|
|
/* revert physical allocation */
|
|
_phys_alloc->free(phys_addr);
|
|
return false;
|
|
}
|
|
|
|
if (verbose_core_mem_alloc)
|
|
printf("added core memory block of %zd bytes at virt=%p phys=%p\n",
|
|
page_rounded_size, virt_addr, phys_addr);
|
|
|
|
/* make physical page accessible at the designated virtual address */
|
|
_map_local((addr_t)virt_addr, (addr_t)phys_addr, get_page_size_log2());
|
|
|
|
/* add new range to core's allocator for mapped virtual memory */
|
|
_alloc.add_range((addr_t)virt_addr, page_rounded_size);
|
|
|
|
/* now that we have added enough memory, try again... */
|
|
return _alloc.alloc(size, out_addr);
|
|
}
|