/* * \brief Utilities for dealing with untyped memory * \author Norman Feske * \date 2015-05-06 */ /* * 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__UNTYPED_MEMORY_H_ #define _CORE__INCLUDE__UNTYPED_MEMORY_H_ /* Genode includes */ #include /* core includes */ #include #include /* seL4 includes */ #include namespace Genode { struct Untyped_memory; } struct Genode::Untyped_memory { class Phys_alloc_failed : Exception { }; static inline addr_t alloc_pages(Range_allocator &phys_alloc, size_t num_pages) { void *out_ptr = nullptr; Range_allocator::Alloc_return alloc_ret = phys_alloc.alloc_aligned(num_pages*get_page_size(), &out_ptr, get_page_size_log2()); if (alloc_ret.error()) { PERR("%s: allocation of untyped memory failed", __FUNCTION__); throw Phys_alloc_failed(); } return (addr_t)out_ptr; } static inline addr_t alloc_page(Range_allocator &phys_alloc) { return alloc_pages(phys_alloc, 1); } /** * Local utility solely used by 'untyped_sel' and 'frame_sel' */ static inline Cap_sel _core_local_sel(Core_cspace::Top_cnode_idx top_idx, addr_t phys_addr) { unsigned const upper_bits = top_idx << Core_cspace::NUM_PHYS_SEL_LOG2; unsigned const lower_bits = phys_addr >> get_page_size_log2(); return Cap_sel(upper_bits | lower_bits); } /** * Return core-local selector for untyped page at given physical address */ static inline Cap_sel untyped_sel(addr_t phys_addr) { return _core_local_sel(Core_cspace::TOP_CNODE_UNTYPED_IDX, phys_addr); } /** * Return core-local selector for 4K page frame at given physical address */ static inline Cap_sel frame_sel(addr_t phys_addr) { return _core_local_sel(Core_cspace::TOP_CNODE_PHYS_IDX, phys_addr); } /** * Create page frames from untyped memory */ static inline void convert_to_page_frames(addr_t phys_addr, size_t num_pages) { for (size_t i = 0; i < num_pages; i++, phys_addr += get_page_size()) { seL4_Untyped const service = untyped_sel(phys_addr).value(); int const type = seL4_X86_4K; int const size_bits = 0; seL4_CNode const root = Core_cspace::TOP_CNODE_SEL; int const node_index = Core_cspace::TOP_CNODE_PHYS_IDX; int const node_depth = Core_cspace::NUM_TOP_SEL_LOG2; int const node_offset = phys_addr >> get_page_size_log2(); int const num_objects = 1; int const ret = seL4_Untyped_Retype(service, type, size_bits, root, node_index, node_depth, node_offset, num_objects); if (ret != 0) { PERR("%s: seL4_Untyped_RetypeAtOffset (IA32_4K) returned %d", __FUNCTION__, ret); return; } } } }; #endif /* _CORE__INCLUDE__UNTYPED_MEMORY_H_ */