From 0a32bc845fba950499b795c5c48bb969922fc6e8 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 7 May 2015 15:53:59 +0200 Subject: [PATCH] sel4: RAM-session supplements --- repos/base-sel4/src/core/core_rm_session.cc | 34 +++++++++++++++++-- .../src/core/include/core_rm_session.h | 6 +++- .../base-sel4/src/core/ram_session_support.cc | 31 +++++++++++++++-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/repos/base-sel4/src/core/core_rm_session.cc b/repos/base-sel4/src/core/core_rm_session.cc index 3ecdeb757..e7462cb9c 100644 --- a/repos/base-sel4/src/core/core_rm_session.cc +++ b/repos/base-sel4/src/core/core_rm_session.cc @@ -28,6 +28,36 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, Rm_session::Local_addr local_addr, bool executable) { - PDBG("not implemented"); - return 0; + Object_pool::Guard ds(_ds_ep->lookup_and_lock(ds_cap)); + if (!ds) + throw Invalid_dataspace(); + + if (size == 0) + size = ds->size(); + + size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask(); + + if (use_local_addr) { + PERR("Parameter 'use_local_addr' not supported within core"); + return 0; + } + + if (offset) { + PERR("Parameter 'offset' not supported within core"); + return 0; + } + + /* allocate range in core's virtual address space */ + void *virt_addr; + if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) { + PERR("Could not allocate virtual address range in core of size %zd\n", + page_rounded_size); + return false; + } + + /* map the dataspace's physical pages to core-local virtual addresses */ + size_t num_pages = page_rounded_size >> get_page_size_log2(); + map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages); + + return virt_addr; } diff --git a/repos/base-sel4/src/core/include/core_rm_session.h b/repos/base-sel4/src/core/include/core_rm_session.h index 79a7f10be..b73746f41 100644 --- a/repos/base-sel4/src/core/include/core_rm_session.h +++ b/repos/base-sel4/src/core/include/core_rm_session.h @@ -26,9 +26,13 @@ namespace Genode { class Core_rm_session; } class Genode::Core_rm_session : public Rm_session { + private: + + Rpc_entrypoint *_ds_ep; + public: - Core_rm_session(Rpc_entrypoint *) { } + Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } Local_addr attach(Dataspace_capability ds_cap, size_t size = 0, off_t offset = 0, bool use_local_addr = false, diff --git a/repos/base-sel4/src/core/ram_session_support.cc b/repos/base-sel4/src/core/ram_session_support.cc index 7300e412d..4293641c4 100644 --- a/repos/base-sel4/src/core/ram_session_support.cc +++ b/repos/base-sel4/src/core/ram_session_support.cc @@ -19,14 +19,16 @@ #include #include - using namespace Genode; + void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { - PDBG("not implemented"); + size_t const num_pages = ds->size() >> get_page_size_log2(); + Untyped_memory::convert_to_page_frames(ds->phys_addr(), num_pages); } + void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { PDBG("not implemented"); @@ -35,5 +37,28 @@ void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) void Ram_session_component::_clear_ds (Dataspace_component *ds) { - PDBG("not implemented"); + size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); + + /* allocate range in core's virtual address space */ + void *virt_addr; + if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) { + PERR("could not allocate virtual address range in core of size %zd\n", + page_rounded_size); + return; + } + + /* map the dataspace's physical pages to core-local virtual addresses */ + size_t num_pages = page_rounded_size >> get_page_size_log2(); + map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages); + + /* clear dataspace */ + size_t num_longwords = page_rounded_size/sizeof(long); + for (long *dst = (long *)virt_addr; num_longwords--;) + *dst++ = 0; + + /* unmap dataspace from core */ + unmap_local((addr_t)virt_addr, num_pages); + + /* free core's virtual address space */ + platform()->region_alloc()->free(virt_addr, page_rounded_size); }