2012-05-30 20:13:09 +02:00
|
|
|
/*
|
2013-11-14 17:29:34 +01:00
|
|
|
* \brief Basic Genode types
|
2012-05-30 20:13:09 +02:00
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2012-01-02
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2012-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.
|
|
|
|
*/
|
|
|
|
|
2013-11-14 13:29:47 +01:00
|
|
|
#ifndef _BASE__NATIVE_TYPES_H_
|
|
|
|
#define _BASE__NATIVE_TYPES_H_
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/* Genode includes */
|
2013-11-14 17:29:34 +01:00
|
|
|
#include <kernel/interface.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
#include <base/native_capability.h>
|
2012-08-29 14:42:56 +02:00
|
|
|
#include <base/stdint.h>
|
2013-11-21 16:43:35 +01:00
|
|
|
#include <util/string.h>
|
|
|
|
|
|
|
|
/* base-hw includes */
|
|
|
|
#include <kernel/log.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
namespace Genode
|
|
|
|
{
|
|
|
|
class Platform_thread;
|
2012-12-10 13:55:19 +01:00
|
|
|
class Tlb;
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-02-25 21:18:26 +01:00
|
|
|
typedef unsigned Native_thread_id;
|
|
|
|
|
|
|
|
struct Native_thread
|
|
|
|
{
|
2013-11-19 15:13:24 +01:00
|
|
|
Platform_thread * platform_thread;
|
|
|
|
Native_thread_id thread_id;
|
2013-02-25 21:18:26 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef int Native_connection_state;
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/* FIXME needs to be MMU dependent */
|
|
|
|
enum { MIN_MAPPING_SIZE_LOG2 = 12 };
|
|
|
|
|
|
|
|
/**
|
2013-11-19 15:13:24 +01:00
|
|
|
* Return kernel thread-name of the caller
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
2013-11-19 15:13:24 +01:00
|
|
|
Native_thread_id thread_get_my_native_id();
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-19 15:13:24 +01:00
|
|
|
* Return an invalid kernel thread-name
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
|
|
|
inline Native_thread_id thread_invalid_id() { return 0; }
|
|
|
|
|
2013-10-17 16:07:47 +02:00
|
|
|
/**
|
2013-11-21 16:58:35 +01:00
|
|
|
* Data bunch with variable size that is communicated between threads
|
2013-11-21 16:43:35 +01:00
|
|
|
*
|
|
|
|
* \param MAX_SIZE maximum size the object is allowed to take
|
2013-10-17 16:07:47 +02:00
|
|
|
*/
|
2013-11-21 16:43:35 +01:00
|
|
|
template <size_t MAX_SIZE>
|
2013-11-21 17:26:44 +01:00
|
|
|
struct Message_tpl;
|
2013-10-17 16:07:47 +02:00
|
|
|
|
|
|
|
/**
|
2013-11-21 17:26:44 +01:00
|
|
|
* Information that a thread creator hands out to a new thread
|
2013-10-17 16:07:47 +02:00
|
|
|
*/
|
2013-11-21 17:04:05 +01:00
|
|
|
class Start_info;
|
2013-10-07 16:01:03 +02:00
|
|
|
|
2013-11-19 15:13:24 +01:00
|
|
|
/**
|
|
|
|
* Memory region that is exclusive to every thread and known by the kernel
|
|
|
|
*/
|
2013-11-21 17:26:44 +01:00
|
|
|
class Native_utcb;
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
struct Cap_dst_policy
|
|
|
|
{
|
|
|
|
typedef Native_thread_id Dst;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate capability destination
|
|
|
|
*/
|
|
|
|
static bool valid(Dst pt) { return pt != 0; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get invalid capability destination
|
|
|
|
*/
|
|
|
|
static Dst invalid() { return 0; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy capability 'src' to a given memory destination 'dst'
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
copy(void * dst, Native_capability_tpl<Cap_dst_policy> * src);
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
|
|
|
|
|
|
|
/**
|
2013-11-19 15:13:24 +01:00
|
|
|
* Coherent address region
|
2012-05-30 20:13:09 +02:00
|
|
|
*/
|
|
|
|
struct Native_region
|
|
|
|
{
|
|
|
|
addr_t base;
|
|
|
|
size_t size;
|
|
|
|
};
|
2012-08-29 14:42:56 +02:00
|
|
|
|
|
|
|
struct Native_config
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Thread-context area configuration.
|
|
|
|
*/
|
2014-01-24 12:06:21 +01:00
|
|
|
static constexpr addr_t context_area_virtual_base() {
|
|
|
|
return 0x40000000UL; }
|
|
|
|
static constexpr addr_t context_area_virtual_size() {
|
|
|
|
return 0x10000000UL; }
|
2012-08-29 14:42:56 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Size of virtual address region holding the context of one thread
|
|
|
|
*/
|
2014-01-24 12:06:21 +01:00
|
|
|
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
2012-08-29 14:42:56 +02:00
|
|
|
};
|
2012-11-21 15:20:21 +01:00
|
|
|
|
|
|
|
struct Native_pd_args { };
|
2012-05-30 20:13:09 +02:00
|
|
|
}
|
|
|
|
|
2013-11-21 16:43:35 +01:00
|
|
|
template <Genode::size_t MAX_SIZE>
|
2013-11-21 17:26:44 +01:00
|
|
|
class Genode::Message_tpl
|
2013-11-21 16:43:35 +01:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
size_t _data_size;
|
|
|
|
uint8_t _data[];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return size of payload-preceding meta data
|
|
|
|
*/
|
|
|
|
size_t _header_size() const { return (addr_t)_data - (addr_t)this; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return maximum payload size
|
|
|
|
*/
|
|
|
|
size_t _max_data_size() const { return MAX_SIZE - _header_size(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return size of header and current payload
|
|
|
|
*/
|
|
|
|
size_t _size() const { return _header_size() + _data_size; }
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get information about current await-request operation
|
|
|
|
*
|
|
|
|
* \return buf_base base of receive buffer
|
|
|
|
* \return buf_size size of receive buffer
|
|
|
|
*/
|
|
|
|
void info_about_await_request(void * & buf_base, size_t & buf_size)
|
2013-11-21 17:26:44 +01:00
|
|
|
const
|
2013-11-21 16:43:35 +01:00
|
|
|
{
|
2013-11-21 17:26:44 +01:00
|
|
|
buf_base = (void *)this;
|
2013-11-21 16:43:35 +01:00
|
|
|
buf_size = MAX_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get information about current send-request operation
|
|
|
|
*
|
|
|
|
* \return msg_base base of complete send-message data
|
|
|
|
* \return msg_size size of complete send-message data
|
|
|
|
* \return buf_base base of receive buffer
|
|
|
|
* \return buf_size size of receive buffer
|
|
|
|
*/
|
|
|
|
void info_about_send_request(void * & msg_base, size_t & msg_size,
|
|
|
|
void * & buf_base, size_t & buf_size)
|
2013-11-21 17:26:44 +01:00
|
|
|
const
|
2013-11-21 16:43:35 +01:00
|
|
|
{
|
2013-11-21 17:26:44 +01:00
|
|
|
msg_base = (void *)this;
|
2013-11-21 16:43:35 +01:00
|
|
|
msg_size = _size();
|
2013-11-21 17:26:44 +01:00
|
|
|
buf_base = (void *)this;
|
2013-11-21 16:43:35 +01:00
|
|
|
buf_size = MAX_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get information about current send-reply operation
|
|
|
|
*
|
|
|
|
* \return msg_base base of complete send-message data
|
|
|
|
* \return msg_size size of complete send-message data
|
|
|
|
*/
|
|
|
|
void info_about_send_reply(void * & msg_base, size_t & msg_size)
|
2013-11-21 17:26:44 +01:00
|
|
|
const
|
2013-11-21 16:43:35 +01:00
|
|
|
{
|
2013-11-21 17:26:44 +01:00
|
|
|
msg_base = (void *)this;
|
2013-11-21 16:43:35 +01:00
|
|
|
msg_size = _size();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Install message that shall be send
|
|
|
|
*
|
2014-01-22 15:50:14 +01:00
|
|
|
* \param data base of payload
|
|
|
|
* \param data_size size of payload
|
|
|
|
* \param name local name that shall be the first payload word
|
2013-11-21 16:43:35 +01:00
|
|
|
*/
|
2014-01-22 15:50:14 +01:00
|
|
|
void prepare_send(void * const data, size_t data_size,
|
2013-11-21 16:43:35 +01:00
|
|
|
unsigned const name)
|
|
|
|
{
|
|
|
|
/* limit data size */
|
|
|
|
if (data_size > _max_data_size()) {
|
2014-01-20 18:24:57 +01:00
|
|
|
Kernel::log() << "oversized message outgoing\n";
|
2014-01-22 15:50:14 +01:00
|
|
|
data_size = _max_data_size();
|
2013-11-21 16:43:35 +01:00
|
|
|
}
|
|
|
|
/* copy data */
|
|
|
|
*(unsigned *)_data = name;
|
2014-01-22 15:50:14 +01:00
|
|
|
void * const data_dst = (void *)((addr_t)_data + sizeof(name));
|
|
|
|
void * const data_src = (void *)((addr_t)data + sizeof(name));
|
|
|
|
memcpy(data_dst, data_src, data_size - sizeof(name));
|
2013-11-21 16:43:35 +01:00
|
|
|
_data_size = data_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read out message that was received
|
|
|
|
*
|
|
|
|
* \param buf_base base of read buffer
|
|
|
|
* \param buf_size size of read buffer
|
|
|
|
*/
|
|
|
|
void finish_receive(void * const buf_base, size_t const buf_size)
|
|
|
|
{
|
|
|
|
/* limit data size */
|
|
|
|
if (_data_size > buf_size) {
|
2014-01-20 18:24:57 +01:00
|
|
|
Kernel::log() << "oversized message incoming\n";
|
2013-11-21 16:43:35 +01:00
|
|
|
_data_size = buf_size;
|
|
|
|
}
|
|
|
|
/* copy data */
|
|
|
|
memcpy(buf_base, _data, _data_size);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-11-21 17:04:05 +01:00
|
|
|
class Genode::Start_info
|
2013-11-19 15:13:24 +01:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2013-12-05 00:08:09 +01:00
|
|
|
Native_thread_id _thread_id;
|
|
|
|
Native_capability _utcb_ds;
|
2013-11-19 15:13:24 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set-up valid startup message
|
|
|
|
*
|
|
|
|
* \param thread_id kernel name of the thread that is started
|
|
|
|
*/
|
2013-12-05 00:08:09 +01:00
|
|
|
void init(Native_thread_id const thread_id,
|
|
|
|
Native_capability const & utcb_ds)
|
|
|
|
{
|
|
|
|
_thread_id = thread_id;
|
|
|
|
_utcb_ds = utcb_ds;
|
|
|
|
}
|
2013-11-19 15:13:24 +01:00
|
|
|
|
2013-11-21 12:04:21 +01:00
|
|
|
|
|
|
|
/***************
|
|
|
|
** Accessors **
|
|
|
|
***************/
|
|
|
|
|
|
|
|
Native_thread_id thread_id() const { return _thread_id; }
|
2013-12-05 00:08:09 +01:00
|
|
|
Native_capability utcb_ds() const { return _utcb_ds; }
|
2013-11-19 15:13:24 +01:00
|
|
|
};
|
|
|
|
|
2013-11-21 17:26:44 +01:00
|
|
|
class Genode::Native_utcb
|
2013-11-19 15:13:24 +01:00
|
|
|
{
|
2013-11-21 17:26:44 +01:00
|
|
|
private:
|
2013-11-21 16:43:35 +01:00
|
|
|
|
2013-11-21 17:26:44 +01:00
|
|
|
uint8_t _data[1 << MIN_MAPPING_SIZE_LOG2];
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef Message_tpl<sizeof(_data)/sizeof(_data[0])> Message;
|
|
|
|
|
|
|
|
|
|
|
|
/***************
|
|
|
|
** Accessors **
|
|
|
|
***************/
|
|
|
|
|
|
|
|
Message * message() const { return (Message *)_data; }
|
|
|
|
|
|
|
|
Start_info * start_info() const { return (Start_info *)_data; }
|
2013-11-19 15:13:24 +01:00
|
|
|
|
2013-11-21 17:26:44 +01:00
|
|
|
size_t size() const { return sizeof(_data)/sizeof(_data[0]); }
|
2013-11-19 15:13:24 +01:00
|
|
|
|
2013-11-21 17:26:44 +01:00
|
|
|
void * base() const { return (void *)_data; }
|
2013-11-19 15:13:24 +01:00
|
|
|
};
|
|
|
|
|
2013-11-23 02:30:24 +01:00
|
|
|
namespace Genode
|
|
|
|
{
|
|
|
|
enum {
|
|
|
|
VIRT_ADDR_SPACE_START = 0x1000,
|
|
|
|
VIRT_ADDR_SPACE_SIZE = 0xfffef000,
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-12-05 00:08:09 +01:00
|
|
|
* Return virtual UTCB location of main threads
|
2013-11-23 02:30:24 +01:00
|
|
|
*/
|
|
|
|
inline Native_utcb * main_thread_utcb()
|
|
|
|
{
|
|
|
|
enum {
|
|
|
|
VAS_TOP = VIRT_ADDR_SPACE_START + VIRT_ADDR_SPACE_SIZE,
|
|
|
|
UTCB = VAS_TOP - sizeof(Native_utcb),
|
|
|
|
UTCB_ALIGNED = UTCB & ~((1 << MIN_MAPPING_SIZE_LOG2) - 1),
|
|
|
|
};
|
|
|
|
return (Native_utcb *)UTCB_ALIGNED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-14 13:29:47 +01:00
|
|
|
#endif /* _BASE__NATIVE_TYPES_H_ */
|
2012-05-30 20:13:09 +02:00
|
|
|
|