Move repositories to 'repos/' subdirectory

This patch changes the top-level directory layout as a preparatory
step for improving the tools for managing 3rd-party source codes.
The rationale is described in the issue referenced below.

Issue #1082
This commit is contained in:
Norman Feske
2014-05-07 11:48:19 +02:00
parent 1f9890d635
commit ca971bbfd8
3943 changed files with 454 additions and 430 deletions

View File

@ -0,0 +1,78 @@
/*
* \brief Console backend for PL011 UART on Codezero
* \author Norman Feske
* \date 2009-10-03
*
* This code assumes a PL011 UART as provided by 'qemu -M versatilepb'. Prior
* executing this code, the kernel already initialized the UART to print some
* startup message. So we can skip the UART initialization here. The kernel
* maps the UART registers to the magic address PL011_BASE when starting mm0.
* So we can just start using the device without any precautions.
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/console.h>
/* codezero includes */
#include <codezero/syscalls.h>
typedef unsigned char uint8_t;
/**
* Base address of default-mapped UART device
*
* defined in 'l4/arch/arm/io.h'
*/
enum { PL011_BASE = USERSPACE_CONSOLE_VBASE };
/**
* UART registers
*/
enum { PL011_REG_UARTDR = PL011_BASE + 0x00 };
enum { PL011_REG_UARTFR = PL011_BASE + 0x18 };
/**
* Returns true if UART is ready to transmit a character
*/
static bool pl011_tx_ready()
{
enum { PL011_TX_FIFO_FULL = 1 << 5 };
return !(*((volatile unsigned *)PL011_REG_UARTFR) & PL011_TX_FIFO_FULL);
}
/**
* Output character to serial port
*/
static void pl011_out_char(uint8_t c)
{
/* wait until serial port is ready */
while (!pl011_tx_ready());
/* output character */
*((volatile unsigned int *)PL011_REG_UARTDR) = c;
}
namespace Genode
{
class Core_console : public Console
{
protected:
void _out_char(char c) {
if(c == '\n')
pl011_out_char('\r');
pl011_out_char(c);
}
};
}

View File

@ -0,0 +1,53 @@
/*
* \brief Support for exceptions libsupc++
* \author Norman Feske
* \author Sebastian Sumpf
* \date 2006-07-21
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
extern "C" char __eh_frame_start__[]; /* from linker script */
extern "C" void __register_frame (const void *begin); /* from libgcc_eh */
/*
* This symbol is set by Genode's dynamic linker (ldso) during binary setup.
* After setup, the symbol will point to the actual implementation of
* 'dl_iterate_phdr', which is located within the linker. 'dl_iterate_phdr'
* iterates through all (linker loaded) binaries and shared libraries. This
* function has to be implemented in order to support C++ exceptions within
* shared libraries.
* Return values of dl_iterate_phdr (gcc 4.2.4):
* < 0 = error
* 0 = continue program header iteration
* > 0 = stop iteration (no errors occured)
*
* See also: man dl_iterate_phdr
*/
int (*genode__dl_iterate_phdr) (int (*callback) (void *info, unsigned long size, void *data), void *data) = 0;
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size, void *data), void *data) __attribute__((weak));
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size, void *data), void *data)
{
if (!genode__dl_iterate_phdr)
return -1;
return genode__dl_iterate_phdr(callback, data);
}
extern "C" void raise()
{
PDBG("raise called - not implemented\n");
}
void init_exception_handling()
{
// __register_frame(__eh_frame_start__);
}

View File

@ -0,0 +1,24 @@
/*
* \brief Functions required for using the arm-none-linux-gnueabi tool chain
* \author Norman Feske
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/stdint.h>
using namespace Genode;
extern "C" int raise(int sig)
{
PWRN("raise - not yet implemented");
return 0;
}

View File

@ -0,0 +1,40 @@
/*
* \brief Helper functions UTCB access on Codezero
* \author Norman Feske
* \date 2012-03-01
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
/**
* Resolve 'Thread_base::myself' when not linking the thread library
*
* This weak symbol is primarily used by test cases. Most other Genode programs
* use the thread library. If the thread library is not used, 'myself' can only
* be called by the main thread, for which 'myself' is defined as zero.
*/
Genode::Thread_base * __attribute__((weak)) Genode::Thread_base::myself() { return 0; }
Genode::Native_utcb *Genode::Thread_base::utcb()
{
/*
* If 'utcb' is called on the object returned by 'myself',
* the 'this' pointer may be NULL (if the calling thread is
* the main thread). Therefore we handle this special case
* here.
*/
if (this == 0) return 0;
return &_context->utcb;
}

