base-hw: make Muen sinfo API publicly available

The sinfo function declared in sinfo_instance.h creates a static sinfo
object instance and returns a pointer to the caller.

- kernel timer and platform support to use sinfo() function to
  instantiate sinfo object
- address and size of the base-hw RAM region via the sinfo API
- log_status() function in sinfo API
This commit is contained in:
Adrian-Ken Rueegsegger 2015-07-02 16:25:51 +02:00 committed by Christian Helmuth
parent 2f11caa8d6
commit c1bb82fb6b
15 changed files with 247 additions and 105 deletions

View File

@ -14,11 +14,13 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ #ifndef _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_
#define _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ #define _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_
#include <base/stdint.h> #include <base/stdint.h>
struct subject_info_type;
namespace Genode namespace Genode
{ {
/** /**
@ -32,10 +34,12 @@ class Genode::Sinfo
public: public:
enum Config { enum Config {
MAX_NAME_LENGTH = 63, PHYSICAL_BASE_ADDR = 0xe00000000,
SIZE = 0x7000,
MAX_NAME_LENGTH = 63,
}; };
Sinfo(); Sinfo(const addr_t base_addr);
/* Structure holding information about a memory region */ /* Structure holding information about a memory region */
struct Memregion_info { struct Memregion_info {
@ -70,7 +74,7 @@ class Genode::Sinfo
/* /*
* Check Muen sinfo Magic. * Check Muen sinfo Magic.
*/ */
static bool check_magic(void); bool check_magic(void);
/* /*
* Return information for a channel given by name. * Return information for a channel given by name.
@ -79,7 +83,7 @@ class Genode::Sinfo
* event_number and vector parameters are only valid if indicated by * event_number and vector parameters are only valid if indicated by
* the has_[event|vector] struct members. * the has_[event|vector] struct members.
*/ */
static bool get_channel_info(const char * const name, bool get_channel_info(const char * const name,
struct Channel_info *channel); struct Channel_info *channel);
/* /*
@ -87,7 +91,7 @@ class Genode::Sinfo
* *
* If no memory region with given name exists, False is returned. * If no memory region with given name exists, False is returned.
*/ */
static bool get_memregion_info(const char * const name, bool get_memregion_info(const char * const name,
struct Memregion_info *memregion); struct Memregion_info *memregion);
/* /*
@ -96,7 +100,7 @@ class Genode::Sinfo
* The function returns false if no device information for the * The function returns false if no device information for the
* specified device exists. * specified device exists.
*/ */
static bool get_dev_info(const uint16_t sid, struct Dev_info *dev); bool get_dev_info(const uint16_t sid, struct Dev_info *dev);
/* /*
* Channel callback. * Channel callback.
@ -114,7 +118,7 @@ class Genode::Sinfo
* invocation of the callback. If a callback invocation returns false, * invocation of the callback. If a callback invocation returns false,
* processing is aborted and false is returned to the caller. * processing is aborted and false is returned to the caller.
*/ */
static bool for_each_channel(Channel_cb func, void *data); bool for_each_channel(Channel_cb func, void *data);
/* /*
* Memory region callback. * Memory region callback.
@ -132,24 +136,48 @@ class Genode::Sinfo
* invocation of the callback. If a callback invocation returns false, * invocation of the callback. If a callback invocation returns false,
* processing is aborted and false is returned to the caller. * processing is aborted and false is returned to the caller.
*/ */
static bool for_each_memregion(Memregion_cb func, void *data); bool for_each_memregion(Memregion_cb func, void *data);
/* /*
* Return TSC tick rate in kHz. * Return TSC tick rate in kHz.
* *
* The function returns 0 if the TSC tick rate cannot be retrieved. * The function returns 0 if the TSC tick rate cannot be retrieved.
*/ */
static uint64_t get_tsc_khz(void); uint64_t get_tsc_khz(void);
/* /*
* Return start time of current minor frame in TSC ticks. * Return start time of current minor frame in TSC ticks.
*/ */
static uint64_t get_sched_start(void); uint64_t get_sched_start(void);
/* /*
* Return end time of current minor frame in TSC ticks. * Return end time of current minor frame in TSC ticks.
*/ */
static uint64_t get_sched_end(void); uint64_t get_sched_end(void);
/*
* Log sinfo status.
*/
void log_status();
private:
subject_info_type * sinfo;
/*
* Fill memregion struct with memory region info from resource given by
* index.
*/
void fill_memregion_data(uint8_t idx, struct Memregion_info *region);
/*
* Fill channel struct with channel information from resource given by
* index.
*/
void fill_channel_data(uint8_t idx, struct Channel_info *channel);
/* Fill dev struct with data from PCI device info given by index. */
void fill_dev_data(uint8_t idx, struct Dev_info *dev);
}; };
#endif /* _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ */ #endif /* _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_ */

View File

@ -0,0 +1,5 @@
SRC_CC += sinfo.cc
vpath %.cc $(REP_DIR)/src/base/muen
include $(REP_DIR)/lib/mk/spec/x86_64/base-common.mk

View File

@ -16,7 +16,6 @@ SRC_S += spec/x86_64/muen/kernel/crt0_translation_table.s
SRC_CC += spec/x86_64/muen/kernel/cpu_exception.cc SRC_CC += spec/x86_64/muen/kernel/cpu_exception.cc
SRC_CC += spec/x86_64/muen/kernel/thread_exception.cc SRC_CC += spec/x86_64/muen/kernel/thread_exception.cc
SRC_CC += spec/x86_64/muen/platform_support.cc SRC_CC += spec/x86_64/muen/platform_support.cc
SRC_CC += spec/x86_64/muen/sinfo.cc
# include less specific configuration # include less specific configuration
include $(REP_DIR)/lib/mk/spec/x86_64/core.inc include $(REP_DIR)/lib/mk/spec/x86_64/core.inc

View File

@ -1,7 +1,7 @@
/* /*
* \brief Muen subject info * \brief Muen subject info
* \author Stefan Kalkowski * \author Reto Buerki
* \date 2015-06-02 * \date 2015-04-21
*/ */
/* /*
@ -11,8 +11,8 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#ifndef _CORE__SPEC__X86_64__MUEN__MUSINFO_H_ #ifndef _BASE__MUEN__MUSINFO_H_
#define _CORE__SPEC__X86_64__MUEN__MUSINFO_H_ #define _BASE__MUEN__MUSINFO_H_
#include <base/stdint.h> #include <base/stdint.h>
@ -82,4 +82,4 @@ struct subject_info_type {
struct dev_info_type dev_info[MAX_RESOURCE_COUNT]; struct dev_info_type dev_info[MAX_RESOURCE_COUNT];
} __attribute__((packed, aligned (8))); } __attribute__((packed, aligned (8)));
#endif /* _CORE__SPEC__X86_64__MUEN__MUSINFO_H_ */ #endif /* _BASE__MUEN__MUSINFO_H_ */

View File

@ -13,18 +13,11 @@
#include <base/printf.h> #include <base/printf.h>
#include <util/string.h> #include <util/string.h>
#include <sinfo.h>
#include <muen/sinfo.h>
#include "musinfo.h" #include "musinfo.h"
enum {
SINFO_BASE_ADDR = 0xe00000000,
};
static const subject_info_type *
const sinfo = ((subject_info_type *)SINFO_BASE_ADDR);
/* Log channel information */ /* Log channel information */
static bool log_channel( static bool log_channel(
const struct Genode::Sinfo::Channel_info * const channel, const struct Genode::Sinfo::Channel_info * const channel,
@ -60,48 +53,6 @@ static bool log_memregion(
} }
/* Fill channel struct with channel information from resource given by index */
static void fill_channel_data(uint8_t idx,
struct Genode::Sinfo::Channel_info *channel)
{
const struct resource_type resource = sinfo->resources[idx];
const struct memregion_type memregion =
sinfo->memregions[resource.memregion_idx - 1];
const struct channel_info_type channel_info =
sinfo->channels_info[resource.channel_info_idx - 1];
memset(&channel->name, 0, MAX_NAME_LENGTH + 1);
memcpy(&channel->name, resource.name.data, resource.name.length);
channel->address = memregion.address;
channel->size = memregion.size;
channel->writable = memregion.flags & MEM_WRITABLE_FLAG;
channel->has_event = channel_info.flags & CHAN_EVENT_FLAG;
channel->event_number = channel_info.event;
channel->has_vector = channel_info.flags & CHAN_VECTOR_FLAG;
channel->vector = channel_info.vector;
}
/* Fill memregion struct with memory region info from resource given by index */
static void fill_memregion_data(uint8_t idx,
struct Genode::Sinfo::Memregion_info *region)
{
const struct resource_type resource = sinfo->resources[idx];
const struct memregion_type memregion =
sinfo->memregions[resource.memregion_idx - 1];
memset(&region->name, 0, MAX_NAME_LENGTH + 1);
memcpy(&region->name, resource.name.data, resource.name.length);
region->address = memregion.address;
region->size = memregion.size;
region->writable = memregion.flags & MEM_WRITABLE_FLAG;
region->executable = memregion.flags & MEM_EXECUTABLE_FLAG;
}
/* Returns true if the given resource is a memory region */ /* Returns true if the given resource is a memory region */
static bool is_memregion(const struct resource_type * const resource) static bool is_memregion(const struct resource_type * const resource)
{ {
@ -116,32 +67,14 @@ static bool is_channel(const struct resource_type * const resource)
} }
/* Fill dev struct with data from PCI device info given by index */ Sinfo::Sinfo(const addr_t base_addr)
static void fill_dev_data(uint8_t idx, struct Genode::Sinfo::Dev_info *dev)
{ {
const struct dev_info_type dev_info = sinfo->dev_info[idx]; sinfo = ((subject_info_type *)base_addr);
dev->sid = dev_info.sid;
dev->irte_start = dev_info.irte_start;
dev->irq_start = dev_info.irq_start;
dev->ir_count = dev_info.ir_count;
dev->msi_capable = dev_info.flags & DEV_MSI_FLAG;
}
Sinfo::Sinfo()
{
if (!check_magic()) { if (!check_magic()) {
PERR("muen-sinfo: Subject information MAGIC mismatch\n"); PERR("muen-sinfo: Subject information MAGIC mismatch\n");
return; return;
} }
PINF("muen-sinfo: Subject information exports %d memory region(s)\n",
sinfo->memregion_count);
for_each_memregion(log_memregion, 0);
PINF("muen-sinfo: Subject information exports %d channel(s)\n",
sinfo->channel_info_count);
for_each_channel(log_channel, 0);
} }
@ -269,3 +202,73 @@ uint64_t Sinfo::get_sched_end(void)
return sinfo->tsc_schedule_end; return sinfo->tsc_schedule_end;
} }
void Sinfo::log_status()
{
if (!sinfo) {
PINF("Sinfo API not initialized");
return;
}
if (!check_magic()) {
PINF("Sinfo MAGIC not found");
return;
}
PINF("muen-sinfo: Subject information exports %d memory region(s)\n",
sinfo->memregion_count);
for_each_memregion(log_memregion, 0);
PINF("muen-sinfo: Subject information exports %d channel(s)\n",
sinfo->channel_info_count);
for_each_channel(log_channel, 0);
}
void Sinfo::fill_memregion_data(uint8_t idx, struct Memregion_info *region)
{
const struct resource_type resource = sinfo->resources[idx];
const struct memregion_type memregion =
sinfo->memregions[resource.memregion_idx - 1];
memset(&region->name, 0, MAX_NAME_LENGTH + 1);
memcpy(&region->name, resource.name.data, resource.name.length);
region->address = memregion.address;
region->size = memregion.size;
region->writable = memregion.flags & MEM_WRITABLE_FLAG;
region->executable = memregion.flags & MEM_EXECUTABLE_FLAG;
}
void Sinfo::fill_channel_data(uint8_t idx, struct Channel_info *channel)
{
const struct resource_type resource = sinfo->resources[idx];
const struct memregion_type memregion =
sinfo->memregions[resource.memregion_idx - 1];
const struct channel_info_type channel_info =
sinfo->channels_info[resource.channel_info_idx - 1];
memset(&channel->name, 0, MAX_NAME_LENGTH + 1);
memcpy(&channel->name, resource.name.data, resource.name.length);
channel->address = memregion.address;
channel->size = memregion.size;
channel->writable = memregion.flags & MEM_WRITABLE_FLAG;
channel->has_event = channel_info.flags & CHAN_EVENT_FLAG;
channel->event_number = channel_info.event;
channel->has_vector = channel_info.flags & CHAN_VECTOR_FLAG;
channel->vector = channel_info.vector;
}
void Sinfo::fill_dev_data(uint8_t idx, struct Dev_info *dev)
{
const struct dev_info_type dev_info = sinfo->dev_info[idx];
dev->sid = dev_info.sid;
dev->irte_start = dev_info.irte_start;
dev->irq_start = dev_info.irq_start;
dev->ir_count = dev_info.ir_count;
dev->msi_capable = dev_info.flags & DEV_MSI_FLAG;
}

View File

@ -75,6 +75,11 @@ namespace Genode {
*/ */
void _init_io_mem_alloc(); void _init_io_mem_alloc();
/**
* Perform additional platform-specific initialization.
*/
void _init_additional();
public: public:
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* \brief x86 mmio constants * \brief x86 constants
* \author Reto Buerki * \author Reto Buerki
* \date 2015-03-18 * \date 2015-03-18
*/ */

View File

@ -0,0 +1,34 @@
/*
* \brief x86_64_muen constants
* \author Adrian-Ken Rueegsegger
* \date 2015-07-02
*/
/*
* 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__SPEC__X86_64__MUEN__BOARD_H_
#define _CORE__INCLUDE__SPEC__X86_64__MUEN__BOARD_H_
namespace Genode
{
struct Board
{
enum {
TIMER_BASE_ADDR = 0xe00010000,
TIMER_SIZE = 0x1000,
VECTOR_REMAP_BASE = 48,
TIMER_VECTOR_KERNEL = 32,
TIMER_VECTOR_USER = 50,
};
void init() { }
};
}
#endif /* _CORE__INCLUDE__SPEC__X86_64__MUEN__BOARD_H_ */

View File

@ -0,0 +1,35 @@
/*
* \brief Sinfo kernel singleton
* \author Reto Buerki
* \date 2016-05-09
*/
/*
* Copyright (C) 2016 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__SPEC__X86_64__MUEN__SINFO_INSTANCE_H_
#define _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_INSTANCE_H_
/* base includes */
#include <base/printf.h>
#include <muen/sinfo.h>
/* core includes */
#include <board.h>
namespace Genode
{
/**
* Return sinfo singleton
*/
static Sinfo * sinfo() {
static Sinfo singleton(Sinfo::PHYSICAL_BASE_ADDR);
return &singleton;
}
}
#endif /* _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_INSTANCE_H_ */

View File

@ -14,12 +14,13 @@
#ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_ #ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_
#define _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_ #define _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_
/* base includes */
#include <base/printf.h> #include <base/printf.h>
#include <kernel/types.h> #include <kernel/types.h>
/* core includes */ /* core includes */
#include <board.h> #include <board.h>
#include <sinfo.h> #include <sinfo_instance.h>
namespace Genode namespace Genode
{ {
@ -47,6 +48,7 @@ class Genode::Timer
struct Subject_timer * _timer_page; struct Subject_timer * _timer_page;
inline uint64_t rdtsc() inline uint64_t rdtsc()
{ {
uint32_t lo, hi; uint32_t lo, hi;
@ -58,10 +60,15 @@ class Genode::Timer
public: public:
Timer() : _tics_per_ms(Sinfo::get_tsc_khz()) Timer() :
_tics_per_ms(sinfo()->get_tsc_khz())
{ {
/* first sinfo instance, output status */
sinfo()->log_status();
struct Sinfo::Memregion_info region; struct Sinfo::Memregion_info region;
if (!Sinfo::get_memregion_info("timer", &region)) { if (!sinfo()->get_memregion_info("timer", &region)) {
PERR("muen-timer: Unable to retrieve time memory region"); PERR("muen-timer: Unable to retrieve time memory region");
throw Invalid_region(); throw Invalid_region();
} }

View File

@ -162,6 +162,8 @@ Platform::Platform()
_rom_fs.insert(rom_module); _rom_fs.insert(rom_module);
} }
_init_additional();
/* print ressource summary */ /* print ressource summary */
if (VERBOSE) { if (VERBOSE) {
printf("Core virtual memory allocator\n"); printf("Core virtual memory allocator\n");

View File

@ -18,6 +18,8 @@ using namespace Genode;
void Platform::_init_io_port_alloc() { }; void Platform::_init_io_port_alloc() { };
void Platform::_init_additional() { };
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
Native_region * mmio_regions(unsigned); Native_region * mmio_regions(unsigned);

View File

@ -34,6 +34,8 @@ void Platform::_init_io_port_alloc() { }
void Platform::_init_io_mem_alloc() { } void Platform::_init_io_mem_alloc() { }
void Platform::_init_additional() { }
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
long Platform::irq(long const user_irq) { return 0; } long Platform::irq(long const user_irq) { return 0; }

View File

@ -16,8 +16,9 @@
#include <util/mmio.h> #include <util/mmio.h>
/* core includes */ /* core includes */
#include <board.h>
#include <platform.h> #include <platform.h>
#include <sinfo.h> #include <sinfo_instance.h>
using namespace Genode; using namespace Genode;
@ -61,10 +62,9 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i)
static Native_region _regions[] = static Native_region _regions[] =
{ {
/* Sinfo pages */ /* Sinfo pages */
{ 0x000e00000000, 0x7000 }, { Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE },
/* Timer page */ /* Timer page */
{ 0x000e00010000, 0x1000 }, { Board::TIMER_BASE_ADDR, Board::TIMER_SIZE },
}; };
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
} }
@ -79,7 +79,7 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address,
const unsigned sid = Mmconf_address::to_sid(mmconf); const unsigned sid = Mmconf_address::to_sid(mmconf);
struct Sinfo::Dev_info dev_info; struct Sinfo::Dev_info dev_info;
if (!Sinfo::get_dev_info(sid, &dev_info)) { if (!sinfo()->get_dev_info(sid, &dev_info)) {
PERR("error retrieving Muen info for device with SID 0x%x", sid); PERR("error retrieving Muen info for device with SID 0x%x", sid);
return false; return false;
} }
@ -100,9 +100,28 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address,
Native_region * Platform::_ram_regions(unsigned const i) Native_region * Platform::_ram_regions(unsigned const i)
{ {
static Native_region _regions[] = if (i)
{ return 0;
{ 25*1024*1024, 256*1024*1024 }
}; static Native_region result = { .base = 0, .size = 0 };
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
if (!result.size) {
struct Sinfo::Memregion_info region;
if (!sinfo()->get_memregion_info("ram", &region)) {
PERR("Unable to retrieve base-hw ram region");
return 0;
}
result = { .base = region.address, .size = region.size };
}
return &result;
}
void Platform::_init_additional()
{
/* export subject info page as ROM module */
_rom_fs.insert(new (core_mem_alloc())
Rom_module((addr_t)Sinfo::PHYSICAL_BASE_ADDR,
Sinfo::SIZE, "subject_info_page"));
} }

View File

@ -23,6 +23,7 @@ using namespace Genode;
/* contains physical pointer to multiboot */ /* contains physical pointer to multiboot */
extern "C" Genode::addr_t __initial_bx; extern "C" Genode::addr_t __initial_bx;
void Platform::_init_additional() { };
Native_region * Platform::_core_only_mmio_regions(unsigned const i) Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{ {