From 95c3e896ddce37388c66284665d0e4cfa6af5e61 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Fri, 8 May 2015 12:18:09 +0200 Subject: [PATCH] sel4: add include/kernel_object.h utilties --- repos/base-sel4/src/core/include/cnode.h | 48 ++------ .../src/core/include/kernel_object.h | 109 ++++++++++++++++++ .../src/core/include/untyped_memory.h | 1 + repos/base-sel4/src/core/include/vm_space.h | 34 +----- repos/base-sel4/src/core/thread_start.cc | 39 +------ 5 files changed, 128 insertions(+), 103 deletions(-) create mode 100644 repos/base-sel4/src/core/include/kernel_object.h diff --git a/repos/base-sel4/src/core/include/cnode.h b/repos/base-sel4/src/core/include/cnode.h index 358ceb3582..94c7dda8e1 100644 --- a/repos/base-sel4/src/core/include/cnode.h +++ b/repos/base-sel4/src/core/include/cnode.h @@ -20,7 +20,7 @@ #include /* core includes */ -#include +#include namespace Genode { @@ -41,13 +41,6 @@ class Genode::Cnode_base unsigned sel() const { return _sel; } size_t size_log2() const { return _size_log2; } - /** - * Return size of underlying backing store in bytes - * - * One cnode entry takes 16 (2^4) bytes. - */ - size_t mem_size_log2() const { return _size_log2 + 4; } - /** * Copy selector from another CNode */ @@ -119,9 +112,10 @@ class Genode::Cnode : public Cnode_base, Noncopyable /** * Constructor * - * \param parent selector of CNode where to place 'dst_sel' - * \param dst_sel designated selector referring to the created - * CNode + * \param parent_sel CNode where to place the cap selector of the + * new CNode + * \param dst_idx designated index within 'parent_sel' referring to + * the created CNode * \param size_log2 number of entries in CNode * \param phys_alloc physical-memory allocator used for allocating * the CNode backing store @@ -129,37 +123,13 @@ class Genode::Cnode : public Cnode_base, Noncopyable * \throw Phys_alloc_failed * \throw Untyped_address::Lookup_failed */ - Cnode(unsigned parent_sel, unsigned dst_sel, size_t size_log2, + Cnode(unsigned parent_sel, unsigned dst_idx, size_t size_log2, Range_allocator &phys_alloc) : - Cnode_base(dst_sel, size_log2) + Cnode_base(dst_idx, size_log2) { - Untyped_address const untyped_addr = - Untyped_memory::alloc_log2(phys_alloc, mem_size_log2()); - - seL4_Untyped const service = untyped_addr.sel(); - int const type = seL4_CapTableObject; - int const offset = untyped_addr.offset(); - int const size_bits = size_log2; - seL4_CNode const root = parent_sel; - int const node_index = 0; - int const node_depth = 0; - int const node_offset = dst_sel; - int const num_objects = 1; - - int const ret = seL4_Untyped_RetypeAtOffset(service, - type, - offset, - size_bits, - root, - node_index, - node_depth, - node_offset, - num_objects); - if (ret != 0) { - PERR("seL4_Untyped_RetypeAtOffset (CapTable) returned %d", ret); - throw Retype_untyped_failed(); - } + Kernel_object::create(phys_alloc, parent_sel, + dst_idx, size_log2); } ~Cnode() diff --git a/repos/base-sel4/src/core/include/kernel_object.h b/repos/base-sel4/src/core/include/kernel_object.h new file mode 100644 index 0000000000..7d16e04436 --- /dev/null +++ b/repos/base-sel4/src/core/include/kernel_object.h @@ -0,0 +1,109 @@ +/* + * \brief Utilities for creating seL4 kernel objects + * \author Norman Feske + * \date 2015-05-08 + */ + +/* + * Copyright (C) 2015 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. + */ + +#ifndef _CORE__INCLUDE__KERNEL_OBJECT_H_ +#define _CORE__INCLUDE__KERNEL_OBJECT_H_ + +/* core includes */ +#include + +namespace Kernel_object { + + using Genode::Untyped_address; + using Genode::Untyped_memory; + using Genode::Range_allocator; + + struct Tcb + { + enum { SEL4_TYPE = seL4_TCBObject, SIZE_LOG2 = 12 }; + static char const *name() { return "TCB"; } + }; + + + struct Endpoint + { + enum { SEL4_TYPE = seL4_EndpointObject, SIZE_LOG2 = 4 }; + static char const *name() { return "endpoint"; } + }; + + + struct Cnode + { + enum { SEL4_TYPE = seL4_CapTableObject, SIZE_LOG2 = 4 }; + static char const *name() { return "cnode"; } + }; + + + struct Page_table + { + enum { SEL4_TYPE = seL4_IA32_PageTableObject, SIZE_LOG2 = 12 }; + static char const *name() { return "page table"; } + }; + + + /** + * Create kernel object from untyped memory + * + * \param KOBJ kernel-object description + * \param phys_alloc allocator for untyped memory + * \param dst_cnode_sel CNode selector where to store the cap pointing to + * the new kernel object + * \param dst_idx designated index of cap selector within 'dst_cnode' + * \param size_log2 size of kernel object in bits, only needed for + * variable-sized objects like CNodes + * + * \throw Phys_alloc_failed + * \throw Untyped_address::Lookup_failed + * + * The kernel-object description is a policy type that contains enum + * definitions for 'SEL4_TYPE' and 'SIZE_LOG2', and a static function + * 'name' that returns the type name as a char const pointer. + */ + template + static Untyped_address create(Range_allocator &phys_alloc, + unsigned dst_cnode_sel, + unsigned dst_idx, + size_t size_log2 = 0) + { + Untyped_address const untyped_addr = + Untyped_memory::alloc_log2(phys_alloc, KOBJ::SIZE_LOG2 + size_log2); + + seL4_Untyped const service = untyped_addr.sel(); + int const type = KOBJ::SEL4_TYPE; + int const offset = untyped_addr.offset(); + int const size_bits = size_log2; + seL4_CNode const root = dst_cnode_sel; + int const node_index = 0; + int const node_depth = 0; + int const node_offset = dst_idx; + int const num_objects = 1; + + int const ret = seL4_Untyped_RetypeAtOffset(service, + type, + offset, + size_bits, + root, + node_index, + node_depth, + node_offset, + num_objects); + + if (ret != 0) + PERR("seL4_Untyped_RetypeAtOffset (%s) returned %d", + KOBJ::name(), ret); + + return untyped_addr; + } +}; + +#endif /* _CORE__INCLUDE__KERNEL_OBJECT_H_ */ diff --git a/repos/base-sel4/src/core/include/untyped_memory.h b/repos/base-sel4/src/core/include/untyped_memory.h index c14c9b7d26..8598de6e1e 100644 --- a/repos/base-sel4/src/core/include/untyped_memory.h +++ b/repos/base-sel4/src/core/include/untyped_memory.h @@ -35,6 +35,7 @@ struct Genode::Untyped_memory * Allocate natually-aligned physical memory for seL4 kernel object * * \throw Phys_alloc_failed + * \throw Untyped_address::Lookup_failed */ static inline Untyped_address alloc_log2(Range_allocator &phys_alloc, size_t const size_log2) diff --git a/repos/base-sel4/src/core/include/vm_space.h b/repos/base-sel4/src/core/include/vm_space.h index d3036bac6b..8ba286ad88 100644 --- a/repos/base-sel4/src/core/include/vm_space.h +++ b/repos/base-sel4/src/core/include/vm_space.h @@ -134,35 +134,11 @@ class Genode::Vm_space /* XXX account the consumed backing store */ - /* allocate backing store for page table */ - size_t const pt_mem_size_log2 = 12; - Untyped_address const untyped_addr = - Untyped_memory::alloc_log2(_phys_alloc, pt_mem_size_log2); - - seL4_Untyped const service = untyped_addr.sel(); - int const type = seL4_IA32_PageTableObject; - int const offset = untyped_addr.offset(); - int const size_bits = pt_mem_size_log2; - seL4_CNode const root = _vm_cnode.sel(); - int const node_index = 0; - int const node_depth = 0; - int const node_offset = pt_idx; - int const num_objects = 1; - - int const ret = seL4_Untyped_RetypeAtOffset(service, - type, - offset, - size_bits, - root, - node_index, - node_depth, - node_offset, - num_objects); - - if (ret != 0) { - PDBG("seL4_Untyped_RetypeAtOffset (page table) returned %d", ret); - throw Alloc_page_table_failed(); - } + try { + Kernel_object::create(_phys_alloc, + _vm_cnode.sel(), + pt_idx); + } catch (...) { throw Alloc_page_table_failed(); } unsigned const pt_sel = _idx_to_sel(pt_idx); diff --git a/repos/base-sel4/src/core/thread_start.cc b/repos/base-sel4/src/core/thread_start.cc index 1ca6242a5c..bc7ac4e8ea 100644 --- a/repos/base-sel4/src/core/thread_start.cc +++ b/repos/base-sel4/src/core/thread_start.cc @@ -19,8 +19,8 @@ /* core includes */ #include #include -#include #include +#include using namespace Genode; @@ -44,39 +44,6 @@ static Untyped_address create_and_map_ipc_buffer(Range_allocator &phys_alloc, } -static void create_tcb(Cnode &core_cnode, Range_allocator &phys_alloc, - unsigned dst_idx) -{ - /* create TCB */ - size_t const tcb_size_log2 = get_page_size_log2(); - Untyped_address const untyped_addr = - Untyped_memory::alloc_log2(phys_alloc, tcb_size_log2); - - seL4_Untyped const service = untyped_addr.sel(); - int const type = seL4_TCBObject; - int const offset = untyped_addr.offset(); - int const size_bits = 0; - seL4_CNode const root = core_cnode.sel(); - int const node_index = 0; - int const node_depth = 0; - int const node_offset = dst_idx; - int const num_objects = 1; - - int const ret = seL4_Untyped_RetypeAtOffset(service, - type, - offset, - size_bits, - root, - node_index, - node_depth, - node_offset, - num_objects); - - if (ret != 0) - PDBG("seL4_Untyped_RetypeAtOffset (TCB) returned %d", ret); -} - - void Thread_base::_init_platform_thread(size_t, Type type) { Platform &platform = *platform_specific(); @@ -89,7 +56,9 @@ void Thread_base::_init_platform_thread(size_t, Type type) /* allocate TCB selector within core's CNode */ unsigned const tcb_idx = platform.alloc_core_sel(); - create_tcb(platform.core_cnode(), phys_alloc, tcb_idx); + Kernel_object::create(phys_alloc, + platform.core_cnode().sel(), tcb_idx); + unsigned const tcb_sel = tcb_idx; _tid.tcb_sel = tcb_sel;