2012-05-30 20:13:09 +02:00
|
|
|
/*
|
|
|
|
* \brief Platform implementation specific for hw
|
|
|
|
* \author Martin Stein
|
2014-04-28 21:31:57 +02:00
|
|
|
* \author Stefan Kalkowski
|
2012-05-30 20:13:09 +02:00
|
|
|
* \date 2011-12-21
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2011-2013 Genode Labs GmbH
|
2012-05-30 20:13:09 +02: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 */
|
2016-06-16 15:55:36 +02:00
|
|
|
#include <base/log.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/* core includes */
|
2016-09-15 16:08:33 +02:00
|
|
|
#include <boot_modules.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
#include <core_parent.h>
|
2014-04-28 21:31:57 +02:00
|
|
|
#include <map_local.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
#include <platform.h>
|
2014-04-28 21:31:57 +02:00
|
|
|
#include <platform_pd.h>
|
2015-06-16 10:59:26 +02:00
|
|
|
#include <page_flags.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
#include <util.h>
|
2014-04-28 21:31:57 +02:00
|
|
|
#include <pic.h>
|
|
|
|
#include <kernel/kernel.h>
|
|
|
|
#include <translation_table.h>
|
2014-07-03 13:39:42 +02:00
|
|
|
#include <trustzone.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2016-03-03 17:57:29 +01:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/stack_area.h>
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
extern int _prog_img_beg;
|
|
|
|
extern int _prog_img_end;
|
|
|
|
|
2015-12-09 12:02:00 +01:00
|
|
|
void __attribute__((weak)) Kernel::init_trustzone(Pic & pic) { }
|
2014-07-03 13:39:42 +02:00
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/**
|
|
|
|
* Helper to initialise allocators through include/exclude region lists
|
|
|
|
*/
|
|
|
|
static void init_alloc(Range_allocator * const alloc,
|
|
|
|
Region_pool incl_regions, Region_pool excl_regions,
|
|
|
|
unsigned const granu_log2 = 0)
|
|
|
|
{
|
|
|
|
/* make all include regions available */
|
|
|
|
Native_region * r = incl_regions(0);
|
|
|
|
for (unsigned i = 0; r; r = incl_regions(++i)) {
|
|
|
|
if (granu_log2) {
|
|
|
|
addr_t const b = trunc(r->base, granu_log2);
|
|
|
|
addr_t const s = round(r->size, granu_log2);
|
|
|
|
alloc->add_range(b, s);
|
|
|
|
}
|
|
|
|
else alloc->add_range(r->base, r->size);
|
|
|
|
}
|
|
|
|
/* preserve all exclude regions */
|
|
|
|
r = excl_regions(0);
|
|
|
|
for (unsigned i = 0; r; r = excl_regions(++i)) {
|
|
|
|
if (granu_log2) {
|
|
|
|
addr_t const b = trunc(r->base, granu_log2);
|
|
|
|
addr_t const s = round(r->size, granu_log2);
|
|
|
|
alloc->remove_range(b, s);
|
|
|
|
}
|
|
|
|
else alloc->remove_range(r->base, r->size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************
|
|
|
|
** Platform **
|
|
|
|
**************/
|
|
|
|
|
2015-06-25 15:53:39 +02:00
|
|
|
addr_t Platform::core_translation_tables()
|
|
|
|
{
|
|
|
|
size_t sz = max((size_t)Translation_table::TABLE_LEVEL_X_SIZE_LOG2,
|
|
|
|
get_page_size_log2());
|
|
|
|
return align_addr<addr_t>((addr_t)&_boot_modules_binaries_end, sz);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
Native_region * Platform::_core_only_ram_regions(unsigned const i)
|
|
|
|
{
|
|
|
|
static Native_region _r[] =
|
|
|
|
{
|
|
|
|
/* core image */
|
|
|
|
{ (addr_t)&_prog_img_beg,
|
|
|
|
(size_t)((addr_t)&_prog_img_end - (addr_t)&_prog_img_beg) },
|
|
|
|
|
|
|
|
/* boot modules */
|
2014-05-05 12:15:31 +02:00
|
|
|
{ (addr_t)&_boot_modules_binaries_begin,
|
|
|
|
(size_t)((addr_t)&_boot_modules_binaries_end -
|
2015-06-25 15:53:39 +02:00
|
|
|
(addr_t)&_boot_modules_binaries_begin) },
|
|
|
|
|
|
|
|
/* translation table allocator */
|
|
|
|
{ core_translation_tables(), core_translation_tables_size() }
|
2012-05-30 20:13:09 +02:00
|
|
|
};
|
|
|
|
return i < sizeof(_r)/sizeof(_r[0]) ? &_r[i] : 0;
|
|
|
|
}
|
|
|
|
|
2014-04-28 21:31:57 +02:00
|
|
|
static Native_region * virt_region(unsigned const i) {
|
|
|
|
static Native_region r = { VIRT_ADDR_SPACE_START, VIRT_ADDR_SPACE_SIZE };
|
|
|
|
return i ? 0 : &r; }
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-11-23 02:30:24 +01:00
|
|
|
Platform::Platform()
|
|
|
|
:
|
2014-04-28 21:31:57 +02:00
|
|
|
_io_mem_alloc(core_mem_alloc()),
|
2015-03-18 23:40:58 +01:00
|
|
|
_io_port_alloc(core_mem_alloc()),
|
2013-11-23 02:30:24 +01:00
|
|
|
_irq_alloc(core_mem_alloc()),
|
|
|
|
_vm_start(VIRT_ADDR_SPACE_START), _vm_size(VIRT_ADDR_SPACE_SIZE)
|
2012-05-30 20:13:09 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Initialise platform resource allocators.
|
|
|
|
* Core mem alloc must come first because it is
|
|
|
|
* used by the other allocators.
|
|
|
|
*/
|
2014-04-28 21:31:57 +02:00
|
|
|
init_alloc(_core_mem_alloc.phys_alloc(), _ram_regions,
|
|
|
|
_core_only_ram_regions, get_page_size_log2());
|
|
|
|
init_alloc(_core_mem_alloc.virt_alloc(), virt_region,
|
|
|
|
_core_only_ram_regions, get_page_size_log2());
|
2013-10-30 13:56:57 +01:00
|
|
|
|
2016-01-20 18:27:18 +01:00
|
|
|
/* preserve stack area in core's virtual address space */
|
2016-03-03 17:57:29 +01:00
|
|
|
_core_mem_alloc.virt_alloc()->remove_range(stack_area_virtual_base(),
|
|
|
|
stack_area_virtual_size());
|
2016-01-15 15:47:34 +01:00
|
|
|
|
2015-03-18 23:40:58 +01:00
|
|
|
_init_io_port_alloc();
|
|
|
|
|
2015-04-03 17:22:16 +02:00
|
|
|
/* make all non-kernel interrupts available to the interrupt allocator */
|
|
|
|
for (unsigned i = 0; i < Kernel::Pic::NR_OF_IRQ; i++) {
|
|
|
|
if (i == Timer::interrupt_id(i) || i == Pic::IPI)
|
|
|
|
continue;
|
2014-04-04 17:36:05 +02:00
|
|
|
_irq_alloc.add_range(i, 1);
|
2015-04-03 17:22:16 +02:00
|
|
|
}
|
2013-04-08 19:05:44 +02:00
|
|
|
|
2015-04-28 14:56:00 +02:00
|
|
|
_init_io_mem_alloc();
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/* add boot modules to ROM FS */
|
2016-09-15 16:08:33 +02:00
|
|
|
Boot_modules_header * header = &_boot_modules_headers_begin;
|
2014-05-05 12:15:31 +02:00
|
|
|
for (; header < &_boot_modules_headers_end; header++) {
|
2012-05-30 20:13:09 +02:00
|
|
|
Rom_module * rom_module = new (core_mem_alloc())
|
|
|
|
Rom_module(header->base, header->size, (const char*)header->name);
|
|
|
|
_rom_fs.insert(rom_module);
|
|
|
|
}
|
2014-04-28 21:31:57 +02:00
|
|
|
|
2015-07-02 16:25:51 +02:00
|
|
|
_init_additional();
|
|
|
|
|
2012-05-30 20:13:09 +02:00
|
|
|
/* print ressource summary */
|
2016-11-02 10:39:13 +01:00
|
|
|
log(":virt_alloc: ", *_core_mem_alloc.virt_alloc());
|
|
|
|
log(":phys_alloc: ", *_core_mem_alloc.phys_alloc());
|
|
|
|
log(":io_mem_alloc: ", _io_mem_alloc);
|
|
|
|
log(":io_port_alloc: ", _io_port_alloc);
|
|
|
|
log(":irq_alloc: ", _irq_alloc);
|
2016-11-02 13:29:50 +01:00
|
|
|
log(":rom_fs: ", _rom_fs);
|
2012-05-30 20:13:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************
|
|
|
|
** Core_parent **
|
|
|
|
*****************/
|
|
|
|
|
|
|
|
void Core_parent::exit(int exit_value)
|
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
warning(__PRETTY_FUNCTION__, "not implemented");
|
2016-06-16 15:55:36 +02:00
|
|
|
while (1);
|
2012-05-30 20:13:09 +02:00
|
|
|
}
|
|
|
|
|
2014-04-28 21:31:57 +02:00
|
|
|
|
|
|
|
/****************************************
|
|
|
|
** Support for core memory management **
|
|
|
|
****************************************/
|
|
|
|
|
2014-07-08 15:46:53 +02:00
|
|
|
bool Genode::map_local(addr_t from_phys, addr_t to_virt, size_t num_pages,
|
|
|
|
Page_flags flags)
|
2014-04-28 21:31:57 +02:00
|
|
|
{
|
2015-04-28 14:07:51 +02:00
|
|
|
Platform_pd * pd = Kernel::core_pd()->platform_pd();
|
|
|
|
return pd->insert_translation(to_virt, from_phys,
|
|
|
|
num_pages * get_page_size(), flags);
|
2014-04-28 21:31:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Genode::unmap_local(addr_t virt_addr, size_t num_pages)
|
|
|
|
{
|
2015-04-28 14:07:51 +02:00
|
|
|
Platform_pd * pd = Kernel::core_pd()->platform_pd();
|
|
|
|
pd->flush(virt_addr, num_pages * get_page_size());
|
|
|
|
return true;
|
2014-04-28 21:31:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-17 14:16:59 +02:00
|
|
|
bool Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr,
|
|
|
|
unsigned size) {
|
2015-06-16 10:59:26 +02:00
|
|
|
return ::map_local(phys_addr, virt_addr, size / get_page_size()); }
|
2014-04-28 21:31:57 +02:00
|
|
|
|
|
|
|
|
2016-07-15 11:05:09 +02:00
|
|
|
bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, addr_t phys_addr,
|
|
|
|
unsigned size) {
|
2015-06-16 10:59:26 +02:00
|
|
|
return ::unmap_local(virt_addr, size / get_page_size()); }
|