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.
*/
#ifndef _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_
#define _CORE__INCLUDE__SPEC__X86_64__MUEN__SINFO_H_
#ifndef _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_
#define _INCLUDE__SPEC__X86_64__MUEN__SINFO_H_
#include <base/stdint.h>
struct subject_info_type;
namespace Genode
{
/**
@ -32,10 +34,12 @@ class Genode::Sinfo
public:
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 */
struct Memregion_info {
@ -70,7 +74,7 @@ class Genode::Sinfo
/*
* Check Muen sinfo Magic.
*/
static bool check_magic(void);
bool check_magic(void);
/*
* 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
* 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);
/*
@ -87,7 +91,7 @@ class Genode::Sinfo
*
* 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);
/*
@ -96,7 +100,7 @@ class Genode::Sinfo
* The function returns false if no device information for the
* 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.
@ -114,7 +118,7 @@ class Genode::Sinfo
* invocation of the callback. If a callback invocation returns false,
* 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.
@ -132,24 +136,48 @@ class Genode::Sinfo
* invocation of the callback. If a callback invocation returns false,
* 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.
*
* 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.
*/
static uint64_t get_sched_start(void);
uint64_t get_sched_start(void);
/*
* 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/thread_exception.cc
SRC_CC += spec/x86_64/muen/platform_support.cc
SRC_CC += spec/x86_64/muen/sinfo.cc
# include less specific configuration
include $(REP_DIR)/lib/mk/spec/x86_64/core.inc

View File

@ -1,7 +1,7 @@
/*
* \brief Muen subject info
* \author Stefan Kalkowski
* \date 2015-06-02
* \author Reto Buerki
* \date 2015-04-21
*/
/*
@ -11,8 +11,8 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__SPEC__X86_64__MUEN__MUSINFO_H_
#define _CORE__SPEC__X86_64__MUEN__MUSINFO_H_
#ifndef _BASE__MUEN__MUSINFO_H_
#define _BASE__MUEN__MUSINFO_H_
#include <base/stdint.h>
@ -82,4 +82,4 @@ struct subject_info_type {
struct dev_info_type dev_info[MAX_RESOURCE_COUNT];
} __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 <util/string.h>
#include <sinfo.h>
#include <muen/sinfo.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 */
static bool log_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 */
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 */
static void fill_dev_data(uint8_t idx, struct Genode::Sinfo::Dev_info *dev)
Sinfo::Sinfo(const addr_t base_addr)
{
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()) {
PERR("muen-sinfo: Subject information MAGIC mismatch\n");
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;
}
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();
/**
* Perform additional platform-specific initialization.
*/
void _init_additional();
public:
/**

View File

@ -1,5 +1,5 @@
/*
* \brief x86 mmio constants
* \brief x86 constants
* \author Reto Buerki
* \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_
#define _CORE__INCLUDE__SPEC__X86_64__MUEN__TIMER_H_
/* base includes */
#include <base/printf.h>
#include <kernel/types.h>
/* core includes */
#include <board.h>
#include <sinfo.h>
#include <sinfo_instance.h>
namespace Genode
{
@ -47,6 +48,7 @@ class Genode::Timer
struct Subject_timer * _timer_page;
inline uint64_t rdtsc()
{
uint32_t lo, hi;
@ -58,10 +60,15 @@ class Genode::Timer
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;
if (!Sinfo::get_memregion_info("timer", &region)) {
if (!sinfo()->get_memregion_info("timer", &region)) {
PERR("muen-timer: Unable to retrieve time memory region");
throw Invalid_region();
}

View File

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

View File

@ -18,6 +18,8 @@ using namespace Genode;
void Platform::_init_io_port_alloc() { };
void Platform::_init_additional() { };
void Platform::setup_irq_mode(unsigned, unsigned, 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_additional() { }
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
long Platform::irq(long const user_irq) { return 0; }

View File

@ -16,8 +16,9 @@
#include <util/mmio.h>
/* core includes */
#include <board.h>
#include <platform.h>
#include <sinfo.h>
#include <sinfo_instance.h>
using namespace Genode;
@ -61,10 +62,9 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i)
static Native_region _regions[] =
{
/* Sinfo pages */
{ 0x000e00000000, 0x7000 },
{ Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE },
/* Timer page */
{ 0x000e00010000, 0x1000 },
{ Board::TIMER_BASE_ADDR, Board::TIMER_SIZE },
};
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);
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);
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)
{
static Native_region _regions[] =
{
{ 25*1024*1024, 256*1024*1024 }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
if (i)
return 0;
static Native_region result = { .base = 0, .size = 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 */
extern "C" Genode::addr_t __initial_bx;
void Platform::_init_additional() { };
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{