View File

@ -0,0 +1,175 @@
/*
* \brief Codezero implementation of the IPC API
* \author Norman Feske
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Codezero includes */
#include <codezero/syscalls.h>
/* Genode includes */
#include <base/ipc.h>
#include <base/printf.h>
#include <base/blocking.h>
#include <util/misc_math.h>
using namespace Genode;
using namespace Codezero;
enum { verbose_ipc = false };
/*****************
** Ipc_ostream **
*****************/
void Ipc_ostream::_send()
{
if (verbose_ipc)
PDBG("thread %d sends IPC to %d, write_offset=%d",
thread_myself(), _dst.dst(), _write_offset);
umword_t snd_size = min(_write_offset, (unsigned)L4_IPC_EXTENDED_MAX_SIZE);
*(umword_t *)_snd_msg->addr() = _dst.local_name();
int ret = l4_send_extended(_dst.dst(), L4_IPC_TAG_SYNC_EXTENDED,
snd_size, _snd_msg->addr());
if (ret < 0)
PERR("l4_send_extended (to thread %d) returned ret=%d",
_dst.dst(), ret);
_write_offset = sizeof(umword_t);
}
Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg)
:
Ipc_marshaller((char *)snd_msg->addr(), snd_msg->size()),
_snd_msg(snd_msg), _dst(dst)
{
_write_offset = sizeof(umword_t);
}
/*****************
** Ipc_istream **
*****************/
void Ipc_istream::_wait()
{
umword_t *rcv_buf = (umword_t *)_rcv_msg->addr();
umword_t rcv_size = min(_rcv_msg->size(), (unsigned)L4_IPC_EXTENDED_MAX_SIZE);
if (verbose_ipc)
PDBG("thread %d waits for IPC from %d, rcv_buf at %p, rcv_size=%d",
dst(), _rcv_cs, rcv_buf, (int)rcv_size);
int ret = l4_receive_extended(_rcv_cs, rcv_size, rcv_buf);
if (ret < 0)
PERR("l4_receive_extended (from any) returned ret=%d", ret);
if (verbose_ipc)
PDBG("thread %d received IPC from %d",
dst(), l4_get_sender());
_read_offset = sizeof(umword_t);
}
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
:
Ipc_unmarshaller((char *)rcv_msg->addr(), rcv_msg->size()),
Native_capability(thread_myself(), 0),
_rcv_msg(rcv_msg)
{
_rcv_cs = L4_ANYTHREAD;
_read_offset = sizeof(umword_t);
}
Ipc_istream::~Ipc_istream() { }
/****************
** Ipc_client **
****************/
void Ipc_client::_call()
{
#warning l4_sendrecv_extended is not yet implemented in l4lib/arch/syslib.h
_send();
_rcv_cs = Ipc_ostream::_dst.dst();
_wait();
_rcv_cs = L4_ANYTHREAD;
_write_offset = _read_offset = sizeof(umword_t);
}
Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg,
Msgbuf_base *rcv_msg, unsigned short)
: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0)
{ }
/****************
** Ipc_server **
****************/
void Ipc_server::_prepare_next_reply_wait()
{
/* now we have a request to reply */
_reply_needed = true;
/* leave space for return value at the beginning of the msgbuf */
_write_offset = 2*sizeof(umword_t);
/* receive buffer offset */
_read_offset = sizeof(umword_t);
}
void Ipc_server::_wait()
{
/* wait for new server request */
try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
/* define destination of next reply */
Ipc_ostream::_dst = Native_capability(l4_get_sender(), badge());
_prepare_next_reply_wait();
}
void Ipc_server::_reply()
{
try { _send(); } catch (Ipc_error) { }
_prepare_next_reply_wait();
}
void Ipc_server::_reply_wait()
{
if (_reply_needed)
_reply();
_wait();
}
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)
{ }

