mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-04 17:53:07 +00:00
parent
c0e88ec69e
commit
2e62543fdb
@ -25,6 +25,27 @@
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map dataspace core-locally
|
||||||
|
*/
|
||||||
|
static inline void * alloc_region(Dataspace_component *ds, const size_t size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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 = 0;
|
||||||
|
size_t align_log2 = log2(ds->size());
|
||||||
|
for (; align_log2 >= get_page_size_log2(); align_log2--) {
|
||||||
|
if (platform()->region_alloc()->alloc_aligned(size,
|
||||||
|
&virt_addr, align_log2).is_ok())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virt_addr;
|
||||||
|
}
|
||||||
|
|
||||||
Rm_session::Local_addr
|
Rm_session::Local_addr
|
||||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||||
@ -46,8 +67,35 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate range in core's virtual address space */
|
const size_t page_rounded_size = align_addr(ds->size(), get_page_size_log2());
|
||||||
return ds->core_local_addr();
|
|
||||||
|
/* allocate the virtual region contiguous for the dataspace */
|
||||||
|
void * virt_ptr = alloc_region(ds, page_rounded_size);
|
||||||
|
if (!virt_ptr)
|
||||||
|
throw Out_of_metadata();
|
||||||
|
|
||||||
|
/* map it */
|
||||||
|
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb());
|
||||||
|
const Nova::Rights rights(true, ds->writable(), executable);
|
||||||
|
|
||||||
|
if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
|
||||||
|
page_rounded_size >> get_page_size_log2(), rights, true)) {
|
||||||
|
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
||||||
|
throw Out_of_metadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
return virt_ptr;
|
||||||
};
|
};
|
||||||
return _ds_ep->apply(ds_cap, lambda);
|
return _ds_ep->apply(ds_cap, lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Core_rm_session::detach(Local_addr core_local_addr)
|
||||||
|
{
|
||||||
|
size_t size = platform_specific()->region_alloc_size_at(core_local_addr);
|
||||||
|
|
||||||
|
unmap_local(reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb()),
|
||||||
|
core_local_addr, size >> get_page_size_log2());
|
||||||
|
|
||||||
|
platform()->region_alloc()->free(core_local_addr);
|
||||||
|
}
|
||||||
|
@ -35,28 +35,21 @@ namespace Genode {
|
|||||||
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
|
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
|
||||||
off_t offset=0, bool use_local_addr = false,
|
off_t offset=0, bool use_local_addr = false,
|
||||||
Local_addr local_addr = 0,
|
Local_addr local_addr = 0,
|
||||||
bool executable = false);
|
bool executable = false) override;
|
||||||
|
|
||||||
void detach(Local_addr)
|
void detach(Local_addr) override;
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The core-local mapping gets established in
|
|
||||||
* 'Ram_session_component::_clear_ds()' and reverted in
|
|
||||||
* 'Ram_session_component::_revoke_ram_ds(), so there's
|
|
||||||
* nothing to do here.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
Pager_capability add_client(Thread_capability thread) {
|
Pager_capability add_client(Thread_capability thread) override {
|
||||||
return Pager_capability(); }
|
return Pager_capability(); }
|
||||||
|
|
||||||
void remove_client(Pager_capability) { }
|
void remove_client(Pager_capability) override { }
|
||||||
|
|
||||||
void fault_handler(Signal_context_capability handler) { }
|
void fault_handler(Signal_context_capability handler) override { }
|
||||||
|
|
||||||
State state() { return State(); }
|
State state() override { return State(); }
|
||||||
|
|
||||||
Dataspace_capability dataspace() { return Dataspace_capability(); }
|
Dataspace_capability dataspace() override {
|
||||||
|
return Dataspace_capability(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,20 +57,22 @@ namespace Genode {
|
|||||||
** Generic platform interface **
|
** Generic platform interface **
|
||||||
********************************/
|
********************************/
|
||||||
|
|
||||||
Range_allocator *ram_alloc() { return _core_mem_alloc.phys_alloc(); }
|
Range_allocator *ram_alloc() override { return _core_mem_alloc.phys_alloc(); }
|
||||||
Range_allocator *io_mem_alloc() { return &_io_mem_alloc; }
|
Range_allocator *io_mem_alloc() override { return &_io_mem_alloc; }
|
||||||
Range_allocator *io_port_alloc() { return &_io_port_alloc; }
|
Range_allocator *io_port_alloc() override { return &_io_port_alloc; }
|
||||||
Range_allocator *irq_alloc() { return &_irq_alloc; }
|
Range_allocator *irq_alloc() override { return &_irq_alloc; }
|
||||||
Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); }
|
Range_allocator *region_alloc() override { return _core_mem_alloc.virt_alloc(); }
|
||||||
Range_allocator *core_mem_alloc() { return &_core_mem_alloc; }
|
Range_allocator *core_mem_alloc() override { return &_core_mem_alloc; }
|
||||||
addr_t vm_start() const { return _vm_base; }
|
addr_t vm_start() const override { return _vm_base; }
|
||||||
size_t vm_size() const { return _vm_size; }
|
size_t vm_size() const override { return _vm_size; }
|
||||||
Rom_fs *rom_fs() { return &_rom_fs; }
|
Rom_fs *rom_fs() override { return &_rom_fs; }
|
||||||
|
|
||||||
void wait_for_exit();
|
void wait_for_exit() override;
|
||||||
bool supports_unmap() { return true; }
|
bool supports_unmap() override { return true; }
|
||||||
|
bool supports_direct_unmap() const override { return true; }
|
||||||
|
|
||||||
Affinity::Space affinity_space() const { return _cpus; }
|
|
||||||
|
Affinity::Space affinity_space() const override { return _cpus; }
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
@ -81,6 +83,13 @@ namespace Genode {
|
|||||||
* Return capability selector of first global system interrupt
|
* Return capability selector of first global system interrupt
|
||||||
*/
|
*/
|
||||||
int gsi_base_sel() const { return _gsi_base_sel; }
|
int gsi_base_sel() const { return _gsi_base_sel; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine size of a core local mapping required for a
|
||||||
|
* core_rm_session detach().
|
||||||
|
*/
|
||||||
|
size_t region_alloc_size_at(void * addr) {
|
||||||
|
return (*_core_mem_alloc.virt_alloc())()->size_at(addr); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ namespace Genode {
|
|||||||
*
|
*
|
||||||
* \return PD selector
|
* \return PD selector
|
||||||
*/
|
*/
|
||||||
addr_t pd_sel() { return _pd_sel; }
|
addr_t pd_sel() const { return _pd_sel; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capability selector of core protection domain
|
* Capability selector of core protection domain
|
||||||
@ -97,11 +97,7 @@ namespace Genode {
|
|||||||
** Address-space interface **
|
** Address-space interface **
|
||||||
*****************************/
|
*****************************/
|
||||||
|
|
||||||
/*
|
void flush(addr_t, size_t);
|
||||||
* On NOVA, we don't use directed unmap but rely on the
|
|
||||||
* in-kernel mapping database. See 'rm_session_support.cc'.
|
|
||||||
*/
|
|
||||||
void flush(addr_t, size_t) { PDBG("not implemented"); }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,13 @@ namespace Genode {
|
|||||||
|
|
||||||
constexpr size_t get_page_size_log2() { return 12; }
|
constexpr size_t get_page_size_log2() { return 12; }
|
||||||
constexpr size_t get_page_size() { return 1 << get_page_size_log2(); }
|
constexpr size_t get_page_size() { return 1 << get_page_size_log2(); }
|
||||||
constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); }
|
|
||||||
constexpr size_t get_super_page_size_log2() { return 22; }
|
constexpr size_t get_super_page_size_log2() { return 22; }
|
||||||
constexpr size_t get_super_page_size() { return 1 << get_super_page_size_log2(); }
|
constexpr size_t get_super_page_size() { return 1 << get_super_page_size_log2(); }
|
||||||
inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); }
|
inline addr_t trunc_page(addr_t addr) { return addr & _align_mask(get_page_size_log2()); }
|
||||||
inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); }
|
inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); }
|
||||||
|
|
||||||
|
|
||||||
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return core_local; }
|
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
|
||||||
|
|
||||||
|
|
||||||
inline size_t constrain_map_size_log2(size_t size_log2) { return size_log2; }
|
inline size_t constrain_map_size_log2(size_t size_log2) { return size_log2; }
|
||||||
|
@ -23,7 +23,7 @@ using namespace Genode;
|
|||||||
|
|
||||||
void Io_mem_session_component::_unmap_local(addr_t base, size_t size)
|
void Io_mem_session_component::_unmap_local(addr_t base, size_t size)
|
||||||
{
|
{
|
||||||
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
|
size_t page_rounded_size = align_addr(size, get_page_size_log2());
|
||||||
|
|
||||||
Nova::Rights rwx(true, true, true);
|
Nova::Rights rwx(true, true, true);
|
||||||
int count = page_rounded_size >> 12;
|
int count = page_rounded_size >> 12;
|
||||||
@ -35,7 +35,7 @@ void Io_mem_session_component::_unmap_local(addr_t base, size_t size)
|
|||||||
|
|
||||||
addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
|
addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
|
||||||
{
|
{
|
||||||
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
|
size_t page_rounded_size = align_addr(size, get_page_size_log2());
|
||||||
|
|
||||||
/* align large I/O dataspaces on a super-page boundary within core */
|
/* align large I/O dataspaces on a super-page boundary within core */
|
||||||
size_t alignment = (size >= get_super_page_size()) ? get_super_page_size_log2()
|
size_t alignment = (size >= get_super_page_size()) ? get_super_page_size_log2()
|
||||||
|
@ -60,7 +60,7 @@ void Ipc_pager::set_reply_mapping(Mapping m)
|
|||||||
{
|
{
|
||||||
Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb();
|
Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb();
|
||||||
utcb->set_msg_word(0);
|
utcb->set_msg_word(0);
|
||||||
bool res = utcb->append_item(m.mem_crd(), m.dst_addr(), false, false,
|
bool res = utcb->append_item(m.mem_crd(), m.dst_addr(), true, false,
|
||||||
false, m.dma(), m.write_combined());
|
false, m.dma(), m.write_combined());
|
||||||
/* one item ever fits on the UTCB */
|
/* one item ever fits on the UTCB */
|
||||||
(void)res;
|
(void)res;
|
||||||
|
@ -521,11 +521,12 @@ Platform::Platform() :
|
|||||||
addr_t const rom_mem_size = rom_mem_end - rom_mem_start;
|
addr_t const rom_mem_size = rom_mem_end - rom_mem_start;
|
||||||
bool const aux_in_rom_area = (rom_mem_start <= mem_desc->aux) &&
|
bool const aux_in_rom_area = (rom_mem_start <= mem_desc->aux) &&
|
||||||
(mem_desc->aux < rom_mem_end);
|
(mem_desc->aux < rom_mem_end);
|
||||||
|
addr_t const pages_mapped = (rom_mem_size >> get_page_size_log2()) +
|
||||||
|
(aux_in_rom_area ? 1 : 0);
|
||||||
|
|
||||||
/* map ROM + extra page for the case aux crosses page boundary */
|
/* map ROM + extra page for the case aux crosses page boundary */
|
||||||
addr_t core_local_addr = _map_pages(rom_mem_start >> get_page_size_log2(),
|
addr_t core_local_addr = _map_pages(rom_mem_start >> get_page_size_log2(),
|
||||||
(rom_mem_size >> get_page_size_log2()) +
|
pages_mapped);
|
||||||
(aux_in_rom_area ? 1 : 0));
|
|
||||||
if (!core_local_addr) {
|
if (!core_local_addr) {
|
||||||
PERR("could not map multi boot module");
|
PERR("could not map multi boot module");
|
||||||
nova_die();
|
nova_die();
|
||||||
@ -535,9 +536,8 @@ Platform::Platform() :
|
|||||||
core_local_addr += mem_desc->addr - rom_mem_start;
|
core_local_addr += mem_desc->addr - rom_mem_start;
|
||||||
|
|
||||||
if (verbose_boot_info)
|
if (verbose_boot_info)
|
||||||
printf("map multi-boot module: physical 0x%8lx -> [0x%8lx-0x%8lx)"
|
printf("map multi-boot module: physical 0x%8lx+0x%8llx"
|
||||||
" - ", (addr_t)mem_desc->addr, (addr_t)core_local_addr,
|
" - ", (addr_t)mem_desc->addr, mem_desc->size);
|
||||||
(addr_t)(core_local_addr + mem_desc->size));
|
|
||||||
|
|
||||||
char * name;
|
char * name;
|
||||||
if (aux_in_rom_area) {
|
if (aux_in_rom_area) {
|
||||||
@ -597,20 +597,35 @@ Platform::Platform() :
|
|||||||
|
|
||||||
printf("%s\n", name);
|
printf("%s\n", name);
|
||||||
|
|
||||||
/* revoke write permission on rom module */
|
/* revoke mapping of rom module - not needed */
|
||||||
unmap_local(__main_thread_utcb, trunc_page(core_local_addr),
|
unmap_local(__main_thread_utcb, trunc_page(core_local_addr),
|
||||||
rom_mem_size >> get_page_size_log2(), true,
|
pages_mapped);
|
||||||
Nova::Rights(false, true, false));
|
region_alloc()->free(reinterpret_cast<void *>(trunc_page(core_local_addr)),
|
||||||
|
pages_mapped << get_page_size_log2());
|
||||||
|
|
||||||
/* create rom module */
|
/* create rom module */
|
||||||
Rom_module *rom_module = new (core_mem_alloc())
|
Rom_module *rom_module = new (core_mem_alloc())
|
||||||
Rom_module(core_local_addr, mem_desc->size, name);
|
Rom_module(rom_mem_start, mem_desc->size, name);
|
||||||
_rom_fs.insert(rom_module);
|
_rom_fs.insert(rom_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* export hypervisor info page as ROM module */
|
/* export hypervisor info page as ROM module */
|
||||||
|
{
|
||||||
|
void * phys_ptr = 0;
|
||||||
|
ram_alloc()->alloc(get_page_size(), &phys_ptr);
|
||||||
|
addr_t phys_addr = reinterpret_cast<addr_t>(phys_ptr);
|
||||||
|
|
||||||
|
addr_t core_local_addr = _map_pages(phys_addr >> get_page_size_log2(), 1);
|
||||||
|
|
||||||
|
memcpy(reinterpret_cast<void *>(core_local_addr), hip, get_page_size());
|
||||||
|
|
||||||
|
unmap_local(__main_thread_utcb, core_local_addr, 1);
|
||||||
|
region_alloc()->free(reinterpret_cast<void *>(core_local_addr), get_page_size());
|
||||||
|
|
||||||
_rom_fs.insert(new (core_mem_alloc())
|
_rom_fs.insert(new (core_mem_alloc())
|
||||||
Rom_module((addr_t)hip, get_page_size(), "hypervisor_info_page"));
|
Rom_module(phys_addr, get_page_size(),
|
||||||
|
"hypervisor_info_page"));
|
||||||
|
}
|
||||||
|
|
||||||
/* I/O port allocator (only meaningful for x86) */
|
/* I/O port allocator (only meaningful for x86) */
|
||||||
_io_port_alloc.add_range(0, 0x10000);
|
_io_port_alloc.add_range(0, 0x10000);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
|
#include <util/flex_iterator.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <platform_pd.h>
|
#include <platform_pd.h>
|
||||||
@ -62,3 +63,19 @@ Platform_pd::~Platform_pd()
|
|||||||
Nova::revoke(Nova::Obj_crd(_pd_sel, 0));
|
Nova::revoke(Nova::Obj_crd(_pd_sel, 0));
|
||||||
cap_map()->remove(_pd_sel, 0, false);
|
cap_map()->remove(_pd_sel, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Platform_pd::flush(addr_t remote_virt, size_t size)
|
||||||
|
{
|
||||||
|
Nova::Rights const revoke_rwx(true, true, true);
|
||||||
|
|
||||||
|
Flexpage_iterator flex(remote_virt, size, remote_virt, size, 0);
|
||||||
|
Flexpage page = flex.page();
|
||||||
|
|
||||||
|
while (page.valid()) {
|
||||||
|
Nova::Mem_crd mem(page.addr >> 12, page.log2_order - 12, revoke_rwx);
|
||||||
|
Nova::revoke(mem, true, true, pd_sel());
|
||||||
|
|
||||||
|
page = flex.page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
* Copyright (C) 2009-2015 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -24,31 +24,12 @@
|
|||||||
/* NOVA includes */
|
/* NOVA includes */
|
||||||
#include <nova/syscalls.h>
|
#include <nova/syscalls.h>
|
||||||
|
|
||||||
enum { verbose_ram_ds = false };
|
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds)
|
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { }
|
||||||
{
|
|
||||||
size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask();
|
|
||||||
|
|
||||||
if (verbose_ram_ds)
|
|
||||||
printf("-- revoke - ram ds size=0x%8zx phys 0x%8lx has core-local addr 0x%8lx - thread 0x%8p\n",
|
|
||||||
page_rounded_size, ds->phys_addr(), ds->core_local_addr(), Thread_base::myself()->utcb());
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map dataspace core-locally
|
|
||||||
*/
|
|
||||||
static inline void * alloc_region(Dataspace_component *ds, const size_t size)
|
static inline void * alloc_region(Dataspace_component *ds, const size_t size)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -71,33 +52,41 @@ static inline void * alloc_region(Dataspace_component *ds, const size_t size)
|
|||||||
|
|
||||||
void Ram_session_component::_clear_ds(Dataspace_component *ds)
|
void Ram_session_component::_clear_ds(Dataspace_component *ds)
|
||||||
{
|
{
|
||||||
memset((void *)ds->core_local_addr(), 0, ds->size());
|
size_t page_rounded_size = align_addr(ds->size(), get_page_size_log2());
|
||||||
|
|
||||||
|
memset((void *)ds->core_local_addr(), 0, page_rounded_size);
|
||||||
|
|
||||||
|
/* we don't keep any core-local mapping */
|
||||||
|
unmap_local(reinterpret_cast<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(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ram_session_component::_export_ram_ds(Dataspace_component *ds) {
|
void Ram_session_component::_export_ram_ds(Dataspace_component *ds) {
|
||||||
|
|
||||||
const size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask();
|
size_t page_rounded_size = align_addr(ds->size(), get_page_size_log2());
|
||||||
|
|
||||||
/* allocate the virtual region contiguous for the dataspace */
|
/* allocate the virtual region contiguous for the dataspace */
|
||||||
void * virt_ptr = alloc_region(ds, page_rounded_size);
|
void * virt_ptr = alloc_region(ds, page_rounded_size);
|
||||||
if (!virt_ptr)
|
if (!virt_ptr)
|
||||||
throw Out_of_metadata();
|
throw Out_of_metadata();
|
||||||
|
|
||||||
/* map it */
|
/* map it writeable for _clear_ds */
|
||||||
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb());
|
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb());
|
||||||
const Nova::Rights rights(true, ds->writable(), true);
|
const Nova::Rights rights_rw(true, true, false);
|
||||||
|
|
||||||
if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
|
if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
|
||||||
page_rounded_size >> get_page_size_log2(), rights, true)) {
|
page_rounded_size >> get_page_size_log2(), rights_rw, true)) {
|
||||||
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
platform()->region_alloc()->free(virt_ptr, page_rounded_size);
|
||||||
throw Out_of_metadata();
|
throw Out_of_metadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we succeeded, so assign the virtual address to the dataspace */
|
/* assign virtual address to the dataspace to be used by clear_ds */
|
||||||
ds->assign_core_local_addr(virt_ptr);
|
ds->assign_core_local_addr(virt_ptr);
|
||||||
|
|
||||||
if (verbose_ram_ds)
|
|
||||||
printf("-- map - ram ds size=0x%8zx phys 0x%8lx has core-local addr 0x%8lx\n",
|
|
||||||
page_rounded_size, ds->phys_addr(), ds->core_local_addr());
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
* Copyright (C) 2009-2015 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -14,17 +14,18 @@
|
|||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <rm_session_component.h>
|
#include <rm_session_component.h>
|
||||||
#include <nova_util.h>
|
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
void Rm_client::unmap(addr_t core_local_base, addr_t, size_t size)
|
|
||||||
|
/***************
|
||||||
|
** Rm_client **
|
||||||
|
***************/
|
||||||
|
|
||||||
|
void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
|
||||||
{
|
{
|
||||||
using namespace Nova;
|
Locked_ptr<Address_space> locked_address_space(_address_space);
|
||||||
|
|
||||||
Utcb * utcb = reinterpret_cast<Utcb *>(Genode::Thread_base::myself()->utcb());
|
if (locked_address_space.is_valid())
|
||||||
|
locked_address_space->flush(virt_base, size);
|
||||||
unmap_local(utcb, trunc_page(core_local_base),
|
|
||||||
(round_page(core_local_base + size) -
|
|
||||||
trunc_page(core_local_base)) / get_page_size(), false);
|
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ void * Mapped_avl_allocator::map_addr(void * addr)
|
|||||||
Range_allocator::Alloc_return
|
Range_allocator::Alloc_return
|
||||||
Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to)
|
Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to)
|
||||||
{
|
{
|
||||||
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
|
size_t page_rounded_size = align_addr(size, get_page_size_log2());
|
||||||
void *phys_addr = 0;
|
void *phys_addr = 0;
|
||||||
align = max((size_t)align, get_page_size_log2());
|
align = max((size_t)align, get_page_size_log2());
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ void Rm_session_component::detach(Local_addr local_addr)
|
|||||||
/*
|
/*
|
||||||
* Deallocate region on platforms that support unmap
|
* Deallocate region on platforms that support unmap
|
||||||
*
|
*
|
||||||
* On platforms without support for unmap (in particular NOVA 0.1), the
|
* On platforms without support for unmap, the
|
||||||
* same virtual address must not be reused. Hence, we never mark used
|
* same virtual address must not be reused. Hence, we never mark used
|
||||||
* regions as free.
|
* regions as free.
|
||||||
*
|
*
|
||||||
@ -513,7 +513,7 @@ void Rm_session_component::detach(Local_addr local_addr)
|
|||||||
/*
|
/*
|
||||||
* XXX Unmapping managed dataspaces on kernels, which take a core-
|
* XXX Unmapping managed dataspaces on kernels, which take a core-
|
||||||
* local virtual address as unmap argument is not supported yet.
|
* local virtual address as unmap argument is not supported yet.
|
||||||
* This is the case for Fiasco, Pistachio, and NOVA. On those
|
* This is the case for Fiasco and Pistachio. On those
|
||||||
* kernels, the unmap operation must be issued for each leaf
|
* kernels, the unmap operation must be issued for each leaf
|
||||||
* dataspace the managed dataspace is composed of. For kernels with
|
* dataspace the managed dataspace is composed of. For kernels with
|
||||||
* support for directed unmap (OKL4), unmap can be
|
* support for directed unmap (OKL4), unmap can be
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <nova_cpu_session/connection.h>
|
#include <nova_cpu_session/connection.h>
|
||||||
#include <cpu_session/connection.h>
|
#include <cpu_session/connection.h>
|
||||||
#include <pd_session/connection.h>
|
#include <pd_session/connection.h>
|
||||||
|
#include <rm_session/connection.h>
|
||||||
|
|
||||||
namespace Vmm {
|
namespace Vmm {
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
|
|||||||
Genode::Pd_connection _pd_session;
|
Genode::Pd_connection _pd_session;
|
||||||
Genode::Affinity::Location _location;
|
Genode::Affinity::Location _location;
|
||||||
Genode::Cpu_session *_cpu_session;
|
Genode::Cpu_session *_cpu_session;
|
||||||
|
Genode::Rm_connection _rm;
|
||||||
|
|
||||||
Genode::addr_t _exc_pt_sel;
|
Genode::addr_t _exc_pt_sel;
|
||||||
|
|
||||||
@ -70,7 +72,7 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
|
|||||||
_pd_session.bind_thread(vcpu_vm);
|
_pd_session.bind_thread(vcpu_vm);
|
||||||
|
|
||||||
/* create new pager object and assign it to the new thread */
|
/* create new pager object and assign it to the new thread */
|
||||||
Pager_capability pager_cap = env()->rm_session()->add_client(vcpu_vm);
|
Pager_capability pager_cap = _rm.add_client(vcpu_vm);
|
||||||
|
|
||||||
_cpu_session->set_pager(vcpu_vm, pager_cap);
|
_cpu_session->set_pager(vcpu_vm, pager_cap);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user