330 lines
6.1 KiB
C++
Executable File
330 lines
6.1 KiB
C++
Executable File
/*
|
|
* \brief Kernel specific data types
|
|
* \author Martin stein
|
|
* \date 2010-10-01
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2010-2013 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 _INCLUDE__KERNEL__TYPES_H_
|
|
#define _INCLUDE__KERNEL__TYPES_H_
|
|
|
|
#include <base/fixed_stdint.h>
|
|
#include <base/stdint.h>
|
|
#include <kernel/config.h>
|
|
|
|
namespace Kernel {
|
|
|
|
using namespace Cpu;
|
|
|
|
enum {THREAD_CREATE_PARAMS_ROOTRIGHT_LSHIFT=0};
|
|
|
|
|
|
struct Utcb_unaligned
|
|
{
|
|
enum {
|
|
ALIGNMENT_LOG2 = 0,
|
|
SIZE_LOG2 = Cpu::_4KB_SIZE_LOG2,
|
|
};
|
|
|
|
union
|
|
{
|
|
volatile Cpu::byte_t byte[1<<SIZE_LOG2];
|
|
volatile Cpu::word_t word[];
|
|
};
|
|
|
|
static inline Cpu::size_t size();
|
|
|
|
static inline unsigned int size_log2();
|
|
};
|
|
|
|
|
|
struct Utcb : Utcb_unaligned
|
|
{
|
|
enum {
|
|
ALIGNMENT_LOG2 = Kernel::DEFAULT_PAGE_SIZE_LOG2,
|
|
};
|
|
} __attribute__((aligned(1 << Kernel::DEFAULT_PAGE_SIZE_LOG2)));
|
|
|
|
|
|
/* syscall type idents */
|
|
/* XXX changes at THREAD_YIELD have to be manually XXX
|
|
* XXX commited to src/platform/xmb/atomic.s XXX
|
|
* XXX in _atomic_syscall_yield XXX
|
|
*/
|
|
enum Syscall_id{
|
|
TLB_LOAD = 1,
|
|
TLB_FLUSH = 2,
|
|
THREAD_CREATE = 3,
|
|
THREAD_KILL = 4,
|
|
THREAD_SLEEP = 5,
|
|
THREAD_WAKE = 6,
|
|
THREAD_YIELD = 7,
|
|
THREAD_PAGER = 8,
|
|
IPC_REQUEST = 9,
|
|
IPC_SERVE = 10,
|
|
PRINT_CHAR = 11,
|
|
PRINT_INFO = 12,
|
|
IRQ_ALLOCATE = 13,
|
|
IRQ_FREE = 14,
|
|
IRQ_WAIT = 15,
|
|
IRQ_RELEASE = 16,
|
|
INVALID_SYSCALL_ID = 17 };
|
|
|
|
enum{THREAD_CREATE__PARAM__IS_ROOT_LSHIFT=0};
|
|
|
|
namespace Thread_create_types {
|
|
|
|
enum Result {
|
|
SUCCESS = 0,
|
|
INSUFFICIENT_PERMISSIONS = -1,
|
|
INAPPROPRIATE_THREAD_ID = -2 };
|
|
}
|
|
|
|
|
|
namespace Thread_kill_types {
|
|
|
|
enum Result {
|
|
SUCCESS = 0,
|
|
INSUFFICIENT_PERMISSIONS = -1,
|
|
SUICIDAL = -2 };
|
|
}
|
|
|
|
|
|
namespace Thread_wake_types {
|
|
|
|
enum Result{
|
|
SUCCESS = 0,
|
|
INSUFFICIENT_PERMISSIONS = -1,
|
|
INAPPROPRIATE_THREAD_ID = -2 };
|
|
}
|
|
|
|
|
|
namespace Ipc {
|
|
|
|
typedef unsigned Payload_size;
|
|
}
|
|
|
|
|
|
namespace Ipc_serve_types {
|
|
|
|
typedef Ipc::Payload_size Result;
|
|
|
|
struct Argument{ Ipc::Payload_size reply_size; };
|
|
}
|
|
|
|
|
|
namespace Paging {
|
|
|
|
enum { UNIVERSAL_PROTECTION_ID = 0 };
|
|
|
|
class Virtual_page
|
|
{
|
|
addr_t _address;
|
|
Protection_id _protection_id;
|
|
bool _valid;
|
|
|
|
public:
|
|
|
|
void *operator new(size_t, void *addr) { return addr; }
|
|
|
|
/**
|
|
* Invalid construction
|
|
*/
|
|
Virtual_page() : _valid(false) { }
|
|
|
|
/**
|
|
* Construction
|
|
*/
|
|
Virtual_page(addr_t a, Protection_id pid)
|
|
: _address(a), _protection_id(pid), _valid(true) { }
|
|
|
|
bool valid(){ return _valid; }
|
|
|
|
addr_t address(){ return _address; }
|
|
|
|
Protection_id protection_id(){ return _protection_id; }
|
|
|
|
void invalidate(){ _valid=false; }
|
|
};
|
|
|
|
|
|
class Physical_page
|
|
{
|
|
public:
|
|
|
|
enum size_t{
|
|
_1KB = 0,
|
|
_4KB = 1,
|
|
_16KB = 2,
|
|
_64KB = 3,
|
|
_256KB = 4,
|
|
_1MB = 5,
|
|
_4MB = 6,
|
|
_16MB = 7,
|
|
MIN_VALID_SIZE = _4KB,
|
|
MAX_VALID_SIZE = _16MB,
|
|
INVALID_SIZE = 8};
|
|
|
|
enum { MAX_SIZE = INVALID_SIZE, MAX_SIZE_LOG2 = 24 };
|
|
|
|
enum Permissions{ R, RW, RX, RWX };
|
|
|
|
private:
|
|
|
|
addr_t _address;
|
|
size_t _size;
|
|
Permissions _permissions;
|
|
bool _valid;
|
|
|
|
public:
|
|
|
|
void *operator new(Kernel::size_t, void *addr) { return addr; }
|
|
|
|
static inline int size_by_size_log2(size_t& s, int const &size_log2);
|
|
|
|
/**
|
|
* Invalid construction
|
|
*/
|
|
Physical_page() : _valid(false) { }
|
|
|
|
/**
|
|
* Construction
|
|
*/
|
|
Physical_page(addr_t a, size_t ps, Permissions pp) :
|
|
_address(a),
|
|
_size(ps),
|
|
_permissions(pp),
|
|
_valid(true) { }
|
|
|
|
bool valid() { return _valid; }
|
|
|
|
size_t size() { return _size; }
|
|
|
|
addr_t address() { return _address; }
|
|
|
|
Permissions permissions() { return _permissions; }
|
|
|
|
void invalidate() { _valid = false; }
|
|
};
|
|
|
|
|
|
static unsigned const
|
|
size_log2_by_physical_page_size [Physical_page::MAX_SIZE + 1] =
|
|
{ 10, 12, 14, 16, 18, 20, 22, 24, 0 };
|
|
|
|
|
|
struct Resolution
|
|
{
|
|
Virtual_page virtual_page;
|
|
Physical_page physical_page;
|
|
bool write_access;
|
|
|
|
Resolution() { }
|
|
|
|
Resolution(Virtual_page* vp, Physical_page* pp) :
|
|
virtual_page(*vp),
|
|
physical_page(*pp),
|
|
write_access(false)
|
|
{ }
|
|
|
|
Resolution(Virtual_page vp, Physical_page pp) :
|
|
virtual_page(vp),
|
|
physical_page(pp),
|
|
write_access(false)
|
|
{ }
|
|
|
|
void invalidate()
|
|
{
|
|
virtual_page.invalidate();
|
|
physical_page.invalidate();
|
|
}
|
|
|
|
bool valid()
|
|
{
|
|
return virtual_page.valid() & physical_page.valid();
|
|
}
|
|
};
|
|
|
|
|
|
struct Request
|
|
{
|
|
void *operator new(Kernel::size_t, void *addr) { return addr; }
|
|
|
|
enum Access { R, RW, RX, RWX };
|
|
|
|
struct Source
|
|
{
|
|
Thread_id tid;
|
|
addr_t ip;
|
|
};
|
|
|
|
Virtual_page virtual_page;
|
|
Source source;
|
|
Access access;
|
|
|
|
Request(){}
|
|
|
|
Request(Virtual_page *vp, Source s, Access as)
|
|
: virtual_page(*vp), source(s), access(as) { }
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
int Kernel::Paging::Physical_page::size_by_size_log2(size_t &s, int const& size_log2)
|
|
{
|
|
static size_t const size_by_size_log2[MAX_SIZE_LOG2 + 1] = {
|
|
|
|
/* Index 0..9 */
|
|
INVALID_SIZE, INVALID_SIZE,
|
|
INVALID_SIZE, INVALID_SIZE,
|
|
INVALID_SIZE, INVALID_SIZE,
|
|
INVALID_SIZE, INVALID_SIZE,
|
|
INVALID_SIZE, INVALID_SIZE,
|
|
|
|
/* Index 10..19 */
|
|
_1KB, INVALID_SIZE,
|
|
_4KB, INVALID_SIZE,
|
|
_16KB, INVALID_SIZE,
|
|
_64KB, INVALID_SIZE,
|
|
_256KB, INVALID_SIZE,
|
|
|
|
/* Index 20..24 */
|
|
_1MB, INVALID_SIZE,
|
|
_4MB, INVALID_SIZE,
|
|
_16MB
|
|
};
|
|
|
|
if (size_log2 < 0)
|
|
return -1;
|
|
|
|
if ((unsigned)size_log2 >= sizeof(size_by_size_log2) / sizeof(size_by_size_log2[0]))
|
|
return -2;
|
|
|
|
if (size_by_size_log2[size_log2] == INVALID_SIZE)
|
|
return -3;
|
|
|
|
s = size_by_size_log2[(unsigned)size_log2];
|
|
return 0;
|
|
}
|
|
|
|
|
|
Cpu::size_t Kernel::Utcb_unaligned::size()
|
|
{
|
|
return (Cpu::size_t)1<<size_log2();
|
|
}
|
|
|
|
|
|
unsigned int Kernel::Utcb_unaligned::size_log2()
|
|
{
|
|
return (Cpu::size_t)SIZE_LOG2;
|
|
}
|
|
|
|
#endif /* _INCLUDE__KERNEL__TYPES_H_ */
|