View File

@ -0,0 +1,175 @@
/*
* \brief Pager support for Codezero
* \author Norman Feske
* \date 2010-02-16
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/ipc_pager.h>
#include <base/printf.h>
/* Codezero includes */
#include <codezero/syscalls.h>
using namespace Genode;
using namespace Codezero;
enum { verbose_page_faults = false };
/************************
** Page-fault utility **
************************/
class Fault
{
public:
enum Type { READ, WRITE, EXEC, UNKNOWN };
private:
/**
* Translate Codezero page-fault information to generic fault type
*
* \param sr status
* \param pte page-table entry
*/
static Type _fault_type(umword_t sr, umword_t pte)
{
if (is_prefetch_abort(sr))
return EXEC;
if ((pte & PTE_PROT_MASK) == (__MAP_USR_RO & PTE_PROT_MASK))
return WRITE;
return READ;
}
Type _type;
umword_t _addr;
umword_t _ip;
public:
/**
* Constructor
*
* \param kdata Codezero-specific page-fault information
*/
Fault(struct fault_kdata const &kdata)
:
_type(_fault_type(kdata.fsr, kdata.pte)),
_addr(_type == EXEC ? kdata.faulty_pc : kdata.far),
_ip(kdata.faulty_pc)
{ }
Type type() const { return _type; }
umword_t addr() const { return _addr; }
umword_t ip() const { return _ip; }
};
/**
* Print page-fault information in a human-readable form
*/
inline void print_page_fault(Fault &fault, int from)
{
printf("page (%s%s%s) fault from %d at pf_addr=%lx, pf_ip=%lx\n",
fault.type() == Fault::READ ? "r" : "-",
fault.type() == Fault::WRITE ? "w" : "-",
fault.type() == Fault::EXEC ? "x" : "-",
from, fault.addr(), fault.ip());
}
/***************
** IPC pager **
***************/
void Ipc_pager::wait_for_fault()
{
for (;;) {
int ret = l4_receive(L4_ANYTHREAD);
if (ret < 0) {
PERR("pager: l4_received returned ret=%d", ret);
continue;
}
umword_t tag = l4_get_tag();
int faulter_tid = l4_get_sender();
if (tag != L4_IPC_TAG_PFAULT) {
PWRN("got an unexpected IPC from %d", faulter_tid);
continue;
}
/* copy fault information from message registers */
struct fault_kdata fault_kdata;
for (unsigned i = 0; i < sizeof(fault_kdata_t)/sizeof(umword_t); i++)
((umword_t *)&fault_kdata)[i] = read_mr(MR_UNUSED_START + i);
Fault fault(fault_kdata);
if (verbose_page_faults)
print_page_fault(fault, faulter_tid);
/* determine corresponding page in our own address space */
_pf_addr = fault.addr();
_pf_write = fault.type() == Fault::WRITE;
_pf_ip = fault.ip();
_last = faulter_tid;
return;
}
}
void Ipc_pager::reply_and_wait_for_fault()
{
/* install mapping */
umword_t flags = _reply_mapping.writeable() ? MAP_USR_RW
: MAP_USR_RO;
/*
* XXX: remove heuristics for mapping device registers.
*/
if (_reply_mapping.from_phys() == 0x10120000 /* LCD */
|| _reply_mapping.from_phys() == 0x10006000 /* keyboard */
|| _reply_mapping.from_phys() == 0x10007000) /* mouse */
flags = MAP_USR_IO;
int ret = l4_map((void *)_reply_mapping.from_phys(),
(void *)_reply_mapping.to_virt(),
_reply_mapping.num_pages(), flags, _last);
/* wake up faulter if mapping succeeded */
if (ret < 0)
PERR("l4_map returned %d, putting thread %d to sleep", ret, _last);
else
acknowledge_wakeup();
/* wait for next page fault */
wait_for_fault();
}
void Ipc_pager::acknowledge_wakeup()
{
enum { SUCCESS = 0 };
l4_set_sender(_last);
l4_ipc_return(SUCCESS);
}
Ipc_pager::Ipc_pager() : Native_capability(thread_myself(), 0) { }

