mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-15 21:58:24 +00:00
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:
78
repos/base-codezero/src/base/console/pl011/core_console.h
Normal file
78
repos/base-codezero/src/base/console/pl011/core_console.h
Normal 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
53
repos/base-codezero/src/base/cxx/exception.cc
Normal file
53
repos/base-codezero/src/base/cxx/exception.cc
Normal 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__);
|
||||
}
|
24
repos/base-codezero/src/base/cxx/memcmp.cc
Normal file
24
repos/base-codezero/src/base/cxx/memcmp.cc
Normal 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;
|
||||
}
|
40
repos/base-codezero/src/base/env/utcb.cc
vendored
Normal file
40
repos/base-codezero/src/base/env/utcb.cc
vendored
Normal 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;
|
||||
}
|
||||
|
175
repos/base-codezero/src/base/ipc/ipc.cc
Normal file
175
repos/base-codezero/src/base/ipc/ipc.cc
Normal 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)
|
||||
{ }
|
175
repos/base-codezero/src/base/ipc/pager.cc
Normal file
175
repos/base-codezero/src/base/ipc/pager.cc
Normal 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) { }
|
||||
|
48
repos/base-codezero/src/base/lock/cmpxchg.cc
Normal file
48
repos/base-codezero/src/base/lock/cmpxchg.cc
Normal 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;
|
||||
}
|
61
repos/base-codezero/src/base/lock/lock_helper.h
Normal file
61
repos/base-codezero/src/base/lock/lock_helper.h
Normal 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);
|
||||
}
|
105
repos/base-codezero/src/base/pager/pager.cc
Normal file
105
repos/base-codezero/src/base/pager/pager.cc
Normal 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);
|
||||
}
|
96
repos/base-codezero/src/base/thread/thread_bootstrap.cc
Normal file
96
repos/base-codezero/src/base/thread/thread_bootstrap.cc
Normal 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());
|
||||
}
|
76
repos/base-codezero/src/base/thread/thread_start.cc
Normal file
76
repos/base-codezero/src/base/thread/thread_start.cc
Normal 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);
|
||||
}
|
68
repos/base-codezero/src/core/core_rm_session.cc
Normal file
68
repos/base-codezero/src/core/core_rm_session.cc
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* \brief Core-local RM session
|
||||
* \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/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_rm_session.h>
|
||||
#include <platform.h>
|
||||
#include <map_local.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Rm_session::Local_addr
|
||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
if (size == 0)
|
||||
size = ds->size();
|
||||
|
||||
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
|
||||
size_t num_pages = page_rounded_size >> get_page_size_log2();
|
||||
|
||||
if (use_local_addr) {
|
||||
PERR("Parameter 'use_local_addr' not supported within core");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
PERR("Parameter 'offset' not supported within core");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate range in core's virtual address space */
|
||||
void *virt_addr;
|
||||
if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) {
|
||||
PERR("Could not allocate virtual address range in core of size %zd\n",
|
||||
page_rounded_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages)) {
|
||||
PERR("core-local memory mapping failed virt=%lx, phys=%lx\n",
|
||||
(addr_t)virt_addr, ds->phys_addr());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return virt_addr;
|
||||
}
|
28
repos/base-codezero/src/core/cpu_session_support.cc
Normal file
28
repos/base-codezero/src/core/cpu_session_support.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Platform-specific parts of cores CPU-service
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/printf.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread_cap)
|
||||
{
|
||||
PERR("%s: Not implemented", __PRETTY_FUNCTION__);
|
||||
return Ram_dataspace_capability();
|
||||
}
|
||||
|
55
repos/base-codezero/src/core/include/core_rm_session.h
Normal file
55
repos/base-codezero/src/core/include/core_rm_session.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* \brief Core-local region manager session
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_
|
||||
#define _CORE__INCLUDE__CORE_RM_SESSION_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <dataspace_component.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Core_rm_session : public Rm_session
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint *_ds_ep;
|
||||
|
||||
public:
|
||||
|
||||
Core_rm_session(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { }
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size = 0,
|
||||
off_t offset = 0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false);
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
Pager_capability add_client(Thread_capability) {
|
||||
return Pager_capability(); }
|
||||
|
||||
void remove_client(Pager_capability) { }
|
||||
|
||||
void fault_handler(Signal_context_capability) { }
|
||||
|
||||
State state() { return State(); }
|
||||
|
||||
Dataspace_capability dataspace() { return Dataspace_capability(); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */
|
71
repos/base-codezero/src/core/include/irq_session_component.h
Normal file
71
repos/base-codezero/src/core/include/irq_session_component.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* \brief IRQ session interface for NOVA
|
||||
* \author Norman Feske
|
||||
* \date 2010-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_
|
||||
|
||||
#include <base/lock.h>
|
||||
#include <util/list.h>
|
||||
|
||||
#include <irq_session/capability.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Irq_session_component : public Rpc_object<Irq_session>,
|
||||
public List<Irq_session_component>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
enum { STACK_SIZE = 4096 };
|
||||
|
||||
unsigned _irq_number;
|
||||
Range_allocator *_irq_alloc;
|
||||
Rpc_entrypoint _entrypoint;
|
||||
Irq_session_capability _cap;
|
||||
bool _attached;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param cap_session capability session to use
|
||||
* \param irq_alloc platform-dependent IRQ allocator
|
||||
* \param args session construction arguments
|
||||
*/
|
||||
Irq_session_component(Cap_session *cap_session,
|
||||
Range_allocator *irq_alloc,
|
||||
const char *args);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Irq_session_component();
|
||||
|
||||
/**
|
||||
* Return capability to this session
|
||||
*
|
||||
* If an initialization error occurs, returned capability is invalid.
|
||||
*/
|
||||
Irq_session_capability cap() const { return _cap; }
|
||||
|
||||
|
||||
/***************************
|
||||
** Irq session interface **
|
||||
***************************/
|
||||
|
||||
void wait_for_irq();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_ */
|
66
repos/base-codezero/src/core/include/map_local.h
Normal file
66
repos/base-codezero/src/core/include/map_local.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* \brief Core-local mapping
|
||||
* \author Norman Feske
|
||||
* \date 2010-02-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__MAP_LOCAL_H_
|
||||
#define _CORE__INCLUDE__MAP_LOCAL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <util.h>
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Map physical pages to core-local virtual address range
|
||||
*
|
||||
* On Codezero, mappings originate from the physical address space.
|
||||
*
|
||||
* \param from_phys physical source address
|
||||
* \param to_virt core-local destination address
|
||||
* \param num_pages number of pages to map
|
||||
*
|
||||
* \return true on success
|
||||
*/
|
||||
inline bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
int res = l4_map((void *)from_phys, (void *)to_virt,
|
||||
num_pages, MAP_USR_RW, thread_myself());
|
||||
if (res < 0) {
|
||||
PERR("l4_map phys 0x%lx -> 0x%lx returned %d", from_phys, to_virt, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool unmap_local(addr_t virt_addr, size_t num_pages)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
int res = l4_unmap((void *)virt_addr, num_pages, thread_myself());
|
||||
if (res < 0) {
|
||||
PERR("l4_unmap returned %d", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__MAP_LOCAL_H_ */
|
72
repos/base-codezero/src/core/include/platform.h
Normal file
72
repos/base-codezero/src/core/include/platform.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* \brief Platform interface
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* local includes */
|
||||
#include <platform_generic.h>
|
||||
#include <core_mem_alloc.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform : public Platform_generic
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Core_mem_allocator::Phys_allocator Phys_allocator;
|
||||
|
||||
Core_mem_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 */
|
||||
|
||||
/**
|
||||
* Virtual address range usable by non-core processes
|
||||
*/
|
||||
addr_t _vm_base;
|
||||
size_t _vm_size;
|
||||
|
||||
int _init_rom_fs();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
|
||||
/********************************
|
||||
** Generic platform interface **
|
||||
********************************/
|
||||
|
||||
Range_allocator *ram_alloc() { return _core_mem_alloc.phys_alloc(); }
|
||||
Range_allocator *io_mem_alloc() { return &_io_mem_alloc; }
|
||||
Range_allocator *io_port_alloc() { return &_io_port_alloc; }
|
||||
Range_allocator *irq_alloc() { return &_irq_alloc; }
|
||||
Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); }
|
||||
Range_allocator *core_mem_alloc() { return &_core_mem_alloc; }
|
||||
addr_t vm_start() const { return _vm_base; }
|
||||
size_t vm_size() const { return _vm_size; }
|
||||
Rom_fs *rom_fs() { return &_rom_fs; }
|
||||
|
||||
void wait_for_exit();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
81
repos/base-codezero/src/core/include/platform_pd.h
Normal file
81
repos/base-codezero/src/core/include/platform_pd.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* \brief Protection-domain facility
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
#include <address_space.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
class Platform_pd : public Address_space
|
||||
{
|
||||
private:
|
||||
|
||||
enum { MAX_THREADS_PER_PD = 32 };
|
||||
enum { UTCB_VIRT_BASE = 0x30000000 };
|
||||
enum { UTCB_AREA_SIZE = MAX_THREADS_PER_PD*sizeof(struct Codezero::utcb) };
|
||||
|
||||
unsigned _space_id;
|
||||
|
||||
bool utcb_in_use[MAX_THREADS_PER_PD];
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Platform_pd(bool core);
|
||||
Platform_pd(char const *, signed pd_id = -1, bool create = true);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_pd();
|
||||
|
||||
/**
|
||||
* Bind thread to protection domain
|
||||
*
|
||||
* \return 0 on success or
|
||||
* -1 if thread ID allocation failed.
|
||||
*/
|
||||
int bind_thread(Platform_thread *thread);
|
||||
|
||||
/**
|
||||
* Unbind thread from protection domain
|
||||
*
|
||||
* Free the thread's slot and update thread object.
|
||||
*/
|
||||
void unbind_thread(Platform_thread *thread);
|
||||
|
||||
/**
|
||||
* Assign parent interface to protection domain
|
||||
*/
|
||||
int assign_parent(Native_capability parent) { return 0; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Address-space interface **
|
||||
*****************************/
|
||||
|
||||
void flush(addr_t, size_t) { PDBG("not implemented"); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */
|
158
repos/base-codezero/src/core/include/platform_thread.h
Normal file
158
repos/base-codezero/src/core/include/platform_thread.h
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/pager.h>
|
||||
#include <base/thread_state.h>
|
||||
#include <base/native_types.h>
|
||||
|
||||
/* core includes */
|
||||
#include <address_space.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_pd;
|
||||
class Platform_thread
|
||||
{
|
||||
private:
|
||||
|
||||
friend class Platform_pd;
|
||||
|
||||
enum { PD_NAME_MAX_LEN = 64 };
|
||||
|
||||
unsigned _tid; /* global codezero thread ID */
|
||||
unsigned _space_id;
|
||||
Weak_ptr<Address_space> _address_space;
|
||||
addr_t _utcb;
|
||||
char _name[PD_NAME_MAX_LEN];
|
||||
Pager_object *_pager;
|
||||
|
||||
/**
|
||||
* Assign physical thread ID and UTCB address to thread
|
||||
*
|
||||
* This function is called from 'Platform_pd::bind_thread'.
|
||||
*/
|
||||
void _assign_physical_thread(unsigned tid, unsigned space_id,
|
||||
addr_t utcb,
|
||||
Weak_ptr<Address_space> address_space)
|
||||
{
|
||||
_tid = tid; _space_id = space_id; _utcb = utcb;
|
||||
_address_space = address_space;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
enum { THREAD_INVALID = -1 }; /* invalid thread number */
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_thread(const char *name = 0, unsigned priority = 0,
|
||||
addr_t utcb = 0, int thread_id = THREAD_INVALID);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_thread();
|
||||
|
||||
/**
|
||||
* Start thread
|
||||
*
|
||||
* \param ip instruction pointer to start at
|
||||
* \param sp stack pointer to use
|
||||
* \param cpu_no target cpu
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread could not be started
|
||||
*/
|
||||
int start(void *ip, void *sp, unsigned int cpu_no = 0);
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause();
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
*/
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
/**
|
||||
* Return the address space to which the thread is bound
|
||||
*/
|
||||
Weak_ptr<Address_space> address_space();
|
||||
|
||||
|
||||
/************************
|
||||
** Accessor functions **
|
||||
************************/
|
||||
|
||||
/**
|
||||
* Set pager capability
|
||||
*/
|
||||
Pager_object *pager(Pager_object *pager) const { return _pager; }
|
||||
void pager(Pager_object *pager) { _pager = pager; }
|
||||
Pager_object *pager() { return _pager; }
|
||||
|
||||
/**
|
||||
* Return identification of thread when faulting
|
||||
*/
|
||||
unsigned long pager_object_badge() const { return _tid; }
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
*/
|
||||
void affinity(Affinity::Location) { }
|
||||
|
||||
/**
|
||||
* Get the executing CPU for this thread
|
||||
*/
|
||||
Affinity::Location affinity() { return Affinity::Location(); }
|
||||
|
||||
/**
|
||||
* Get thread name
|
||||
*/
|
||||
const char *name() const { return "noname"; }
|
||||
|
||||
|
||||
/***********************
|
||||
** Codezero specific **
|
||||
***********************/
|
||||
|
||||
addr_t utcb() const { return _utcb; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
|
46
repos/base-codezero/src/core/include/util.h
Normal file
46
repos/base-codezero/src/core/include/util.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Core-internal utilities
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__UTIL_H_
|
||||
#define _CORE__INCLUDE__UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
constexpr size_t get_page_size_log2() { return 12; }
|
||||
constexpr size_t get_page_size() { return 1 << get_page_size_log2(); }
|
||||
constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); }
|
||||
inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); }
|
||||
inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); }
|
||||
|
||||
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
|
||||
inline size_t constrain_map_size_log2(size_t size_log2) { return get_page_size_log2(); }
|
||||
|
||||
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)\n", msg,
|
||||
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ",
|
||||
(void *)pf_addr, (void *)pf_ip,
|
||||
faulter_badge);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__UTIL_H_ */
|
27
repos/base-codezero/src/core/io_mem_session_support.cc
Normal file
27
repos/base-codezero/src/core/io_mem_session_support.cc
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* \brief Implementation of the IO_MEM session interface
|
||||
* \author Norman Feske
|
||||
* \date 2009-03-29
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* 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 0; }
|
72
repos/base-codezero/src/core/irq_session_component.cc
Normal file
72
repos/base-codezero/src/core/irq_session_component.cc
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* \brief Implementation of IRQ session component
|
||||
* \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/printf.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* core includes */
|
||||
#include <irq_root.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Irq_session_component::wait_for_irq()
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
/* attach thread to IRQ when first called */
|
||||
if (!_attached) {
|
||||
int ret = l4_irq_control(IRQ_CONTROL_REGISTER, 0, _irq_number);
|
||||
if (ret < 0) {
|
||||
PERR("l4_irq_control(IRQ_CONTROL_REGISTER) returned %d", ret);
|
||||
sleep_forever();
|
||||
}
|
||||
_attached = true;
|
||||
}
|
||||
|
||||
/* block for IRQ */
|
||||
int ret = l4_irq_control(IRQ_CONTROL_WAIT, 0, _irq_number);
|
||||
if (ret < 0)
|
||||
PWRN("l4_irq_control(IRQ_CONTROL_WAIT) returned %d", ret);
|
||||
}
|
||||
|
||||
|
||||
Irq_session_component::Irq_session_component(Cap_session *cap_session,
|
||||
Range_allocator *irq_alloc,
|
||||
const char *args)
|
||||
:
|
||||
_irq_alloc(irq_alloc),
|
||||
_entrypoint(cap_session, STACK_SIZE, "irq"),
|
||||
_attached(false)
|
||||
{
|
||||
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
|
||||
if (!irq_alloc || (irq_number == -1)||
|
||||
irq_alloc->alloc_addr(1, irq_number).is_error()) {
|
||||
PERR("unavailable IRQ %lx requested", irq_number);
|
||||
return;
|
||||
}
|
||||
_irq_number = irq_number;
|
||||
_cap = Irq_session_capability(_entrypoint.manage(this));
|
||||
}
|
||||
|
||||
|
||||
Irq_session_component::~Irq_session_component()
|
||||
{
|
||||
PERR("not yet implemented");
|
||||
}
|
||||
|
302
repos/base-codezero/src/core/platform.cc
Normal file
302
repos/base-codezero/src/core/platform.cc
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* \brief Platform interface implementation
|
||||
* \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/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_parent.h>
|
||||
#include <platform.h>
|
||||
#include <map_local.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum { verbose_boot_info = true };
|
||||
|
||||
/*
|
||||
* Memory-layout information provided by the linker script
|
||||
*/
|
||||
|
||||
/* virtual address range consumed by core's program image */
|
||||
extern unsigned _prog_img_beg, _prog_img_end;
|
||||
|
||||
/* physical address range occupied by core */
|
||||
extern addr_t _vma_start, _lma_start;
|
||||
|
||||
|
||||
/**************************
|
||||
** Boot-module handling **
|
||||
**************************/
|
||||
|
||||
/**
|
||||
* Scan ROM module image for boot modules
|
||||
*
|
||||
* By convention, the boot modules start at the page after core's BSS segment.
|
||||
*/
|
||||
int Platform::_init_rom_fs()
|
||||
{
|
||||
/**
|
||||
* Format of module meta-data as found in the ROM module image
|
||||
*/
|
||||
struct Module
|
||||
{
|
||||
long name; /* physical address of null-terminated string */
|
||||
long base; /* physical address of module data */
|
||||
long size; /* size of module data in bytes */
|
||||
};
|
||||
|
||||
/* find base address of ROM module image */
|
||||
addr_t phys_base = round_page((addr_t)&_prog_img_end);
|
||||
|
||||
/* map the first page of the image containing the module meta data */
|
||||
class Out_of_virtual_memory_during_rom_fs_init { };
|
||||
void *virt_base = 0;
|
||||
if (!_core_mem_alloc.virt_alloc()->alloc(get_page_size(), &virt_base))
|
||||
throw Out_of_virtual_memory_during_rom_fs_init();
|
||||
|
||||
if (!map_local(phys_base, (addr_t)virt_base, 1)) {
|
||||
PERR("map_local failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* remove page containing module infos from physical memory allocator */
|
||||
_core_mem_alloc.phys_alloc()->remove_range(phys_base, get_page_size());
|
||||
|
||||
/* validate the presence of a ROM image by checking the magic cookie */
|
||||
const char cookie[4] = {'G', 'R', 'O', 'M'};
|
||||
for (size_t i = 0; i < sizeof(cookie); i++)
|
||||
if (cookie[i] != ((char *)virt_base)[i]) {
|
||||
PERR("could not detect ROM modules");
|
||||
return -2;
|
||||
}
|
||||
|
||||
printf("detected ROM module image at 0x%p\n", (void *)phys_base);
|
||||
|
||||
/* detect overly large meta data, we only support 4K */
|
||||
addr_t end_of_header = ((long *)virt_base)[1];
|
||||
size_t header_size = end_of_header - (long)phys_base;
|
||||
if (header_size > get_page_size()) {
|
||||
PERR("ROM fs module header exceeds %d bytes", get_page_size());
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* start of module list */
|
||||
Module *module = (Module *)((addr_t)virt_base + 2*sizeof(long));
|
||||
|
||||
/*
|
||||
* Interate over module list and populate core's ROM file system with
|
||||
* 'Rom_module' objects.
|
||||
*/
|
||||
for (; module->name; module++) {
|
||||
|
||||
/* convert physical address of module name to core-local address */
|
||||
char *name = (char *)(module->name - phys_base + (addr_t)virt_base);
|
||||
|
||||
printf("ROM module \"%s\" at physical address 0x%p, size=%zd\n",
|
||||
name, (void *)module->base, (size_t)module->size);
|
||||
|
||||
Rom_module *rom_module = new (core_mem_alloc())
|
||||
Rom_module(module->base, module->size, name);
|
||||
|
||||
_rom_fs.insert(rom_module);
|
||||
|
||||
/* remove module from physical memory allocator */
|
||||
_core_mem_alloc.phys_alloc()->remove_range(module->base, round_page(module->size));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************
|
||||
** Support for core memory management **
|
||||
****************************************/
|
||||
|
||||
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
|
||||
addr_t phys_addr,
|
||||
unsigned size)
|
||||
{
|
||||
return map_local(phys_addr, virt_addr, size / get_page_size());
|
||||
}
|
||||
|
||||
|
||||
bool Core_mem_allocator::Mapped_mem_allocator::_unmap_local(addr_t virt_addr,
|
||||
unsigned size)
|
||||
{
|
||||
return unmap_local(virt_addr, size / get_page_size());
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
** Platform interface **
|
||||
************************/
|
||||
|
||||
Platform::Platform() :
|
||||
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
||||
_irq_alloc(core_mem_alloc()), _vm_base(0), _vm_size(0)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
/* init core UTCB */
|
||||
static char main_utcb[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
|
||||
static struct exregs_data exregs;
|
||||
exregs_set_utcb(&exregs, (unsigned long)&main_utcb[0]);
|
||||
l4_exchange_registers(&exregs, thread_myself());
|
||||
|
||||
/* error handling is futile at this point */
|
||||
|
||||
/* read number of capabilities */
|
||||
int num_caps;
|
||||
int ret;
|
||||
if ((ret = l4_capability_control(CAP_CONTROL_NCAPS,
|
||||
0, &num_caps)) < 0) {
|
||||
PERR("l4_capability_control(CAP_CONTROL_NCAPS) returned %d", ret);
|
||||
class Could_not_obtain_num_of_capabilities { };
|
||||
throw Could_not_obtain_num_of_capabilities();
|
||||
}
|
||||
|
||||
struct capability cap_array[num_caps];
|
||||
|
||||
if (verbose_boot_info)
|
||||
printf("allocated cap array[%d] of size %d on stack\n",
|
||||
num_caps, sizeof(cap_array));
|
||||
|
||||
/* read all capabilities */
|
||||
if ((ret = l4_capability_control(CAP_CONTROL_READ,
|
||||
0, cap_array)) < 0) {
|
||||
PERR("l4_capability_control(CAP_CONTROL_READ) returned %d", ret);
|
||||
class Read_caps_failed { };
|
||||
throw Read_caps_failed();
|
||||
}
|
||||
|
||||
/* initialize core allocators */
|
||||
bool phys_mem_defined = false;
|
||||
addr_t dev_mem_base = 0;
|
||||
for (int i = 0; i < num_caps; i++) {
|
||||
struct capability *cap = &cap_array[i];
|
||||
|
||||
addr_t base = cap->start << get_page_size_log2(),
|
||||
size = cap->size << get_page_size_log2();
|
||||
|
||||
if (verbose_boot_info)
|
||||
printf("cap type=%x, rtype=%x, base=%lx, size=%lx\n",
|
||||
cap_type(cap), cap_rtype(cap), base, size);
|
||||
|
||||
switch (cap_type(cap)) {
|
||||
|
||||
case CAP_TYPE_MAP_VIRTMEM:
|
||||
|
||||
/*
|
||||
* Use first non-UTCB virtual address range as default
|
||||
* virtual memory range usable for all processes.
|
||||
*/
|
||||
if (_vm_size == 0) {
|
||||
|
||||
/* exclude page at virtual address 0 */
|
||||
if (base == 0 && size >= get_page_size()) {
|
||||
base += get_page_size();
|
||||
size -= get_page_size();
|
||||
}
|
||||
|
||||
_vm_base = base;
|
||||
_vm_size = size;
|
||||
|
||||
/* add range as free range to core's virtual address allocator */
|
||||
_core_mem_alloc.virt_alloc()->add_range(base, size);
|
||||
break;
|
||||
}
|
||||
|
||||
PWRN("ignoring additional virtual address range [%lx,%lx)",
|
||||
base, base + size);
|
||||
break;
|
||||
|
||||
case CAP_TYPE_MAP_PHYSMEM:
|
||||
|
||||
/*
|
||||
* We interpret the first physical memory resource that is bigger
|
||||
* than typical device resources as RAM.
|
||||
*/
|
||||
enum { RAM_SIZE_MIN = 16*1024*1024 };
|
||||
if (!phys_mem_defined && size > RAM_SIZE_MIN) {
|
||||
_core_mem_alloc.phys_alloc()->add_range(base, size);
|
||||
phys_mem_defined = true;
|
||||
dev_mem_base = base + size;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAP_TYPE_IPC:
|
||||
case CAP_TYPE_UMUTEX:
|
||||
case CAP_TYPE_IRQCTRL:
|
||||
case CAP_TYPE_QUANTITY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addr_t core_virt_beg = trunc_page((addr_t)&_prog_img_beg),
|
||||
core_virt_end = round_page((addr_t)&_prog_img_end);
|
||||
size_t core_size = core_virt_end - core_virt_beg;
|
||||
|
||||
printf("core image:\n");
|
||||
printf(" virtual address range [%08lx,%08lx) size=0x%zx\n",
|
||||
core_virt_beg, core_virt_end, core_size);
|
||||
printf(" physically located at 0x%08lx\n", _lma_start);
|
||||
|
||||
/* remove core image from core's virtual address allocator */
|
||||
_core_mem_alloc.virt_alloc()->remove_range(core_virt_beg, core_size);
|
||||
|
||||
/* preserve context area in core's virtual address space */
|
||||
_core_mem_alloc.virt_alloc()->raw()->remove_range(Native_config::context_area_virtual_base(),
|
||||
Native_config::context_area_virtual_size());
|
||||
|
||||
/* remove used core memory from physical memory allocator */
|
||||
_core_mem_alloc.phys_alloc()->remove_range(_lma_start, core_size);
|
||||
|
||||
/* remove magically mapped UART from core virtual memory */
|
||||
_core_mem_alloc.virt_alloc()->remove_range(USERSPACE_CONSOLE_VBASE, get_page_size());
|
||||
|
||||
/* add boot modules to ROM fs */
|
||||
if (_init_rom_fs() < 0) {
|
||||
PERR("initialization of romfs failed - halt.");
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* initialize interrupt allocator */
|
||||
_irq_alloc.add_range(0, 255);
|
||||
|
||||
/* regard physical addresses higher than memory area as MMIO */
|
||||
_io_mem_alloc.add_range(dev_mem_base, 0x80000000 - dev_mem_base);
|
||||
|
||||
/*
|
||||
* Print statistics about allocator initialization
|
||||
*/
|
||||
printf("VM area at [%08lx,%08lx)\n", _vm_base, _vm_base + _vm_size);
|
||||
|
||||
if (verbose_boot_info) {
|
||||
printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
|
||||
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
|
||||
printf(":io_mem_alloc: "); _io_mem_alloc.raw()->dump_addr_tree();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Platform::wait_for_exit()
|
||||
{
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Core_parent::exit(int exit_value) { }
|
126
repos/base-codezero/src/core/platform_pd.cc
Normal file
126
repos/base-codezero/src/core/platform_pd.cc
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* \brief Protection-domain facility
|
||||
* \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/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_pd.h>
|
||||
#include <platform.h>
|
||||
#include <util.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
/***************************
|
||||
** Public object members **
|
||||
***************************/
|
||||
|
||||
int Platform_pd::bind_thread(Platform_thread *thread)
|
||||
{
|
||||
/* allocate new thread at the kernel */
|
||||
struct task_ids ids = { 1, _space_id, TASK_ID_INVALID };
|
||||
int ret = l4_thread_control(THREAD_CREATE | TC_SHARE_SPACE, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control returned %d, tid=%d\n", ret, ids.tid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate UTCB for new thread */
|
||||
int utcb_idx;
|
||||
for (utcb_idx = 0; utcb_idx < MAX_THREADS_PER_PD; utcb_idx++)
|
||||
if (!utcb_in_use[utcb_idx]) break;
|
||||
|
||||
if (utcb_idx == MAX_THREADS_PER_PD) {
|
||||
PERR("UTCB allocation failed");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* mark UTCB as being in use */
|
||||
utcb_in_use[utcb_idx] = true;
|
||||
|
||||
/* map UTCB area for the first thread of a new PD */
|
||||
if (utcb_idx == 0) {
|
||||
void *utcb_phys = 0;
|
||||
if (!platform()->ram_alloc()->alloc(UTCB_AREA_SIZE, &utcb_phys)) {
|
||||
PERR("could not allocate physical pages for UTCB");
|
||||
return -3;
|
||||
}
|
||||
|
||||
ret = l4_map(utcb_phys, (void *)UTCB_VIRT_BASE,
|
||||
UTCB_AREA_SIZE/get_page_size(), MAP_USR_RW, ids.tid);
|
||||
if (ret < 0) {
|
||||
PERR("UTCB mapping into new PD failed, ret=%d", ret);
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
addr_t utcb_addr = UTCB_VIRT_BASE + utcb_idx*sizeof(struct utcb);
|
||||
thread->_assign_physical_thread(ids.tid, _space_id, utcb_addr,
|
||||
this->Address_space::weak_ptr());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform_pd::unbind_thread(Platform_thread *thread)
|
||||
{
|
||||
/* find UTCB index of thread */
|
||||
unsigned utcb_idx;
|
||||
for (utcb_idx = 0; utcb_idx < MAX_THREADS_PER_PD; utcb_idx++)
|
||||
if (thread->utcb() == UTCB_VIRT_BASE + utcb_idx*sizeof(struct utcb))
|
||||
break;
|
||||
|
||||
if (utcb_idx == MAX_THREADS_PER_PD) {
|
||||
PWRN("could not find UTCB index of thread");
|
||||
return;
|
||||
}
|
||||
|
||||
utcb_in_use[utcb_idx] = false;
|
||||
|
||||
PWRN("not fully implemented");
|
||||
}
|
||||
|
||||
|
||||
Platform_pd::Platform_pd(bool core)
|
||||
{
|
||||
PWRN("not yet implemented");
|
||||
}
|
||||
|
||||
|
||||
Platform_pd::Platform_pd(char const *, signed pd_id, bool create)
|
||||
: _space_id(TASK_ID_INVALID)
|
||||
{
|
||||
_space_id = TASK_ID_INVALID;
|
||||
|
||||
/* mark all UTCBs of the new PD as free */
|
||||
for (int i = 0; i < MAX_THREADS_PER_PD; i++)
|
||||
utcb_in_use[i] = false;
|
||||
|
||||
struct task_ids ids = { TASK_ID_INVALID, TASK_ID_INVALID, TASK_ID_INVALID };
|
||||
|
||||
int ret = l4_thread_control(THREAD_CREATE | TC_NEW_SPACE, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control(THREAD_CREATE | TC_NEW_SPACE) returned %d", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set space ID to valid value to indicate success */
|
||||
_space_id = ids.spid;
|
||||
}
|
||||
|
||||
|
||||
Platform_pd::~Platform_pd()
|
||||
{
|
||||
PWRN("not yet implemented");
|
||||
}
|
112
repos/base-codezero/src/core/platform_thread.cc
Normal file
112
repos/base-codezero/src/core/platform_thread.cc
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \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/printf.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no)
|
||||
{
|
||||
Native_thread_id pager = _pager ? _pager->cap().dst() : THREAD_INVALID;
|
||||
|
||||
/* setup thread context */
|
||||
struct exregs_data exregs;
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_stack(&exregs, (unsigned long)sp);
|
||||
exregs_set_pc (&exregs, (unsigned long)ip);
|
||||
exregs_set_pager(&exregs, pager);
|
||||
exregs_set_utcb (&exregs, _utcb);
|
||||
|
||||
int ret = l4_exchange_registers(&exregs, _tid);
|
||||
if (ret < 0) {
|
||||
printf("l4_exchange_registers returned ret=%d\n", ret);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* start execution */
|
||||
struct task_ids ids = { _tid, _space_id, _tid };
|
||||
ret = l4_thread_control(THREAD_RUN, &ids);
|
||||
if (ret < 0) {
|
||||
printf("Error: l4_thread_control(THREAD_RUN) returned %d\n", ret);
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (verbose_thread_start)
|
||||
printf("core started thread \"%s\" with ID %d inside space ID %d\n",
|
||||
_name, _tid, _space_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::pause()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::resume()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::cancel_blocking()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
Weak_ptr<Address_space> Platform_thread::address_space()
|
||||
{
|
||||
return _address_space;
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(const char *name, unsigned, addr_t,
|
||||
int thread_id)
|
||||
: _tid(THREAD_INVALID)
|
||||
{
|
||||
strncpy(_name, name, sizeof(_name));
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::~Platform_thread()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
65
repos/base-codezero/src/core/ram_session_support.cc
Normal file
65
repos/base-codezero/src/core/ram_session_support.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* \brief Export RAM dataspace as shared memory object (dummy)
|
||||
* \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/printf.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
/* core includes */
|
||||
#include <ram_session_component.h>
|
||||
#include <platform.h>
|
||||
#include <map_local.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)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
/*
|
||||
* Map dataspace core-locally, memset, unmap dataspace
|
||||
*/
|
||||
|
||||
size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask();
|
||||
size_t num_pages = page_rounded_size >> get_page_size_log2();
|
||||
|
||||
/* allocate range in core's virtual address space */
|
||||
void *virt_addr;
|
||||
if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) {
|
||||
PERR("Could not allocate virtual address range in core of size %zd\n",
|
||||
page_rounded_size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* map the dataspace's physical pages to corresponding virtual addresses */
|
||||
if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages)) {
|
||||
PERR("core-local memory mapping failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(virt_addr, 0, ds->size());
|
||||
|
||||
/* unmap dataspace from core */
|
||||
if (!unmap_local((addr_t)virt_addr, num_pages)) {
|
||||
PERR("could not unmap %zd pages from virtual address range at %p",
|
||||
num_pages, virt_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* free core's virtual address space */
|
||||
platform()->region_alloc()->free(virt_addr, page_rounded_size);
|
||||
}
|
28
repos/base-codezero/src/core/rm_session_support.cc
Normal file
28
repos/base-codezero/src/core/rm_session_support.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief RM-session implementation
|
||||
* \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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <rm_session_component.h>
|
||||
#include <util.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
|
||||
{
|
||||
l4_unmap((void *)virt_base, size >> get_page_size_log2(), badge());
|
||||
}
|
57
repos/base-codezero/src/core/target.inc
Normal file
57
repos/base-codezero/src/core/target.inc
Normal file
@ -0,0 +1,57 @@
|
||||
TARGET = core
|
||||
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
|
||||
SRC_CC += \
|
||||
main.cc \
|
||||
ram_session_component.cc \
|
||||
ram_session_support.cc \
|
||||
rom_session_component.cc \
|
||||
cpu_session_component.cc \
|
||||
cpu_session_support.cc \
|
||||
pd_session_component.cc \
|
||||
io_mem_session_component.cc \
|
||||
io_mem_session_support.cc \
|
||||
thread_start.cc \
|
||||
platform_thread.cc \
|
||||
platform_pd.cc \
|
||||
platform_services.cc \
|
||||
platform.cc \
|
||||
dataspace_component.cc \
|
||||
rm_session_component.cc \
|
||||
rm_session_support.cc \
|
||||
irq_session_component.cc \
|
||||
signal_session_component.cc \
|
||||
signal_source_component.cc \
|
||||
trace_session_component.cc \
|
||||
core_rm_session.cc \
|
||||
core_mem_alloc.cc \
|
||||
dump_alloc.cc \
|
||||
context_area.cc
|
||||
|
||||
LIBS += core_printf base-common
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(GEN_CORE_DIR)/include \
|
||||
$(REP_DIR)/include/codezero/dummies \
|
||||
$(BASE_DIR)/src/base/thread
|
||||
|
||||
include $(GEN_CORE_DIR)/version.inc
|
||||
|
||||
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 platform_services.cc $(GEN_CORE_DIR)
|
||||
vpath signal_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath signal_source_component.cc $(GEN_CORE_DIR)
|
||||
vpath trace_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath dataspace_component.cc $(GEN_CORE_DIR)
|
||||
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
|
||||
vpath dump_alloc.cc $(GEN_CORE_DIR)
|
||||
vpath context_area.cc $(GEN_CORE_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/core
|
4
repos/base-codezero/src/core/target.mk
Normal file
4
repos/base-codezero/src/core/target.mk
Normal file
@ -0,0 +1,4 @@
|
||||
include $(PRG_DIR)/target.inc
|
||||
|
||||
LD_TEXT_ADDR = 0x100000
|
||||
|
120
repos/base-codezero/src/core/thread_start.cc
Normal file
120
repos/base-codezero/src/core/thread_start.cc
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* \brief Implementation of Thread API interface for core
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
|
||||
/**
|
||||
* Create and start new thread
|
||||
*
|
||||
* \param space_no space ID in which the new thread will be executed
|
||||
* \param sp initial stack pointer
|
||||
* \param ip initial instruction pointer
|
||||
* \return new thread ID, or
|
||||
* negative error code
|
||||
*/
|
||||
inline int create_thread(unsigned space_no,
|
||||
void *sp, void *ip,
|
||||
int pager_tid = 1)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
struct task_ids ids = { 1U, space_no, TASK_ID_INVALID };
|
||||
|
||||
/* allocate new thread at the kernel */
|
||||
unsigned long flags = THREAD_CREATE | TC_SHARE_SPACE | TC_SHARE_GROUP;
|
||||
int ret = l4_thread_control(flags, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control returned %d, spid=%d\n",
|
||||
ret, ids.spid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long utcb_base_addr = (unsigned long)l4_get_utcb();
|
||||
|
||||
/* calculate utcb address of new thread */
|
||||
unsigned long new_utcb = utcb_base_addr + ids.tid*sizeof(struct utcb);
|
||||
|
||||
/* setup thread context */
|
||||
struct exregs_data exregs;
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_stack(&exregs, (unsigned long)sp);
|
||||
exregs_set_pc (&exregs, (unsigned long)ip);
|
||||
exregs_set_pager(&exregs, pager_tid);
|
||||
exregs_set_utcb (&exregs, new_utcb);
|
||||
|
||||
ret = l4_exchange_registers(&exregs, ids.tid);
|
||||
if (ret < 0) {
|
||||
printf("l4_exchange_registers returned ret=%d\n", ret);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* start execution */
|
||||
ret = l4_thread_control(THREAD_RUN, &ids);
|
||||
if (ret < 0) {
|
||||
printf("Error: l4_thread_control(THREAD_RUN) returned %d\n", ret);
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* return new thread ID allocated by the kernel */
|
||||
return ids.tid;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
Thread_base::myself()->_thread_bootstrap();
|
||||
Thread_base::myself()->entry();
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform()->core_mem_alloc()) Platform_thread(_context->name);
|
||||
|
||||
_tid.l4id = create_thread(1, stack_top(), (void *)&_thread_start);
|
||||
|
||||
if (_tid.l4id < 0)
|
||||
PERR("create_thread returned %d", _tid.l4id);
|
||||
|
||||
if (verbose_thread_start)
|
||||
printf("core started local thread \"%s\" with ID %d\n",
|
||||
_context->name, _tid.l4id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
PWRN("not implemented");
|
||||
}
|
||||
|
||||
|
74
repos/base-codezero/src/kernel/target.mk
Normal file
74
repos/base-codezero/src/kernel/target.mk
Normal file
@ -0,0 +1,74 @@
|
||||
TARGET = codezero
|
||||
|
||||
-include $(BUILD_BASE_DIR)/etc/codezero.conf
|
||||
ifeq ($(wildcard $(CODEZERO_DIR)),)
|
||||
$(error No valid kernel configured in 'etc/codezero.conf')
|
||||
endif
|
||||
|
||||
include $(REP_DIR)/lib/mk/codezero_cml.inc
|
||||
|
||||
TOOL_CHAIN_DIR = $(dir $(CROSS_DEV_PREFIX))
|
||||
CODEZERO_DST_DIR = $(BUILD_BASE_DIR)/kernel/codezero
|
||||
CODEZERO_BUILD_DIR = $(CODEZERO_DST_DIR)/build
|
||||
|
||||
.PHONY: $(TARGET)
|
||||
|
||||
MIRROR_COPY := conts/baremetal/empty conts/userlibs \
|
||||
build.py include SConstruct src loader
|
||||
|
||||
MIRROR_SYMLINK := scripts tools
|
||||
|
||||
update_copy = $(VERBOSE)tar c -C $(CODEZERO_DIR) $(MIRROR_COPY) | tar x -C $(CODEZERO_DST_DIR)
|
||||
|
||||
ifneq ($(VERBOSE),)
|
||||
CODEZERO_STDOUT := > /dev/null
|
||||
endif
|
||||
|
||||
#
|
||||
# Environment variables passed to the Codezero build system
|
||||
#
|
||||
BUILD_ENV = PATH=$(dir $(CROSS_DEV_PREFIX)):$$PATH
|
||||
|
||||
#
|
||||
# Local copy of the CML file used for supplying the configuration
|
||||
# to the Codezero build system.
|
||||
#
|
||||
LOCAL_CONFIG_CML := $(shell pwd)/config.cml
|
||||
|
||||
$(TARGET): $(CODEZERO_BUILD_DIR)
|
||||
$(MSG_BUILD)kernel
|
||||
$(update_copy)
|
||||
$(VERBOSE)cd $(CODEZERO_DST_DIR); $(BUILD_ENV) ./build.py $(CODEZERO_STDOUT)
|
||||
|
||||
#
|
||||
# Mirror the parts of the Codezero source tree that are relevant for building
|
||||
# the kernel
|
||||
#
|
||||
$(CODEZERO_DST_DIR): $(CODEZERO_DIR)
|
||||
$(VERBOSE)test -d $@ || mkdir -p $@
|
||||
$(VERBOSE)for d in $(MIRROR_SYMLINK); do ln -sf $(realpath $^)/$$d $@/$$d; done
|
||||
|
||||
$(CODEZERO_BUILD_DIR): $(CODEZERO_DST_DIR) $(CODEZERO_CML)
|
||||
$(update_copy)
|
||||
$(VERBOSE)cp $(CODEZERO_CML) $(LOCAL_CONFIG_CML)
|
||||
@#
|
||||
@# Create copy of the CML config in the local build directory to update
|
||||
@# the tool chain parameters according to the CROSS_DEV_PREFIX configured
|
||||
@# for Genode.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/TOOLCHAIN_USERSPACE/s/\".*\"/\"$(notdir $(CROSS_DEV_PREFIX))\"/" $(LOCAL_CONFIG_CML)
|
||||
$(VERBOSE)sed -i "/TOOLCHAIN_KERNEL/s/\".*\"/\"$(notdir $(CROSS_DEV_PREFIX))\"/" $(LOCAL_CONFIG_CML)
|
||||
$(VERBOSE)cd $(CODEZERO_DST_DIR); $(BUILD_ENV) ./build.py -C -b -f $(LOCAL_CONFIG_CML) $(CODEZERO_STDOUT)
|
||||
|
||||
clean cleanall: clean_codezero
|
||||
|
||||
#
|
||||
# Make sure to execute the 'clean_codezero' rule prior the generic clean
|
||||
# rule in 'prg.mk' because the generic rule will attempt to remove $(TARGET)
|
||||
# file, which is a directory in our case.
|
||||
#
|
||||
clean_prg_objects: clean_codezero
|
||||
|
||||
clean_codezero:
|
||||
$(VERBOSE)rm -f $(LOCAL_CONFIG_CML)
|
||||
$(VERBOSE)rm -rf $(CODEZERO_DST_DIR)
|
131
repos/base-codezero/src/platform/genode.ld
Normal file
131
repos/base-codezero/src/platform/genode.ld
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* \brief Linker script for Genode programs
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-04-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* values taken from Codezero's mm0 linker script */
|
||||
/*physical_base = 0x00208000;*/
|
||||
/*virtual_base = 0xe0000000;*/
|
||||
/*offset = virtual_base - physical_base;*/
|
||||
|
||||
/*
|
||||
* Addresses correspond to the linker script generated by
|
||||
* the Codezero build system.
|
||||
*/
|
||||
vma_start = 0x100000;
|
||||
lma_start = 0x40000;
|
||||
offset = vma_start - lma_start;
|
||||
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
ro PT_LOAD;
|
||||
rw PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = vma_start;
|
||||
|
||||
.text : AT (ADDR(.text) - offset) {
|
||||
/* begin of program image (link address) */
|
||||
_prog_img_beg = .;
|
||||
|
||||
*(.text.crt0)
|
||||
*(.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 : AT (ADDR(.data) - offset) {
|
||||
/*
|
||||
* Leave space for parent capability parameters at start of data
|
||||
* section. The protection domain creator is reponsible for storing
|
||||
* sane values here.
|
||||
*/
|
||||
_parent_cap = .;
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
_vma_start = .;
|
||||
LONG(vma_start);
|
||||
_lma_start = .;
|
||||
LONG(lma_start);
|
||||
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
} : rw
|
||||
|
||||
/* exception frames for C++ */
|
||||
.eh_frame : {
|
||||
__eh_frame_start__ = .;
|
||||
KEEP (*(.eh_frame))
|
||||
LONG(0)
|
||||
} : rw
|
||||
|
||||
.init_array : {
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
|
||||
.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
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
.bss : AT (ADDR(.bss) - offset) {
|
||||
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
|
||||
}
|
||||
|
||||
/* end of program image -- must be after last section */
|
||||
_prog_img_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.note)
|
||||
*(.note.ABI-tag)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user