mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-19 23:53:55 +00:00
Run Genode directly on hardware with 'base-hw'.
This commit is contained in:
committed by
Norman Feske
parent
8220ea272c
commit
ff65f6f021
160
base-hw/src/base/arm_v7a/syscall.cc
Normal file
160
base-hw/src/base/arm_v7a/syscall.cc
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* \brief Syscall-framework implementation for ARM V7A systems
|
||||
* \author Martin stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/syscall.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
/******************************************************************
|
||||
** Inline assembly templates for syscalls with 1 to 6 arguments **
|
||||
******************************************************************/
|
||||
|
||||
#define SYSCALL_6_ASM_OPS \
|
||||
"mov r5, #0 \n" \
|
||||
"add r5, %[arg_5] \n" \
|
||||
SYSCALL_5_ASM_OPS
|
||||
|
||||
#define SYSCALL_5_ASM_OPS \
|
||||
"mov r4, #0 \n" \
|
||||
"add r4, %[arg_4] \n" \
|
||||
SYSCALL_4_ASM_OPS
|
||||
|
||||
#define SYSCALL_4_ASM_OPS \
|
||||
"mov r3, #0 \n" \
|
||||
"add r3, %[arg_3] \n" \
|
||||
SYSCALL_3_ASM_OPS
|
||||
|
||||
#define SYSCALL_3_ASM_OPS \
|
||||
"mov r2, #0 \n" \
|
||||
"add r2, %[arg_2] \n" \
|
||||
SYSCALL_2_ASM_OPS
|
||||
|
||||
#define SYSCALL_2_ASM_OPS \
|
||||
"mov r1, #0 \n" \
|
||||
"add r1, %[arg_1] \n" \
|
||||
SYSCALL_1_ASM_OPS
|
||||
|
||||
#define SYSCALL_1_ASM_OPS \
|
||||
"mov r0, #0 \n" \
|
||||
"add r0, %[arg_0] \n" \
|
||||
"svc 0x0 \n" \
|
||||
"mov %[result], #0 \n" \
|
||||
"add %[result], r0 "
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Inline assembly "writeable" template-args for syscalls with 1 to 6 args **
|
||||
*****************************************************************************/
|
||||
|
||||
#define SYSCALL_6_ASM_WRITE [arg_5] "+r" (arg_5), SYSCALL_5_ASM_WRITE
|
||||
#define SYSCALL_5_ASM_WRITE [arg_4] "+r" (arg_4), SYSCALL_4_ASM_WRITE
|
||||
#define SYSCALL_4_ASM_WRITE [arg_3] "+r" (arg_3), SYSCALL_3_ASM_WRITE
|
||||
#define SYSCALL_3_ASM_WRITE [arg_2] "+r" (arg_2), SYSCALL_2_ASM_WRITE
|
||||
#define SYSCALL_2_ASM_WRITE [arg_1] "+r" (arg_1), SYSCALL_1_ASM_WRITE
|
||||
#define SYSCALL_1_ASM_WRITE \
|
||||
[arg_0] "+r" (arg_0), \
|
||||
[result] "+r" (result)
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
** Inline assembly clobber lists for syscalls with 1 to 6 arguments **
|
||||
**********************************************************************/
|
||||
|
||||
#define SYSCALL_6_ASM_CLOBBER "r5", SYSCALL_5_ASM_CLOBBER
|
||||
#define SYSCALL_5_ASM_CLOBBER "r4", SYSCALL_4_ASM_CLOBBER
|
||||
#define SYSCALL_4_ASM_CLOBBER "r3", SYSCALL_3_ASM_CLOBBER
|
||||
#define SYSCALL_3_ASM_CLOBBER "r2", SYSCALL_2_ASM_CLOBBER
|
||||
#define SYSCALL_2_ASM_CLOBBER "r1", SYSCALL_1_ASM_CLOBBER
|
||||
#define SYSCALL_1_ASM_CLOBBER "r0"
|
||||
|
||||
|
||||
/************************************
|
||||
** Syscalls with 1 to 6 arguments **
|
||||
************************************/
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_1_ASM_OPS
|
||||
: SYSCALL_1_ASM_WRITE
|
||||
:: SYSCALL_1_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_2_ASM_OPS
|
||||
: SYSCALL_2_ASM_WRITE
|
||||
:: SYSCALL_2_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_3_ASM_OPS
|
||||
: SYSCALL_3_ASM_WRITE
|
||||
:: SYSCALL_3_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_4_ASM_OPS
|
||||
: SYSCALL_4_ASM_WRITE
|
||||
:: SYSCALL_4_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3,
|
||||
Syscall_arg arg_4)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_5_ASM_OPS
|
||||
: SYSCALL_5_ASM_WRITE
|
||||
:: SYSCALL_5_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3,
|
||||
Syscall_arg arg_4,
|
||||
Syscall_arg arg_5)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_6_ASM_OPS
|
||||
: SYSCALL_6_ASM_WRITE
|
||||
:: SYSCALL_6_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
73
base-hw/src/base/console.cc
Normal file
73
base-hw/src/base/console.cc
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* \brief Genode-console backend
|
||||
* \author Martin Stein
|
||||
* \date 2011-10-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/console.h>
|
||||
#include <base/printf.h>
|
||||
#include <drivers/serial_log.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Platform specific Genode console
|
||||
*/
|
||||
class Platform_console : public Console,
|
||||
public Serial_log
|
||||
{
|
||||
enum { BAUD_RATE = 115200 };
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Print a char to the console
|
||||
*/
|
||||
void _out_char(char c) { Serial_log::put_char(c); }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_console() : Serial_log(BAUD_RATE) { }
|
||||
};
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Static object to print log output
|
||||
*/
|
||||
static Platform_console * platform_console()
|
||||
{
|
||||
static Platform_console static_platform_console;
|
||||
return &static_platform_console;
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
** Genode print functions **
|
||||
****************************/
|
||||
|
||||
void Genode::printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
platform_console()->vprintf(format, list);
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
|
||||
void Genode::vprintf(const char *format, va_list list)
|
||||
{ platform_console()->vprintf(format, list); }
|
||||
|
220
base-hw/src/base/ipc.cc
Normal file
220
base-hw/src/base/ipc.cc
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* \brief Implementation of the Genode IPC-framework
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/ipc.h>
|
||||
#include <base/thread.h>
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum
|
||||
{
|
||||
/* size of the callee-local name of a targeted RPC object */
|
||||
RPC_OBJECT_ID_SIZE = sizeof(umword_t),
|
||||
|
||||
/*
|
||||
* The RPC framework marshalls a return value into reply messages to
|
||||
* deliver exceptions, wich occured during the RPC call to the caller.
|
||||
* This defines the size of this value.
|
||||
*/
|
||||
RPC_RETURN_VALUE_SIZE = sizeof(umword_t),
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
|
||||
/**
|
||||
* Translate byte size 's' to size in words
|
||||
*/
|
||||
static unsigned long size_in_words(unsigned long const s)
|
||||
{ return (s + sizeof(unsigned long) - 1) / sizeof(unsigned long); }
|
||||
|
||||
|
||||
/**
|
||||
* Copy message payload to message buffer
|
||||
*/
|
||||
static void copy_utcb_to_msgbuf(Msgbuf_base * const receive_buffer,
|
||||
unsigned long const message_size)
|
||||
{
|
||||
/* log data that is received via IPC */
|
||||
enum { VERBOSE = 0 };
|
||||
|
||||
/* get pointers and message attributes */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
unsigned long * const msgbuf = (unsigned long *)receive_buffer->buf;
|
||||
unsigned long const message_wsize = size_in_words(message_size);
|
||||
|
||||
/* assertions, avoid 'printf' in here, it may lead to infinite recursion */
|
||||
if (message_wsize > size_in_words(utcb->size()))
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Oversized message\n";
|
||||
while (1) ;
|
||||
}
|
||||
/* fill message buffer with message */
|
||||
for (unsigned i=0; i < message_wsize; i++)
|
||||
msgbuf[i] = *utcb->word(i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy message payload to the UTCB
|
||||
*/
|
||||
static void copy_msgbuf_to_utcb(Msgbuf_base * const send_buffer,
|
||||
unsigned long const message_size,
|
||||
unsigned long const local_name)
|
||||
{
|
||||
/* log data that is send via IPC */
|
||||
enum { VERBOSE = 0 };
|
||||
|
||||
/* get pointers and message attributes */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
unsigned long * const msgbuf = (unsigned long *)send_buffer->buf;
|
||||
unsigned long const message_wsize = size_in_words(message_size);
|
||||
|
||||
/* assertions, avoid 'printf' in here, it may lead to infinite recursion */
|
||||
if (message_wsize > size_in_words(utcb->size()))
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Oversized message\n";
|
||||
while (1) ;
|
||||
}
|
||||
/* address message to an object that the targeted thread knows */
|
||||
*utcb->word(0) = local_name;
|
||||
|
||||
/* write message payload */
|
||||
for (unsigned long i = 1; i < message_wsize; i++)
|
||||
*utcb->word(i) = msgbuf[i];
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_ostream **
|
||||
*****************/
|
||||
|
||||
Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg)
|
||||
:
|
||||
Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()),
|
||||
_snd_msg(snd_msg), _dst(dst)
|
||||
{
|
||||
_write_offset = RPC_OBJECT_ID_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_istream **
|
||||
*****************/
|
||||
|
||||
void Ipc_istream::_wait()
|
||||
{
|
||||
/* FIXME this shall be not supported */
|
||||
Kernel::pause_thread();
|
||||
}
|
||||
|
||||
|
||||
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
|
||||
:
|
||||
Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()),
|
||||
Native_capability(Genode::thread_get_my_native_id(), 0),
|
||||
_rcv_msg(rcv_msg), _rcv_cs(-1)
|
||||
{ _read_offset = RPC_OBJECT_ID_SIZE; }
|
||||
|
||||
|
||||
Ipc_istream::~Ipc_istream() { }
|
||||
|
||||
|
||||
/****************
|
||||
** Ipc_client **
|
||||
****************/
|
||||
|
||||
void Ipc_client::_call()
|
||||
{
|
||||
using namespace Kernel;
|
||||
|
||||
/* send request and receive reply */
|
||||
copy_msgbuf_to_utcb(_snd_msg, _write_offset,
|
||||
Ipc_ostream::_dst.local_name());
|
||||
size_t const s = request_and_wait(Ipc_ostream::_dst.dst(), _write_offset);
|
||||
copy_utcb_to_msgbuf(_rcv_msg, s);
|
||||
|
||||
/* reset unmarshaller */
|
||||
_write_offset = _read_offset = RPC_OBJECT_ID_SIZE;
|
||||
}
|
||||
|
||||
|
||||
Ipc_client::Ipc_client(Native_capability const &srv,
|
||||
Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
|
||||
: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) { }
|
||||
|
||||
|
||||
/****************
|
||||
** Ipc_server **
|
||||
****************/
|
||||
|
||||
Ipc_server::Ipc_server(Msgbuf_base *snd_msg,
|
||||
Msgbuf_base *rcv_msg) :
|
||||
Ipc_istream(rcv_msg),
|
||||
Ipc_ostream(Native_capability(), snd_msg),
|
||||
_reply_needed(false)
|
||||
{ }
|
||||
|
||||
|
||||
void Ipc_server::_prepare_next_reply_wait()
|
||||
{
|
||||
/* now we have a request to reply */
|
||||
_reply_needed = true;
|
||||
|
||||
/* leave space for RPC method return value */
|
||||
_write_offset = RPC_OBJECT_ID_SIZE + RPC_RETURN_VALUE_SIZE;
|
||||
|
||||
/* reset unmarshaller */
|
||||
_read_offset = RPC_OBJECT_ID_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_wait()
|
||||
{
|
||||
/* receive next request */
|
||||
copy_utcb_to_msgbuf(_rcv_msg, Kernel::wait_for_request());
|
||||
|
||||
/* update server state */
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_reply()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Unexpected call\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_reply_wait()
|
||||
{
|
||||
/* if there is no reply simply do wait for request */
|
||||
/* FIXME this shall be not supported */
|
||||
if (!_reply_needed) {
|
||||
_wait();
|
||||
return;
|
||||
}
|
||||
/* send reply and receive next request */
|
||||
copy_msgbuf_to_utcb(_snd_msg, _write_offset,
|
||||
Ipc_ostream::_dst.local_name());
|
||||
copy_utcb_to_msgbuf(_rcv_msg, Kernel::reply_and_wait(_write_offset));
|
||||
|
||||
/* update server state */
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
58
base-hw/src/base/lock/lock_helper.h
Normal file
58
base-hw/src/base/lock/lock_helper.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Helper functions for the Lock implementation
|
||||
* \author Martin Stein
|
||||
* \date 2011-01-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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 _SRC__BASE__LOCK__LOCK_HELPER_H_
|
||||
#define _SRC__BASE__LOCK__LOCK_HELPER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
|
||||
|
||||
/**
|
||||
* Yield CPU to any other thread
|
||||
*/
|
||||
static inline void thread_yield()
|
||||
{ Kernel::yield_thread(); }
|
||||
|
||||
|
||||
/**
|
||||
* Yield CPU to a specified thread 't'
|
||||
*/
|
||||
static inline void
|
||||
thread_switch_to(Genode::Native_thread_id const t)
|
||||
{ Kernel::yield_thread(t); }
|
||||
|
||||
|
||||
/**
|
||||
* Resume another thread 't' and return if it were paused or not
|
||||
*/
|
||||
static inline bool
|
||||
thread_check_stopped_and_restart(Genode::Native_thread_id const t)
|
||||
{ return Kernel::resume_thread(t) == 0; }
|
||||
|
||||
|
||||
/**
|
||||
* Validation kernel thread-identifier 'id'
|
||||
*/
|
||||
static inline bool thread_id_valid(Genode::Native_thread_id const id)
|
||||
{ return id != Genode::thread_invalid_id(); }
|
||||
|
||||
|
||||
/**
|
||||
* Exclude ourselves from CPU scheduling for now
|
||||
*/
|
||||
static inline void thread_stop_myself() { Kernel::pause_thread(); }
|
||||
|
||||
|
||||
#endif /* _SRC__BASE__LOCK__LOCK_HELPER_H_ */
|
||||
|
127
base-hw/src/base/pager.cc
Normal file
127
base-hw/src/base/pager.cc
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* \brief Pager implementations that are specific for the HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/pager.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/***************************
|
||||
** Pager_activation_base **
|
||||
***************************/
|
||||
|
||||
void Pager_activation_base::entry()
|
||||
{
|
||||
/* acknowledge that we're ready to work */
|
||||
Ipc_pager pager;
|
||||
_cap = pager;
|
||||
_cap_valid.unlock();
|
||||
|
||||
/* wait for the first pagefault */
|
||||
pager.wait_for_fault();
|
||||
while (1)
|
||||
{
|
||||
/* lookup pager object for the current faulter */
|
||||
Pager_object * o = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
if (!o) {
|
||||
PERR("%s:%d: Invalid pager object", __FILE__, __LINE__);
|
||||
while (1) ;
|
||||
}
|
||||
/* let pager handle the pagefault, apply mapping, await pagefault */
|
||||
if (o->pager(pager)) pager.wait_for_fault();
|
||||
else pager.resolve_and_wait_for_fault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** Pager_entrypoint **
|
||||
**********************/
|
||||
|
||||
Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
||||
Pager_activation_base * const a)
|
||||
: _activation(a) { _activation->ep(this); }
|
||||
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o) { remove(o); }
|
||||
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
|
||||
{
|
||||
/* do we have an activation */
|
||||
if (!_activation) return Pager_capability();
|
||||
|
||||
/* create cap with the object badge as local name */
|
||||
Native_capability c;
|
||||
c = Native_capability(_activation->cap().dst(), o->badge());
|
||||
|
||||
/* let activation provide the pager object */
|
||||
o->cap(c);
|
||||
insert(o);
|
||||
|
||||
/* return pager-object cap */
|
||||
return reinterpret_cap_cast<Pager_object>(c);
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Ipc_pager **
|
||||
***************/
|
||||
|
||||
|
||||
void Ipc_pager::wait_for_fault()
|
||||
{
|
||||
/* receive first message */
|
||||
size_t s = Kernel::wait_for_request();
|
||||
while (1) {
|
||||
switch (s) {
|
||||
|
||||
case sizeof(Pagefault): {
|
||||
|
||||
/* message is a pagefault */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
Pagefault * const pf = (Pagefault *)utcb;
|
||||
if (pf->valid())
|
||||
{
|
||||
/* give our caller the chance to handle the fault */
|
||||
_pagefault = *pf;
|
||||
return;
|
||||
}
|
||||
/* pagefault is invalid so get the next message */
|
||||
else {
|
||||
PERR("%s:%d: Invalid pagefault", __FILE__, __LINE__);
|
||||
continue;
|
||||
}
|
||||
continue; }
|
||||
|
||||
case sizeof(Pagefault_resolved): {
|
||||
|
||||
/* message is a release request from a RM session */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
Pagefault_resolved * const msg = (Pagefault_resolved *)utcb;
|
||||
|
||||
/* resume faulter, send ack to RM and get the next message */
|
||||
Kernel::resume_thread(msg->pager_object->badge());
|
||||
s = Kernel::reply_and_wait(0);
|
||||
continue; }
|
||||
|
||||
default: {
|
||||
|
||||
PERR("%s:%d: Invalid message format", __FILE__, __LINE__);
|
||||
continue; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
130
base-hw/src/base/signal/signal.cc
Normal file
130
base-hw/src/base/signal/signal.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* \brief Implementations of the signaling framework specific for HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/signal.h>
|
||||
#include <signal_session/connection.h>
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Provide a static signal connection
|
||||
*/
|
||||
static Signal_connection * signal_connection()
|
||||
{
|
||||
static Signal_connection _object;
|
||||
return &_object;
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** Signal_receiver **
|
||||
*********************/
|
||||
|
||||
|
||||
Signal_receiver::Signal_receiver() :
|
||||
_cap(signal_connection()->alloc_receiver())
|
||||
{
|
||||
if (!_cap.valid()) {
|
||||
PERR("%s: Failed to create receiver", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Signal_receiver::~Signal_receiver()
|
||||
{
|
||||
/* dissolve all contexts that are managed by us */
|
||||
Lock::Guard contexts_guard(_contexts_lock);
|
||||
while (1) {
|
||||
Signal_context * const c = _contexts.first();
|
||||
if (!c) break;
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
_unsync_dissolve(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Signal_context_capability Signal_receiver::manage(Signal_context * const c)
|
||||
{
|
||||
/* check if the context is already managed */
|
||||
Lock::Guard contexts_guard(_contexts_lock);
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
if (c->_receiver) throw Context_already_in_use();
|
||||
|
||||
/* create a kernel object that corresponds to the context */
|
||||
bool session_upgraded = 0;
|
||||
Signal_connection * const s = signal_connection();
|
||||
while (1) {
|
||||
try {
|
||||
c->_cap = s->alloc_context(_cap, (unsigned long)c);
|
||||
break;
|
||||
} catch (Signal_session::Out_of_metadata)
|
||||
{
|
||||
/* upgrade session quota and try again, but only once */
|
||||
if (session_upgraded) return Signal_context_capability();
|
||||
env()->parent()->upgrade(s->cap(), "ram_quota=4K");
|
||||
session_upgraded = 1;
|
||||
}
|
||||
}
|
||||
/* assign the context to us */
|
||||
c->_receiver = this;
|
||||
_contexts.insert(c);
|
||||
return c->_cap;
|
||||
}
|
||||
|
||||
|
||||
Signal Signal_receiver::wait_for_signal()
|
||||
{
|
||||
/* await a signal */
|
||||
Kernel::await_signal(_cap.dst());
|
||||
Signal s = *(Signal *)Thread_base::myself()->utcb();
|
||||
Signal_context * c = s.context();
|
||||
|
||||
/* check if the context of the signal is managed by us */
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
if (c->_receiver != this) {
|
||||
PERR("%s: Context not managed by this receiver", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
}
|
||||
/* check attributes of the signal and return it */
|
||||
if (s.num() == 0) PWRN("Returning signal with num == 0");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void Signal_receiver::dissolve(Signal_context * const c)
|
||||
{
|
||||
/* check if the context is managed by us */
|
||||
Lock::Guard contexts_guard(_contexts_lock);
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
if (c->_receiver != this) throw Context_not_associated();
|
||||
|
||||
/* unassign the context */
|
||||
_unsync_dissolve(c);
|
||||
}
|
||||
|
||||
|
||||
void Signal_receiver::_unsync_dissolve(Signal_context * const c)
|
||||
{
|
||||
/* reset the context */
|
||||
c->_receiver = 0;
|
||||
c->_cap = Signal_context_capability();
|
||||
|
||||
/* forget the context */
|
||||
_contexts.remove(c);
|
||||
}
|
||||
|
91
base-hw/src/base/thread_support.cc
Normal file
91
base-hw/src/base/thread_support.cc
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* \brief Platform specific parts of the thread API
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/env.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Native_utcb * _main_utcb;
|
||||
|
||||
namespace Genode { Rm_session *env_context_area_rm_session(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
/* this is a main thread, so CRT0 provides UTCB through '_main_utcb' */
|
||||
if (!this) return _main_utcb;
|
||||
|
||||
/* otherwise we have a valid thread base */
|
||||
return &_context->utcb;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
Thread_base::myself()->_thread_bootstrap();
|
||||
Thread_base::myself()->entry();
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{ env()->cpu_session()->kill_thread(_thread_cap); }
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
Cpu_session * cpu = env()->cpu_session();
|
||||
_thread_cap = cpu->create_thread(buf, (addr_t)&_context->utcb);
|
||||
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
|
||||
/* create new pager object and assign it to the new thread */
|
||||
Pager_capability pager_cap = env()->rm_session()->add_client(_thread_cap);
|
||||
env()->cpu_session()->set_pager(_thread_cap, pager_cap);
|
||||
|
||||
/* attach UTCB */
|
||||
try {
|
||||
Ram_dataspace_capability ds = env()->cpu_session()->utcb(_thread_cap);
|
||||
size_t const size = sizeof(_context->utcb);
|
||||
addr_t dst = Context_allocator::addr_to_base(_context) +
|
||||
CONTEXT_VIRTUAL_SIZE - size - CONTEXT_AREA_VIRTUAL_BASE;
|
||||
env_context_area_rm_session()->attach_at(ds, dst, size);
|
||||
} catch (...) {
|
||||
PERR("%s: Failed to attach UTCB", __PRETTY_FUNCTION__);
|
||||
sleep_forever();
|
||||
}
|
||||
/* start thread with its initial IP and aligned SP */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
thread_sp &= ~0xf;
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{ env()->cpu_session()->cancel_blocking(_thread_cap); }
|
||||
|
33
base-hw/src/core/arm_v7a/boot_modules.s
Normal file
33
base-hw/src/core/arm_v7a/boot_modules.s
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* \brief Dummy version of a boot modules file to enable a 'core' standalone image
|
||||
* \author Martin Stein
|
||||
* \date 2011-12-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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.
|
||||
*/
|
||||
|
||||
.section .data
|
||||
|
||||
.align 3
|
||||
.global _boot_modules_begin
|
||||
_boot_modules_begin:
|
||||
.string "GROM"
|
||||
|
||||
.align 3
|
||||
.global _boot_module_headers_begin
|
||||
_boot_module_headers_begin:
|
||||
|
||||
/* no module headers */
|
||||
|
||||
.global _boot_module_headers_end
|
||||
_boot_module_headers_end:
|
||||
|
||||
/* no modules */
|
||||
|
||||
.global _boot_modules_end
|
||||
_boot_modules_end:
|
72
base-hw/src/core/arm_v7a/crt0.s
Normal file
72
base-hw/src/core/arm_v7a/crt0.s
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* \brief Startup code for the Genode Kernel on ARM
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-10-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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.
|
||||
*/
|
||||
|
||||
.section .text
|
||||
|
||||
/* ELF entry symbol */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* idle a little initially because 'u-boot' likes it this way */
|
||||
.rept 8
|
||||
nop
|
||||
.endr
|
||||
|
||||
/* zero-fill BSS segment */
|
||||
.extern _bss_start
|
||||
.extern _bss_end
|
||||
ldr r0, =_bss_start
|
||||
ldr r1, =_bss_end
|
||||
mov r2, #0
|
||||
sub r1, r1, #4
|
||||
1:
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
cmp r0, r1
|
||||
bne 1b
|
||||
|
||||
/* call kernel routine */
|
||||
.extern kernel
|
||||
_start_kernel:
|
||||
ldr sp, =_kernel_stack_high
|
||||
bl kernel
|
||||
|
||||
/* jump to code that kernel has designated for when he has returned */
|
||||
ldr r1, =_call_after_kernel
|
||||
ldr r1, [r1]
|
||||
add pc, r1, #0
|
||||
|
||||
/* handle for dynamic symbol objects */
|
||||
.align 3
|
||||
.global __dso_handle
|
||||
__dso_handle: .long 0
|
||||
|
||||
.section .bss
|
||||
|
||||
/* instruction pointer wich gets loaded when kernel returns */
|
||||
.align 3
|
||||
.global _call_after_kernel
|
||||
_call_after_kernel: .long 0
|
||||
|
||||
/* kernel stack */
|
||||
.align 3
|
||||
.space 64*1024
|
||||
.global _kernel_stack_high
|
||||
_kernel_stack_high:
|
||||
|
||||
/* main thread UTCB pointer for the Genode thread API */
|
||||
.align 3
|
||||
.global _main_utcb
|
||||
_main_utcb: .long 0
|
||||
|
205
base-hw/src/core/arm_v7a/mode_transition.s
Normal file
205
base-hw/src/core/arm_v7a/mode_transition.s
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* \brief Transition between kernel and userland
|
||||
* \author Martin stein
|
||||
* \date 2011-11-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Invalidate all entries of the branch predictor array
|
||||
*/
|
||||
.macro _flush_branch_predictor
|
||||
mcr p15, 0, sp, c7, c5, 6
|
||||
isb
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Switch from an interrupted user context to a kernel context
|
||||
*
|
||||
* \param exception_type immediate exception type ID
|
||||
* \param pc_adjust immediate value that gets subtracted from the
|
||||
* user PC before it gets saved
|
||||
*/
|
||||
.macro _user_to_kernel_pic exception_type, pc_adjust
|
||||
|
||||
/*
|
||||
* We expect that privileged modes are never interrupted by an
|
||||
* exception. Thus we can assume that we always come from
|
||||
* user mode at this point.
|
||||
*/
|
||||
|
||||
/************************************************
|
||||
** We're still in the user protection domain, **
|
||||
** so we must avoid access to kernel memory **
|
||||
************************************************/
|
||||
|
||||
/* load kernel contextidr */
|
||||
adr sp, _mt_kernel_context_begin
|
||||
ldr sp, [sp, #17*4]
|
||||
mcr p15, 0, sp, c13, c0, 1
|
||||
_flush_branch_predictor
|
||||
|
||||
/* load kernel section table */
|
||||
adr sp, _mt_kernel_context_begin
|
||||
ldr sp, [sp, #19*4]
|
||||
mcr p15, 0, sp, c2, c0, 0
|
||||
_flush_branch_predictor
|
||||
|
||||
/*******************************************
|
||||
** Now it's save to access kernel memory **
|
||||
*******************************************/
|
||||
|
||||
/* get user context pointer */
|
||||
ldr sp, _mt_user_context_ptr
|
||||
|
||||
/*
|
||||
* Save user r0 ... r12. We explicitely target user registers
|
||||
* via '^' because we might be in FIQ exception-mode where
|
||||
* some of them are banked. Doesn't affect other modes.
|
||||
*/
|
||||
stmia sp, {r0-r12}^
|
||||
|
||||
/* save user lr and sp */
|
||||
add r0, sp, #13*4
|
||||
stmia r0, {sp,lr}^
|
||||
|
||||
/* adjust and save user pc */
|
||||
.if \pc_adjust != 0
|
||||
sub lr, lr, #\pc_adjust
|
||||
.endif
|
||||
str lr, [sp, #15*4]
|
||||
|
||||
/* save user psr */
|
||||
mrs r0, spsr
|
||||
str r0, [sp, #16*4]
|
||||
|
||||
/* save type of exception that interrupted the user */
|
||||
mov r0, #\exception_type
|
||||
str r0, [sp, #18*4]
|
||||
|
||||
/*
|
||||
* Switch to supervisor mode
|
||||
* FIXME This is done due to incorrect behavior when running the kernel
|
||||
* high-level-code in FIQ-exception mode. Please debug this behavior
|
||||
* and remove this switch.
|
||||
*/
|
||||
cps #19
|
||||
|
||||
/* get kernel context pointer */
|
||||
adr r0, _mt_kernel_context_begin
|
||||
|
||||
/* load kernel context */
|
||||
add r0, r0, #13*4
|
||||
ldmia r0, {sp, lr, pc}
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.section .text
|
||||
|
||||
/*
|
||||
* The mode transition PIC switches between a kernel context and a user
|
||||
* context and thereby between their address spaces. Due to the latter
|
||||
* it must be mapped executable to the same region in every address space.
|
||||
* To enable such switching, the kernel context must be stored within this
|
||||
* region, thus one should map it solely accessable for privileged modes.
|
||||
*/
|
||||
.align 3
|
||||
.global _mode_transition_begin
|
||||
_mode_transition_begin:
|
||||
|
||||
/*
|
||||
* On user exceptions the CPU has to jump to one of the following
|
||||
* 7 entry vectors to switch to a kernel context.
|
||||
*/
|
||||
.align 3
|
||||
.global _mt_kernel_entry_pic
|
||||
_mt_kernel_entry_pic:
|
||||
|
||||
b _rst_entry /* reset */
|
||||
b _und_entry /* undefined instruction */
|
||||
b _svc_entry /* supervisor call */
|
||||
b _pab_entry /* prefetch abort */
|
||||
b _dab_entry /* data abort */
|
||||
nop /* reserved */
|
||||
b _irq_entry /* interrupt request */
|
||||
b _fiq_entry /* fast interrupt request */
|
||||
|
||||
/* PICs that switch from an user exception to the kernel */
|
||||
_rst_entry: _user_to_kernel_pic 1, 0
|
||||
_und_entry: _user_to_kernel_pic 2, 4
|
||||
_svc_entry: _user_to_kernel_pic 3, 0
|
||||
_pab_entry: _user_to_kernel_pic 4, 4
|
||||
_dab_entry: _user_to_kernel_pic 5, 8
|
||||
_irq_entry: _user_to_kernel_pic 6, 4
|
||||
_fiq_entry: _user_to_kernel_pic 7, 4
|
||||
|
||||
/* kernel must jump to this point to switch to a user context */
|
||||
.align 3
|
||||
.global _mt_user_entry_pic
|
||||
_mt_user_entry_pic:
|
||||
|
||||
/* get user context pointer */
|
||||
ldr lr, _mt_user_context_ptr
|
||||
|
||||
/* buffer user pc */
|
||||
ldr r0, [lr, #15*4]
|
||||
adr r1, _mt_buffer
|
||||
str r0, [r1]
|
||||
|
||||
/* buffer user psr */
|
||||
ldr r0, [lr, #16*4]
|
||||
msr spsr, r0
|
||||
|
||||
/* load user r0 ... r12 */
|
||||
ldmia lr, {r0-r12}
|
||||
|
||||
/* load user sp and lr */
|
||||
add sp, lr, #13*4
|
||||
ldmia sp, {sp,lr}^
|
||||
|
||||
/* get user contextidr and section table */
|
||||
ldr sp, [lr, #17*4]
|
||||
ldr lr, [lr, #19*4]
|
||||
|
||||
/********************************************************
|
||||
** From now on, until we leave kernel mode, we must **
|
||||
** avoid access to memory that is not mapped globally **
|
||||
********************************************************/
|
||||
|
||||
/* apply user contextidr and section table */
|
||||
mcr p15, 0, sp, c13, c0, 1
|
||||
mcr p15, 0, lr, c2, c0, 0
|
||||
_flush_branch_predictor
|
||||
|
||||
/* load user pc (implies application of the user psr) */
|
||||
adr lr, _mt_buffer
|
||||
ldmia lr, {pc}^
|
||||
|
||||
/* leave some space for the kernel context */
|
||||
.align 3
|
||||
.global _mt_kernel_context_begin
|
||||
_mt_kernel_context_begin: .space 32*4
|
||||
.global _mt_kernel_context_end
|
||||
_mt_kernel_context_end:
|
||||
|
||||
/* pointer to the user context backup space */
|
||||
.align 3
|
||||
.global _mt_user_context_ptr
|
||||
_mt_user_context_ptr: .long 0
|
||||
|
||||
/* a local word-sized buffer */
|
||||
.align 3
|
||||
.global _mt_buffer
|
||||
_mt_buffer: .long 0
|
||||
|
||||
.align 3
|
||||
.global _mode_transition_end
|
||||
_mode_transition_end:
|
||||
|
34
base-hw/src/core/cpu_session_support.cc
Normal file
34
base-hw/src/core/cpu_session_support.cc
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* \brief Platform specific parts of CPU session
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <dataspace/capability.h>
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Ram_dataspace_capability
|
||||
Cpu_session_component::utcb(Thread_capability thread_cap)
|
||||
{
|
||||
/* serialize access */
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
/* lookup requested UTCB dataspace */
|
||||
Cpu_thread_component * t = _lookup_thread(thread_cap);
|
||||
if (!t) return Ram_dataspace_capability();
|
||||
return t->platform_thread()->utcb();
|
||||
}
|
||||
|
36
base-hw/src/core/include/assert.h
Normal file
36
base-hw/src/core/include/assert.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* \brief Assertion macro
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__ASSERT_H_
|
||||
#define _CORE__INCLUDE__ASSERT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/**
|
||||
* Assert a condition
|
||||
*
|
||||
* \param expression Expression that must be true
|
||||
*/
|
||||
#define assert(expression) \
|
||||
do { \
|
||||
if (!(expression)) { \
|
||||
PERR("Assertion failed: "#expression""); \
|
||||
PERR(" File: %s:%d", __FILE__, __LINE__); \
|
||||
PERR(" Function: %s", __PRETTY_FUNCTION__); \
|
||||
while (1) ; \
|
||||
} \
|
||||
} while (0) ;
|
||||
|
||||
#endif /* _CORE__INCLUDE__ASSERT_H_ */
|
||||
|
54
base-hw/src/core/include/cortex_a9/kernel_support.h
Normal file
54
base-hw/src/core/include/cortex_a9/kernel_support.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* \brief Parts of kernel support that are identical for all Cortex A9 systems
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__CORTEX_A9__KERNEL_SUPPORT_H_
|
||||
#define _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/**
|
||||
* CPU driver
|
||||
*/
|
||||
class Cpu : public Genode::Cortex_a9 { };
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/* import Genode types */
|
||||
typedef Genode::Cortex_a9 Cortex_a9;
|
||||
typedef Genode::Pl390_base Pl390_base;
|
||||
|
||||
/**
|
||||
* Kernel interrupt-controller
|
||||
*/
|
||||
class Pic : public Pl390_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Pic() : Pl390_base(Cortex_a9::PL390_DISTRIBUTOR_MMIO_BASE,
|
||||
Cortex_a9::PL390_CPU_MMIO_BASE)
|
||||
{ }
|
||||
};
|
||||
|
||||
/**
|
||||
* Kernel timer
|
||||
*/
|
||||
class Timer : public Cortex_a9::Private_timer { };
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_ */
|
||||
|
68
base-hw/src/core/include/cpu_thread_allocator.h
Normal file
68
base-hw/src/core/include/cpu_thread_allocator.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* \brief Platform specific parts of the core CPU session
|
||||
* \author Martin Stein
|
||||
* \date 2012-03-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__CPU_SESSION_SUPPORT_H_
|
||||
#define _CORE__INCLUDE__CPU_SESSION_SUPPORT_H_
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <base/allocator.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Thread allocator for cores CPU service
|
||||
*
|
||||
* Normally one would use a SLAB for threads because usually they
|
||||
* are tiny objects, but in 'base-hw' they contain the whole kernel
|
||||
* object in addition. Thus we use the given allocator directly.
|
||||
*/
|
||||
class Cpu_thread_allocator : public Allocator
|
||||
{
|
||||
Allocator * const _alloc;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param alloc allocator backend
|
||||
*/
|
||||
Cpu_thread_allocator(Allocator * alloc) : _alloc(alloc) { }
|
||||
|
||||
/*************************
|
||||
** Allocator interface **
|
||||
*************************/
|
||||
|
||||
bool alloc(size_t size, void **out_addr) {
|
||||
return _alloc->alloc(size, out_addr); }
|
||||
|
||||
void free(void *addr, size_t size) {
|
||||
_alloc->free(addr, size); }
|
||||
|
||||
size_t consumed() {
|
||||
PDBG("Unexprected call");
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t overhead(size_t size) {
|
||||
PDBG("Unexprected call");
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool need_size_for_free() const { return true; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CPU_SESSION_SUPPORT_H_ */
|
111
base-hw/src/core/include/platform.h
Normal file
111
base-hw/src/core/include/platform.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* \brief Platform interface
|
||||
* \author Martin Stein
|
||||
* \date 2011-12-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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__PLATFORM_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/sync_allocator.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <kernel/log.h>
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_generic.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Manages all platform ressources
|
||||
*/
|
||||
class Platform : public Platform_generic
|
||||
{
|
||||
typedef Synchronized_range_allocator<Allocator_avl> Phys_allocator;
|
||||
|
||||
Phys_allocator _core_mem_alloc; /* core-accessible memory */
|
||||
Phys_allocator _io_mem_alloc; /* MMIO allocator */
|
||||
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_fs _rom_fs; /* ROM file system */
|
||||
|
||||
addr_t _vm_base; /* base of virtual address space */
|
||||
size_t _vm_size; /* size of virtual address space */
|
||||
|
||||
/**
|
||||
* Get one of the consecutively numbered available resource regions
|
||||
*
|
||||
* \return >0 region pointer if region with index 'i' exists
|
||||
* 0 if region with index 'i' doesn't exist
|
||||
*
|
||||
* These functions should provide all ressources that are available
|
||||
* on the current platform.
|
||||
*/
|
||||
static Native_region * _ram_regions(unsigned i);
|
||||
static Native_region * _mmio_regions(unsigned i);
|
||||
static Native_region * _irq_regions(unsigned i);
|
||||
|
||||
/**
|
||||
* Get one of the consecutively numbered core regions
|
||||
*
|
||||
* \return >0 Region pointer if region with index 'i' exists
|
||||
* 0 If region with index 'i' doesn't exist
|
||||
*
|
||||
* Core regions are address regions that must be permitted to
|
||||
* core only, such as the core image ROM. These regions are normally
|
||||
* a subset of the ressource regions provided above.
|
||||
*/
|
||||
static Native_region * _core_only_ram_regions(unsigned i);
|
||||
static Native_region * _core_only_mmio_regions(unsigned i);
|
||||
static Native_region * _core_only_irq_regions(unsigned i);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
|
||||
/********************************
|
||||
** Platform_generic interface **
|
||||
********************************/
|
||||
|
||||
inline Range_allocator * core_mem_alloc() { return &_core_mem_alloc; }
|
||||
|
||||
inline Range_allocator * ram_alloc() { return &_core_mem_alloc; }
|
||||
|
||||
inline Range_allocator * io_mem_alloc() { return &_io_mem_alloc; }
|
||||
|
||||
inline Range_allocator * io_port_alloc() { return &_io_port_alloc; }
|
||||
|
||||
inline Range_allocator * irq_alloc() { return &_irq_alloc; }
|
||||
|
||||
inline addr_t vm_start() const { return _vm_base; }
|
||||
|
||||
inline size_t vm_size() const { return _vm_size; }
|
||||
|
||||
inline Rom_fs *rom_fs() { return &_rom_fs; }
|
||||
|
||||
inline void wait_for_exit() { while (1) Kernel::pause_thread(); };
|
||||
|
||||
inline Range_allocator * region_alloc()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
||||
|
105
base-hw/src/core/include/platform_pd.h
Normal file
105
base-hw/src/core/include/platform_pd.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* \brief Platform specific part of a Genode protection domain
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2012 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__PLATFORM_PD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
Genode::size_t pd_size();
|
||||
unsigned pd_alignm_log2();
|
||||
}
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Platform_thread;
|
||||
|
||||
/**
|
||||
* Platform specific part of a Genode protection domain
|
||||
*/
|
||||
class Platform_pd
|
||||
{
|
||||
unsigned long _id; /* ID of our kernel object */
|
||||
Native_capability _parent; /* our parent interface */
|
||||
Native_thread_id _main_thread; /* the first thread that gets
|
||||
* executed in this PD */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_pd() : _main_thread(0)
|
||||
{
|
||||
/* get some aligned space for the kernel object */
|
||||
void * kernel_pd;
|
||||
Range_allocator * ram = platform()->ram_alloc();
|
||||
assert(ram->alloc_aligned(Kernel::pd_size(), &kernel_pd,
|
||||
Kernel::pd_alignm_log2()));
|
||||
|
||||
/* create kernel object */
|
||||
_id = Kernel::new_pd(kernel_pd);
|
||||
assert(_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_pd();
|
||||
|
||||
/**
|
||||
* Bind thread 't' to protection domain
|
||||
*
|
||||
* \return 0 on success or
|
||||
* -1 if failed
|
||||
*/
|
||||
int bind_thread(Platform_thread * t)
|
||||
{
|
||||
/* is this the first and therefore main thread in this PD? */
|
||||
if (!_main_thread)
|
||||
{
|
||||
/* annotate that we've got a main thread from now on */
|
||||
_main_thread = t->id();
|
||||
return t->join_pd(_id, 1);
|
||||
}
|
||||
return t->join_pd(_id, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind thread from protection domain
|
||||
*
|
||||
* Free the thread's slot and update thread object.
|
||||
*/
|
||||
void unbind_thread(Platform_thread * t);
|
||||
|
||||
/**
|
||||
* Assign parent interface to protection domain
|
||||
*/
|
||||
int assign_parent(Native_capability parent)
|
||||
{
|
||||
assert(parent.valid());
|
||||
_parent = parent;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */
|
||||
|
184
base-hw/src/core/include/platform_thread.h
Normal file
184
base-hw/src/core/include/platform_thread.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* \brief Userland interface for the management of kernel thread-objects
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__PLATFORM_THREAD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <base/native_types.h>
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Pager_object;
|
||||
class Thread_state;
|
||||
class Thread_base;
|
||||
class Rm_client;
|
||||
class Platform_thread;
|
||||
|
||||
size_t kernel_thread_size();
|
||||
|
||||
/**
|
||||
* Userland interface for the management of kernel thread-objects
|
||||
*/
|
||||
class Platform_thread
|
||||
{
|
||||
enum { NAME_MAX_LEN = 32 };
|
||||
|
||||
Thread_base * _thread_base;
|
||||
unsigned long _stack_size;
|
||||
unsigned long _pd_id;
|
||||
unsigned long _id;
|
||||
Rm_client * _rm_client;
|
||||
bool _main_thread;
|
||||
Native_utcb * _phys_utcb;
|
||||
Native_utcb * _virt_utcb;
|
||||
Software_tlb * _software_tlb;
|
||||
Ram_dataspace_capability _utcb;
|
||||
char _name[NAME_MAX_LEN];
|
||||
|
||||
/**
|
||||
* Common construction part
|
||||
*/
|
||||
void _init();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for core threads
|
||||
*/
|
||||
Platform_thread(const char * name,
|
||||
Thread_base * const thread_base,
|
||||
unsigned long const stack_size,
|
||||
unsigned long const pd_id);
|
||||
|
||||
/**
|
||||
* Constructor for threads outside of core
|
||||
*/
|
||||
Platform_thread(const char * name, unsigned int priority,
|
||||
addr_t utcb);
|
||||
|
||||
/**
|
||||
* Join PD identified by 'pd_id'
|
||||
*
|
||||
* \param pd_id ID of targeted PD
|
||||
* \param main_thread wether we are the main thread in this PD
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval <0 otherwise
|
||||
*/
|
||||
int join_pd(unsigned long const pd_id,
|
||||
bool const main_thread);
|
||||
|
||||
/**
|
||||
* Run this thread
|
||||
*/
|
||||
int start(void * ip, void * sp, unsigned int cpu_no = 0);
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause() { Kernel::pause_thread(_id); }
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume() { Kernel::resume_thread(_id); }
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
*/
|
||||
void cancel_blocking()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request our raw thread state
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
*/
|
||||
int state(Genode::Thread_state * state_dst)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_thread()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return unique identification of this thread as faulter
|
||||
*/
|
||||
unsigned long pager_object_badge() { return _id; }
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread.
|
||||
*/
|
||||
void set_cpu(unsigned int cpu_no)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
inline char const * name() const { return _name; }
|
||||
|
||||
void pager(Pager_object * const pager);
|
||||
|
||||
Pager_object * pager() const;
|
||||
|
||||
unsigned long pd_id() const { return _pd_id; }
|
||||
|
||||
Native_thread_id id() const { return _id; }
|
||||
|
||||
unsigned long stack_size() const { return _stack_size; }
|
||||
|
||||
Thread_base * thread_base()
|
||||
{
|
||||
if (!_thread_base) assert(_main_thread);
|
||||
return _thread_base;
|
||||
}
|
||||
|
||||
Native_utcb * phys_utcb() const { return _phys_utcb; }
|
||||
|
||||
Native_utcb * virt_utcb() const { return _virt_utcb; }
|
||||
|
||||
Ram_dataspace_capability utcb() const { return _utcb; }
|
||||
|
||||
Software_tlb * software_tlb() const { return _software_tlb; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
|
||||
|
93
base-hw/src/core/include/signal_root.h
Normal file
93
base-hw/src/core/include/signal_root.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* \brief Signal root interface on HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__SIGNAL_ROOT_H_
|
||||
#define _CORE__INCLUDE__SIGNAL_ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <root/component.h>
|
||||
|
||||
/* core includes */
|
||||
#include <signal_session_component.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provide EP to signal root before it initialises root component
|
||||
*/
|
||||
class Signal_handler
|
||||
{
|
||||
enum { STACK_SIZE = 4096 };
|
||||
|
||||
Rpc_entrypoint _entrypoint;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Signal_handler(Cap_session * const c)
|
||||
: _entrypoint(c, STACK_SIZE, "signal") { }
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Rpc_entrypoint * entrypoint() { return &_entrypoint; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides signal service by managing appropriate sessions to the clients
|
||||
*/
|
||||
class Signal_root : private Signal_handler,
|
||||
public Root_component<Signal_session_component>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param md Meta-data allocator to be used by root component
|
||||
* \param c CAP session to be used by the root entrypoint
|
||||
*/
|
||||
Signal_root(Allocator * const md, Cap_session * const c) :
|
||||
Signal_handler(c),
|
||||
Root_component<Signal_session_component>(entrypoint(), md)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
/********************************
|
||||
** 'Root_component' interface **
|
||||
********************************/
|
||||
|
||||
Signal_session_component * _create_session(const char * args)
|
||||
{
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota").long_value(0);
|
||||
return new (md_alloc())
|
||||
Signal_session_component(md_alloc(), ram_quota);
|
||||
}
|
||||
|
||||
void _upgrade_session(Signal_session_component *s,
|
||||
const char * args)
|
||||
{
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota").long_value(0);
|
||||
s->upgrade_ram_quota(ram_quota);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__SIGNAL_ROOT_H_ */
|
||||
|
68
base-hw/src/core/include/signal_session_component.h
Normal file
68
base-hw/src/core/include/signal_session_component.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* \brief Signal service on the HW-core
|
||||
* \author Martin stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__SIGNAL_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <signal_session/signal_session.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/slab.h>
|
||||
#include <base/allocator_guard.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provides the signal service
|
||||
*/
|
||||
class Signal_session_component : public Rpc_object<Signal_session>
|
||||
{
|
||||
Allocator_guard _md_alloc; /* Metadata allocator */
|
||||
Slab _receivers_slab; /* SLAB to allocate receiver kernel-objects */
|
||||
Slab _contexts_slab; /* SLAB to allocate context kernel-objects */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param md Metadata allocator
|
||||
* \param ram_quota Amount of RAM quota donated to this session
|
||||
*/
|
||||
Signal_session_component(Allocator * const md,
|
||||
size_t const ram_quota);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Signal_session_component();
|
||||
|
||||
/**
|
||||
* Raise the quota of this session by 'q'
|
||||
*/
|
||||
void upgrade_ram_quota(size_t const q) { _md_alloc.upgrade(q); }
|
||||
|
||||
/******************************
|
||||
** Signal_session interface **
|
||||
******************************/
|
||||
|
||||
Signal_receiver_capability alloc_receiver();
|
||||
|
||||
Signal_context_capability
|
||||
alloc_context(Signal_receiver_capability const r,
|
||||
unsigned long const imprint);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */
|
||||
|
109
base-hw/src/core/include/util.h
Normal file
109
base-hw/src/core/include/util.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* \brief Core-internal utilities
|
||||
* \author Martin Stein
|
||||
* \date 2012-01-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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__UTIL_H_
|
||||
#define _CORE__INCLUDE__UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
enum { MIN_PAGE_SIZE_LOG2 = 12 };
|
||||
|
||||
|
||||
/**
|
||||
* Get the the minimal supported page-size log 2
|
||||
*/
|
||||
inline size_t get_page_size_log2() { return MIN_PAGE_SIZE_LOG2; }
|
||||
|
||||
|
||||
/**
|
||||
* Get the the minimal supported page-size
|
||||
*/
|
||||
inline size_t get_page_size() { return 1 << get_page_size_log2(); }
|
||||
|
||||
|
||||
/**
|
||||
* Get the base mask for the minimal supported page-size
|
||||
*/
|
||||
inline addr_t get_page_mask() { return ~(get_page_size() - 1); }
|
||||
|
||||
|
||||
/**
|
||||
* Round down to the minimal page-size alignment
|
||||
*/
|
||||
inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); }
|
||||
|
||||
|
||||
/**
|
||||
* Round up to the minimal page-size alignment
|
||||
*/
|
||||
inline addr_t round_page(addr_t addr)
|
||||
{ return trunc_page(addr + get_page_size() - 1); }
|
||||
|
||||
|
||||
/**
|
||||
* Round down to a specific alignment
|
||||
*/
|
||||
inline addr_t trunc(addr_t const addr, unsigned const alignm_log2)
|
||||
{ return addr & ~((1 << alignm_log2) - 1); }
|
||||
|
||||
|
||||
/**
|
||||
* Round up to a specific alignment
|
||||
*/
|
||||
inline addr_t round(addr_t const addr, unsigned const alignm_log2)
|
||||
{ return trunc(addr + (1<<alignm_log2) - 1, alignm_log2); }
|
||||
|
||||
|
||||
/**
|
||||
* Select source used for map operations
|
||||
*/
|
||||
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
|
||||
|
||||
|
||||
/**
|
||||
* Return highest supported flexpage size for the given mapping size
|
||||
*
|
||||
* This function is called by the page-fault handler to determine the
|
||||
* mapping granularity to be used for a page-fault answer. If a kernel
|
||||
* supports flexible page sizes, this function can just return the
|
||||
* argument. If a kernel only supports a certain set of map sizes such
|
||||
* as 4K and 4M, this function should select one of those smaller or
|
||||
* equal to the argument.
|
||||
*/
|
||||
inline size_t constrain_map_size_log2(size_t size_log2)
|
||||
{
|
||||
if (size_log2<20) return 12;
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Debug output on page faults
|
||||
*/
|
||||
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
|
||||
Rm_session::Fault_type pf_type,
|
||||
unsigned long faulter_badge)
|
||||
{
|
||||
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)", msg,
|
||||
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ",
|
||||
(void *)pf_addr, (void *)pf_ip,
|
||||
faulter_badge);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__UTIL_H_ */
|
||||
|
29
base-hw/src/core/io_mem_session_support.cc
Normal file
29
base-hw/src/core/io_mem_session_support.cc
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* \brief Implementation of the IO_MEM session interface
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <io_mem_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Io_mem_session_component::_unmap_local(addr_t base, size_t size) { }
|
||||
|
||||
|
||||
addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
|
||||
{ return base; }
|
||||
|
85
base-hw/src/core/io_port_session_component.cc
Normal file
85
base-hw/src/core/io_port_session_component.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief Implementation of the IO_PORT session interface
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <io_port_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
unsigned char Io_port_session_component::inb(unsigned short address)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned short Io_port_session_component::inw(unsigned short address)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned Io_port_session_component::inl(unsigned short address)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Io_port_session_component::outb(unsigned short address,
|
||||
unsigned char value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Io_port_session_component::outw(unsigned short address,
|
||||
unsigned short value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Io_port_session_component::outl(unsigned short address, unsigned value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
Io_port_session_component::
|
||||
Io_port_session_component(Range_allocator * io_port_alloc,
|
||||
const char * args)
|
||||
: _io_port_alloc(io_port_alloc)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
Io_port_session_component::~Io_port_session_component()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
69
base-hw/src/core/irq_session_component.cc
Normal file
69
base-hw/src/core/irq_session_component.cc
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* \brief Implementation of IRQ session component
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
/* core includes */
|
||||
#include <irq_root.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
bool
|
||||
Irq_session_component::Irq_control_component::associate_to_irq(unsigned irq)
|
||||
{ return Kernel::allocate_irq(irq); }
|
||||
|
||||
|
||||
void Irq_session_component::wait_for_irq() { Kernel::await_irq(); }
|
||||
|
||||
|
||||
Irq_session_component::~Irq_session_component()
|
||||
{
|
||||
/* free IRQ for other threads */
|
||||
if (Kernel::free_irq(_irq_number))
|
||||
PERR("Could not free IRQ %u", _irq_number);
|
||||
}
|
||||
|
||||
|
||||
Irq_session_component::Irq_session_component(Cap_session * cap_session,
|
||||
Range_allocator * irq_alloc,
|
||||
const char * args)
|
||||
:
|
||||
_irq_alloc(irq_alloc), _ep(cap_session, STACK_SIZE, "irqctrl"),
|
||||
_control_cap(_ep.manage(&_control_component)),
|
||||
_control_client(_control_cap)
|
||||
{
|
||||
/* check arguments */
|
||||
bool shared = Arg_string::find_arg(args, "irq_shared").bool_value(false);
|
||||
if (shared) {
|
||||
PERR("IRQ sharing not supported");
|
||||
throw Root::Invalid_args();
|
||||
}
|
||||
/* allocate IRQ */
|
||||
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
|
||||
if (irq_number == -1 || !irq_alloc ||
|
||||
irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) {
|
||||
PERR("Unavailable IRQ %lu requested", irq_number);
|
||||
throw Root::Invalid_args();
|
||||
}
|
||||
_irq_number = irq_number;
|
||||
|
||||
/* configure control client */
|
||||
if (!_control_client.associate_to_irq(irq_number)) {
|
||||
PERR("IRQ association failed");
|
||||
throw Root::Invalid_args();
|
||||
}
|
||||
/* create IRQ capability */
|
||||
_irq_cap = Irq_session_capability(_ep.manage(this));
|
||||
}
|
2088
base-hw/src/core/kernel.cc
Normal file
2088
base-hw/src/core/kernel.cc
Normal file
File diff suppressed because it is too large
Load Diff
21
base-hw/src/core/panda_a2/kernel_support.h
Normal file
21
base-hw/src/core/panda_a2/kernel_support.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Kernel support specific for the PandaBoard A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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 _SRC__CORE__PANDA_A2__KERNEL_SUPPORT_H_
|
||||
#define _SRC__CORE__PANDA_A2__KERNEL_SUPPORT_H_
|
||||
|
||||
/* local includes */
|
||||
#include <cortex_a9/kernel_support.h>
|
||||
|
||||
#endif /* _SRC__CORE__PANDA_A2__KERNEL_SUPPORT_H_ */
|
||||
|
84
base-hw/src/core/panda_a2/platform_support.cc
Normal file
84
base-hw/src/core/panda_a2/platform_support.cc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and Panda A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/panda_a2.h>
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Panda_a2::EMIF1_EMIF2_CS0_SDRAM_BASE,
|
||||
Panda_a2::EMIF1_EMIF2_CS0_SDRAM_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 0, Pl390_base::MAX_INTERRUPT_ID + 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer */
|
||||
{ Cortex_a9::PRIVATE_TIMER_IRQ, 1 },
|
||||
|
||||
/* core UART */
|
||||
{ Panda_a2::TL16C750_3_IRQ, 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Panda_a2::L4_PER_BASE, Panda_a2::L4_PER_SIZE },
|
||||
{ Panda_a2::L4_CFG_BASE, Panda_a2::L4_CFG_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer and PIC */
|
||||
{ Panda_a2::CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
Panda_a2::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* core UART */
|
||||
{ Panda_a2::TL16C750_3_MMIO_BASE, Panda_a2::TL16C750_3_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
26
base-hw/src/core/panda_a2/software_tlb.h
Normal file
26
base-hw/src/core/panda_a2/software_tlb.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Software TLB controls specific for the PandaBoard A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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 _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_
|
||||
#define _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/section_table.h>
|
||||
|
||||
/**
|
||||
* Software TLB controls
|
||||
*/
|
||||
class Software_tlb : public Genode::Section_table { };
|
||||
|
||||
#endif /* _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_ */
|
||||
|
21
base-hw/src/core/pbxa9/kernel_support.h
Normal file
21
base-hw/src/core/pbxa9/kernel_support.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Kernel support specific for the Realview PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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 _SRC__CORE__PBXA9__KERNEL_SUPPORT_H_
|
||||
#define _SRC__CORE__PBXA9__KERNEL_SUPPORT_H_
|
||||
|
||||
/* local includes */
|
||||
#include <cortex_a9/kernel_support.h>
|
||||
|
||||
#endif /* _SRC__CORE__PBXA9__KERNEL_SUPPORT_H_ */
|
||||
|
82
base-hw/src/core/pbxa9/platform_support.cc
Normal file
82
base-hw/src/core/pbxa9/platform_support.cc
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* \brief Parts of platform that are specific to PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/pbxa9.h>
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Pbxa9::NORTHBRIDGE_DDR_0_BASE, Pbxa9::NORTHBRIDGE_DDR_0_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 0, Pl390_base::MAX_INTERRUPT_ID + 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer */
|
||||
{ Cortex_a9::PRIVATE_TIMER_IRQ, 1 },
|
||||
|
||||
/* core UART */
|
||||
{ Pbxa9::PL011_0_IRQ, 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Pbxa9::SOUTHBRIDGE_APB_BASE, Pbxa9::SOUTHBRIDGE_APB_SIZE },
|
||||
{ Pbxa9::NORTHBRIDGE_AHB_BASE, Pbxa9::NORTHBRIDGE_AHB_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer and PIC */
|
||||
{ Pbxa9::CORTEX_A9_PRIVATE_MEM_BASE, Pbxa9::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* core UART */
|
||||
{ Pbxa9::PL011_0_MMIO_BASE, Pbxa9::PL011_0_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
26
base-hw/src/core/pbxa9/software_tlb.h
Normal file
26
base-hw/src/core/pbxa9/software_tlb.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Software TLB controls specific for the Realview PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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 _SRC__CORE__PBXA9__SOFTWARE_TLB_H_
|
||||
#define _SRC__CORE__PBXA9__SOFTWARE_TLB_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/section_table.h>
|
||||
|
||||
/**
|
||||
* Software TLB controls
|
||||
*/
|
||||
class Software_tlb : public Genode::Section_table { };
|
||||
|
||||
#endif /* _SRC__CORE__PBXA9__SOFTWARE_TLB_H_ */
|
||||
|
162
base-hw/src/core/platform.cc
Normal file
162
base-hw/src/core/platform.cc
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* \brief Platform implementation specific for hw
|
||||
* \author Martin Stein
|
||||
* \date 2011-12-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_parent.h>
|
||||
#include <platform.h>
|
||||
#include <util.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern int _prog_img_beg;
|
||||
extern int _prog_img_end;
|
||||
|
||||
/**
|
||||
* Format of a boot-module header
|
||||
*/
|
||||
struct Bm_header
|
||||
{
|
||||
long name; /* physical address of null-terminated string */
|
||||
long base; /* physical address of module data */
|
||||
long size; /* size of module data in bytes */
|
||||
};
|
||||
|
||||
extern int _boot_modules_begin;
|
||||
extern Bm_header _boot_module_headers_begin;
|
||||
extern Bm_header _boot_module_headers_end;
|
||||
extern int _boot_modules_end;
|
||||
|
||||
/**
|
||||
* Functionpointer that provides accessor to a pool of address regions
|
||||
*/
|
||||
typedef Native_region * (*Region_pool)(unsigned const);
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
addr_t mode_transition_virt_base();
|
||||
size_t mode_transition_size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 **
|
||||
**************/
|
||||
|
||||
Native_region * Platform::_core_only_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _r[] =
|
||||
{
|
||||
/* avoid null pointers */
|
||||
{ 0, 1 },
|
||||
|
||||
/* mode transition region */
|
||||
{ Kernel::mode_transition_virt_base(), Kernel::mode_transition_size() },
|
||||
|
||||
/* core image */
|
||||
{ (addr_t)&_prog_img_beg,
|
||||
(size_t)((addr_t)&_prog_img_end - (addr_t)&_prog_img_beg) },
|
||||
|
||||
/* boot modules */
|
||||
{ (addr_t)&_boot_modules_begin,
|
||||
(size_t)((addr_t)&_boot_modules_end - (addr_t)&_boot_modules_begin) }
|
||||
};
|
||||
return i < sizeof(_r)/sizeof(_r[0]) ? &_r[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Platform::Platform() :
|
||||
_core_mem_alloc(0),
|
||||
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
||||
_irq_alloc(core_mem_alloc()), _vm_base(0), _vm_size(0xffff0000)
|
||||
{
|
||||
/*
|
||||
* Initialise platform resource allocators.
|
||||
* Core mem alloc must come first because it is
|
||||
* used by the other allocators.
|
||||
*/
|
||||
enum { VERBOSE = 0 };
|
||||
unsigned const psl2 = get_page_size_log2();
|
||||
init_alloc(&_core_mem_alloc, _ram_regions, _core_only_ram_regions, psl2);
|
||||
init_alloc(&_irq_alloc, _irq_regions, _core_only_irq_regions);
|
||||
init_alloc(&_io_mem_alloc, _mmio_regions, _core_only_mmio_regions, psl2);
|
||||
|
||||
/* add boot modules to ROM FS */
|
||||
Bm_header * header = &_boot_module_headers_begin;
|
||||
for (; header < &_boot_module_headers_end; header++) {
|
||||
Rom_module * rom_module = new (core_mem_alloc())
|
||||
Rom_module(header->base, header->size, (const char*)header->name);
|
||||
_rom_fs.insert(rom_module);
|
||||
}
|
||||
/* print ressource summary */
|
||||
if (VERBOSE) {
|
||||
printf("Core memory allocator\n");
|
||||
printf("---------------------\n");
|
||||
_core_mem_alloc.raw()->dump_addr_tree();
|
||||
printf("\n");
|
||||
printf("IO memory allocator\n");
|
||||
printf("-------------------\n");
|
||||
_io_mem_alloc.raw()->dump_addr_tree();
|
||||
printf("\n");
|
||||
printf("ROM filesystem\n");
|
||||
printf("--------------\n");
|
||||
_rom_fs.print_fs();
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Core_parent **
|
||||
*****************/
|
||||
|
||||
void Core_parent::exit(int exit_value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
28
base-hw/src/core/platform_pd.cc
Normal file
28
base-hw/src/core/platform_pd.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Protection-domain facility
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform_pd.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/*****************
|
||||
** Platform PD **
|
||||
*****************/
|
||||
|
||||
void Platform_pd::unbind_thread(Platform_thread *thread) { assert(0); }
|
||||
|
||||
|
||||
Platform_pd::~Platform_pd() { assert(0); }
|
||||
|
145
base-hw/src/core/platform_thread.cc
Normal file
145
base-hw/src/core/platform_thread.cc
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
#include <core_env.h>
|
||||
#include <rm_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(const char * name,
|
||||
Thread_base * const thread_base,
|
||||
unsigned long const stack_size,
|
||||
unsigned long const pd_id)
|
||||
:
|
||||
_thread_base(thread_base), _stack_size(stack_size),
|
||||
_pd_id(pd_id), _rm_client(0), _virt_utcb(0)
|
||||
{
|
||||
strncpy(_name, name, NAME_MAX_LEN);
|
||||
|
||||
/* create UTCB for a core thread */
|
||||
Range_allocator * const ram = platform()->ram_alloc();
|
||||
assert(ram->alloc_aligned(sizeof(Native_utcb), (void **)&_phys_utcb,
|
||||
MIN_MAPPING_SIZE_LOG2));
|
||||
_virt_utcb = _phys_utcb;
|
||||
|
||||
/* common constructor parts */
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(const char * name, unsigned int priority,
|
||||
addr_t utcb)
|
||||
:
|
||||
_thread_base(0), _stack_size(0), _pd_id(0), _rm_client(0),
|
||||
_virt_utcb((Native_utcb *)utcb)
|
||||
{
|
||||
strncpy(_name, name, NAME_MAX_LEN);
|
||||
|
||||
/*
|
||||
* Allocate UTCB backing store for a thread outside of core. Page alignment
|
||||
* is done by RAM session by default. It's save to use core env because
|
||||
* this cannot be its server activation thread.
|
||||
*/
|
||||
try {
|
||||
Ram_session_component * const ram =
|
||||
dynamic_cast<Ram_session_component *>(core_env()->ram_session());
|
||||
assert(ram);
|
||||
_utcb = ram->alloc(sizeof(Native_utcb), 1);
|
||||
_phys_utcb = (Native_utcb *)ram->phys_addr(_utcb);
|
||||
}
|
||||
catch (...) { assert(0); }
|
||||
|
||||
/* common constructor parts */
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::join_pd(unsigned long const pd_id,
|
||||
bool const main_thread)
|
||||
{
|
||||
/* check if we're already in another PD */
|
||||
if (_pd_id && _pd_id != pd_id) return -1;
|
||||
|
||||
/* denote configuration for start method */
|
||||
_pd_id = pd_id;
|
||||
_main_thread = main_thread;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::_init()
|
||||
{
|
||||
/* create kernel object */
|
||||
void * kernel_thread;
|
||||
Range_allocator * ram = platform()->ram_alloc();
|
||||
assert(ram->alloc(Kernel::thread_size(), &kernel_thread));
|
||||
_id = Kernel::new_thread(kernel_thread, this);
|
||||
assert(_id);
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::start(void * ip, void * sp, unsigned int cpu_no)
|
||||
{
|
||||
/* check thread attributes */
|
||||
assert(_pd_id);
|
||||
|
||||
/*
|
||||
* If this is a main thread outside of core it'll not manage its
|
||||
* virtual context area by itself, as it is done for other threads
|
||||
* through a sub RM-session. Therefore we attach the UTCB to its
|
||||
* address space before it gets started.
|
||||
*/
|
||||
if (_pd_id != Kernel::core_id() && _main_thread)
|
||||
{
|
||||
/*
|
||||
* Declare page aligned virtual UTCB outside the context area.
|
||||
* Kernel afterwards offers this as bootstrap argument to the thread.
|
||||
*/
|
||||
_virt_utcb = (Native_utcb *)((platform()->vm_start()
|
||||
+ platform()->vm_size() - sizeof(Native_utcb))
|
||||
& ~((1<<MIN_MAPPING_SIZE_LOG2)-1));
|
||||
|
||||
/* attach UTCB */
|
||||
assert(_rm_client);
|
||||
Rm_session_component * const rm = _rm_client->member_rm_session();
|
||||
try { rm->attach(_utcb, 0, 0, true, _virt_utcb, 0); }
|
||||
catch (...) { assert(0); }
|
||||
}
|
||||
/* let thread participate in CPU scheduling */
|
||||
_software_tlb = Kernel::start_thread(this, ip, sp, cpu_no);
|
||||
return _software_tlb ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::pager(Pager_object * const pager)
|
||||
{
|
||||
/* announce pager thread to kernel */
|
||||
Kernel::set_pager(pager->cap().dst(), _id);
|
||||
|
||||
/* get RM client from pager pointer */
|
||||
_rm_client = dynamic_cast<Rm_client *>(pager);
|
||||
assert(_rm_client);
|
||||
}
|
||||
|
||||
|
||||
Genode::Pager_object * Platform_thread::pager() const
|
||||
{
|
||||
assert(_rm_client)
|
||||
return static_cast<Pager_object *>(_rm_client);
|
||||
}
|
||||
|
31
base-hw/src/core/ram_session_support.cc
Normal file
31
base-hw/src/core/ram_session_support.cc
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* \brief Export RAM dataspace as shared memory object (dummy)
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <ram_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { }
|
||||
|
||||
|
||||
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { }
|
||||
|
||||
|
||||
void Ram_session_component::_clear_ds (Dataspace_component * ds)
|
||||
{ memset((void *)ds->phys_addr(), 0, ds->size()); }
|
||||
|
85
base-hw/src/core/rm_session_support.cc
Normal file
85
base-hw/src/core/rm_session_support.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief RM- and pager implementations specific for base-hw and core
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/ipc_pager.h>
|
||||
|
||||
/* core includes */
|
||||
#include <rm_session_component.h>
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
#include <assert.h>
|
||||
#include <software_tlb.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/***************
|
||||
** Rm_client **
|
||||
***************/
|
||||
|
||||
|
||||
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
|
||||
{
|
||||
/* get software TLB of the thread that we serve */
|
||||
Platform_thread * const pt = Kernel::get_thread(badge());
|
||||
assert(pt);
|
||||
Software_tlb * const tlb = pt->software_tlb();
|
||||
assert(tlb);
|
||||
|
||||
/* update all translation caches */
|
||||
tlb->remove_region(virt_base, size);
|
||||
Kernel::update_pd(pt->pd_id());
|
||||
|
||||
/* try to regain administrative memory that has been freed by unmap */
|
||||
size_t s;
|
||||
void * base;
|
||||
while (tlb->regain_memory(base, s)) platform()->ram_alloc()->free(base, s);
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Ipc_pager **
|
||||
***************/
|
||||
|
||||
void Ipc_pager::resolve_and_wait_for_fault()
|
||||
{
|
||||
/* valid mapping? */
|
||||
assert(_mapping.valid());
|
||||
|
||||
/* do we need extra space to resolve pagefault? */
|
||||
Software_tlb * const tlb = _pagefault.software_tlb;
|
||||
enum Mapping_attributes { X = 1, K = 0, G = 0 };
|
||||
unsigned sl2 = tlb->insert_translation(_mapping.virt_address,
|
||||
_mapping.phys_address, _mapping.size_log2,
|
||||
_mapping.writable, X, K, G);
|
||||
if (sl2)
|
||||
{
|
||||
/* try to get some natural aligned space */
|
||||
void * space;
|
||||
assert(platform()->ram_alloc()->alloc_aligned(1<<sl2, &space, sl2));
|
||||
|
||||
/* try to translate again with extra space */
|
||||
sl2 = tlb->insert_translation(_mapping.virt_address,
|
||||
_mapping.phys_address,
|
||||
_mapping.size_log2,
|
||||
_mapping.writable, X, K, G, space);
|
||||
assert(!sl2);
|
||||
}
|
||||
/* try to wake up faulter */
|
||||
assert(!Kernel::resume_thread(_pagefault.thread_id));
|
||||
|
||||
/* wait for next page fault */
|
||||
wait_for_fault();
|
||||
}
|
||||
|
79
base-hw/src/core/signal_session_component.cc
Normal file
79
base-hw/src/core/signal_session_component.cc
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* \brief Implementation of the SIGNAL service on the HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
/* core includes */
|
||||
#include <signal_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum {
|
||||
RECEIVER_SLAB_CHUNK_SIZE = 32,
|
||||
CONTEXT_SLAB_CHUNK_SIZE = 32,
|
||||
};
|
||||
|
||||
|
||||
Signal_session_component::Signal_session_component(Allocator * const md,
|
||||
size_t const ram_quota) :
|
||||
_md_alloc(md, ram_quota),
|
||||
_receivers_slab(Kernel::signal_receiver_size(),
|
||||
RECEIVER_SLAB_CHUNK_SIZE * Kernel::signal_receiver_size(),
|
||||
0, &_md_alloc),
|
||||
|
||||
_contexts_slab(Kernel::signal_context_size(),
|
||||
CONTEXT_SLAB_CHUNK_SIZE * Kernel::signal_context_size(),
|
||||
0, &_md_alloc)
|
||||
{ }
|
||||
|
||||
|
||||
Signal_session_component::~Signal_session_component()
|
||||
{
|
||||
PERR("%s: Not implemented", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
Signal_receiver_capability Signal_session_component::alloc_receiver()
|
||||
{
|
||||
/* create receiver kernel-object */
|
||||
size_t const s = Kernel::signal_receiver_size();
|
||||
void * p;
|
||||
if (!_receivers_slab.alloc(s, &p)) throw Out_of_metadata();
|
||||
unsigned long const id = Kernel::new_signal_receiver(p);
|
||||
if (!id) throw Out_of_metadata();
|
||||
|
||||
/* return reference to the new kernel-object */
|
||||
Native_capability c(id, 0);
|
||||
return reinterpret_cap_cast<Signal_receiver>(c);
|
||||
}
|
||||
|
||||
|
||||
Signal_context_capability
|
||||
Signal_session_component::alloc_context(Signal_receiver_capability r,
|
||||
unsigned long imprint)
|
||||
{
|
||||
/* create context kernel-object */
|
||||
size_t const s = Kernel::signal_context_size();
|
||||
void * p;
|
||||
if (!_contexts_slab.alloc(s, &p)) throw Out_of_metadata();
|
||||
unsigned long const id = Kernel::new_signal_context(p, r.dst(), imprint);
|
||||
if (!id) throw Out_of_metadata();
|
||||
|
||||
/* return reference to the new kernel-object */
|
||||
Native_capability c(id, 0);
|
||||
return reinterpret_cap_cast<Signal_context>(c);
|
||||
}
|
||||
|
49
base-hw/src/core/target.mk
Normal file
49
base-hw/src/core/target.mk
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# \brief The core of Genode
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-16
|
||||
#
|
||||
|
||||
# set program name
|
||||
TARGET = core
|
||||
|
||||
# use core specific startup library
|
||||
STARTUP_LIB = startup_core
|
||||
|
||||
# add library dependencies
|
||||
LIBS += cxx raw_ipc heap process pager lock console signal raw_server \
|
||||
syscall startup_core core_support
|
||||
|
||||
# add include paths
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
INC_DIR += $(REP_DIR)/src/core/include $(REP_DIR)/include \
|
||||
$(REP_DIR)/src/platform $(GEN_CORE_DIR)/include \
|
||||
$(BASE_DIR)/src/platform $(BASE_DIR)/src/core/include \
|
||||
$(BASE_DIR)/include
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += main.cc _main.cc ram_session_component.cc \
|
||||
ram_session_support.cc rom_session_component.cc \
|
||||
pd_session_component.cc io_mem_session_component.cc \
|
||||
io_mem_session_support.cc thread.cc platform_pd.cc platform.cc \
|
||||
platform_thread.cc dataspace_component.cc rm_session_component.cc \
|
||||
io_port_session_component.cc \
|
||||
irq_session_component.cc signal_session_component.cc \
|
||||
dump_alloc.cc cpu_session_component.cc \
|
||||
cpu_session_support.cc console.cc
|
||||
|
||||
# declare file locations
|
||||
vpath _main.cc $(BASE_DIR)/src/platform
|
||||
vpath main.cc $(GEN_CORE_DIR)
|
||||
vpath ram_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath rom_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath cpu_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath pd_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath rm_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
|
||||
vpath dataspace_component.cc $(GEN_CORE_DIR)
|
||||
vpath dump_alloc.cc $(GEN_CORE_DIR)
|
||||
vpath console.cc $(REP_DIR)/src/base
|
||||
vpath % $(REP_DIR)/src/core
|
||||
|
92
base-hw/src/core/thread.cc
Normal file
92
base-hw/src/core/thread.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* \brief Implementation of Thread API interface for core
|
||||
* \author Martin Stein
|
||||
* \date 2012-01-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Genode::Native_utcb * _main_utcb;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
/* this is the main thread */
|
||||
if (!this) { return _main_utcb; }
|
||||
|
||||
/* this isn't the main thread */
|
||||
return _tid->phys_utcb();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns 0 if this is the main thread or the thread base pointer otherwise
|
||||
*/
|
||||
Thread_base * Thread_base::myself()
|
||||
{
|
||||
/* get our platform thread wich holds our thread base or 0 */
|
||||
Platform_thread * const pt = Kernel::get_thread();
|
||||
if (pt) return pt->thread_base();
|
||||
|
||||
/* we are core main, the only thread beside idle with no platform thread */
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
static void thread_entry()
|
||||
{
|
||||
/* this is never called by a main thread */
|
||||
Thread_base::myself()->entry();
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
: _list_element(this), _tid(0)
|
||||
{
|
||||
_tid = new (platform()->core_mem_alloc())
|
||||
Platform_thread(name, this, stack_size, Kernel::core_id());
|
||||
}
|
||||
|
||||
|
||||
Thread_base::~Thread_base()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
size_t const stack_size = _tid->stack_size()/sizeof(unsigned long) + 1;
|
||||
void * const stack_base = new (platform()->core_mem_alloc())
|
||||
unsigned long [stack_size];
|
||||
void * sp = (void *)((addr_t)stack_base + _tid->stack_size());
|
||||
void * ip = (void *)&thread_entry;
|
||||
if (_tid->start(ip, sp)) PERR("Couldn't start thread");
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
21
base-hw/src/core/vea9x4/kernel_support.h
Normal file
21
base-hw/src/core/vea9x4/kernel_support.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Kernel support specific for the Versatile VEA9X4
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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 _SRC__CORE__VEA9X4__KERNEL_SUPPORT_H_
|
||||
#define _SRC__CORE__VEA9X4__KERNEL_SUPPORT_H_
|
||||
|
||||
/* local includes */
|
||||
#include <cortex_a9/kernel_support.h>
|
||||
|
||||
#endif /* _SRC__CORE__VEA9X4__KERNEL_SUPPORT_H_ */
|
||||
|
83
base-hw/src/core/vea9x4/platform_support.cc
Normal file
83
base-hw/src/core/vea9x4/platform_support.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and VEA9X4
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/vea9x4.h>
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Vea9x4::LOCAL_DDR2_BASE, Vea9x4::LOCAL_DDR2_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 0, Pl390_base::MAX_INTERRUPT_ID + 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* Core timer */
|
||||
{ Cortex_a9::PRIVATE_TIMER_IRQ, 1 },
|
||||
|
||||
/* Core UART */
|
||||
{ Vea9x4::PL011_0_IRQ, 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Vea9x4::SMB_CS7_BASE, Vea9x4::SMB_CS7_SIZE },
|
||||
{ Vea9x4::SMB_CS0_TO_CS6_BASE, Vea9x4::SMB_CS0_TO_CS6_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* Core timer and PIC */
|
||||
{ Vea9x4::CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
Vea9x4::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* Core UART */
|
||||
{ Vea9x4::PL011_0_MMIO_BASE, Vea9x4::PL011_0_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
26
base-hw/src/core/vea9x4/software_tlb.h
Normal file
26
base-hw/src/core/vea9x4/software_tlb.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Software TLB controls specific for the Versatile VEA9X4
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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 _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_
|
||||
#define _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/section_table.h>
|
||||
|
||||
/**
|
||||
* Software TLB controls
|
||||
*/
|
||||
class Software_tlb : public Genode::Section_table { };
|
||||
|
||||
#endif /* _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_ */
|
||||
|
20
base-hw/src/platform/_main_helper.h
Normal file
20
base-hw/src/platform/_main_helper.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Martin Stein
|
||||
* \date 2010-09-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2012 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 _SRC__PLATFORM__MAIN_HELPER_H_
|
||||
#define _SRC__PLATFORM__MAIN_HELPER_H_
|
||||
|
||||
static void main_thread_bootstrap() { }
|
||||
|
||||
#endif /* _SRC__PLATFORM__MAIN_HELPER_H_ */
|
||||
|
61
base-hw/src/platform/crt0.s
Normal file
61
base-hw/src/platform/crt0.s
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* \brief Startup code for Genode programs on Cortex A9
|
||||
* \author Martin Stein
|
||||
* \date 2011-10-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
.section .text
|
||||
|
||||
/* ELF entry symbol */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* zero-fill BSS segment but don't pollute thread-entry arguments */
|
||||
.extern _bss_start
|
||||
ldr r4, =_bss_start
|
||||
.extern _bss_end
|
||||
ldr r3, =_bss_end
|
||||
mov r2, #0
|
||||
sub r3, r3, #4
|
||||
1:
|
||||
str r2, [r4]
|
||||
add r4, r4, #4
|
||||
cmp r4, r3
|
||||
bne 1b
|
||||
|
||||
/* fetch thread-entry arguments to their destinations in BSS */
|
||||
ldr r1, =_main_utcb
|
||||
str r0, [r1]
|
||||
|
||||
/* call _main routine */
|
||||
ldr sp, =_main_stack_high
|
||||
.extern _main
|
||||
bl _main
|
||||
1:
|
||||
b 1b
|
||||
|
||||
/* dynamic symbol object handle */
|
||||
.align 3
|
||||
.global __dso_handle
|
||||
__dso_handle: .long 0
|
||||
|
||||
.section .bss
|
||||
|
||||
/* main-thread stack */
|
||||
.align 3
|
||||
.space 64*1024
|
||||
.global _main_stack_high
|
||||
_main_stack_high:
|
||||
|
||||
/* main-thread UTCB-pointer for the Genode thread-API */
|
||||
.align 3
|
||||
.global _main_utcb
|
||||
_main_utcb: .long 0
|
||||
|
123
base-hw/src/platform/genode.ld
Normal file
123
base-hw/src/platform/genode.ld
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* \brief Linker script for Genode programs
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-04-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2012 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.
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
ro PT_LOAD;
|
||||
rw PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
_prog_img_beg = .;
|
||||
|
||||
*(.init)
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.fini)
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
. = ALIGN(0x08);
|
||||
|
||||
_ctors_start = .;
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
|
||||
_ctors_end = .;
|
||||
_dtors_start = .;
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
_dtors_end = .;
|
||||
} : ro = 0x90909090
|
||||
|
||||
/* Linux: exception section for uaccess mechanism */
|
||||
__ex_table : { *(__ex_table) }
|
||||
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
_prog_img_data = .;
|
||||
|
||||
.data : {
|
||||
/*
|
||||
* Leave space for parent capability parameters at start of data
|
||||
* section. The protection domain creator is reponsible for storing
|
||||
* sane values here.
|
||||
*/
|
||||
_parent_cap = .;
|
||||
_parent_cap_thread_id = .;
|
||||
LONG(0xffffffff);
|
||||
_parent_cap_local_name = .;
|
||||
LONG(0xffffffff);
|
||||
|
||||
/*
|
||||
* Platform-specific entry for Fiasco.OC.
|
||||
*
|
||||
* PIC-code compiled for Fiasco.OC, needs some PIC-compatible
|
||||
* way to enter the kernel, the fixed address of the kernel
|
||||
* entry code address needs to be found here.
|
||||
*/
|
||||
__l4sys_invoke_indirect = .;
|
||||
LONG(0xeacff000);
|
||||
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
} : rw
|
||||
|
||||
/* exception frames for C++ */
|
||||
.eh_frame : {
|
||||
__eh_frame_start__ = .;
|
||||
KEEP (*(.eh_frame))
|
||||
LONG(0)
|
||||
} : rw
|
||||
|
||||
.init_array : {
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
}
|
||||
|
||||
.gcc_except_table : {
|
||||
KEEP(*(.gcc_except_table))
|
||||
KEEP(*(.gcc_except_table.*))
|
||||
}
|
||||
|
||||
.dynamic : { *(.dynamic) }
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : {
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
}
|
||||
__exidx_end = .;
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab*)
|
||||
} : rw
|
||||
|
||||
.bss : {
|
||||
_bss_start = .;
|
||||
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
|
||||
}
|
||||
_bss_end = .;
|
||||
_prog_img_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.note)
|
||||
*(.note.ABI-tag)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user