View File

@ -0,0 +1,48 @@
/*
* \brief Codezero-specific implementation of cmpxchg
* \author Norman Feske
* \date 2009-10-12
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <cpu/atomic.h>
#include <base/printf.h>
#include <base/lock.h>
/* Codezero includes */
#include <codezero/syscalls.h>
static bool mutex_initialized;
static Codezero::l4_mutex mutex;
int Genode::cmpxchg(volatile int *dest, int cmp_val, int new_val)
{
if (!mutex_initialized) {
Codezero::l4_mutex_init(&mutex);
mutex_initialized = true;
}
int ret = Codezero::l4_mutex_lock(&mutex);
if (ret < 0)
mutex_initialized = false;
bool result = false;
if (*dest == cmp_val) {
*dest = new_val;
result = true;
}
ret = Codezero::l4_mutex_unlock(&mutex);
if (ret < 0)
mutex_initialized = false;
return result;
}

View File

@ -0,0 +1,61 @@
/*
* \brief Helper functions for the Lock implementation
* \author Norman Feske
* \date 2010-04-20
*
* For documentation about the interface, please revisit the 'base-pistachio'
* implementation.
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/native_types.h>
#include <base/thread.h>
/* Codezero includes */
#include <codezero/syscalls.h>
extern Genode::Native_thread_id main_thread_tid;
extern Codezero::l4_mutex main_thread_running_lock;
static inline void thread_yield()
{
Codezero::l4_thread_switch(-1);
}
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{
Codezero::l4_mutex *running_lock = thread_base ?
thread_base->utcb()->running_lock() :
&main_thread_running_lock;
Codezero::l4_mutex_unlock(running_lock);
return true;
}
static inline void thread_switch_to(Genode::Thread_base *thread_base)
{
Genode::Native_thread_id tid = thread_base ?
thread_base->tid().l4id :
main_thread_tid;
Codezero::l4_thread_switch(tid);
}
static inline void thread_stop_myself()
{
Genode::Thread_base *myself = Genode::Thread_base::myself();
Codezero::l4_mutex *running_lock = myself ?
myself->utcb()->running_lock() :
&main_thread_running_lock;
Codezero::l4_mutex_lock(running_lock);
}

View File

@ -0,0 +1,105 @@
/*
* \brief Dummy pager framework
* \author Norman Feske
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/pager.h>
using namespace Genode;
/**********************
** Pager activation **
**********************/
void Pager_activation_base::entry()
{
Ipc_pager pager;
_cap = pager;
_cap_valid.unlock();
bool reply = false;
while (1) {
if (reply)
pager.reply_and_wait_for_fault();
else
pager.wait_for_fault();
/* lookup referenced object */
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
Pager_object * obj = _obj;
reply = false;
/* handle request */
if (obj) {
reply = !obj->pager(pager);
/* something strange occurred - leave thread in pagefault */
continue;
}
/*
* We got a request from one of cores region-manager sessions
* to answer the pending page fault of a resolved region-manager
* client. Hence, we have to send the page-fault reply to the
* specified thread and answer the call of the region-manager
* session.
*
* When called from a region-manager session, we receive the
* core-local address of the targeted pager object via the
* first message word, which corresponds to the 'fault_ip'
* argument of normal page-fault messages.
*/
obj = reinterpret_cast<Pager_object *>(pager.fault_ip());
/* send reply to the calling region-manager session */
pager.acknowledge_wakeup();
/* answer page fault of resolved pager object */
pager.set_reply_dst(obj->cap());
pager.acknowledge_wakeup();
}
}
/**********************
** Pager entrypoint **
**********************/
Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
: _activation(a)
{ _activation->ep(this); }
void Pager_entrypoint::dissolve(Pager_object *obj)
{
remove_locked(obj);
}
Pager_capability Pager_entrypoint::manage(Pager_object *obj)
{
/* return invalid capability if no activation is present */
if (!_activation) return Pager_capability();
_activation->cap();
Untyped_capability cap = Native_capability(_activation->cap().dst(), obj->badge());
/* add server object to object pool */
obj->cap(cap);
insert(obj);
/* return capability that uses the object id as badge */
return reinterpret_cap_cast<Pager_object>(cap);
}

