/* * \brief Allocator for core-local memory * \author Norman Feske * \date 2009-10-12 */ /* * Copyright (C) 2009-2013 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 /* local includes */ #include #include 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); }