2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Export RAM dataspace as shared memory object
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2009-10-02
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2012-01-03 15:35:05 +01:00
|
|
|
* Copyright (C) 2009-2012 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* 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>
|
|
|
|
#include <base/thread.h>
|
|
|
|
|
|
|
|
/* core includes */
|
|
|
|
#include <ram_session_component.h>
|
|
|
|
#include <platform.h>
|
|
|
|
#include <util.h>
|
|
|
|
#include <nova_util.h>
|
|
|
|
|
|
|
|
/* NOVA includes */
|
|
|
|
#include <nova/syscalls.h>
|
|
|
|
|
|
|
|
enum { verbose_ram_ds = false };
|
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { }
|
2012-10-17 15:50:05 +02:00
|
|
|
|
|
|
|
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds)
|
|
|
|
{
|
|
|
|
size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask();
|
|
|
|
|
|
|
|
unmap_local((Nova::Utcb *)Thread_base::myself()->utcb(),
|
|
|
|
ds->core_local_addr(),
|
|
|
|
page_rounded_size >> get_page_size_log2());
|
|
|
|
|
|
|
|
platform()->region_alloc()->free((void*)ds->core_local_addr(),
|
|
|
|
page_rounded_size);
|
|
|
|
|
|
|
|
ds->assign_core_local_addr(0);
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
void Ram_session_component::_clear_ds(Dataspace_component *ds)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Map dataspace core-locally and clear its content
|
|
|
|
*/
|
|
|
|
|
|
|
|
size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate range in core's virtual address space
|
|
|
|
*
|
|
|
|
* Start with trying to use natural alignment. If this does not work,
|
|
|
|
* successively weaken the alignment constraint until we hit the page size.
|
|
|
|
*/
|
|
|
|
void *virt_addr;
|
|
|
|
bool virt_alloc_succeeded = false;
|
|
|
|
size_t align_log2 = log2(ds->size());
|
|
|
|
for (; align_log2 >= get_page_size_log2(); align_log2--) {
|
|
|
|
if (platform()->region_alloc()->alloc_aligned(page_rounded_size,
|
2012-11-28 22:50:08 +01:00
|
|
|
&virt_addr, align_log2).is_ok()) {
|
2011-12-22 16:19:25 +01:00
|
|
|
virt_alloc_succeeded = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!virt_alloc_succeeded) {
|
|
|
|
PERR("Could not allocate virtual address range in core of size %zd\n",
|
|
|
|
page_rounded_size);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (verbose_ram_ds)
|
2012-06-07 09:35:22 +02:00
|
|
|
printf("-- ram ds size=%zx phys %lx has core-local addr %p\n",
|
2011-12-22 16:19:25 +01:00
|
|
|
page_rounded_size, ds->phys_addr(), virt_addr);
|
|
|
|
|
|
|
|
/* map the dataspace's physical pages to local addresses */
|
2012-11-20 10:05:14 +01:00
|
|
|
const Nova::Rights rights(true, true, true);
|
2011-12-22 16:19:25 +01:00
|
|
|
map_local((Nova::Utcb *)Thread_base::myself()->utcb(),
|
|
|
|
ds->phys_addr(), (addr_t)virt_addr,
|
2012-11-20 10:05:14 +01:00
|
|
|
page_rounded_size >> get_page_size_log2(), rights, true);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
memset(virt_addr, 0, page_rounded_size);
|
|
|
|
|
|
|
|
ds->assign_core_local_addr(virt_addr);
|
|
|
|
}
|