View File

@ -0,0 +1,96 @@
/*
* \brief Thread bootstrap code
* \author Christian Prochaska
* \author Martin Stein
* \date 2013-02-15
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
#include <base/env.h>
#include <util/string.h>
/* Codezero includes */
#include <codezero/syscalls.h>
Genode::Native_thread_id main_thread_tid;
Codezero::l4_mutex main_thread_running_lock;
/*****************************
** Startup library support **
*****************************/
void prepare_init_main_thread()
{
/* initialize codezero environment */
Codezero::__l4_init();
/* provide kernel identification of thread through temporary environment */
main_thread_tid = Codezero::thread_myself();
}
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
/****************************
** Codezero libl4 support **
****************************/
/*
* Unfortunately, the function 'exregs_print_registers' in 'exregs.c' refers to
* 'memset'. Because we do not want to link core against a C library, we have to
* resolve this function here.
*/
extern "C" void *memset(void *s, int c, Genode::size_t n) __attribute__((weak));
extern "C" void *memset(void *s, int c, Genode::size_t n)
{
return Genode::memset(s, c, n);
}
/*
* Same problem as for 'memset'. The 'printf' symbol is referenced from
* 'mutex.c' and 'exregs.c' of Codezero's libl4.
*/
extern "C" int printf(const char *format, ...) __attribute__((weak));
extern "C" int printf(const char *format, ...)
{
va_list list;
va_start(list, format);
Genode::vprintf(format, list);
va_end(list);
return 0;
}
/*****************
** Thread_base **
*****************/
void Genode::Thread_base::_thread_bootstrap()
{
Codezero::l4_mutex_init(utcb()->running_lock());
Codezero::l4_mutex_lock(utcb()->running_lock()); /* block on first mutex lock */
}
void Genode::Thread_base::_init_platform_thread(Type type)
{
if (type == NORMAL) { return; }
/* adjust values whose computation differs for a main thread */
_tid.l4id = main_thread_tid;
_thread_cap = Genode::env()->parent()->main_thread_cap();
/* get first mutex lock (normally done by _thread_bootstrap) */
Codezero::l4_mutex_init(utcb()->running_lock());
Codezero::l4_mutex_lock(utcb()->running_lock());
}

View File

@ -0,0 +1,76 @@
/*
* \brief NOVA-specific implementation of the Thread API
* \author Norman Feske
* \date 2010-01-19
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
#include <base/printf.h>
#include <base/sleep.h>
#include <base/env.h>
/* Codezero includes */
#include <codezero/syscalls.h>
using namespace Genode;
/**
* Entry point entered by new threads
*/
void Thread_base::_thread_start()
{
Thread_base::myself()->_thread_bootstrap();
Thread_base::myself()->entry();
Thread_base::myself()->_join_lock.unlock();
Genode::sleep_forever();
}
/*****************
** Thread base **
*****************/
void Thread_base::_deinit_platform_thread()
{
_cpu_session->kill_thread(_thread_cap);
env()->rm_session()->remove_client(_pager_cap);
}
void Thread_base::start()
{
/* if no cpu session is given, use it from the environment */
if (!_cpu_session)
_cpu_session = env()->cpu_session();
/* create thread at core */
char buf[48];
name(buf, sizeof(buf));
_thread_cap = _cpu_session->create_thread(buf);
/* assign thread to protection domain */
env()->pd_session()->bind_thread(_thread_cap);
/* create new pager object and assign it to the new thread */
_pager_cap = env()->rm_session()->add_client(_thread_cap);
_cpu_session->set_pager(_thread_cap, _pager_cap);
/* register initial IP and SP at core */
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
}
void Thread_base::cancel_blocking()
{
Codezero::l4_mutex_unlock(utcb()->running_lock());
_cpu_session->cancel_blocking(_thread_cap);
}