mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
Run Genode directly on hardware with 'base-hw'.
This commit is contained in:
parent
8220ea272c
commit
ff65f6f021
67
base-hw/doc/hw.txt
Normal file
67
base-hw/doc/hw.txt
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
======================================
|
||||
How to use Genode directly on hardware
|
||||
======================================
|
||||
|
||||
Martin Stein
|
||||
|
||||
|
||||
The 'base-hw' repository provides an implementation of Genodes core that runs
|
||||
directly on hardware, without an intermediate third-party kernel. Currently it
|
||||
runs on the ARM platforms Realview PBXA9, Versatile Express A9X4 and
|
||||
PandaBoard A2.
|
||||
|
||||
This document provides brief instructions about building and booting Genode
|
||||
directly on hardware.
|
||||
|
||||
|
||||
Prerequisites
|
||||
#############
|
||||
|
||||
To build Genode you need to download and install the tool-chain used by Genode.
|
||||
Have a look at this page:
|
||||
|
||||
:[http://genode.org/download/tool-chain]:
|
||||
Genode tool-chain
|
||||
|
||||
If you want to use the so called run-scripts in Genode, a mechanism that
|
||||
automates building, integration and testing of components, you have to install
|
||||
the following, additional package:
|
||||
|
||||
! apt-get install expect
|
||||
|
||||
If you want to examine the examples that are given in this document, you will
|
||||
need Qemu for ARM emulations to run them on your machine:
|
||||
|
||||
! apt-get install qemu-kvm-extras
|
||||
|
||||
Building Genode to run directly on hardware
|
||||
###########################################
|
||||
|
||||
The current version of the Genode source code is available at this page:
|
||||
|
||||
:http://genode.org/download/repository:
|
||||
Donwloading the Genode source code
|
||||
|
||||
Now, go to a directory where you want the Genode build directory to
|
||||
remain. Use the helper script in the 'tool' directory of the Genode
|
||||
source tree to create the initial build environment. You need to state the
|
||||
build directory you want to create, and the hardware system to run
|
||||
Genode on. Choose 'hw_pbxa9', 'hw_vea9x4', or 'hw_panda_a2' depending on the
|
||||
hardware system you aim at.
|
||||
|
||||
! <genode-dir>/tool/create_builddir hw_pbxa9 BUILD_DIR=<build-dir>
|
||||
|
||||
Now, go to the newly created build directory make a test:
|
||||
|
||||
! cd <build-dir>
|
||||
! make run/nested_init
|
||||
|
||||
This will build the Genode components that are needed to run a simple test
|
||||
with 3 nested init programs, and than execute it via Qemu.
|
||||
|
||||
For further informations according to the specific hardware systems, have
|
||||
look into the other documentations:
|
||||
|
||||
! base-hw/doc/<system>.txt
|
||||
|
95
base-hw/doc/panda_a2.txt
Normal file
95
base-hw/doc/panda_a2.txt
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
======================================================
|
||||
Getting started with 'genode/base-hw' on PandaBoard A2
|
||||
======================================================
|
||||
|
||||
|
||||
Martin Stein
|
||||
|
||||
Abstract
|
||||
########
|
||||
|
||||
This is a short tutorial that depicts a handy way to get a Genode ELF image,
|
||||
build with 'base-hw', started on the PandaBoard A2. It is dedicated to common
|
||||
Linux systems, but all examples originate from a Ubuntu 10.10.
|
||||
|
||||
|
||||
Tutorial
|
||||
########
|
||||
|
||||
Connect the PandaBoard to your local Ethernet through its RJ45 connector.
|
||||
Additionally connect the PandaBoard to your machine through its COM port.
|
||||
Ensure that you have installed the genode tool chain that is available at:
|
||||
|
||||
[http://genode.org/download/tool-chain - Get the genode tool chain]
|
||||
|
||||
Ensure that '<GENODE_GCC_DIR>/bin/' is in your 'PATH' variable.
|
||||
Get the linaro U-Boot repository and compile U-Boot for PandaBoard:
|
||||
|
||||
! git clone git://git.linaro.org/boot/u-boot-linaro-stable.git
|
||||
! cd <UBOOT_DIR>
|
||||
! make CROSS_COMPILE=genode-arm- omap4_panda_config
|
||||
! make CROSS_COMPILE=genode-arm-
|
||||
|
||||
During the compilation i had some errors. The first was in assembly code,
|
||||
it seemed to originate from a slip with the typo and was easy to fix.
|
||||
The second kind of errors occured because the GCC version had no support for
|
||||
direct array initialization, thus i avoided them by simply initialize
|
||||
the array elements separately.
|
||||
|
||||
Now install the following packages to communicate with the PandaBoard:
|
||||
|
||||
! sudo apt-get install tftp-hpa minicom
|
||||
|
||||
Open '/etc/default/tftpd-hpa' with a text editor and ensure that it has
|
||||
the following content:
|
||||
|
||||
! # /etc/default/tftpd-hpa
|
||||
! TFTP_USERNAME="tftp"
|
||||
! TFTP_DIRECTORY="/var/lib/tftpboot"
|
||||
! TFTP_ADDRESS="0.0.0.0:69"
|
||||
! TFTP_OPTIONS="-l"
|
||||
|
||||
Tell U-Boot wich image to load on boot command:
|
||||
|
||||
! cd /var/lib/tftpboot/
|
||||
! ln -s <GENODE_BOOT_ELF> image.elf
|
||||
|
||||
Start TFTP to enable the upload of the image:
|
||||
|
||||
! sudo service tftp-hpa restart
|
||||
|
||||
Start Minicom in configuration mode:
|
||||
|
||||
! minicom -s
|
||||
|
||||
Go to 'Serial port setting' and ensure that the device is set the
|
||||
TTY of the COM port you've conntected PandaBoard with, in my case it was
|
||||
'/dev/ttyS0'. Configure the other settings for a baud rate of '115200',
|
||||
8 bit char length, no parity and 1 stop bit. Quit Minicom and start
|
||||
it once more:
|
||||
|
||||
! minicom
|
||||
|
||||
Mount your SD-card and copy the U-Boot files to its boot partition:
|
||||
|
||||
! cd <UBOOT_DIR>; cp MLO /media/boot/; cp u-boot.bin /media/boot/
|
||||
|
||||
Unmount the SD card and insert it into the appropriate PandaBoard slot.
|
||||
Plug in the power connector or push the 'S1' button if the PandaBoard is
|
||||
already powered.
|
||||
|
||||
Minicom should now show the following message:
|
||||
|
||||
! Hit any key to stop autoboot:
|
||||
|
||||
We have to stop autoboot and type in this line to load and boot the genode
|
||||
image via ethernet:
|
||||
|
||||
! usb start; dhcp; bootelf 0x82000000
|
||||
|
||||
Now the ELF image should start correctly and offer some debug output in
|
||||
minicom. You can now boot further images by redirecting the link
|
||||
'/var/lib/tftpboot/image.elf' accordingly, restarting your pandaboard
|
||||
and instructing 'uboot' again as described above.
|
||||
|
62
base-hw/include/arm_v7a/base/syscall.h
Normal file
62
base-hw/include/arm_v7a/base/syscall.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* \brief Syscall declarations specific for ARM V7A systems
|
||||
* \author Martin Stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__ARM_V7A__BASE__SYSCALL_H_
|
||||
#define _INCLUDE__ARM_V7A__BASE__SYSCALL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
typedef Genode::uint32_t Syscall_arg;
|
||||
typedef Genode::uint32_t Syscall_ret;
|
||||
|
||||
/*****************************************************************
|
||||
** Syscall with 1 to 6 arguments **
|
||||
** **
|
||||
** These functions must not be inline to ensure that objects, **
|
||||
** wich are referenced by arguments, are tagged as "used" even **
|
||||
** though only the pointer gets handled in here. **
|
||||
*****************************************************************/
|
||||
|
||||
Syscall_ret syscall(Syscall_arg arg_0);
|
||||
|
||||
Syscall_ret syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1);
|
||||
|
||||
Syscall_ret syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2);
|
||||
|
||||
Syscall_ret syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3);
|
||||
|
||||
Syscall_ret syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3,
|
||||
Syscall_arg arg_4);
|
||||
|
||||
Syscall_ret syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3,
|
||||
Syscall_arg arg_4,
|
||||
Syscall_arg arg_5);
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__ARM_V7A__BASE__SYSCALL_H_ */
|
||||
|
71
base-hw/include/base/ipc_msgbuf.h
Normal file
71
base-hw/include/base/ipc_msgbuf.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* \brief IPC message buffers
|
||||
* \author Martin Stein
|
||||
* \date 2012-01-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__IPC_MSGBUF_H_
|
||||
#define _INCLUDE__BASE__IPC_MSGBUF_H_
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* IPC message buffer layout
|
||||
*/
|
||||
class Msgbuf_base
|
||||
{
|
||||
protected:
|
||||
|
||||
size_t _size; /* buffer size in bytes */
|
||||
|
||||
public:
|
||||
|
||||
char buf[]; /* begin of actual message buffer */
|
||||
|
||||
/*************************************************
|
||||
** 'buf' must be the last member of this class **
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* Return size of message buffer
|
||||
*/
|
||||
inline size_t size() const { return _size; }
|
||||
|
||||
/**
|
||||
* Return address of message buffer
|
||||
*/
|
||||
inline void *addr() { return &buf[0]; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance of IPC message buffer with specified buffer size
|
||||
*
|
||||
* 'Msgbuf_base' must be the last class this class inherits from.
|
||||
*/
|
||||
template <unsigned BUF_SIZE>
|
||||
class Msgbuf : public Msgbuf_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**************************************************
|
||||
** 'buf' must be the first member of this class **
|
||||
**************************************************/
|
||||
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Msgbuf() { _size = BUF_SIZE; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__IPC_MSGBUF_H_ */
|
||||
|
172
base-hw/include/base/ipc_pager.h
Normal file
172
base-hw/include/base/ipc_pager.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* \brief IPC backend for a Genode pager
|
||||
* \author Martin Stein
|
||||
* \date 2012-03-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__IPC_PAGER_H_
|
||||
#define _INCLUDE__BASE__IPC_PAGER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/ipc.h>
|
||||
#include <base/native_types.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Pager_object;
|
||||
|
||||
/**
|
||||
* Translation of a virtual page frame
|
||||
*/
|
||||
struct Mapping
|
||||
{
|
||||
addr_t virt_address;
|
||||
addr_t phys_address;
|
||||
bool write_combined;
|
||||
unsigned size_log2;
|
||||
bool writable;
|
||||
|
||||
/**
|
||||
* Construct valid mapping
|
||||
*/
|
||||
Mapping(addr_t const va, addr_t const pa, bool const wc,
|
||||
unsigned const sl2 = MIN_MAPPING_SIZE_LOG2, bool w = 1)
|
||||
:
|
||||
virt_address(va), phys_address(pa), write_combined(wc),
|
||||
size_log2(sl2), writable(w)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Construct invalid mapping
|
||||
*/
|
||||
Mapping() : size_log2(0) { }
|
||||
|
||||
/**
|
||||
* Dummy, all data is available since construction
|
||||
*/
|
||||
void prepare_map_operation() { }
|
||||
|
||||
/**
|
||||
* Validation
|
||||
*/
|
||||
bool valid() { return size_log2 > 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Message format for the acknowledgment of a resolved pagefault
|
||||
*/
|
||||
struct Pagefault_resolved
|
||||
{
|
||||
Native_thread_id const reply_dst;
|
||||
Pager_object * const pager_object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Special paging server class
|
||||
*/
|
||||
class Ipc_pager : public Native_capability
|
||||
{
|
||||
enum { VERBOSE = 1 };
|
||||
|
||||
Pagefault _pagefault; /* data of lastly received pagefault */
|
||||
Mapping _mapping; /* mapping to resolve last pagefault */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Ipc_pager() :
|
||||
Native_capability(Genode::thread_get_my_native_id(), 0)
|
||||
{
|
||||
/* check if we can distinguish all message types */
|
||||
if (sizeof(Pagefault) == sizeof(Pagefault_resolved))
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__
|
||||
<< ": Message types indiscernible\n";
|
||||
while (1) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the next pagefault request
|
||||
*/
|
||||
void wait_for_fault();
|
||||
|
||||
/**
|
||||
* Resolve current pagefault and wait for a new one
|
||||
*/
|
||||
void resolve_and_wait_for_fault();
|
||||
|
||||
/**
|
||||
* Request instruction pointer of current page fault
|
||||
*/
|
||||
addr_t fault_ip() { return _pagefault.virt_ip; }
|
||||
|
||||
/**
|
||||
* Request fault address of current page fault
|
||||
*/
|
||||
addr_t fault_addr() { return _pagefault.virt_address; }
|
||||
|
||||
/**
|
||||
* Set parameters for next reply
|
||||
*/
|
||||
void set_reply_mapping(Mapping m) { _mapping = m; }
|
||||
|
||||
/**
|
||||
* Set destination for next reply
|
||||
*/
|
||||
void set_reply_dst(Native_capability pager_object) {
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer call without sending a flex-page mapping
|
||||
*
|
||||
* This function is used to acknowledge local calls from one of
|
||||
* core's region-manager sessions.
|
||||
*/
|
||||
void acknowledge_wakeup() {
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return thread ID of last faulter
|
||||
*/
|
||||
Native_thread_id last() const { return _pagefault.thread_id; }
|
||||
|
||||
/**
|
||||
* Return badge for faulting thread
|
||||
*/
|
||||
unsigned long badge() const { return _pagefault.thread_id; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was a write fault
|
||||
*/
|
||||
bool is_write_fault() const { return _pagefault.write; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was an exception
|
||||
*/
|
||||
bool is_exception() const
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__IPC_PAGER_H_ */
|
||||
|
142
base-hw/include/base/native_types.h
Normal file
142
base-hw/include/base/native_types.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* \brief Platform specific basic Genode types
|
||||
* \author Martin Stein
|
||||
* \date 2012-01-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
#define _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/syscalls.h>
|
||||
#include <base/native_capability.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Platform_thread;
|
||||
|
||||
typedef int volatile Native_lock;
|
||||
typedef Platform_thread * Native_thread;
|
||||
typedef unsigned long Native_thread_id;
|
||||
typedef int Native_connection_state;
|
||||
|
||||
/* FIXME needs to be MMU dependent */
|
||||
enum { MIN_MAPPING_SIZE_LOG2 = 12 };
|
||||
|
||||
/**
|
||||
* Get kernel-object identifier of the current thread
|
||||
*/
|
||||
inline Native_thread_id thread_get_my_native_id()
|
||||
{ return Kernel::current_thread_id(); }
|
||||
|
||||
/**
|
||||
* Get the thread ID, wich is handled as invalid by the kernel
|
||||
*/
|
||||
inline Native_thread_id thread_invalid_id() { return 0; }
|
||||
|
||||
/**
|
||||
* Describes a pagefault
|
||||
*/
|
||||
struct Pagefault
|
||||
{
|
||||
unsigned long thread_id; /* thread ID of the faulter */
|
||||
Software_tlb * software_tlb; /* TLB to wich the faulter is assigned */
|
||||
addr_t virt_ip; /* the faulters virtual instruction pointer */
|
||||
addr_t virt_address; /* virtual fault address */
|
||||
bool write; /* write access attempted at fault? */
|
||||
|
||||
/**
|
||||
* Placement new operator
|
||||
*/
|
||||
void * operator new (size_t, void * p) { return p; }
|
||||
|
||||
/**
|
||||
* Construct invalid pagefault
|
||||
*/
|
||||
Pagefault() : thread_id(0) { }
|
||||
|
||||
/**
|
||||
* Construct valid pagefault
|
||||
*/
|
||||
Pagefault(unsigned const tid, Software_tlb * const sw_tlb,
|
||||
addr_t const vip, addr_t const va, bool const w)
|
||||
:
|
||||
thread_id(tid), software_tlb(sw_tlb), virt_ip(vip),
|
||||
virt_address(va), write(w)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Validation
|
||||
*/
|
||||
bool valid() const { return thread_id != 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes a userland-thread-context region
|
||||
*/
|
||||
struct Native_utcb
|
||||
{
|
||||
/* UTCB payload */
|
||||
union {
|
||||
char bytes[1<<MIN_MAPPING_SIZE_LOG2];
|
||||
umword_t words[sizeof(bytes)/sizeof(umword_t)];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get pointer to a specific word within the UTCB
|
||||
*/
|
||||
umword_t * word(unsigned long const index) { return &words[index]; }
|
||||
|
||||
/**
|
||||
* Get the base of the UTCB
|
||||
*/
|
||||
void * base() { return (void *)bytes; }
|
||||
|
||||
/**
|
||||
* Get the UTCB size
|
||||
*/
|
||||
unsigned long size() { return sizeof(bytes); }
|
||||
};
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
typedef Native_thread_id Dst;
|
||||
|
||||
/**
|
||||
* Validate capability destination
|
||||
*/
|
||||
static bool valid(Dst pt) { return pt != 0; }
|
||||
|
||||
/**
|
||||
* Get invalid capability destination
|
||||
*/
|
||||
static Dst invalid() { return 0; }
|
||||
|
||||
/**
|
||||
* Copy capability 'src' to a given memory destination 'dst'
|
||||
*/
|
||||
static void
|
||||
copy(void * dst, Native_capability_tpl<Cap_dst_policy> * src);
|
||||
};
|
||||
|
||||
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
||||
|
||||
/**
|
||||
* A coherent address region
|
||||
*/
|
||||
struct Native_region
|
||||
{
|
||||
addr_t base;
|
||||
size_t size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */
|
||||
|
172
base-hw/include/base/signal.h
Normal file
172
base-hw/include/base/signal.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* \brief Delivery and reception of asynchronous notifications on HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__SIGNAL_H__
|
||||
#define _INCLUDE__BASE__SIGNAL_H__
|
||||
|
||||
/* Genode includes */
|
||||
#include <signal_session/signal_session.h>
|
||||
#include <base/lock.h>
|
||||
#include <util/list.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* A bunch of asynchronuosly triggered events that target the same context
|
||||
*
|
||||
* Because a signal can trigger asynchronously at a context,
|
||||
* the kernel accumulates them and provides them as such a bunch,
|
||||
* once the receiver indicates that he is ready to receive.
|
||||
*/
|
||||
class Signal
|
||||
{
|
||||
unsigned long _imprint; /* receiver-local signal-context pointer */
|
||||
int _num; /* how often this signal has been triggered */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct valid signal
|
||||
*/
|
||||
Signal(unsigned long const imprint, int const num)
|
||||
: _imprint(imprint), _num(num) { }
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Signal_context * context() { return (Signal_context *)_imprint; }
|
||||
|
||||
int num() { return _num; }
|
||||
};
|
||||
|
||||
typedef List<Signal_context> Context_list;
|
||||
|
||||
/**
|
||||
* A specific signal type that a transmitter can target when it submits
|
||||
*
|
||||
* One receiver might handle multiple signal contexts,
|
||||
* but a signal context is owned by exactly one signal receiver.
|
||||
*/
|
||||
class Signal_context : public Context_list::Element
|
||||
{
|
||||
friend class Signal_receiver;
|
||||
|
||||
Signal_receiver * _receiver; /* receiver that manages us */
|
||||
Lock _lock; /* serialize object access */
|
||||
Signal_context_capability _cap; /* holds the name of our context
|
||||
* kernel-object as 'dst' */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct context that is not yet managed by a receiver
|
||||
*/
|
||||
Signal_context() : _receiver(0), _lock(Lock::UNLOCKED) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Signal_context() { }
|
||||
|
||||
/* solely needed to enable one to type a capability with us */
|
||||
GENODE_RPC_INTERFACE();
|
||||
};
|
||||
|
||||
/**
|
||||
* To submit signals to one specific context
|
||||
*
|
||||
* Multiple transmitters can submit to the same context.
|
||||
*/
|
||||
class Signal_transmitter
|
||||
{
|
||||
/* names the targeted context kernel-object with its 'dst' field */
|
||||
Signal_context_capability _context;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Signal_transmitter(Signal_context_capability const c =
|
||||
Signal_context_capability())
|
||||
: _context(c) { }
|
||||
|
||||
/**
|
||||
* Trigger a signal 'num' times at the context we target
|
||||
*/
|
||||
void submit(int const num = 1)
|
||||
{ Kernel::submit_signal(_context.dst(), num); }
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
void context(Signal_context_capability const c) { _context = c; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Manage multiple signal contexts and receive signals targeted to them
|
||||
*/
|
||||
class Signal_receiver
|
||||
{
|
||||
Context_list _contexts; /* contexts that we manage */
|
||||
Lock _contexts_lock; /* serialize access to
|
||||
* 'contexts' */
|
||||
Signal_receiver_capability _cap; /* holds name of our receiver
|
||||
* kernel-object as 'dst' */
|
||||
|
||||
/**
|
||||
* Let a context 'c' no longer be managed by us
|
||||
*
|
||||
* Doesn't serialize any member access.
|
||||
*/
|
||||
void _unsync_dissolve(Signal_context * const c);
|
||||
|
||||
public:
|
||||
|
||||
class Context_already_in_use : public Exception { };
|
||||
class Context_not_associated : public Exception { };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Signal_receiver();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Signal_receiver();
|
||||
|
||||
/**
|
||||
* Let a context 'c' be managed by us
|
||||
*
|
||||
* \return Capability wich names the context kernel-object in its
|
||||
* 'dst' field . Can be used as target for transmitters.
|
||||
*/
|
||||
Signal_context_capability manage(Signal_context * const c);
|
||||
|
||||
/**
|
||||
* Let a context 'c' no longer be managed by us
|
||||
*/
|
||||
void dissolve(Signal_context * const c);
|
||||
|
||||
/**
|
||||
* Block on any signal that is triggered at one of our contexts
|
||||
*/
|
||||
Signal wait_for_signal();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__SIGNAL_H__ */
|
||||
|
109
base-hw/include/kernel/log.h
Normal file
109
base-hw/include/kernel/log.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* \brief Print to kernel log output
|
||||
* \author Martin stein
|
||||
* \date 2012-04-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__KERNEL__LOG_H_
|
||||
#define _INCLUDE__KERNEL__LOG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Prints incoming streams to the kernel log output
|
||||
*/
|
||||
class Kernel_log
|
||||
{
|
||||
/**
|
||||
* Print an unsigned 4 bit integer as hexadecimal value
|
||||
*/
|
||||
void _print_4bit_hex(unsigned char x) const
|
||||
{
|
||||
/* decode to ASCII char */
|
||||
x &= 0x0f;
|
||||
if (x > 9) x += 39;
|
||||
x += 48;
|
||||
|
||||
/* print ASCII char */
|
||||
Kernel::print_char(x);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Print zero-terminated string
|
||||
*/
|
||||
Kernel_log & operator << (char const * s)
|
||||
{
|
||||
while (*s) Kernel::print_char(*s++);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an unsigned integer as hexadecimal value
|
||||
*/
|
||||
Kernel_log & operator << (unsigned int const & x)
|
||||
{
|
||||
enum {
|
||||
BYTE_WIDTH = 8,
|
||||
CW = sizeof(unsigned char)*BYTE_WIDTH,
|
||||
IW = sizeof(unsigned int)*BYTE_WIDTH
|
||||
};
|
||||
|
||||
/*
|
||||
* Walk from most significant to least significant bit and
|
||||
* process 2 hex digits per step.
|
||||
*/
|
||||
bool leading = true;
|
||||
for (int i = IW - CW; i >= 0; i = i - CW)
|
||||
{
|
||||
/* fetch the 2 current digits */
|
||||
unsigned char c = (char)((x >> i) & 0xff);
|
||||
|
||||
/* has the payload part of the value already begun? */
|
||||
if (leading)
|
||||
{
|
||||
/* ignore leading zeros ... */
|
||||
if (!c)
|
||||
{
|
||||
/* ... expect they are the only digits */
|
||||
if (i == 0) _print_4bit_hex(c);
|
||||
continue;
|
||||
}
|
||||
/* transit from leading to payload part */
|
||||
leading = false;
|
||||
if (c < 0x10) {
|
||||
_print_4bit_hex(c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* print both digits */
|
||||
_print_4bit_hex(c >> 4);
|
||||
_print_4bit_hex(c);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Give static 'Kernel_log' reference as target for common log output
|
||||
*/
|
||||
inline Kernel_log & kernel_log()
|
||||
{
|
||||
static Kernel_log _log;
|
||||
return _log;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__KERNEL__LOG_H_ */
|
||||
|
427
base-hw/include/kernel/syscalls.h
Normal file
427
base-hw/include/kernel/syscalls.h
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* \brief Kernels syscall frontend
|
||||
* \author Martin stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__KERNEL__SYSCALLS_H_
|
||||
#define _INCLUDE__KERNEL__SYSCALLS_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/syscall.h>
|
||||
|
||||
class Software_tlb;
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Platform_thread;
|
||||
}
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* Unique opcodes of all syscalls supported by the kernel
|
||||
*/
|
||||
enum Syscall_type
|
||||
{
|
||||
INVALID_SYSCALL = 0,
|
||||
|
||||
/* execution control */
|
||||
NEW_THREAD = 1,
|
||||
START_THREAD = 2,
|
||||
PAUSE_THREAD = 3,
|
||||
RESUME_THREAD = 4,
|
||||
GET_THREAD = 5,
|
||||
CURRENT_THREAD_ID = 6,
|
||||
YIELD_THREAD = 7,
|
||||
READ_REGISTER = 18,
|
||||
WRITE_REGISTER = 19,
|
||||
|
||||
/* interprocess communication */
|
||||
REQUEST_AND_WAIT = 8,
|
||||
REPLY_AND_WAIT = 9,
|
||||
WAIT_FOR_REQUEST = 10,
|
||||
|
||||
/* management of resource protection-domains */
|
||||
SET_PAGER = 11,
|
||||
UPDATE_PD = 12,
|
||||
NEW_PD = 13,
|
||||
|
||||
/* interrupt handling */
|
||||
ALLOCATE_IRQ = 14,
|
||||
AWAIT_IRQ = 15,
|
||||
FREE_IRQ = 16,
|
||||
|
||||
/* debugging */
|
||||
PRINT_CHAR = 17,
|
||||
|
||||
/* asynchronous signalling */
|
||||
NEW_SIGNAL_RECEIVER = 20,
|
||||
NEW_SIGNAL_CONTEXT = 21,
|
||||
AWAIT_SIGNAL = 22,
|
||||
SUBMIT_SIGNAL = 23,
|
||||
};
|
||||
|
||||
/**
|
||||
* Virtual range of the mode transition region in every PD
|
||||
*/
|
||||
Genode::addr_t mode_transition_virt_base();
|
||||
Genode::size_t mode_transition_size();
|
||||
|
||||
/**
|
||||
* Get sizes of the kernel objects
|
||||
*/
|
||||
Genode::size_t thread_size();
|
||||
Genode::size_t pd_size();
|
||||
Genode::size_t signal_context_size();
|
||||
Genode::size_t signal_receiver_size();
|
||||
|
||||
/**
|
||||
* Get alignment constraints of the kernel objects
|
||||
*/
|
||||
unsigned kernel_pd_alignm_log2();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new PD
|
||||
*
|
||||
* \param dst physical base of an appropriate portion of memory
|
||||
* that is thereupon allocated to the kernel
|
||||
*
|
||||
* \retval >0 ID of the new PD
|
||||
* \retval 0 if no new PD was created
|
||||
*
|
||||
* Restricted to core threads. Regaining of the supplied memory is not
|
||||
* supported by now.
|
||||
*/
|
||||
inline int new_pd(void * const dst)
|
||||
{ return syscall(NEW_PD, (Syscall_arg)dst); }
|
||||
|
||||
|
||||
/**
|
||||
* Propagate changes in PD configuration
|
||||
*
|
||||
* \param pd_id ID of the PD that has been configured
|
||||
*
|
||||
* It might be, that the kernel and/or the hardware caches parts of PD
|
||||
* configurations such as virtual address translations. This syscall
|
||||
* ensures that the current configuration of the targeted PD gets fully
|
||||
* applied from the moment it returns to the userland. This syscall is
|
||||
* inappropriate in case that a PD wants to change its own configuration.
|
||||
* There's no need for this syscall after a configuration change that
|
||||
* can't affect the kernel and/or hardware caches.
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline void update_pd(unsigned long const pd_id)
|
||||
{ syscall(UPDATE_PD, (Syscall_arg)pd_id); }
|
||||
|
||||
|
||||
/**
|
||||
* Create a new thread that is stopped initially
|
||||
*
|
||||
* \param dst physical base of an appropriate portion of memory
|
||||
* that is thereupon allocated to the kernel
|
||||
* \param pt assigned platform thread
|
||||
*
|
||||
* \retval >0 ID of the new thread
|
||||
* \retval 0 if no new thread was created
|
||||
*
|
||||
* Restricted to core threads. Regaining of the supplied memory is not
|
||||
* supported by now.
|
||||
*/
|
||||
inline int new_thread(void * const dst, Genode::Platform_thread * const pt)
|
||||
{ return syscall(NEW_THREAD, (Syscall_arg)dst, (Syscall_arg)pt); }
|
||||
|
||||
|
||||
/**
|
||||
* Start thread with a given context and let it participate in CPU scheduling
|
||||
*
|
||||
* \param id ID of targeted thread
|
||||
* \param ip initial instruction pointer
|
||||
* \param sp initial stack pointer
|
||||
*
|
||||
* \retval >0 success, return value is the software TLB of the thread
|
||||
* \retval 0 the targeted thread wasn't started or was already started
|
||||
* when this gets called (in both cases it remains untouched)
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline Software_tlb *
|
||||
start_thread(Genode::Platform_thread * const phys_pt, void * ip, void * sp,
|
||||
unsigned int cpu_no)
|
||||
{
|
||||
return (Software_tlb *)syscall(START_THREAD,
|
||||
(Syscall_arg)phys_pt,
|
||||
(Syscall_arg)ip,
|
||||
(Syscall_arg)sp,
|
||||
(Syscall_arg)cpu_no);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prevent thread from participating in CPU scheduling
|
||||
*
|
||||
* \param id ID of the targeted thread. If not set
|
||||
* this will target the current thread.
|
||||
*
|
||||
* \retval 0 syscall was successful
|
||||
* \retval <0 if the targeted thread does not exist or still participates
|
||||
* in CPU scheduling after
|
||||
*
|
||||
* If the caller doesn't target itself, this is restricted to core threads.
|
||||
*/
|
||||
inline int pause_thread(unsigned long const id = 0)
|
||||
{ return syscall(PAUSE_THREAD, id); }
|
||||
|
||||
|
||||
/**
|
||||
* Let an already started thread participate in CPU scheduling
|
||||
*
|
||||
* \param id ID of the targeted thread
|
||||
*
|
||||
* \retval 0 if syscall was successful and thread were paused beforehand
|
||||
* \retval >0 if syscall was successful and thread were already active
|
||||
* \retval <0 if targeted thread doesn't participate in CPU
|
||||
* scheduling after
|
||||
*/
|
||||
inline int resume_thread(unsigned long const id = 0)
|
||||
{ return syscall(RESUME_THREAD, id); }
|
||||
|
||||
|
||||
/**
|
||||
* Let the current thread give up its remaining timeslice
|
||||
*
|
||||
* \param id if this thread ID is set and valid this will resume the
|
||||
* targeted thread additionally
|
||||
*/
|
||||
inline void yield_thread(unsigned long const id = 0)
|
||||
{ syscall(YIELD_THREAD, id); }
|
||||
|
||||
|
||||
/**
|
||||
* Get the thread ID of the current thread
|
||||
*/
|
||||
inline int current_thread_id() { return syscall(CURRENT_THREAD_ID); }
|
||||
|
||||
|
||||
/**
|
||||
* Get platform thread by ID or 0 if target is "core main" or "idle"
|
||||
*
|
||||
* \param id ID of the targeted thread or 0 if caller targets itself
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline Genode::Platform_thread * get_thread(unsigned long const id = 0)
|
||||
{ return (Genode::Platform_thread *)syscall(GET_THREAD, id); }
|
||||
|
||||
|
||||
/**
|
||||
* Send IPC request and wait for reply
|
||||
*
|
||||
* \param id ID of the receiver thread
|
||||
* \param size request size (beginning with the callers UTCB base)
|
||||
*
|
||||
* \return size of received reply (beginning with the callers UTCB base)
|
||||
*
|
||||
* If the receiver exists, this blocks execution until a dedicated reply
|
||||
* message has been send by the receiver. The receiver may never do so.
|
||||
*/
|
||||
inline unsigned long request_and_wait(unsigned long const id,
|
||||
unsigned long const size)
|
||||
{ return (unsigned long)syscall(REQUEST_AND_WAIT, id, size); }
|
||||
|
||||
|
||||
/**
|
||||
* Wait for next IPC request, discard current request
|
||||
*
|
||||
* \return size of received request (beginning with the callers UTCB base)
|
||||
*/
|
||||
inline unsigned long wait_for_request()
|
||||
{ return (unsigned long)syscall(WAIT_FOR_REQUEST); }
|
||||
|
||||
|
||||
/**
|
||||
* Send reply of the last received request and wait for next request
|
||||
*
|
||||
* \param size reply-message size (beginning with the callers UTCB base)
|
||||
*
|
||||
* \return size of received request (beginning with the callers UTCB base)
|
||||
*/
|
||||
inline unsigned long reply_and_wait(unsigned long const size)
|
||||
{ return (unsigned long)syscall(REPLY_AND_WAIT, size); }
|
||||
|
||||
|
||||
/**
|
||||
* Set a thread that gets informed about pagefaults of another thread
|
||||
*
|
||||
* \param pager_id ID of the thread that shall get informed.
|
||||
* Subsequently this thread gets an IPC message,
|
||||
* wich contains an according 'Pagefault' object for
|
||||
* every pagefault the faulter throws.
|
||||
* \param faulter_id ID of the thread that throws the pagefaults
|
||||
* wich shall be notified. After every pagefault this
|
||||
* thread remains paused to be reactivated by
|
||||
* 'resume_thread'.
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline void set_pager(unsigned long const pager_id,
|
||||
unsigned long const faulter_id)
|
||||
{ syscall(SET_PAGER, pager_id, faulter_id); }
|
||||
|
||||
/**
|
||||
* Print a char 'c' to the kernels serial ouput
|
||||
*/
|
||||
inline void print_char(char const c)
|
||||
{ syscall(PRINT_CHAR, (Syscall_arg)c); }
|
||||
|
||||
/**
|
||||
* Allocate an IRQ to the caller if the IRQ is not allocated already
|
||||
*
|
||||
* \param id ID of the targeted IRQ
|
||||
*
|
||||
* \return wether the IRQ has been allocated to this thread or not
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline bool allocate_irq(unsigned long const id)
|
||||
{ return syscall(ALLOCATE_IRQ, (Syscall_arg)id); }
|
||||
|
||||
|
||||
/**
|
||||
* Free an IRQ from allocation if it is allocated by the caller
|
||||
*
|
||||
* \param id ID of the targeted IRQ
|
||||
*
|
||||
* \return wether the IRQ has been freed or not
|
||||
*
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline bool free_irq(unsigned long const id)
|
||||
{ return syscall(FREE_IRQ, (Syscall_arg)id); }
|
||||
|
||||
|
||||
/**
|
||||
* Block caller for the occurence of its IRQ
|
||||
*
|
||||
* Restricted to core threads. Blocks the caller forever
|
||||
* if he has not allocated any IRQ.
|
||||
*/
|
||||
inline void await_irq() { syscall(AWAIT_IRQ); }
|
||||
|
||||
|
||||
/**
|
||||
* Get the current value of a register of a specific CPU context
|
||||
*
|
||||
* \param thread_id ID of the thread that owns the targeted context
|
||||
* \param reg_id platform-specific ID of the targeted register
|
||||
*
|
||||
* Restricted to core threads. One can also read from its own context,
|
||||
* or any thread that is active in the meantime. In these cases
|
||||
* be aware of the fact, that the result reflects the context
|
||||
* state that were backed at the last kernel entry of the thread.
|
||||
*/
|
||||
inline unsigned long read_register(unsigned long const thread_id,
|
||||
unsigned long const reg_id)
|
||||
{
|
||||
return syscall(READ_REGISTER, (Syscall_arg)thread_id,
|
||||
(Syscall_arg)reg_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a value to a register of a specific CPU context
|
||||
*
|
||||
* \param thread_id ID of the thread that owns the targeted context
|
||||
* \param reg_id platform-specific ID of the targeted register
|
||||
* \param value value that shall be written to the register
|
||||
*
|
||||
* Restricted to core threads. One can also write to its own context, or
|
||||
* to that of a thread that is active in the meantime.
|
||||
*/
|
||||
inline void write_register(unsigned long const thread_id,
|
||||
unsigned long const reg_id,
|
||||
unsigned long const value)
|
||||
{
|
||||
syscall(WRITE_REGISTER, (Syscall_arg)thread_id, (Syscall_arg)reg_id,
|
||||
(Syscall_arg)value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a kernel object that acts as receiver for asynchronous signals
|
||||
*
|
||||
* \param dst physical base of an appropriate portion of memory
|
||||
* that is thereupon allocated to the kernel
|
||||
*
|
||||
* \return ID of the new kernel object
|
||||
*
|
||||
* Restricted to core threads. Regaining of the supplied memory is not
|
||||
* supported by now.
|
||||
*/
|
||||
inline unsigned long new_signal_receiver(void * dst)
|
||||
{ return syscall(NEW_SIGNAL_RECEIVER, (Syscall_arg)dst); }
|
||||
|
||||
|
||||
/**
|
||||
* Create a kernel object that acts as a distinct signal type at a receiver
|
||||
*
|
||||
* \param dst physical base of an appropriate portion of memory
|
||||
* that is thereupon allocated to the kernel
|
||||
* \param receiver_id ID of the receiver kernel-object that shall
|
||||
* provide the new signal context
|
||||
* \param imprint Every signal, one receives at the new context,
|
||||
* will hold this imprint. This enables the receiver
|
||||
* to interrelate signals with the context.
|
||||
*
|
||||
* \return ID of the new kernel object
|
||||
*
|
||||
* Core-only syscall. Regaining of the supplied memory is not
|
||||
* supported by now.
|
||||
*/
|
||||
inline unsigned long new_signal_context(void * dst,
|
||||
unsigned long receiver_id,
|
||||
unsigned long imprint)
|
||||
{
|
||||
return syscall(NEW_SIGNAL_CONTEXT, (Syscall_arg)dst,
|
||||
(Syscall_arg)receiver_id, (Syscall_arg)imprint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wait for occurence of at least one signal at any context of a receiver
|
||||
*
|
||||
* \param receiver_id ID of the targeted receiver kernel-object
|
||||
*
|
||||
* When this call returns, an instance of 'Signal' is located at the base
|
||||
* of the callers UTCB. It holds information about wich context was
|
||||
* triggered how often. It is granted that every occurence of a signal is
|
||||
* provided through this function, exactly till it gets delivered through
|
||||
* this function. If multiple threads listen at the same receiver and/or
|
||||
* multiple contexts trigger simultanously there is no assertion about
|
||||
* wich thread receives the 'Signal' instance of wich context.
|
||||
*/
|
||||
inline void await_signal(unsigned long receiver_id)
|
||||
{ syscall(AWAIT_SIGNAL, (Syscall_arg)receiver_id); }
|
||||
|
||||
|
||||
/**
|
||||
* Trigger a specific signal context
|
||||
*
|
||||
* \param context_id ID of the targeted context kernel-object
|
||||
* \param num how often the context shall be triggered by this call
|
||||
*/
|
||||
inline void submit_signal(unsigned long context_id, int num)
|
||||
{ syscall(SUBMIT_SIGNAL, (Syscall_arg)context_id, (Syscall_arg)num); }
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__KERNEL__SYSCALLS_H_ */
|
||||
|
43
base-hw/include/pl011/drivers/serial_log.h
Normal file
43
base-hw/include/pl011/drivers/serial_log.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* \brief Serial output driver specific for the ARM PL011
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PL011__DRIVERS__SERIAL_LOG_H_
|
||||
#define _INCLUDE__PL011__DRIVERS__SERIAL_LOG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board.h>
|
||||
#include <drivers/uart/pl011_base.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Serial output driver specific for the ARM PL011
|
||||
*/
|
||||
class Serial_log : public Pl011_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param baud_rate targeted transfer baud-rate
|
||||
*/
|
||||
Serial_log(unsigned const baud_rate) :
|
||||
Pl011_base(Board::LOG_PL011_MMIO_BASE,
|
||||
Board::LOG_PL011_CLOCK, baud_rate)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__PL011__DRIVERS__SERIAL_LOG_H_ */
|
||||
|
37
base-hw/include/platform/panda_a2/drivers/board.h
Normal file
37
base-hw/include/platform/panda_a2/drivers/board.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* \brief Motherboard driver specific for the PandaBoard A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-03-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__PANDA_A2__DRIVERS__BOARD_H_
|
||||
#define _INCLUDE__PLATFORM__PANDA_A2__DRIVERS__BOARD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/panda_a2.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provide specific board driver
|
||||
*/
|
||||
class Board : public Panda_a2
|
||||
{
|
||||
public:
|
||||
|
||||
enum {
|
||||
LOG_TL16C750_MMIO_BASE = TL16C750_3_MMIO_BASE,
|
||||
LOG_TL16C750_CLOCK = TL16C750_3_CLOCK,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__PANDA_A2__DRIVERS__BOARD_H_ */
|
||||
|
38
base-hw/include/platform/pbxa9/drivers/board.h
Normal file
38
base-hw/include/platform/pbxa9/drivers/board.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* \brief Motherboard driver specific for the Realview PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2011-11-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__PBXA9__DRIVERS__BOARD_H_
|
||||
#define _INCLUDE__PLATFORM__PBXA9__DRIVERS__BOARD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/pbxa9.h>
|
||||
#include <base/native_types.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provide specific board driver
|
||||
*/
|
||||
class Board : public Pbxa9
|
||||
{
|
||||
public:
|
||||
|
||||
enum {
|
||||
LOG_PL011_MMIO_BASE = PL011_0_MMIO_BASE,
|
||||
LOG_PL011_CLOCK = PL011_0_CLOCK,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__PBXA9__DRIVERS__BOARD_H_ */
|
||||
|
37
base-hw/include/platform/vea9x4/drivers/board.h
Normal file
37
base-hw/include/platform/vea9x4/drivers/board.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* \brief Provide specific board driver
|
||||
* \author Martin Stein
|
||||
* \date 2011-11-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__VEA9X4__DRIVERS__BOARD_H_
|
||||
#define _INCLUDE__PLATFORM__VEA9X4__DRIVERS__BOARD_H_
|
||||
|
||||
/* Genode inlcudes */
|
||||
#include <drivers/board/vea9x4.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provide specific board driver
|
||||
*/
|
||||
class Board : public Vea9x4
|
||||
{
|
||||
public:
|
||||
|
||||
enum {
|
||||
LOG_PL011_MMIO_BASE = PL011_0_MMIO_BASE,
|
||||
LOG_PL011_CLOCK = PL011_0_CLOCK,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__VEA9X4__DRIVERS__BOARD_H_ */
|
||||
|
51
base-hw/include/signal_session/client.h
Normal file
51
base-hw/include/signal_session/client.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Client-side implementation of the signal session interface
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__SIGNAL_SESSION__CLIENT_H_
|
||||
#define _INCLUDE__SIGNAL_SESSION__CLIENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <signal_session/capability.h>
|
||||
#include <signal_session/signal_session.h>
|
||||
#include <base/rpc_client.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Client-side implementation of the signal session interface
|
||||
*/
|
||||
struct Signal_session_client : Rpc_client<Signal_session>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param s targeted signal session
|
||||
*/
|
||||
explicit Signal_session_client(Signal_session_capability const s)
|
||||
: Rpc_client<Signal_session>(s) { }
|
||||
|
||||
/******************************
|
||||
** Signal_session interface **
|
||||
******************************/
|
||||
|
||||
Signal_receiver_capability alloc_receiver()
|
||||
{ return call<Rpc_alloc_receiver>(); }
|
||||
|
||||
Signal_context_capability
|
||||
alloc_context(Signal_receiver_capability const r,
|
||||
unsigned long const imprint)
|
||||
{ return call<Rpc_alloc_context>(r, imprint); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__SIGNAL_SESSION__CLIENT_H_ */
|
96
base-hw/include/signal_session/signal_session.h
Normal file
96
base-hw/include/signal_session/signal_session.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* \brief Signal session interface
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_
|
||||
#define _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/capability.h>
|
||||
#include <base/exception.h>
|
||||
#include <session/session.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Signal_receiver;
|
||||
class Signal_context;
|
||||
|
||||
/*
|
||||
* The 'dst' of this cap is used to communicate the ID of the
|
||||
* corresponding signal-receiver kernel-object or 0 if the cap is invalid.
|
||||
*/
|
||||
typedef Capability<Signal_receiver> Signal_receiver_capability;
|
||||
|
||||
/*
|
||||
* The 'dst' of this cap is used to communicate the ID of the
|
||||
* corresponding signal-context kernel-object or 0 if the cap is invalid.
|
||||
*/
|
||||
typedef Capability<Signal_context> Signal_context_capability;
|
||||
|
||||
/**
|
||||
* Signal session interface
|
||||
*/
|
||||
struct Signal_session : Session
|
||||
{
|
||||
class Out_of_metadata : public Exception { };
|
||||
|
||||
/**
|
||||
* String that can be used to refer to this service
|
||||
*/
|
||||
static const char * service_name() { return "SIGNAL"; }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Signal_session() { }
|
||||
|
||||
/**
|
||||
* Create a new signal-receiver kernel-object
|
||||
*
|
||||
* \return a cap that acts as reference to the created object
|
||||
*
|
||||
* \throw Out_of_metadata
|
||||
*/
|
||||
virtual Signal_receiver_capability alloc_receiver() = 0;
|
||||
|
||||
/**
|
||||
* Create a new signal-context kernel-object
|
||||
*
|
||||
* \param r names the signal receiver that shall provide
|
||||
* the new context
|
||||
* \param imprint every signal that occures on the new context gets
|
||||
* signed with this value
|
||||
*
|
||||
* \return a cap that acts as reference to the created object
|
||||
*
|
||||
* \throw Out_of_metadata
|
||||
*/
|
||||
virtual Signal_context_capability
|
||||
alloc_context(Signal_receiver_capability const r,
|
||||
unsigned long const imprint) = 0;
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
*********************/
|
||||
|
||||
GENODE_RPC_THROW(Rpc_alloc_receiver, Signal_receiver_capability,
|
||||
alloc_receiver, GENODE_TYPE_LIST(Out_of_metadata));
|
||||
GENODE_RPC_THROW(Rpc_alloc_context, Signal_context_capability,
|
||||
alloc_context, GENODE_TYPE_LIST(Out_of_metadata),
|
||||
Signal_receiver_capability, unsigned long);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_alloc_receiver, Rpc_alloc_context);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ */
|
||||
|
43
base-hw/include/tl16c750/drivers/serial_log.h
Normal file
43
base-hw/include/tl16c750/drivers/serial_log.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* \brief Serial output driver specific for the Texas Instruments TL16C750
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__TL16C750__DRIVERS__SERIAL_LOG_H_
|
||||
#define _INCLUDE__TL16C750__DRIVERS__SERIAL_LOG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board.h>
|
||||
#include <drivers/uart/tl16c750_base.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Serial output driver specific for the Texas Instruments TL16C750
|
||||
*/
|
||||
class Serial_log : public Tl16c750_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param baud_rate targeted transfer baud-rate
|
||||
*/
|
||||
Serial_log(unsigned const baud_rate) :
|
||||
Tl16c750_base(Board::LOG_TL16C750_MMIO_BASE,
|
||||
Board::LOG_TL16C750_CLOCK, baud_rate)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__TL16C750__DRIVERS__SERIAL_LOG_H_ */
|
||||
|
22
base-hw/lib/mk/arm_v7a/startup.mk
Executable file
22
base-hw/lib/mk/arm_v7a/startup.mk
Executable file
@ -0,0 +1,22 @@
|
||||
#
|
||||
# \brief Essential platform specific sources for common programs
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# add libraries
|
||||
LIBS += cxx lock
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += _main.cc
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += crt0.s syscall.cc
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/platform $(BASE_DIR)/src/platform
|
||||
|
||||
# declare source paths
|
||||
vpath crt0.s $(REP_DIR)/src/platform
|
||||
vpath _main.cc $(BASE_DIR)/src/platform
|
||||
vpath syscall.cc $(REP_DIR)/src/base/arm_v7a
|
29
base-hw/lib/mk/arm_v7a/startup_core.mk
Normal file
29
base-hw/lib/mk/arm_v7a/startup_core.mk
Normal file
@ -0,0 +1,29 @@
|
||||
#
|
||||
# \brief Essential platform specific sources for core
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# Aad C++ sources
|
||||
SRC_CC += syscall.cc
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += crt0.s mode_transition.s boot_modules.s
|
||||
|
||||
# add inlucde paths
|
||||
INC_DIR += $(BASE_DIR)/src/core/include/
|
||||
|
||||
#
|
||||
# Check if there are other images wich shall be linked to core.
|
||||
# If not use a dummy boot-modules file wich includes only the symbols.
|
||||
#
|
||||
ifeq ($(wildcard $(BUILD_BASE_DIR)/boot_modules.s),)
|
||||
vpath boot_modules.s $(REP_DIR)/src/core/arm_v7a
|
||||
else
|
||||
INC_DIR += $(BUILD_BASE_DIR)
|
||||
vpath boot_modules.s $(BUILD_BASE_DIR)
|
||||
endif
|
||||
|
||||
# declare remaining source paths
|
||||
vpath syscall.cc $(REP_DIR)/src/base/arm_v7a
|
||||
vpath % $(REP_DIR)/src/core/arm_v7a
|
20
base-hw/lib/mk/core_support.inc
Normal file
20
base-hw/lib/mk/core_support.inc
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# \brief Generic parts of the core-support lib
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-27
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(BOARD_DIR) $(REP_DIR)/src/core/include $(REP_DIR)/include \
|
||||
$(BASE_DIR)/src/core/include $(BASE_DIR)/include
|
||||
|
||||
# set entry point of core's first thread
|
||||
CC_OPT += -DCORE_MAIN=_main
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += platform_support.cc kernel.cc rm_session_support.cc
|
||||
|
||||
# declare source paths
|
||||
vpath platform_support.cc $(BOARD_DIR)
|
||||
vpath % $(REP_DIR)/src/core
|
||||
|
12
base-hw/lib/mk/ipc.mk
Normal file
12
base-hw/lib/mk/ipc.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# \brief Interprocess communication
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# add library dependencies
|
||||
LIBS += thread
|
||||
|
||||
# include implied libraries
|
||||
include $(REP_DIR)/lib/mk/raw_ipc.mk
|
||||
|
14
base-hw/lib/mk/lock.mk
Normal file
14
base-hw/lib/mk/lock.mk
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# \brief Synchronisation through locks
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += lock.cc
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
|
||||
# declare source paths
|
||||
vpath % $(BASE_DIR)/src/base/lock
|
11
base-hw/lib/mk/pager.mk
Normal file
11
base-hw/lib/mk/pager.mk
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# \brief Genode pager threads
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += pager.cc
|
||||
|
||||
# declare source paths
|
||||
vpath % $(REP_DIR)/src/base
|
12
base-hw/lib/mk/platform_panda_a2/core_support.mk
Normal file
12
base-hw/lib/mk/platform_panda_a2/core_support.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# \brief Parts of core that depend on the PandaBoard A2
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-27
|
||||
#
|
||||
|
||||
# declare location of core files that are board specific
|
||||
BOARD_DIR = $(REP_DIR)/src/core/panda_a2
|
||||
|
||||
# include generic parts of core support
|
||||
include $(REP_DIR)/lib/mk/core_support.inc
|
||||
|
16
base-hw/lib/mk/platform_panda_a2/platform_support.mk
Normal file
16
base-hw/lib/mk/platform_panda_a2/platform_support.mk
Normal file
@ -0,0 +1,16 @@
|
||||
#
|
||||
# \brief Platform implementations specific for base-hw and Panda A2
|
||||
# \author Martin Stein
|
||||
# \date 2012-05-10
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(BASE_DIR)/src/core/include
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += platform_support.cc
|
||||
|
||||
# declare source paths
|
||||
vpath % $(REP_DIR)/src/core/panda_a2
|
||||
|
12
base-hw/lib/mk/platform_pbxa9/core_support.mk
Normal file
12
base-hw/lib/mk/platform_pbxa9/core_support.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# \brief Parts of core that depend on the Realview PBXA9
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-27
|
||||
#
|
||||
|
||||
# declare location of core files that are board specific
|
||||
BOARD_DIR = $(REP_DIR)/src/core/pbxa9
|
||||
|
||||
# include generic part of core support
|
||||
include $(REP_DIR)/lib/mk/core_support.inc
|
||||
|
12
base-hw/lib/mk/platform_vea9x4/core_support.mk
Normal file
12
base-hw/lib/mk/platform_vea9x4/core_support.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# \brief Parts of core that depend on the Versatile VEA9X4
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-27
|
||||
#
|
||||
|
||||
# declare location of core files that are board specific
|
||||
BOARD_DIR = $(REP_DIR)/src/core/vea9x4
|
||||
|
||||
# include generic part of core support
|
||||
include $(REP_DIR)/lib/mk/core_support.inc
|
||||
|
11
base-hw/lib/mk/raw_ipc.mk
Normal file
11
base-hw/lib/mk/raw_ipc.mk
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# \brief Interprocess communication without thread implementations
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# add C++ source files
|
||||
SRC_CC += ipc.cc
|
||||
|
||||
# declare source paths
|
||||
vpath % $(REP_DIR)/src/base
|
15
base-hw/lib/mk/raw_signal.mk
Normal file
15
base-hw/lib/mk/raw_signal.mk
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# \brief Submit and receive asynchronous events
|
||||
# \author Martin Stein
|
||||
# \date 2012-05-07
|
||||
#
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += signal.cc
|
||||
|
||||
# add library dependencies
|
||||
LIBS += slab
|
||||
|
||||
# declare source paths
|
||||
vpath % $(REP_DIR)/src/base/signal
|
||||
|
9
base-hw/lib/mk/signal.mk
Normal file
9
base-hw/lib/mk/signal.mk
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# \brief Shortcut for raw-signal lib to ensure Genode compliance
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# include implied libraries
|
||||
include $(REP_DIR)/lib/mk/raw_signal.mk
|
||||
|
12
base-hw/lib/mk/thread.mk
Normal file
12
base-hw/lib/mk/thread.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# \brief Implementation of the Genode thread-API
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += thread.cc thread_bootstrap.cc thread_support.cc
|
||||
|
||||
# declare source paths
|
||||
vpath thread_support.cc $(REP_DIR)/src/base/
|
||||
vpath % $(BASE_DIR)/src/base/thread/
|
12
base-hw/mk/spec-hw.mk
Normal file
12
base-hw/mk/spec-hw.mk
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-16
|
||||
#
|
||||
|
||||
#
|
||||
# Denote library that brings the setup sequence for C++ enviroment.
|
||||
# Also add an according dependency.
|
||||
#
|
||||
STARTUP_LIB ?= startup
|
||||
PRG_LIBS += $(STARTUP_LIB)
|
15
base-hw/mk/spec-hw_panda_a2.mk
Normal file
15
base-hw/mk/spec-hw_panda_a2.mk
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw and Pandaboard A2
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-20
|
||||
#
|
||||
|
||||
# denote wich specs are also fullfilled by this spec
|
||||
SPECS += hw platform_panda_a2
|
||||
|
||||
# set address where to link the text segment at
|
||||
LD_TEXT_ADDR ?= 0x80000000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
include $(call select_from_repositories,mk/spec-platform_panda_a2.mk)
|
15
base-hw/mk/spec-hw_pbxa9.mk
Normal file
15
base-hw/mk/spec-hw_pbxa9.mk
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw and PBXA9
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-20
|
||||
#
|
||||
|
||||
# denote wich specs are also fullfilled by this spec
|
||||
SPECS += hw platform_pbxa9
|
||||
|
||||
# set address where to link text segment at
|
||||
LD_TEXT_ADDR ?= 0x01000000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
include $(call select_from_repositories,mk/spec-platform_pbxa9.mk)
|
15
base-hw/mk/spec-hw_vea9x4.mk
Normal file
15
base-hw/mk/spec-hw_vea9x4.mk
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw and VEA9X4
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-20
|
||||
#
|
||||
|
||||
# denote wich specs are also fullfilled by this spec
|
||||
SPECS += hw platform_vea9x4
|
||||
|
||||
# set address where to link text segment at
|
||||
LD_TEXT_ADDR ?= 0x01000000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
include $(call select_from_repositories,mk/spec-platform_vea9x4.mk)
|
229
base-hw/run/env
Normal file
229
base-hw/run/env
Normal file
@ -0,0 +1,229 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
#
|
||||
# \brief Implementation of the interface provided by 'tool/run'
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-16
|
||||
#
|
||||
|
||||
|
||||
######################
|
||||
## Utility routines ##
|
||||
######################
|
||||
|
||||
#
|
||||
# Build an assembly file that enables the creation of a single boot image
|
||||
#
|
||||
# \param file targeted file
|
||||
# \parem binaries targeted boot modules, must reside in '[run_dir]/genode/'
|
||||
#
|
||||
# This file rawly includes all binaries given in
|
||||
# 'binaries', minus 'core' if given, plus 'config' if available. It also
|
||||
# provides a simple file system that enables Genode to access these BLOBs.
|
||||
#
|
||||
proc boot_modules_arm_v7a {{file} {binaries}} {
|
||||
|
||||
set load_store_alignm 0x3
|
||||
set min_page_alignm 12
|
||||
|
||||
# introduce boot module headers
|
||||
exec echo -e \
|
||||
"/**" \
|
||||
"\n * This file was automatically generated by the procedure" \
|
||||
"\n * 'boot_modules_arm_v7a' in 'run/env'." \
|
||||
"\n */" \
|
||||
"\n" \
|
||||
"\n.section .data" \
|
||||
"\n" \
|
||||
"\n.align ${load_store_alignm}" \
|
||||
"\n.global _boot_modules_begin" \
|
||||
"\n_boot_modules_begin:" \
|
||||
"\n.string \"GROM\"" \
|
||||
"\n" \
|
||||
"\n.align ${load_store_alignm}" \
|
||||
"\n.global _boot_module_headers_begin" \
|
||||
"\n_boot_module_headers_begin:" > $file
|
||||
|
||||
# generate header for each boot module except core
|
||||
set i 1
|
||||
foreach binary $binaries {
|
||||
if {$binary == "core"} { continue }
|
||||
exec echo -e \
|
||||
"\n.long mod${i}_name" \
|
||||
"\n.long mod${i}_start" \
|
||||
"\n.long mod${i}_end - mod${i}_start" >> $file
|
||||
incr i
|
||||
}
|
||||
|
||||
# end boot module headers
|
||||
exec echo -e \
|
||||
"\n.global _boot_module_headers_end" \
|
||||
"\n_boot_module_headers_end:" \
|
||||
"\n" >> $file
|
||||
|
||||
# generate name string for each module except core
|
||||
set i 1
|
||||
foreach binary $binaries {
|
||||
if {$binary == "core"} { continue }
|
||||
exec echo -e \
|
||||
".align ${load_store_alignm}" \
|
||||
"\nmod${i}_name:" \
|
||||
"\n.string \"${binary}\"" \
|
||||
"\n.byte 0" \
|
||||
"\n" >> $file
|
||||
incr i
|
||||
}
|
||||
|
||||
# include raw data of modules consecutively but page aligned
|
||||
set i 1
|
||||
foreach binary $binaries {
|
||||
if {$binary == "core"} { continue }
|
||||
exec echo -e \
|
||||
".align ${min_page_alignm}" \
|
||||
"\nmod${i}_start:" \
|
||||
"\n.incbin \"[run_dir]/genode/${binary}\"" \
|
||||
"\nmod${i}_end:" \
|
||||
"\n" >> $file
|
||||
incr i
|
||||
}
|
||||
|
||||
# end boot-modules file
|
||||
exec echo -e \
|
||||
".global _boot_modules_end" \
|
||||
"\n_boot_modules_end:" >> $file
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Ensure that the next Genode build includes no target specific boot modules
|
||||
#
|
||||
proc disable_specific_boot_modules { } {
|
||||
|
||||
exec rm -rf boot_modules.s
|
||||
exec rm -rf var/libcache/boot_modules/boot_modules.o
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Ensure that the next Genode build includes target specific boot modules
|
||||
#
|
||||
proc enable_specific_boot_modules {file} {
|
||||
|
||||
exec rm -rf boot_modules.s
|
||||
exec ln -s $file boot_modules.s
|
||||
exec rm -rf var/libcache/boot_modules/boot_modules.o
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Apply the boot modules file 'file' to the core image
|
||||
#
|
||||
proc apply_boot_modules_to_core {file} {
|
||||
|
||||
# recompile 'core', with specific boot modules
|
||||
puts "Building single boot image"
|
||||
set timeout 10000
|
||||
enable_specific_boot_modules $file
|
||||
set pid [eval "spawn make core"]
|
||||
expect { eof { } }
|
||||
if {[lindex [wait $pid] end] != 0} {
|
||||
puts "Error: Genode build failed"
|
||||
exit -4
|
||||
}
|
||||
|
||||
# clean up for subsequent builds
|
||||
disable_specific_boot_modules
|
||||
puts "Single boot image built"
|
||||
}
|
||||
|
||||
|
||||
######################################
|
||||
## Interface supplied by 'tool/run' ##
|
||||
######################################
|
||||
|
||||
proc build {targets} {
|
||||
|
||||
# skip targets that shall not be build
|
||||
if {[get_cmd_switch --skip-build]} return
|
||||
|
||||
# handle false remnants of previous builds
|
||||
disable_specific_boot_modules
|
||||
|
||||
#
|
||||
# Build all remaining targets.
|
||||
# Core is build with a dummy boot-modules file first.
|
||||
#
|
||||
regsub -all {\s\s+} $targets " " targets
|
||||
puts "building targets: $targets"
|
||||
set timeout 10000
|
||||
set pid [eval "spawn make $targets"]
|
||||
expect { eof { } }
|
||||
if {[lindex [wait $pid] end] != 0} {
|
||||
puts "Error: Genode build failed"
|
||||
exit -4
|
||||
}
|
||||
puts "genode build completed"
|
||||
}
|
||||
|
||||
|
||||
proc install_config {config} {
|
||||
|
||||
set fh [open "bin/config" "WRONLY CREAT TRUNC"]
|
||||
puts $fh $config
|
||||
close $fh
|
||||
}
|
||||
|
||||
|
||||
proc create_boot_directory { } {
|
||||
|
||||
exec rm -rf [run_dir]
|
||||
exec mkdir -p [run_dir]/genode
|
||||
}
|
||||
|
||||
|
||||
proc build_boot_image {binaries} {
|
||||
|
||||
# create additional stripped version of any binary
|
||||
copy_and_strip_genode_binaries_to_run_dir $binaries
|
||||
|
||||
# append init configuration if existent to the binaries
|
||||
if {[file exists "bin/config"] == 1} {
|
||||
exec cp bin/config [run_dir]/genode
|
||||
append binaries " config"
|
||||
}
|
||||
|
||||
# create scenario-specific 'boot_modules.s' of all given binaries
|
||||
set boot_modules "[run_dir]/boot_modules.s"
|
||||
if { [have_spec {arm_v7a}] } {
|
||||
boot_modules_arm_v7a $boot_modules $binaries
|
||||
}
|
||||
|
||||
# preserve stand-alone core for debugging
|
||||
exec mv core/core core/core.standalone
|
||||
|
||||
# apply the new 'boot_modules.s' to 'core' to create single boot image
|
||||
apply_boot_modules_to_core $boot_modules
|
||||
exec mv core/core [run_dir]/image.elf
|
||||
exec [cross_dev_prefix]strip [run_dir]/image.elf
|
||||
|
||||
# remove stripped binaries and retrieve stand-alone core
|
||||
exec mv core/core.standalone core/core
|
||||
exec rm -r [run_dir]/genode
|
||||
}
|
||||
|
||||
|
||||
proc run_genode_until {{wait_for_re forever} {timeout_value 0}} {
|
||||
|
||||
# get the targeted method of execution, the default is 'qemu'
|
||||
set image [run_dir]/image.elf
|
||||
set target [get_cmd_arg --target "qemu"]
|
||||
|
||||
# try to execute image according to the targeted method of execution
|
||||
if { $target == "qemu" } {
|
||||
spawn_qemu $wait_for_re $timeout_value
|
||||
} else {
|
||||
puts stderr "Error: Target '${target}' is not supported"
|
||||
puts stderr " Supported targets are: 'qemu'"; exit -3
|
||||
}
|
||||
}
|
||||
|
75
base-hw/run/nested_init.run
Normal file
75
base-hw/run/nested_init.run
Normal file
@ -0,0 +1,75 @@
|
||||
#
|
||||
# \brief Test genode basics by starting init instances in a nested manner
|
||||
# \author Martin Stein
|
||||
# \date 2012-05-30
|
||||
#
|
||||
|
||||
# build program images
|
||||
build "core init"
|
||||
|
||||
# create directory where the boot files are written to
|
||||
create_boot_directory
|
||||
|
||||
# create XML configuration for init
|
||||
install_config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route><any-service><parent/></any-service></default-route>
|
||||
|
||||
<start name="init">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route><any-service><parent/></any-service></default-route>
|
||||
|
||||
<start name="init">
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service><parent/></any-service>
|
||||
</default-route>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
}
|
||||
|
||||
# create single boot image from the compiled program images
|
||||
build_boot_image "core init"
|
||||
|
||||
# configure qemu to use 64 MB RAM and avoid GUI mode
|
||||
append qemu_args " -m 64 -nographic"
|
||||
|
||||
# execute the test in qemu if the targeted platform is supported
|
||||
if {[have_spec hw_vea9x4] || [have_spec hw_pbxa9]} {
|
||||
run_genode_until "No children to start.*\n" 10
|
||||
}
|
||||
|
160
base-hw/src/base/arm_v7a/syscall.cc
Normal file
160
base-hw/src/base/arm_v7a/syscall.cc
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* \brief Syscall-framework implementation for ARM V7A systems
|
||||
* \author Martin stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/syscall.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
/******************************************************************
|
||||
** Inline assembly templates for syscalls with 1 to 6 arguments **
|
||||
******************************************************************/
|
||||
|
||||
#define SYSCALL_6_ASM_OPS \
|
||||
"mov r5, #0 \n" \
|
||||
"add r5, %[arg_5] \n" \
|
||||
SYSCALL_5_ASM_OPS
|
||||
|
||||
#define SYSCALL_5_ASM_OPS \
|
||||
"mov r4, #0 \n" \
|
||||
"add r4, %[arg_4] \n" \
|
||||
SYSCALL_4_ASM_OPS
|
||||
|
||||
#define SYSCALL_4_ASM_OPS \
|
||||
"mov r3, #0 \n" \
|
||||
"add r3, %[arg_3] \n" \
|
||||
SYSCALL_3_ASM_OPS
|
||||
|
||||
#define SYSCALL_3_ASM_OPS \
|
||||
"mov r2, #0 \n" \
|
||||
"add r2, %[arg_2] \n" \
|
||||
SYSCALL_2_ASM_OPS
|
||||
|
||||
#define SYSCALL_2_ASM_OPS \
|
||||
"mov r1, #0 \n" \
|
||||
"add r1, %[arg_1] \n" \
|
||||
SYSCALL_1_ASM_OPS
|
||||
|
||||
#define SYSCALL_1_ASM_OPS \
|
||||
"mov r0, #0 \n" \
|
||||
"add r0, %[arg_0] \n" \
|
||||
"svc 0x0 \n" \
|
||||
"mov %[result], #0 \n" \
|
||||
"add %[result], r0 "
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Inline assembly "writeable" template-args for syscalls with 1 to 6 args **
|
||||
*****************************************************************************/
|
||||
|
||||
#define SYSCALL_6_ASM_WRITE [arg_5] "+r" (arg_5), SYSCALL_5_ASM_WRITE
|
||||
#define SYSCALL_5_ASM_WRITE [arg_4] "+r" (arg_4), SYSCALL_4_ASM_WRITE
|
||||
#define SYSCALL_4_ASM_WRITE [arg_3] "+r" (arg_3), SYSCALL_3_ASM_WRITE
|
||||
#define SYSCALL_3_ASM_WRITE [arg_2] "+r" (arg_2), SYSCALL_2_ASM_WRITE
|
||||
#define SYSCALL_2_ASM_WRITE [arg_1] "+r" (arg_1), SYSCALL_1_ASM_WRITE
|
||||
#define SYSCALL_1_ASM_WRITE \
|
||||
[arg_0] "+r" (arg_0), \
|
||||
[result] "+r" (result)
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
** Inline assembly clobber lists for syscalls with 1 to 6 arguments **
|
||||
**********************************************************************/
|
||||
|
||||
#define SYSCALL_6_ASM_CLOBBER "r5", SYSCALL_5_ASM_CLOBBER
|
||||
#define SYSCALL_5_ASM_CLOBBER "r4", SYSCALL_4_ASM_CLOBBER
|
||||
#define SYSCALL_4_ASM_CLOBBER "r3", SYSCALL_3_ASM_CLOBBER
|
||||
#define SYSCALL_3_ASM_CLOBBER "r2", SYSCALL_2_ASM_CLOBBER
|
||||
#define SYSCALL_2_ASM_CLOBBER "r1", SYSCALL_1_ASM_CLOBBER
|
||||
#define SYSCALL_1_ASM_CLOBBER "r0"
|
||||
|
||||
|
||||
/************************************
|
||||
** Syscalls with 1 to 6 arguments **
|
||||
************************************/
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_1_ASM_OPS
|
||||
: SYSCALL_1_ASM_WRITE
|
||||
:: SYSCALL_1_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_2_ASM_OPS
|
||||
: SYSCALL_2_ASM_WRITE
|
||||
:: SYSCALL_2_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_3_ASM_OPS
|
||||
: SYSCALL_3_ASM_WRITE
|
||||
:: SYSCALL_3_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_4_ASM_OPS
|
||||
: SYSCALL_4_ASM_WRITE
|
||||
:: SYSCALL_4_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3,
|
||||
Syscall_arg arg_4)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_5_ASM_OPS
|
||||
: SYSCALL_5_ASM_WRITE
|
||||
:: SYSCALL_5_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Syscall_ret Kernel::syscall(Syscall_arg arg_0,
|
||||
Syscall_arg arg_1,
|
||||
Syscall_arg arg_2,
|
||||
Syscall_arg arg_3,
|
||||
Syscall_arg arg_4,
|
||||
Syscall_arg arg_5)
|
||||
{
|
||||
Syscall_ret result = 0;
|
||||
asm volatile(SYSCALL_6_ASM_OPS
|
||||
: SYSCALL_6_ASM_WRITE
|
||||
:: SYSCALL_6_ASM_CLOBBER);
|
||||
return result;
|
||||
}
|
||||
|
73
base-hw/src/base/console.cc
Normal file
73
base-hw/src/base/console.cc
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* \brief Genode-console backend
|
||||
* \author Martin Stein
|
||||
* \date 2011-10-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/console.h>
|
||||
#include <base/printf.h>
|
||||
#include <drivers/serial_log.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Platform specific Genode console
|
||||
*/
|
||||
class Platform_console : public Console,
|
||||
public Serial_log
|
||||
{
|
||||
enum { BAUD_RATE = 115200 };
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Print a char to the console
|
||||
*/
|
||||
void _out_char(char c) { Serial_log::put_char(c); }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_console() : Serial_log(BAUD_RATE) { }
|
||||
};
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Static object to print log output
|
||||
*/
|
||||
static Platform_console * platform_console()
|
||||
{
|
||||
static Platform_console static_platform_console;
|
||||
return &static_platform_console;
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
** Genode print functions **
|
||||
****************************/
|
||||
|
||||
void Genode::printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
platform_console()->vprintf(format, list);
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
|
||||
void Genode::vprintf(const char *format, va_list list)
|
||||
{ platform_console()->vprintf(format, list); }
|
||||
|
220
base-hw/src/base/ipc.cc
Normal file
220
base-hw/src/base/ipc.cc
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* \brief Implementation of the Genode IPC-framework
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/ipc.h>
|
||||
#include <base/thread.h>
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum
|
||||
{
|
||||
/* size of the callee-local name of a targeted RPC object */
|
||||
RPC_OBJECT_ID_SIZE = sizeof(umword_t),
|
||||
|
||||
/*
|
||||
* The RPC framework marshalls a return value into reply messages to
|
||||
* deliver exceptions, wich occured during the RPC call to the caller.
|
||||
* This defines the size of this value.
|
||||
*/
|
||||
RPC_RETURN_VALUE_SIZE = sizeof(umword_t),
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
|
||||
/**
|
||||
* Translate byte size 's' to size in words
|
||||
*/
|
||||
static unsigned long size_in_words(unsigned long const s)
|
||||
{ return (s + sizeof(unsigned long) - 1) / sizeof(unsigned long); }
|
||||
|
||||
|
||||
/**
|
||||
* Copy message payload to message buffer
|
||||
*/
|
||||
static void copy_utcb_to_msgbuf(Msgbuf_base * const receive_buffer,
|
||||
unsigned long const message_size)
|
||||
{
|
||||
/* log data that is received via IPC */
|
||||
enum { VERBOSE = 0 };
|
||||
|
||||
/* get pointers and message attributes */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
unsigned long * const msgbuf = (unsigned long *)receive_buffer->buf;
|
||||
unsigned long const message_wsize = size_in_words(message_size);
|
||||
|
||||
/* assertions, avoid 'printf' in here, it may lead to infinite recursion */
|
||||
if (message_wsize > size_in_words(utcb->size()))
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Oversized message\n";
|
||||
while (1) ;
|
||||
}
|
||||
/* fill message buffer with message */
|
||||
for (unsigned i=0; i < message_wsize; i++)
|
||||
msgbuf[i] = *utcb->word(i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy message payload to the UTCB
|
||||
*/
|
||||
static void copy_msgbuf_to_utcb(Msgbuf_base * const send_buffer,
|
||||
unsigned long const message_size,
|
||||
unsigned long const local_name)
|
||||
{
|
||||
/* log data that is send via IPC */
|
||||
enum { VERBOSE = 0 };
|
||||
|
||||
/* get pointers and message attributes */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
unsigned long * const msgbuf = (unsigned long *)send_buffer->buf;
|
||||
unsigned long const message_wsize = size_in_words(message_size);
|
||||
|
||||
/* assertions, avoid 'printf' in here, it may lead to infinite recursion */
|
||||
if (message_wsize > size_in_words(utcb->size()))
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Oversized message\n";
|
||||
while (1) ;
|
||||
}
|
||||
/* address message to an object that the targeted thread knows */
|
||||
*utcb->word(0) = local_name;
|
||||
|
||||
/* write message payload */
|
||||
for (unsigned long i = 1; i < message_wsize; i++)
|
||||
*utcb->word(i) = msgbuf[i];
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_ostream **
|
||||
*****************/
|
||||
|
||||
Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg)
|
||||
:
|
||||
Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()),
|
||||
_snd_msg(snd_msg), _dst(dst)
|
||||
{
|
||||
_write_offset = RPC_OBJECT_ID_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_istream **
|
||||
*****************/
|
||||
|
||||
void Ipc_istream::_wait()
|
||||
{
|
||||
/* FIXME this shall be not supported */
|
||||
Kernel::pause_thread();
|
||||
}
|
||||
|
||||
|
||||
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
|
||||
:
|
||||
Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()),
|
||||
Native_capability(Genode::thread_get_my_native_id(), 0),
|
||||
_rcv_msg(rcv_msg), _rcv_cs(-1)
|
||||
{ _read_offset = RPC_OBJECT_ID_SIZE; }
|
||||
|
||||
|
||||
Ipc_istream::~Ipc_istream() { }
|
||||
|
||||
|
||||
/****************
|
||||
** Ipc_client **
|
||||
****************/
|
||||
|
||||
void Ipc_client::_call()
|
||||
{
|
||||
using namespace Kernel;
|
||||
|
||||
/* send request and receive reply */
|
||||
copy_msgbuf_to_utcb(_snd_msg, _write_offset,
|
||||
Ipc_ostream::_dst.local_name());
|
||||
size_t const s = request_and_wait(Ipc_ostream::_dst.dst(), _write_offset);
|
||||
copy_utcb_to_msgbuf(_rcv_msg, s);
|
||||
|
||||
/* reset unmarshaller */
|
||||
_write_offset = _read_offset = RPC_OBJECT_ID_SIZE;
|
||||
}
|
||||
|
||||
|
||||
Ipc_client::Ipc_client(Native_capability const &srv,
|
||||
Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
|
||||
: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) { }
|
||||
|
||||
|
||||
/****************
|
||||
** Ipc_server **
|
||||
****************/
|
||||
|
||||
Ipc_server::Ipc_server(Msgbuf_base *snd_msg,
|
||||
Msgbuf_base *rcv_msg) :
|
||||
Ipc_istream(rcv_msg),
|
||||
Ipc_ostream(Native_capability(), snd_msg),
|
||||
_reply_needed(false)
|
||||
{ }
|
||||
|
||||
|
||||
void Ipc_server::_prepare_next_reply_wait()
|
||||
{
|
||||
/* now we have a request to reply */
|
||||
_reply_needed = true;
|
||||
|
||||
/* leave space for RPC method return value */
|
||||
_write_offset = RPC_OBJECT_ID_SIZE + RPC_RETURN_VALUE_SIZE;
|
||||
|
||||
/* reset unmarshaller */
|
||||
_read_offset = RPC_OBJECT_ID_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_wait()
|
||||
{
|
||||
/* receive next request */
|
||||
copy_utcb_to_msgbuf(_rcv_msg, Kernel::wait_for_request());
|
||||
|
||||
/* update server state */
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_reply()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Unexpected call\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_reply_wait()
|
||||
{
|
||||
/* if there is no reply simply do wait for request */
|
||||
/* FIXME this shall be not supported */
|
||||
if (!_reply_needed) {
|
||||
_wait();
|
||||
return;
|
||||
}
|
||||
/* send reply and receive next request */
|
||||
copy_msgbuf_to_utcb(_snd_msg, _write_offset,
|
||||
Ipc_ostream::_dst.local_name());
|
||||
copy_utcb_to_msgbuf(_rcv_msg, Kernel::reply_and_wait(_write_offset));
|
||||
|
||||
/* update server state */
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
58
base-hw/src/base/lock/lock_helper.h
Normal file
58
base-hw/src/base/lock/lock_helper.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Helper functions for the Lock implementation
|
||||
* \author Martin Stein
|
||||
* \date 2011-01-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__BASE__LOCK__LOCK_HELPER_H_
|
||||
#define _SRC__BASE__LOCK__LOCK_HELPER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
|
||||
|
||||
/**
|
||||
* Yield CPU to any other thread
|
||||
*/
|
||||
static inline void thread_yield()
|
||||
{ Kernel::yield_thread(); }
|
||||
|
||||
|
||||
/**
|
||||
* Yield CPU to a specified thread 't'
|
||||
*/
|
||||
static inline void
|
||||
thread_switch_to(Genode::Native_thread_id const t)
|
||||
{ Kernel::yield_thread(t); }
|
||||
|
||||
|
||||
/**
|
||||
* Resume another thread 't' and return if it were paused or not
|
||||
*/
|
||||
static inline bool
|
||||
thread_check_stopped_and_restart(Genode::Native_thread_id const t)
|
||||
{ return Kernel::resume_thread(t) == 0; }
|
||||
|
||||
|
||||
/**
|
||||
* Validation kernel thread-identifier 'id'
|
||||
*/
|
||||
static inline bool thread_id_valid(Genode::Native_thread_id const id)
|
||||
{ return id != Genode::thread_invalid_id(); }
|
||||
|
||||
|
||||
/**
|
||||
* Exclude ourselves from CPU scheduling for now
|
||||
*/
|
||||
static inline void thread_stop_myself() { Kernel::pause_thread(); }
|
||||
|
||||
|
||||
#endif /* _SRC__BASE__LOCK__LOCK_HELPER_H_ */
|
||||
|
127
base-hw/src/base/pager.cc
Normal file
127
base-hw/src/base/pager.cc
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* \brief Pager implementations that are specific for the HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/pager.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/***************************
|
||||
** Pager_activation_base **
|
||||
***************************/
|
||||
|
||||
void Pager_activation_base::entry()
|
||||
{
|
||||
/* acknowledge that we're ready to work */
|
||||
Ipc_pager pager;
|
||||
_cap = pager;
|
||||
_cap_valid.unlock();
|
||||
|
||||
/* wait for the first pagefault */
|
||||
pager.wait_for_fault();
|
||||
while (1)
|
||||
{
|
||||
/* lookup pager object for the current faulter */
|
||||
Pager_object * o = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
if (!o) {
|
||||
PERR("%s:%d: Invalid pager object", __FILE__, __LINE__);
|
||||
while (1) ;
|
||||
}
|
||||
/* let pager handle the pagefault, apply mapping, await pagefault */
|
||||
if (o->pager(pager)) pager.wait_for_fault();
|
||||
else pager.resolve_and_wait_for_fault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** Pager_entrypoint **
|
||||
**********************/
|
||||
|
||||
Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
||||
Pager_activation_base * const a)
|
||||
: _activation(a) { _activation->ep(this); }
|
||||
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o) { remove(o); }
|
||||
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
|
||||
{
|
||||
/* do we have an activation */
|
||||
if (!_activation) return Pager_capability();
|
||||
|
||||
/* create cap with the object badge as local name */
|
||||
Native_capability c;
|
||||
c = Native_capability(_activation->cap().dst(), o->badge());
|
||||
|
||||
/* let activation provide the pager object */
|
||||
o->cap(c);
|
||||
insert(o);
|
||||
|
||||
/* return pager-object cap */
|
||||
return reinterpret_cap_cast<Pager_object>(c);
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Ipc_pager **
|
||||
***************/
|
||||
|
||||
|
||||
void Ipc_pager::wait_for_fault()
|
||||
{
|
||||
/* receive first message */
|
||||
size_t s = Kernel::wait_for_request();
|
||||
while (1) {
|
||||
switch (s) {
|
||||
|
||||
case sizeof(Pagefault): {
|
||||
|
||||
/* message is a pagefault */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
Pagefault * const pf = (Pagefault *)utcb;
|
||||
if (pf->valid())
|
||||
{
|
||||
/* give our caller the chance to handle the fault */
|
||||
_pagefault = *pf;
|
||||
return;
|
||||
}
|
||||
/* pagefault is invalid so get the next message */
|
||||
else {
|
||||
PERR("%s:%d: Invalid pagefault", __FILE__, __LINE__);
|
||||
continue;
|
||||
}
|
||||
continue; }
|
||||
|
||||
case sizeof(Pagefault_resolved): {
|
||||
|
||||
/* message is a release request from a RM session */
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
Pagefault_resolved * const msg = (Pagefault_resolved *)utcb;
|
||||
|
||||
/* resume faulter, send ack to RM and get the next message */
|
||||
Kernel::resume_thread(msg->pager_object->badge());
|
||||
s = Kernel::reply_and_wait(0);
|
||||
continue; }
|
||||
|
||||
default: {
|
||||
|
||||
PERR("%s:%d: Invalid message format", __FILE__, __LINE__);
|
||||
continue; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
130
base-hw/src/base/signal/signal.cc
Normal file
130
base-hw/src/base/signal/signal.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* \brief Implementations of the signaling framework specific for HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/signal.h>
|
||||
#include <signal_session/connection.h>
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Provide a static signal connection
|
||||
*/
|
||||
static Signal_connection * signal_connection()
|
||||
{
|
||||
static Signal_connection _object;
|
||||
return &_object;
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** Signal_receiver **
|
||||
*********************/
|
||||
|
||||
|
||||
Signal_receiver::Signal_receiver() :
|
||||
_cap(signal_connection()->alloc_receiver())
|
||||
{
|
||||
if (!_cap.valid()) {
|
||||
PERR("%s: Failed to create receiver", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Signal_receiver::~Signal_receiver()
|
||||
{
|
||||
/* dissolve all contexts that are managed by us */
|
||||
Lock::Guard contexts_guard(_contexts_lock);
|
||||
while (1) {
|
||||
Signal_context * const c = _contexts.first();
|
||||
if (!c) break;
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
_unsync_dissolve(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Signal_context_capability Signal_receiver::manage(Signal_context * const c)
|
||||
{
|
||||
/* check if the context is already managed */
|
||||
Lock::Guard contexts_guard(_contexts_lock);
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
if (c->_receiver) throw Context_already_in_use();
|
||||
|
||||
/* create a kernel object that corresponds to the context */
|
||||
bool session_upgraded = 0;
|
||||
Signal_connection * const s = signal_connection();
|
||||
while (1) {
|
||||
try {
|
||||
c->_cap = s->alloc_context(_cap, (unsigned long)c);
|
||||
break;
|
||||
} catch (Signal_session::Out_of_metadata)
|
||||
{
|
||||
/* upgrade session quota and try again, but only once */
|
||||
if (session_upgraded) return Signal_context_capability();
|
||||
env()->parent()->upgrade(s->cap(), "ram_quota=4K");
|
||||
session_upgraded = 1;
|
||||
}
|
||||
}
|
||||
/* assign the context to us */
|
||||
c->_receiver = this;
|
||||
_contexts.insert(c);
|
||||
return c->_cap;
|
||||
}
|
||||
|
||||
|
||||
Signal Signal_receiver::wait_for_signal()
|
||||
{
|
||||
/* await a signal */
|
||||
Kernel::await_signal(_cap.dst());
|
||||
Signal s = *(Signal *)Thread_base::myself()->utcb();
|
||||
Signal_context * c = s.context();
|
||||
|
||||
/* check if the context of the signal is managed by us */
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
if (c->_receiver != this) {
|
||||
PERR("%s: Context not managed by this receiver", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
}
|
||||
/* check attributes of the signal and return it */
|
||||
if (s.num() == 0) PWRN("Returning signal with num == 0");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void Signal_receiver::dissolve(Signal_context * const c)
|
||||
{
|
||||
/* check if the context is managed by us */
|
||||
Lock::Guard contexts_guard(_contexts_lock);
|
||||
Lock::Guard context_guard(c->_lock);
|
||||
if (c->_receiver != this) throw Context_not_associated();
|
||||
|
||||
/* unassign the context */
|
||||
_unsync_dissolve(c);
|
||||
}
|
||||
|
||||
|
||||
void Signal_receiver::_unsync_dissolve(Signal_context * const c)
|
||||
{
|
||||
/* reset the context */
|
||||
c->_receiver = 0;
|
||||
c->_cap = Signal_context_capability();
|
||||
|
||||
/* forget the context */
|
||||
_contexts.remove(c);
|
||||
}
|
||||
|
91
base-hw/src/base/thread_support.cc
Normal file
91
base-hw/src/base/thread_support.cc
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* \brief Platform specific parts of the thread API
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/env.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Native_utcb * _main_utcb;
|
||||
|
||||
namespace Genode { Rm_session *env_context_area_rm_session(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
/* this is a main thread, so CRT0 provides UTCB through '_main_utcb' */
|
||||
if (!this) return _main_utcb;
|
||||
|
||||
/* otherwise we have a valid thread base */
|
||||
return &_context->utcb;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
Thread_base::myself()->_thread_bootstrap();
|
||||
Thread_base::myself()->entry();
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{ env()->cpu_session()->kill_thread(_thread_cap); }
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
Cpu_session * cpu = env()->cpu_session();
|
||||
_thread_cap = cpu->create_thread(buf, (addr_t)&_context->utcb);
|
||||
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
|
||||
/* create new pager object and assign it to the new thread */
|
||||
Pager_capability pager_cap = env()->rm_session()->add_client(_thread_cap);
|
||||
env()->cpu_session()->set_pager(_thread_cap, pager_cap);
|
||||
|
||||
/* attach UTCB */
|
||||
try {
|
||||
Ram_dataspace_capability ds = env()->cpu_session()->utcb(_thread_cap);
|
||||
size_t const size = sizeof(_context->utcb);
|
||||
addr_t dst = Context_allocator::addr_to_base(_context) +
|
||||
CONTEXT_VIRTUAL_SIZE - size - CONTEXT_AREA_VIRTUAL_BASE;
|
||||
env_context_area_rm_session()->attach_at(ds, dst, size);
|
||||
} catch (...) {
|
||||
PERR("%s: Failed to attach UTCB", __PRETTY_FUNCTION__);
|
||||
sleep_forever();
|
||||
}
|
||||
/* start thread with its initial IP and aligned SP */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
thread_sp &= ~0xf;
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{ env()->cpu_session()->cancel_blocking(_thread_cap); }
|
||||
|
33
base-hw/src/core/arm_v7a/boot_modules.s
Normal file
33
base-hw/src/core/arm_v7a/boot_modules.s
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* \brief Dummy version of a boot modules file to enable a 'core' standalone image
|
||||
* \author Martin Stein
|
||||
* \date 2011-12-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
.section .data
|
||||
|
||||
.align 3
|
||||
.global _boot_modules_begin
|
||||
_boot_modules_begin:
|
||||
.string "GROM"
|
||||
|
||||
.align 3
|
||||
.global _boot_module_headers_begin
|
||||
_boot_module_headers_begin:
|
||||
|
||||
/* no module headers */
|
||||
|
||||
.global _boot_module_headers_end
|
||||
_boot_module_headers_end:
|
||||
|
||||
/* no modules */
|
||||
|
||||
.global _boot_modules_end
|
||||
_boot_modules_end:
|
72
base-hw/src/core/arm_v7a/crt0.s
Normal file
72
base-hw/src/core/arm_v7a/crt0.s
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* \brief Startup code for the Genode Kernel on ARM
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-10-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
.section .text
|
||||
|
||||
/* ELF entry symbol */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* idle a little initially because 'u-boot' likes it this way */
|
||||
.rept 8
|
||||
nop
|
||||
.endr
|
||||
|
||||
/* zero-fill BSS segment */
|
||||
.extern _bss_start
|
||||
.extern _bss_end
|
||||
ldr r0, =_bss_start
|
||||
ldr r1, =_bss_end
|
||||
mov r2, #0
|
||||
sub r1, r1, #4
|
||||
1:
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
cmp r0, r1
|
||||
bne 1b
|
||||
|
||||
/* call kernel routine */
|
||||
.extern kernel
|
||||
_start_kernel:
|
||||
ldr sp, =_kernel_stack_high
|
||||
bl kernel
|
||||
|
||||
/* jump to code that kernel has designated for when he has returned */
|
||||
ldr r1, =_call_after_kernel
|
||||
ldr r1, [r1]
|
||||
add pc, r1, #0
|
||||
|
||||
/* handle for dynamic symbol objects */
|
||||
.align 3
|
||||
.global __dso_handle
|
||||
__dso_handle: .long 0
|
||||
|
||||
.section .bss
|
||||
|
||||
/* instruction pointer wich gets loaded when kernel returns */
|
||||
.align 3
|
||||
.global _call_after_kernel
|
||||
_call_after_kernel: .long 0
|
||||
|
||||
/* kernel stack */
|
||||
.align 3
|
||||
.space 64*1024
|
||||
.global _kernel_stack_high
|
||||
_kernel_stack_high:
|
||||
|
||||
/* main thread UTCB pointer for the Genode thread API */
|
||||
.align 3
|
||||
.global _main_utcb
|
||||
_main_utcb: .long 0
|
||||
|
205
base-hw/src/core/arm_v7a/mode_transition.s
Normal file
205
base-hw/src/core/arm_v7a/mode_transition.s
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* \brief Transition between kernel and userland
|
||||
* \author Martin stein
|
||||
* \date 2011-11-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Invalidate all entries of the branch predictor array
|
||||
*/
|
||||
.macro _flush_branch_predictor
|
||||
mcr p15, 0, sp, c7, c5, 6
|
||||
isb
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Switch from an interrupted user context to a kernel context
|
||||
*
|
||||
* \param exception_type immediate exception type ID
|
||||
* \param pc_adjust immediate value that gets subtracted from the
|
||||
* user PC before it gets saved
|
||||
*/
|
||||
.macro _user_to_kernel_pic exception_type, pc_adjust
|
||||
|
||||
/*
|
||||
* We expect that privileged modes are never interrupted by an
|
||||
* exception. Thus we can assume that we always come from
|
||||
* user mode at this point.
|
||||
*/
|
||||
|
||||
/************************************************
|
||||
** We're still in the user protection domain, **
|
||||
** so we must avoid access to kernel memory **
|
||||
************************************************/
|
||||
|
||||
/* load kernel contextidr */
|
||||
adr sp, _mt_kernel_context_begin
|
||||
ldr sp, [sp, #17*4]
|
||||
mcr p15, 0, sp, c13, c0, 1
|
||||
_flush_branch_predictor
|
||||
|
||||
/* load kernel section table */
|
||||
adr sp, _mt_kernel_context_begin
|
||||
ldr sp, [sp, #19*4]
|
||||
mcr p15, 0, sp, c2, c0, 0
|
||||
_flush_branch_predictor
|
||||
|
||||
/*******************************************
|
||||
** Now it's save to access kernel memory **
|
||||
*******************************************/
|
||||
|
||||
/* get user context pointer */
|
||||
ldr sp, _mt_user_context_ptr
|
||||
|
||||
/*
|
||||
* Save user r0 ... r12. We explicitely target user registers
|
||||
* via '^' because we might be in FIQ exception-mode where
|
||||
* some of them are banked. Doesn't affect other modes.
|
||||
*/
|
||||
stmia sp, {r0-r12}^
|
||||
|
||||
/* save user lr and sp */
|
||||
add r0, sp, #13*4
|
||||
stmia r0, {sp,lr}^
|
||||
|
||||
/* adjust and save user pc */
|
||||
.if \pc_adjust != 0
|
||||
sub lr, lr, #\pc_adjust
|
||||
.endif
|
||||
str lr, [sp, #15*4]
|
||||
|
||||
/* save user psr */
|
||||
mrs r0, spsr
|
||||
str r0, [sp, #16*4]
|
||||
|
||||
/* save type of exception that interrupted the user */
|
||||
mov r0, #\exception_type
|
||||
str r0, [sp, #18*4]
|
||||
|
||||
/*
|
||||
* Switch to supervisor mode
|
||||
* FIXME This is done due to incorrect behavior when running the kernel
|
||||
* high-level-code in FIQ-exception mode. Please debug this behavior
|
||||
* and remove this switch.
|
||||
*/
|
||||
cps #19
|
||||
|
||||
/* get kernel context pointer */
|
||||
adr r0, _mt_kernel_context_begin
|
||||
|
||||
/* load kernel context */
|
||||
add r0, r0, #13*4
|
||||
ldmia r0, {sp, lr, pc}
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.section .text
|
||||
|
||||
/*
|
||||
* The mode transition PIC switches between a kernel context and a user
|
||||
* context and thereby between their address spaces. Due to the latter
|
||||
* it must be mapped executable to the same region in every address space.
|
||||
* To enable such switching, the kernel context must be stored within this
|
||||
* region, thus one should map it solely accessable for privileged modes.
|
||||
*/
|
||||
.align 3
|
||||
.global _mode_transition_begin
|
||||
_mode_transition_begin:
|
||||
|
||||
/*
|
||||
* On user exceptions the CPU has to jump to one of the following
|
||||
* 7 entry vectors to switch to a kernel context.
|
||||
*/
|
||||
.align 3
|
||||
.global _mt_kernel_entry_pic
|
||||
_mt_kernel_entry_pic:
|
||||
|
||||
b _rst_entry /* reset */
|
||||
b _und_entry /* undefined instruction */
|
||||
b _svc_entry /* supervisor call */
|
||||
b _pab_entry /* prefetch abort */
|
||||
b _dab_entry /* data abort */
|
||||
nop /* reserved */
|
||||
b _irq_entry /* interrupt request */
|
||||
b _fiq_entry /* fast interrupt request */
|
||||
|
||||
/* PICs that switch from an user exception to the kernel */
|
||||
_rst_entry: _user_to_kernel_pic 1, 0
|
||||
_und_entry: _user_to_kernel_pic 2, 4
|
||||
_svc_entry: _user_to_kernel_pic 3, 0
|
||||
_pab_entry: _user_to_kernel_pic 4, 4
|
||||
_dab_entry: _user_to_kernel_pic 5, 8
|
||||
_irq_entry: _user_to_kernel_pic 6, 4
|
||||
_fiq_entry: _user_to_kernel_pic 7, 4
|
||||
|
||||
/* kernel must jump to this point to switch to a user context */
|
||||
.align 3
|
||||
.global _mt_user_entry_pic
|
||||
_mt_user_entry_pic:
|
||||
|
||||
/* get user context pointer */
|
||||
ldr lr, _mt_user_context_ptr
|
||||
|
||||
/* buffer user pc */
|
||||
ldr r0, [lr, #15*4]
|
||||
adr r1, _mt_buffer
|
||||
str r0, [r1]
|
||||
|
||||
/* buffer user psr */
|
||||
ldr r0, [lr, #16*4]
|
||||
msr spsr, r0
|
||||
|
||||
/* load user r0 ... r12 */
|
||||
ldmia lr, {r0-r12}
|
||||
|
||||
/* load user sp and lr */
|
||||
add sp, lr, #13*4
|
||||
ldmia sp, {sp,lr}^
|
||||
|
||||
/* get user contextidr and section table */
|
||||
ldr sp, [lr, #17*4]
|
||||
ldr lr, [lr, #19*4]
|
||||
|
||||
/********************************************************
|
||||
** From now on, until we leave kernel mode, we must **
|
||||
** avoid access to memory that is not mapped globally **
|
||||
********************************************************/
|
||||
|
||||
/* apply user contextidr and section table */
|
||||
mcr p15, 0, sp, c13, c0, 1
|
||||
mcr p15, 0, lr, c2, c0, 0
|
||||
_flush_branch_predictor
|
||||
|
||||
/* load user pc (implies application of the user psr) */
|
||||
adr lr, _mt_buffer
|
||||
ldmia lr, {pc}^
|
||||
|
||||
/* leave some space for the kernel context */
|
||||
.align 3
|
||||
.global _mt_kernel_context_begin
|
||||
_mt_kernel_context_begin: .space 32*4
|
||||
.global _mt_kernel_context_end
|
||||
_mt_kernel_context_end:
|
||||
|
||||
/* pointer to the user context backup space */
|
||||
.align 3
|
||||
.global _mt_user_context_ptr
|
||||
_mt_user_context_ptr: .long 0
|
||||
|
||||
/* a local word-sized buffer */
|
||||
.align 3
|
||||
.global _mt_buffer
|
||||
_mt_buffer: .long 0
|
||||
|
||||
.align 3
|
||||
.global _mode_transition_end
|
||||
_mode_transition_end:
|
||||
|
34
base-hw/src/core/cpu_session_support.cc
Normal file
34
base-hw/src/core/cpu_session_support.cc
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* \brief Platform specific parts of CPU session
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <dataspace/capability.h>
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Ram_dataspace_capability
|
||||
Cpu_session_component::utcb(Thread_capability thread_cap)
|
||||
{
|
||||
/* serialize access */
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
/* lookup requested UTCB dataspace */
|
||||
Cpu_thread_component * t = _lookup_thread(thread_cap);
|
||||
if (!t) return Ram_dataspace_capability();
|
||||
return t->platform_thread()->utcb();
|
||||
}
|
||||
|
36
base-hw/src/core/include/assert.h
Normal file
36
base-hw/src/core/include/assert.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* \brief Assertion macro
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__ASSERT_H_
|
||||
#define _CORE__INCLUDE__ASSERT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/**
|
||||
* Assert a condition
|
||||
*
|
||||
* \param expression Expression that must be true
|
||||
*/
|
||||
#define assert(expression) \
|
||||
do { \
|
||||
if (!(expression)) { \
|
||||
PERR("Assertion failed: "#expression""); \
|
||||
PERR(" File: %s:%d", __FILE__, __LINE__); \
|
||||
PERR(" Function: %s", __PRETTY_FUNCTION__); \
|
||||
while (1) ; \
|
||||
} \
|
||||
} while (0) ;
|
||||
|
||||
#endif /* _CORE__INCLUDE__ASSERT_H_ */
|
||||
|
54
base-hw/src/core/include/cortex_a9/kernel_support.h
Normal file
54
base-hw/src/core/include/cortex_a9/kernel_support.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* \brief Parts of kernel support that are identical for all Cortex A9 systems
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_
|
||||
#define _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/**
|
||||
* CPU driver
|
||||
*/
|
||||
class Cpu : public Genode::Cortex_a9 { };
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/* import Genode types */
|
||||
typedef Genode::Cortex_a9 Cortex_a9;
|
||||
typedef Genode::Pl390_base Pl390_base;
|
||||
|
||||
/**
|
||||
* Kernel interrupt-controller
|
||||
*/
|
||||
class Pic : public Pl390_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Pic() : Pl390_base(Cortex_a9::PL390_DISTRIBUTOR_MMIO_BASE,
|
||||
Cortex_a9::PL390_CPU_MMIO_BASE)
|
||||
{ }
|
||||
};
|
||||
|
||||
/**
|
||||
* Kernel timer
|
||||
*/
|
||||
class Timer : public Cortex_a9::Private_timer { };
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CORTEX_A9__KERNEL_SUPPORT_H_ */
|
||||
|
68
base-hw/src/core/include/cpu_thread_allocator.h
Normal file
68
base-hw/src/core/include/cpu_thread_allocator.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* \brief Platform specific parts of the core CPU session
|
||||
* \author Martin Stein
|
||||
* \date 2012-03-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__CPU_SESSION_SUPPORT_H_
|
||||
#define _CORE__INCLUDE__CPU_SESSION_SUPPORT_H_
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <base/allocator.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Thread allocator for cores CPU service
|
||||
*
|
||||
* Normally one would use a SLAB for threads because usually they
|
||||
* are tiny objects, but in 'base-hw' they contain the whole kernel
|
||||
* object in addition. Thus we use the given allocator directly.
|
||||
*/
|
||||
class Cpu_thread_allocator : public Allocator
|
||||
{
|
||||
Allocator * const _alloc;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param alloc allocator backend
|
||||
*/
|
||||
Cpu_thread_allocator(Allocator * alloc) : _alloc(alloc) { }
|
||||
|
||||
/*************************
|
||||
** Allocator interface **
|
||||
*************************/
|
||||
|
||||
bool alloc(size_t size, void **out_addr) {
|
||||
return _alloc->alloc(size, out_addr); }
|
||||
|
||||
void free(void *addr, size_t size) {
|
||||
_alloc->free(addr, size); }
|
||||
|
||||
size_t consumed() {
|
||||
PDBG("Unexprected call");
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t overhead(size_t size) {
|
||||
PDBG("Unexprected call");
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool need_size_for_free() const { return true; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CPU_SESSION_SUPPORT_H_ */
|
111
base-hw/src/core/include/platform.h
Normal file
111
base-hw/src/core/include/platform.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* \brief Platform interface
|
||||
* \author Martin Stein
|
||||
* \date 2011-12-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/sync_allocator.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <kernel/log.h>
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_generic.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Manages all platform ressources
|
||||
*/
|
||||
class Platform : public Platform_generic
|
||||
{
|
||||
typedef Synchronized_range_allocator<Allocator_avl> Phys_allocator;
|
||||
|
||||
Phys_allocator _core_mem_alloc; /* core-accessible memory */
|
||||
Phys_allocator _io_mem_alloc; /* MMIO allocator */
|
||||
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_fs _rom_fs; /* ROM file system */
|
||||
|
||||
addr_t _vm_base; /* base of virtual address space */
|
||||
size_t _vm_size; /* size of virtual address space */
|
||||
|
||||
/**
|
||||
* Get one of the consecutively numbered available resource regions
|
||||
*
|
||||
* \return >0 region pointer if region with index 'i' exists
|
||||
* 0 if region with index 'i' doesn't exist
|
||||
*
|
||||
* These functions should provide all ressources that are available
|
||||
* on the current platform.
|
||||
*/
|
||||
static Native_region * _ram_regions(unsigned i);
|
||||
static Native_region * _mmio_regions(unsigned i);
|
||||
static Native_region * _irq_regions(unsigned i);
|
||||
|
||||
/**
|
||||
* Get one of the consecutively numbered core regions
|
||||
*
|
||||
* \return >0 Region pointer if region with index 'i' exists
|
||||
* 0 If region with index 'i' doesn't exist
|
||||
*
|
||||
* Core regions are address regions that must be permitted to
|
||||
* core only, such as the core image ROM. These regions are normally
|
||||
* a subset of the ressource regions provided above.
|
||||
*/
|
||||
static Native_region * _core_only_ram_regions(unsigned i);
|
||||
static Native_region * _core_only_mmio_regions(unsigned i);
|
||||
static Native_region * _core_only_irq_regions(unsigned i);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
|
||||
/********************************
|
||||
** Platform_generic interface **
|
||||
********************************/
|
||||
|
||||
inline Range_allocator * core_mem_alloc() { return &_core_mem_alloc; }
|
||||
|
||||
inline Range_allocator * ram_alloc() { return &_core_mem_alloc; }
|
||||
|
||||
inline Range_allocator * io_mem_alloc() { return &_io_mem_alloc; }
|
||||
|
||||
inline Range_allocator * io_port_alloc() { return &_io_port_alloc; }
|
||||
|
||||
inline Range_allocator * irq_alloc() { return &_irq_alloc; }
|
||||
|
||||
inline addr_t vm_start() const { return _vm_base; }
|
||||
|
||||
inline size_t vm_size() const { return _vm_size; }
|
||||
|
||||
inline Rom_fs *rom_fs() { return &_rom_fs; }
|
||||
|
||||
inline void wait_for_exit() { while (1) Kernel::pause_thread(); };
|
||||
|
||||
inline Range_allocator * region_alloc()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
||||
|
105
base-hw/src/core/include/platform_pd.h
Normal file
105
base-hw/src/core/include/platform_pd.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* \brief Platform specific part of a Genode protection domain
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
Genode::size_t pd_size();
|
||||
unsigned pd_alignm_log2();
|
||||
}
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Platform_thread;
|
||||
|
||||
/**
|
||||
* Platform specific part of a Genode protection domain
|
||||
*/
|
||||
class Platform_pd
|
||||
{
|
||||
unsigned long _id; /* ID of our kernel object */
|
||||
Native_capability _parent; /* our parent interface */
|
||||
Native_thread_id _main_thread; /* the first thread that gets
|
||||
* executed in this PD */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_pd() : _main_thread(0)
|
||||
{
|
||||
/* get some aligned space for the kernel object */
|
||||
void * kernel_pd;
|
||||
Range_allocator * ram = platform()->ram_alloc();
|
||||
assert(ram->alloc_aligned(Kernel::pd_size(), &kernel_pd,
|
||||
Kernel::pd_alignm_log2()));
|
||||
|
||||
/* create kernel object */
|
||||
_id = Kernel::new_pd(kernel_pd);
|
||||
assert(_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_pd();
|
||||
|
||||
/**
|
||||
* Bind thread 't' to protection domain
|
||||
*
|
||||
* \return 0 on success or
|
||||
* -1 if failed
|
||||
*/
|
||||
int bind_thread(Platform_thread * t)
|
||||
{
|
||||
/* is this the first and therefore main thread in this PD? */
|
||||
if (!_main_thread)
|
||||
{
|
||||
/* annotate that we've got a main thread from now on */
|
||||
_main_thread = t->id();
|
||||
return t->join_pd(_id, 1);
|
||||
}
|
||||
return t->join_pd(_id, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind thread from protection domain
|
||||
*
|
||||
* Free the thread's slot and update thread object.
|
||||
*/
|
||||
void unbind_thread(Platform_thread * t);
|
||||
|
||||
/**
|
||||
* Assign parent interface to protection domain
|
||||
*/
|
||||
int assign_parent(Native_capability parent)
|
||||
{
|
||||
assert(parent.valid());
|
||||
_parent = parent;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */
|
||||
|
184
base-hw/src/core/include/platform_thread.h
Normal file
184
base-hw/src/core/include/platform_thread.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* \brief Userland interface for the management of kernel thread-objects
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <base/native_types.h>
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Pager_object;
|
||||
class Thread_state;
|
||||
class Thread_base;
|
||||
class Rm_client;
|
||||
class Platform_thread;
|
||||
|
||||
size_t kernel_thread_size();
|
||||
|
||||
/**
|
||||
* Userland interface for the management of kernel thread-objects
|
||||
*/
|
||||
class Platform_thread
|
||||
{
|
||||
enum { NAME_MAX_LEN = 32 };
|
||||
|
||||
Thread_base * _thread_base;
|
||||
unsigned long _stack_size;
|
||||
unsigned long _pd_id;
|
||||
unsigned long _id;
|
||||
Rm_client * _rm_client;
|
||||
bool _main_thread;
|
||||
Native_utcb * _phys_utcb;
|
||||
Native_utcb * _virt_utcb;
|
||||
Software_tlb * _software_tlb;
|
||||
Ram_dataspace_capability _utcb;
|
||||
char _name[NAME_MAX_LEN];
|
||||
|
||||
/**
|
||||
* Common construction part
|
||||
*/
|
||||
void _init();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for core threads
|
||||
*/
|
||||
Platform_thread(const char * name,
|
||||
Thread_base * const thread_base,
|
||||
unsigned long const stack_size,
|
||||
unsigned long const pd_id);
|
||||
|
||||
/**
|
||||
* Constructor for threads outside of core
|
||||
*/
|
||||
Platform_thread(const char * name, unsigned int priority,
|
||||
addr_t utcb);
|
||||
|
||||
/**
|
||||
* Join PD identified by 'pd_id'
|
||||
*
|
||||
* \param pd_id ID of targeted PD
|
||||
* \param main_thread wether we are the main thread in this PD
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval <0 otherwise
|
||||
*/
|
||||
int join_pd(unsigned long const pd_id,
|
||||
bool const main_thread);
|
||||
|
||||
/**
|
||||
* Run this thread
|
||||
*/
|
||||
int start(void * ip, void * sp, unsigned int cpu_no = 0);
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause() { Kernel::pause_thread(_id); }
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume() { Kernel::resume_thread(_id); }
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
*/
|
||||
void cancel_blocking()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request our raw thread state
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
*/
|
||||
int state(Genode::Thread_state * state_dst)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_thread()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return unique identification of this thread as faulter
|
||||
*/
|
||||
unsigned long pager_object_badge() { return _id; }
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread.
|
||||
*/
|
||||
void set_cpu(unsigned int cpu_no)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
inline char const * name() const { return _name; }
|
||||
|
||||
void pager(Pager_object * const pager);
|
||||
|
||||
Pager_object * pager() const;
|
||||
|
||||
unsigned long pd_id() const { return _pd_id; }
|
||||
|
||||
Native_thread_id id() const { return _id; }
|
||||
|
||||
unsigned long stack_size() const { return _stack_size; }
|
||||
|
||||
Thread_base * thread_base()
|
||||
{
|
||||
if (!_thread_base) assert(_main_thread);
|
||||
return _thread_base;
|
||||
}
|
||||
|
||||
Native_utcb * phys_utcb() const { return _phys_utcb; }
|
||||
|
||||
Native_utcb * virt_utcb() const { return _virt_utcb; }
|
||||
|
||||
Ram_dataspace_capability utcb() const { return _utcb; }
|
||||
|
||||
Software_tlb * software_tlb() const { return _software_tlb; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
|
||||
|
93
base-hw/src/core/include/signal_root.h
Normal file
93
base-hw/src/core/include/signal_root.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* \brief Signal root interface on HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__SIGNAL_ROOT_H_
|
||||
#define _CORE__INCLUDE__SIGNAL_ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <root/component.h>
|
||||
|
||||
/* core includes */
|
||||
#include <signal_session_component.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provide EP to signal root before it initialises root component
|
||||
*/
|
||||
class Signal_handler
|
||||
{
|
||||
enum { STACK_SIZE = 4096 };
|
||||
|
||||
Rpc_entrypoint _entrypoint;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Signal_handler(Cap_session * const c)
|
||||
: _entrypoint(c, STACK_SIZE, "signal") { }
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Rpc_entrypoint * entrypoint() { return &_entrypoint; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides signal service by managing appropriate sessions to the clients
|
||||
*/
|
||||
class Signal_root : private Signal_handler,
|
||||
public Root_component<Signal_session_component>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param md Meta-data allocator to be used by root component
|
||||
* \param c CAP session to be used by the root entrypoint
|
||||
*/
|
||||
Signal_root(Allocator * const md, Cap_session * const c) :
|
||||
Signal_handler(c),
|
||||
Root_component<Signal_session_component>(entrypoint(), md)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
/********************************
|
||||
** 'Root_component' interface **
|
||||
********************************/
|
||||
|
||||
Signal_session_component * _create_session(const char * args)
|
||||
{
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota").long_value(0);
|
||||
return new (md_alloc())
|
||||
Signal_session_component(md_alloc(), ram_quota);
|
||||
}
|
||||
|
||||
void _upgrade_session(Signal_session_component *s,
|
||||
const char * args)
|
||||
{
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota").long_value(0);
|
||||
s->upgrade_ram_quota(ram_quota);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__SIGNAL_ROOT_H_ */
|
||||
|
68
base-hw/src/core/include/signal_session_component.h
Normal file
68
base-hw/src/core/include/signal_session_component.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* \brief Signal service on the HW-core
|
||||
* \author Martin stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <signal_session/signal_session.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/slab.h>
|
||||
#include <base/allocator_guard.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Provides the signal service
|
||||
*/
|
||||
class Signal_session_component : public Rpc_object<Signal_session>
|
||||
{
|
||||
Allocator_guard _md_alloc; /* Metadata allocator */
|
||||
Slab _receivers_slab; /* SLAB to allocate receiver kernel-objects */
|
||||
Slab _contexts_slab; /* SLAB to allocate context kernel-objects */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param md Metadata allocator
|
||||
* \param ram_quota Amount of RAM quota donated to this session
|
||||
*/
|
||||
Signal_session_component(Allocator * const md,
|
||||
size_t const ram_quota);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Signal_session_component();
|
||||
|
||||
/**
|
||||
* Raise the quota of this session by 'q'
|
||||
*/
|
||||
void upgrade_ram_quota(size_t const q) { _md_alloc.upgrade(q); }
|
||||
|
||||
/******************************
|
||||
** Signal_session interface **
|
||||
******************************/
|
||||
|
||||
Signal_receiver_capability alloc_receiver();
|
||||
|
||||
Signal_context_capability
|
||||
alloc_context(Signal_receiver_capability const r,
|
||||
unsigned long const imprint);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */
|
||||
|
109
base-hw/src/core/include/util.h
Normal file
109
base-hw/src/core/include/util.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* \brief Core-internal utilities
|
||||
* \author Martin Stein
|
||||
* \date 2012-01-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__UTIL_H_
|
||||
#define _CORE__INCLUDE__UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
enum { MIN_PAGE_SIZE_LOG2 = 12 };
|
||||
|
||||
|
||||
/**
|
||||
* Get the the minimal supported page-size log 2
|
||||
*/
|
||||
inline size_t get_page_size_log2() { return MIN_PAGE_SIZE_LOG2; }
|
||||
|
||||
|
||||
/**
|
||||
* Get the the minimal supported page-size
|
||||
*/
|
||||
inline size_t get_page_size() { return 1 << get_page_size_log2(); }
|
||||
|
||||
|
||||
/**
|
||||
* Get the base mask for the minimal supported page-size
|
||||
*/
|
||||
inline addr_t get_page_mask() { return ~(get_page_size() - 1); }
|
||||
|
||||
|
||||
/**
|
||||
* Round down to the minimal page-size alignment
|
||||
*/
|
||||
inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); }
|
||||
|
||||
|
||||
/**
|
||||
* Round up to the minimal page-size alignment
|
||||
*/
|
||||
inline addr_t round_page(addr_t addr)
|
||||
{ return trunc_page(addr + get_page_size() - 1); }
|
||||
|
||||
|
||||
/**
|
||||
* Round down to a specific alignment
|
||||
*/
|
||||
inline addr_t trunc(addr_t const addr, unsigned const alignm_log2)
|
||||
{ return addr & ~((1 << alignm_log2) - 1); }
|
||||
|
||||
|
||||
/**
|
||||
* Round up to a specific alignment
|
||||
*/
|
||||
inline addr_t round(addr_t const addr, unsigned const alignm_log2)
|
||||
{ return trunc(addr + (1<<alignm_log2) - 1, alignm_log2); }
|
||||
|
||||
|
||||
/**
|
||||
* Select source used for map operations
|
||||
*/
|
||||
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
|
||||
|
||||
|
||||
/**
|
||||
* Return highest supported flexpage size for the given mapping size
|
||||
*
|
||||
* This function is called by the page-fault handler to determine the
|
||||
* mapping granularity to be used for a page-fault answer. If a kernel
|
||||
* supports flexible page sizes, this function can just return the
|
||||
* argument. If a kernel only supports a certain set of map sizes such
|
||||
* as 4K and 4M, this function should select one of those smaller or
|
||||
* equal to the argument.
|
||||
*/
|
||||
inline size_t constrain_map_size_log2(size_t size_log2)
|
||||
{
|
||||
if (size_log2<20) return 12;
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Debug output on page faults
|
||||
*/
|
||||
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
|
||||
Rm_session::Fault_type pf_type,
|
||||
unsigned long faulter_badge)
|
||||
{
|
||||
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)", msg,
|
||||
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ",
|
||||
(void *)pf_addr, (void *)pf_ip,
|
||||
faulter_badge);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__UTIL_H_ */
|
||||
|
29
base-hw/src/core/io_mem_session_support.cc
Normal file
29
base-hw/src/core/io_mem_session_support.cc
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* \brief Implementation of the IO_MEM session interface
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <io_mem_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Io_mem_session_component::_unmap_local(addr_t base, size_t size) { }
|
||||
|
||||
|
||||
addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
|
||||
{ return base; }
|
||||
|
85
base-hw/src/core/io_port_session_component.cc
Normal file
85
base-hw/src/core/io_port_session_component.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief Implementation of the IO_PORT session interface
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <io_port_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
unsigned char Io_port_session_component::inb(unsigned short address)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned short Io_port_session_component::inw(unsigned short address)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned Io_port_session_component::inl(unsigned short address)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Io_port_session_component::outb(unsigned short address,
|
||||
unsigned char value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Io_port_session_component::outw(unsigned short address,
|
||||
unsigned short value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Io_port_session_component::outl(unsigned short address, unsigned value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
Io_port_session_component::
|
||||
Io_port_session_component(Range_allocator * io_port_alloc,
|
||||
const char * args)
|
||||
: _io_port_alloc(io_port_alloc)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
Io_port_session_component::~Io_port_session_component()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
69
base-hw/src/core/irq_session_component.cc
Normal file
69
base-hw/src/core/irq_session_component.cc
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* \brief Implementation of IRQ session component
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
/* core includes */
|
||||
#include <irq_root.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
bool
|
||||
Irq_session_component::Irq_control_component::associate_to_irq(unsigned irq)
|
||||
{ return Kernel::allocate_irq(irq); }
|
||||
|
||||
|
||||
void Irq_session_component::wait_for_irq() { Kernel::await_irq(); }
|
||||
|
||||
|
||||
Irq_session_component::~Irq_session_component()
|
||||
{
|
||||
/* free IRQ for other threads */
|
||||
if (Kernel::free_irq(_irq_number))
|
||||
PERR("Could not free IRQ %u", _irq_number);
|
||||
}
|
||||
|
||||
|
||||
Irq_session_component::Irq_session_component(Cap_session * cap_session,
|
||||
Range_allocator * irq_alloc,
|
||||
const char * args)
|
||||
:
|
||||
_irq_alloc(irq_alloc), _ep(cap_session, STACK_SIZE, "irqctrl"),
|
||||
_control_cap(_ep.manage(&_control_component)),
|
||||
_control_client(_control_cap)
|
||||
{
|
||||
/* check arguments */
|
||||
bool shared = Arg_string::find_arg(args, "irq_shared").bool_value(false);
|
||||
if (shared) {
|
||||
PERR("IRQ sharing not supported");
|
||||
throw Root::Invalid_args();
|
||||
}
|
||||
/* allocate IRQ */
|
||||
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
|
||||
if (irq_number == -1 || !irq_alloc ||
|
||||
irq_alloc->alloc_addr(1, irq_number) != Range_allocator::ALLOC_OK) {
|
||||
PERR("Unavailable IRQ %lu requested", irq_number);
|
||||
throw Root::Invalid_args();
|
||||
}
|
||||
_irq_number = irq_number;
|
||||
|
||||
/* configure control client */
|
||||
if (!_control_client.associate_to_irq(irq_number)) {
|
||||
PERR("IRQ association failed");
|
||||
throw Root::Invalid_args();
|
||||
}
|
||||
/* create IRQ capability */
|
||||
_irq_cap = Irq_session_capability(_ep.manage(this));
|
||||
}
|
2088
base-hw/src/core/kernel.cc
Normal file
2088
base-hw/src/core/kernel.cc
Normal file
File diff suppressed because it is too large
Load Diff
21
base-hw/src/core/panda_a2/kernel_support.h
Normal file
21
base-hw/src/core/panda_a2/kernel_support.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Kernel support specific for the PandaBoard A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__CORE__PANDA_A2__KERNEL_SUPPORT_H_
|
||||
#define _SRC__CORE__PANDA_A2__KERNEL_SUPPORT_H_
|
||||
|
||||
/* local includes */
|
||||
#include <cortex_a9/kernel_support.h>
|
||||
|
||||
#endif /* _SRC__CORE__PANDA_A2__KERNEL_SUPPORT_H_ */
|
||||
|
84
base-hw/src/core/panda_a2/platform_support.cc
Normal file
84
base-hw/src/core/panda_a2/platform_support.cc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and Panda A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/panda_a2.h>
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Panda_a2::EMIF1_EMIF2_CS0_SDRAM_BASE,
|
||||
Panda_a2::EMIF1_EMIF2_CS0_SDRAM_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 0, Pl390_base::MAX_INTERRUPT_ID + 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer */
|
||||
{ Cortex_a9::PRIVATE_TIMER_IRQ, 1 },
|
||||
|
||||
/* core UART */
|
||||
{ Panda_a2::TL16C750_3_IRQ, 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Panda_a2::L4_PER_BASE, Panda_a2::L4_PER_SIZE },
|
||||
{ Panda_a2::L4_CFG_BASE, Panda_a2::L4_CFG_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer and PIC */
|
||||
{ Panda_a2::CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
Panda_a2::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* core UART */
|
||||
{ Panda_a2::TL16C750_3_MMIO_BASE, Panda_a2::TL16C750_3_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
26
base-hw/src/core/panda_a2/software_tlb.h
Normal file
26
base-hw/src/core/panda_a2/software_tlb.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Software TLB controls specific for the PandaBoard A2
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_
|
||||
#define _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/section_table.h>
|
||||
|
||||
/**
|
||||
* Software TLB controls
|
||||
*/
|
||||
class Software_tlb : public Genode::Section_table { };
|
||||
|
||||
#endif /* _SRC__CORE__PANDA_A2__SOFTWARE_TLB_H_ */
|
||||
|
21
base-hw/src/core/pbxa9/kernel_support.h
Normal file
21
base-hw/src/core/pbxa9/kernel_support.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Kernel support specific for the Realview PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__CORE__PBXA9__KERNEL_SUPPORT_H_
|
||||
#define _SRC__CORE__PBXA9__KERNEL_SUPPORT_H_
|
||||
|
||||
/* local includes */
|
||||
#include <cortex_a9/kernel_support.h>
|
||||
|
||||
#endif /* _SRC__CORE__PBXA9__KERNEL_SUPPORT_H_ */
|
||||
|
82
base-hw/src/core/pbxa9/platform_support.cc
Normal file
82
base-hw/src/core/pbxa9/platform_support.cc
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* \brief Parts of platform that are specific to PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/pbxa9.h>
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Pbxa9::NORTHBRIDGE_DDR_0_BASE, Pbxa9::NORTHBRIDGE_DDR_0_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 0, Pl390_base::MAX_INTERRUPT_ID + 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer */
|
||||
{ Cortex_a9::PRIVATE_TIMER_IRQ, 1 },
|
||||
|
||||
/* core UART */
|
||||
{ Pbxa9::PL011_0_IRQ, 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Pbxa9::SOUTHBRIDGE_APB_BASE, Pbxa9::SOUTHBRIDGE_APB_SIZE },
|
||||
{ Pbxa9::NORTHBRIDGE_AHB_BASE, Pbxa9::NORTHBRIDGE_AHB_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* core timer and PIC */
|
||||
{ Pbxa9::CORTEX_A9_PRIVATE_MEM_BASE, Pbxa9::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* core UART */
|
||||
{ Pbxa9::PL011_0_MMIO_BASE, Pbxa9::PL011_0_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
26
base-hw/src/core/pbxa9/software_tlb.h
Normal file
26
base-hw/src/core/pbxa9/software_tlb.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Software TLB controls specific for the Realview PBXA9
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__CORE__PBXA9__SOFTWARE_TLB_H_
|
||||
#define _SRC__CORE__PBXA9__SOFTWARE_TLB_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/section_table.h>
|
||||
|
||||
/**
|
||||
* Software TLB controls
|
||||
*/
|
||||
class Software_tlb : public Genode::Section_table { };
|
||||
|
||||
#endif /* _SRC__CORE__PBXA9__SOFTWARE_TLB_H_ */
|
||||
|
162
base-hw/src/core/platform.cc
Normal file
162
base-hw/src/core/platform.cc
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* \brief Platform implementation specific for hw
|
||||
* \author Martin Stein
|
||||
* \date 2011-12-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_parent.h>
|
||||
#include <platform.h>
|
||||
#include <util.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern int _prog_img_beg;
|
||||
extern int _prog_img_end;
|
||||
|
||||
/**
|
||||
* Format of a boot-module header
|
||||
*/
|
||||
struct Bm_header
|
||||
{
|
||||
long name; /* physical address of null-terminated string */
|
||||
long base; /* physical address of module data */
|
||||
long size; /* size of module data in bytes */
|
||||
};
|
||||
|
||||
extern int _boot_modules_begin;
|
||||
extern Bm_header _boot_module_headers_begin;
|
||||
extern Bm_header _boot_module_headers_end;
|
||||
extern int _boot_modules_end;
|
||||
|
||||
/**
|
||||
* Functionpointer that provides accessor to a pool of address regions
|
||||
*/
|
||||
typedef Native_region * (*Region_pool)(unsigned const);
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
addr_t mode_transition_virt_base();
|
||||
size_t mode_transition_size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to initialise allocators through include/exclude region lists
|
||||
*/
|
||||
static void init_alloc(Range_allocator * const alloc,
|
||||
Region_pool incl_regions, Region_pool excl_regions,
|
||||
unsigned const granu_log2 = 0)
|
||||
{
|
||||
/* make all include regions available */
|
||||
Native_region * r = incl_regions(0);
|
||||
for (unsigned i = 0; r; r = incl_regions(++i)) {
|
||||
if (granu_log2) {
|
||||
addr_t const b = trunc(r->base, granu_log2);
|
||||
addr_t const s = round(r->size, granu_log2);
|
||||
alloc->add_range(b, s);
|
||||
}
|
||||
else alloc->add_range(r->base, r->size);
|
||||
}
|
||||
/* preserve all exclude regions */
|
||||
r = excl_regions(0);
|
||||
for (unsigned i = 0; r; r = excl_regions(++i)) {
|
||||
if (granu_log2) {
|
||||
addr_t const b = trunc(r->base, granu_log2);
|
||||
addr_t const s = round(r->size, granu_log2);
|
||||
alloc->remove_range(b, s);
|
||||
}
|
||||
else alloc->remove_range(r->base, r->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************
|
||||
** Platform **
|
||||
**************/
|
||||
|
||||
Native_region * Platform::_core_only_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _r[] =
|
||||
{
|
||||
/* avoid null pointers */
|
||||
{ 0, 1 },
|
||||
|
||||
/* mode transition region */
|
||||
{ Kernel::mode_transition_virt_base(), Kernel::mode_transition_size() },
|
||||
|
||||
/* core image */
|
||||
{ (addr_t)&_prog_img_beg,
|
||||
(size_t)((addr_t)&_prog_img_end - (addr_t)&_prog_img_beg) },
|
||||
|
||||
/* boot modules */
|
||||
{ (addr_t)&_boot_modules_begin,
|
||||
(size_t)((addr_t)&_boot_modules_end - (addr_t)&_boot_modules_begin) }
|
||||
};
|
||||
return i < sizeof(_r)/sizeof(_r[0]) ? &_r[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Platform::Platform() :
|
||||
_core_mem_alloc(0),
|
||||
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
||||
_irq_alloc(core_mem_alloc()), _vm_base(0), _vm_size(0xffff0000)
|
||||
{
|
||||
/*
|
||||
* Initialise platform resource allocators.
|
||||
* Core mem alloc must come first because it is
|
||||
* used by the other allocators.
|
||||
*/
|
||||
enum { VERBOSE = 0 };
|
||||
unsigned const psl2 = get_page_size_log2();
|
||||
init_alloc(&_core_mem_alloc, _ram_regions, _core_only_ram_regions, psl2);
|
||||
init_alloc(&_irq_alloc, _irq_regions, _core_only_irq_regions);
|
||||
init_alloc(&_io_mem_alloc, _mmio_regions, _core_only_mmio_regions, psl2);
|
||||
|
||||
/* add boot modules to ROM FS */
|
||||
Bm_header * header = &_boot_module_headers_begin;
|
||||
for (; header < &_boot_module_headers_end; header++) {
|
||||
Rom_module * rom_module = new (core_mem_alloc())
|
||||
Rom_module(header->base, header->size, (const char*)header->name);
|
||||
_rom_fs.insert(rom_module);
|
||||
}
|
||||
/* print ressource summary */
|
||||
if (VERBOSE) {
|
||||
printf("Core memory allocator\n");
|
||||
printf("---------------------\n");
|
||||
_core_mem_alloc.raw()->dump_addr_tree();
|
||||
printf("\n");
|
||||
printf("IO memory allocator\n");
|
||||
printf("-------------------\n");
|
||||
_io_mem_alloc.raw()->dump_addr_tree();
|
||||
printf("\n");
|
||||
printf("ROM filesystem\n");
|
||||
printf("--------------\n");
|
||||
_rom_fs.print_fs();
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Core_parent **
|
||||
*****************/
|
||||
|
||||
void Core_parent::exit(int exit_value)
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
28
base-hw/src/core/platform_pd.cc
Normal file
28
base-hw/src/core/platform_pd.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Protection-domain facility
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform_pd.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/*****************
|
||||
** Platform PD **
|
||||
*****************/
|
||||
|
||||
void Platform_pd::unbind_thread(Platform_thread *thread) { assert(0); }
|
||||
|
||||
|
||||
Platform_pd::~Platform_pd() { assert(0); }
|
||||
|
145
base-hw/src/core/platform_thread.cc
Normal file
145
base-hw/src/core/platform_thread.cc
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
#include <core_env.h>
|
||||
#include <rm_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(const char * name,
|
||||
Thread_base * const thread_base,
|
||||
unsigned long const stack_size,
|
||||
unsigned long const pd_id)
|
||||
:
|
||||
_thread_base(thread_base), _stack_size(stack_size),
|
||||
_pd_id(pd_id), _rm_client(0), _virt_utcb(0)
|
||||
{
|
||||
strncpy(_name, name, NAME_MAX_LEN);
|
||||
|
||||
/* create UTCB for a core thread */
|
||||
Range_allocator * const ram = platform()->ram_alloc();
|
||||
assert(ram->alloc_aligned(sizeof(Native_utcb), (void **)&_phys_utcb,
|
||||
MIN_MAPPING_SIZE_LOG2));
|
||||
_virt_utcb = _phys_utcb;
|
||||
|
||||
/* common constructor parts */
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(const char * name, unsigned int priority,
|
||||
addr_t utcb)
|
||||
:
|
||||
_thread_base(0), _stack_size(0), _pd_id(0), _rm_client(0),
|
||||
_virt_utcb((Native_utcb *)utcb)
|
||||
{
|
||||
strncpy(_name, name, NAME_MAX_LEN);
|
||||
|
||||
/*
|
||||
* Allocate UTCB backing store for a thread outside of core. Page alignment
|
||||
* is done by RAM session by default. It's save to use core env because
|
||||
* this cannot be its server activation thread.
|
||||
*/
|
||||
try {
|
||||
Ram_session_component * const ram =
|
||||
dynamic_cast<Ram_session_component *>(core_env()->ram_session());
|
||||
assert(ram);
|
||||
_utcb = ram->alloc(sizeof(Native_utcb), 1);
|
||||
_phys_utcb = (Native_utcb *)ram->phys_addr(_utcb);
|
||||
}
|
||||
catch (...) { assert(0); }
|
||||
|
||||
/* common constructor parts */
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::join_pd(unsigned long const pd_id,
|
||||
bool const main_thread)
|
||||
{
|
||||
/* check if we're already in another PD */
|
||||
if (_pd_id && _pd_id != pd_id) return -1;
|
||||
|
||||
/* denote configuration for start method */
|
||||
_pd_id = pd_id;
|
||||
_main_thread = main_thread;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::_init()
|
||||
{
|
||||
/* create kernel object */
|
||||
void * kernel_thread;
|
||||
Range_allocator * ram = platform()->ram_alloc();
|
||||
assert(ram->alloc(Kernel::thread_size(), &kernel_thread));
|
||||
_id = Kernel::new_thread(kernel_thread, this);
|
||||
assert(_id);
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::start(void * ip, void * sp, unsigned int cpu_no)
|
||||
{
|
||||
/* check thread attributes */
|
||||
assert(_pd_id);
|
||||
|
||||
/*
|
||||
* If this is a main thread outside of core it'll not manage its
|
||||
* virtual context area by itself, as it is done for other threads
|
||||
* through a sub RM-session. Therefore we attach the UTCB to its
|
||||
* address space before it gets started.
|
||||
*/
|
||||
if (_pd_id != Kernel::core_id() && _main_thread)
|
||||
{
|
||||
/*
|
||||
* Declare page aligned virtual UTCB outside the context area.
|
||||
* Kernel afterwards offers this as bootstrap argument to the thread.
|
||||
*/
|
||||
_virt_utcb = (Native_utcb *)((platform()->vm_start()
|
||||
+ platform()->vm_size() - sizeof(Native_utcb))
|
||||
& ~((1<<MIN_MAPPING_SIZE_LOG2)-1));
|
||||
|
||||
/* attach UTCB */
|
||||
assert(_rm_client);
|
||||
Rm_session_component * const rm = _rm_client->member_rm_session();
|
||||
try { rm->attach(_utcb, 0, 0, true, _virt_utcb, 0); }
|
||||
catch (...) { assert(0); }
|
||||
}
|
||||
/* let thread participate in CPU scheduling */
|
||||
_software_tlb = Kernel::start_thread(this, ip, sp, cpu_no);
|
||||
return _software_tlb ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::pager(Pager_object * const pager)
|
||||
{
|
||||
/* announce pager thread to kernel */
|
||||
Kernel::set_pager(pager->cap().dst(), _id);
|
||||
|
||||
/* get RM client from pager pointer */
|
||||
_rm_client = dynamic_cast<Rm_client *>(pager);
|
||||
assert(_rm_client);
|
||||
}
|
||||
|
||||
|
||||
Genode::Pager_object * Platform_thread::pager() const
|
||||
{
|
||||
assert(_rm_client)
|
||||
return static_cast<Pager_object *>(_rm_client);
|
||||
}
|
||||
|
31
base-hw/src/core/ram_session_support.cc
Normal file
31
base-hw/src/core/ram_session_support.cc
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* \brief Export RAM dataspace as shared memory object (dummy)
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <ram_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { }
|
||||
|
||||
|
||||
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { }
|
||||
|
||||
|
||||
void Ram_session_component::_clear_ds (Dataspace_component * ds)
|
||||
{ memset((void *)ds->phys_addr(), 0, ds->size()); }
|
||||
|
85
base-hw/src/core/rm_session_support.cc
Normal file
85
base-hw/src/core/rm_session_support.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief RM- and pager implementations specific for base-hw and core
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/ipc_pager.h>
|
||||
|
||||
/* core includes */
|
||||
#include <rm_session_component.h>
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
#include <assert.h>
|
||||
#include <software_tlb.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/***************
|
||||
** Rm_client **
|
||||
***************/
|
||||
|
||||
|
||||
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
|
||||
{
|
||||
/* get software TLB of the thread that we serve */
|
||||
Platform_thread * const pt = Kernel::get_thread(badge());
|
||||
assert(pt);
|
||||
Software_tlb * const tlb = pt->software_tlb();
|
||||
assert(tlb);
|
||||
|
||||
/* update all translation caches */
|
||||
tlb->remove_region(virt_base, size);
|
||||
Kernel::update_pd(pt->pd_id());
|
||||
|
||||
/* try to regain administrative memory that has been freed by unmap */
|
||||
size_t s;
|
||||
void * base;
|
||||
while (tlb->regain_memory(base, s)) platform()->ram_alloc()->free(base, s);
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Ipc_pager **
|
||||
***************/
|
||||
|
||||
void Ipc_pager::resolve_and_wait_for_fault()
|
||||
{
|
||||
/* valid mapping? */
|
||||
assert(_mapping.valid());
|
||||
|
||||
/* do we need extra space to resolve pagefault? */
|
||||
Software_tlb * const tlb = _pagefault.software_tlb;
|
||||
enum Mapping_attributes { X = 1, K = 0, G = 0 };
|
||||
unsigned sl2 = tlb->insert_translation(_mapping.virt_address,
|
||||
_mapping.phys_address, _mapping.size_log2,
|
||||
_mapping.writable, X, K, G);
|
||||
if (sl2)
|
||||
{
|
||||
/* try to get some natural aligned space */
|
||||
void * space;
|
||||
assert(platform()->ram_alloc()->alloc_aligned(1<<sl2, &space, sl2));
|
||||
|
||||
/* try to translate again with extra space */
|
||||
sl2 = tlb->insert_translation(_mapping.virt_address,
|
||||
_mapping.phys_address,
|
||||
_mapping.size_log2,
|
||||
_mapping.writable, X, K, G, space);
|
||||
assert(!sl2);
|
||||
}
|
||||
/* try to wake up faulter */
|
||||
assert(!Kernel::resume_thread(_pagefault.thread_id));
|
||||
|
||||
/* wait for next page fault */
|
||||
wait_for_fault();
|
||||
}
|
||||
|
79
base-hw/src/core/signal_session_component.cc
Normal file
79
base-hw/src/core/signal_session_component.cc
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* \brief Implementation of the SIGNAL service on the HW-core
|
||||
* \author Martin Stein
|
||||
* \date 2012-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <kernel/syscalls.h>
|
||||
|
||||
/* core includes */
|
||||
#include <signal_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum {
|
||||
RECEIVER_SLAB_CHUNK_SIZE = 32,
|
||||
CONTEXT_SLAB_CHUNK_SIZE = 32,
|
||||
};
|
||||
|
||||
|
||||
Signal_session_component::Signal_session_component(Allocator * const md,
|
||||
size_t const ram_quota) :
|
||||
_md_alloc(md, ram_quota),
|
||||
_receivers_slab(Kernel::signal_receiver_size(),
|
||||
RECEIVER_SLAB_CHUNK_SIZE * Kernel::signal_receiver_size(),
|
||||
0, &_md_alloc),
|
||||
|
||||
_contexts_slab(Kernel::signal_context_size(),
|
||||
CONTEXT_SLAB_CHUNK_SIZE * Kernel::signal_context_size(),
|
||||
0, &_md_alloc)
|
||||
{ }
|
||||
|
||||
|
||||
Signal_session_component::~Signal_session_component()
|
||||
{
|
||||
PERR("%s: Not implemented", __PRETTY_FUNCTION__);
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
Signal_receiver_capability Signal_session_component::alloc_receiver()
|
||||
{
|
||||
/* create receiver kernel-object */
|
||||
size_t const s = Kernel::signal_receiver_size();
|
||||
void * p;
|
||||
if (!_receivers_slab.alloc(s, &p)) throw Out_of_metadata();
|
||||
unsigned long const id = Kernel::new_signal_receiver(p);
|
||||
if (!id) throw Out_of_metadata();
|
||||
|
||||
/* return reference to the new kernel-object */
|
||||
Native_capability c(id, 0);
|
||||
return reinterpret_cap_cast<Signal_receiver>(c);
|
||||
}
|
||||
|
||||
|
||||
Signal_context_capability
|
||||
Signal_session_component::alloc_context(Signal_receiver_capability r,
|
||||
unsigned long imprint)
|
||||
{
|
||||
/* create context kernel-object */
|
||||
size_t const s = Kernel::signal_context_size();
|
||||
void * p;
|
||||
if (!_contexts_slab.alloc(s, &p)) throw Out_of_metadata();
|
||||
unsigned long const id = Kernel::new_signal_context(p, r.dst(), imprint);
|
||||
if (!id) throw Out_of_metadata();
|
||||
|
||||
/* return reference to the new kernel-object */
|
||||
Native_capability c(id, 0);
|
||||
return reinterpret_cap_cast<Signal_context>(c);
|
||||
}
|
||||
|
49
base-hw/src/core/target.mk
Normal file
49
base-hw/src/core/target.mk
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# \brief The core of Genode
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-16
|
||||
#
|
||||
|
||||
# set program name
|
||||
TARGET = core
|
||||
|
||||
# use core specific startup library
|
||||
STARTUP_LIB = startup_core
|
||||
|
||||
# add library dependencies
|
||||
LIBS += cxx raw_ipc heap process pager lock console signal raw_server \
|
||||
syscall startup_core core_support
|
||||
|
||||
# add include paths
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
INC_DIR += $(REP_DIR)/src/core/include $(REP_DIR)/include \
|
||||
$(REP_DIR)/src/platform $(GEN_CORE_DIR)/include \
|
||||
$(BASE_DIR)/src/platform $(BASE_DIR)/src/core/include \
|
||||
$(BASE_DIR)/include
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += main.cc _main.cc ram_session_component.cc \
|
||||
ram_session_support.cc rom_session_component.cc \
|
||||
pd_session_component.cc io_mem_session_component.cc \
|
||||
io_mem_session_support.cc thread.cc platform_pd.cc platform.cc \
|
||||
platform_thread.cc dataspace_component.cc rm_session_component.cc \
|
||||
io_port_session_component.cc \
|
||||
irq_session_component.cc signal_session_component.cc \
|
||||
dump_alloc.cc cpu_session_component.cc \
|
||||
cpu_session_support.cc console.cc
|
||||
|
||||
# declare file locations
|
||||
vpath _main.cc $(BASE_DIR)/src/platform
|
||||
vpath main.cc $(GEN_CORE_DIR)
|
||||
vpath ram_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath rom_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath cpu_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath pd_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath rm_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
|
||||
vpath dataspace_component.cc $(GEN_CORE_DIR)
|
||||
vpath dump_alloc.cc $(GEN_CORE_DIR)
|
||||
vpath console.cc $(REP_DIR)/src/base
|
||||
vpath % $(REP_DIR)/src/core
|
||||
|
92
base-hw/src/core/thread.cc
Normal file
92
base-hw/src/core/thread.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* \brief Implementation of Thread API interface for core
|
||||
* \author Martin Stein
|
||||
* \date 2012-01-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
#include <kernel/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Genode::Native_utcb * _main_utcb;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
/* this is the main thread */
|
||||
if (!this) { return _main_utcb; }
|
||||
|
||||
/* this isn't the main thread */
|
||||
return _tid->phys_utcb();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns 0 if this is the main thread or the thread base pointer otherwise
|
||||
*/
|
||||
Thread_base * Thread_base::myself()
|
||||
{
|
||||
/* get our platform thread wich holds our thread base or 0 */
|
||||
Platform_thread * const pt = Kernel::get_thread();
|
||||
if (pt) return pt->thread_base();
|
||||
|
||||
/* we are core main, the only thread beside idle with no platform thread */
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
static void thread_entry()
|
||||
{
|
||||
/* this is never called by a main thread */
|
||||
Thread_base::myself()->entry();
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
: _list_element(this), _tid(0)
|
||||
{
|
||||
_tid = new (platform()->core_mem_alloc())
|
||||
Platform_thread(name, this, stack_size, Kernel::core_id());
|
||||
}
|
||||
|
||||
|
||||
Thread_base::~Thread_base()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
size_t const stack_size = _tid->stack_size()/sizeof(unsigned long) + 1;
|
||||
void * const stack_base = new (platform()->core_mem_alloc())
|
||||
unsigned long [stack_size];
|
||||
void * sp = (void *)((addr_t)stack_base + _tid->stack_size());
|
||||
void * ip = (void *)&thread_entry;
|
||||
if (_tid->start(ip, sp)) PERR("Couldn't start thread");
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
}
|
||||
|
21
base-hw/src/core/vea9x4/kernel_support.h
Normal file
21
base-hw/src/core/vea9x4/kernel_support.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* \brief Kernel support specific for the Versatile VEA9X4
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__CORE__VEA9X4__KERNEL_SUPPORT_H_
|
||||
#define _SRC__CORE__VEA9X4__KERNEL_SUPPORT_H_
|
||||
|
||||
/* local includes */
|
||||
#include <cortex_a9/kernel_support.h>
|
||||
|
||||
#endif /* _SRC__CORE__VEA9X4__KERNEL_SUPPORT_H_ */
|
||||
|
83
base-hw/src/core/vea9x4/platform_support.cc
Normal file
83
base-hw/src/core/vea9x4/platform_support.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and VEA9X4
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/board/vea9x4.h>
|
||||
#include <drivers/cpu/cortex_a9/core.h>
|
||||
#include <drivers/pic/pl390_base.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Vea9x4::LOCAL_DDR2_BASE, Vea9x4::LOCAL_DDR2_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 0, Pl390_base::MAX_INTERRUPT_ID + 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_irq_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* Core timer */
|
||||
{ Cortex_a9::PRIVATE_TIMER_IRQ, 1 },
|
||||
|
||||
/* Core UART */
|
||||
{ Vea9x4::PL011_0_IRQ, 1 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ Vea9x4::SMB_CS7_BASE, Vea9x4::SMB_CS7_SIZE },
|
||||
{ Vea9x4::SMB_CS0_TO_CS6_BASE, Vea9x4::SMB_CS0_TO_CS6_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
/* Core timer and PIC */
|
||||
{ Vea9x4::CORTEX_A9_PRIVATE_MEM_BASE,
|
||||
Vea9x4::CORTEX_A9_PRIVATE_MEM_SIZE },
|
||||
|
||||
/* Core UART */
|
||||
{ Vea9x4::PL011_0_MMIO_BASE, Vea9x4::PL011_0_MMIO_SIZE }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
26
base-hw/src/core/vea9x4/software_tlb.h
Normal file
26
base-hw/src/core/vea9x4/software_tlb.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Software TLB controls specific for the Versatile VEA9X4
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_
|
||||
#define _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <drivers/cpu/cortex_a9/section_table.h>
|
||||
|
||||
/**
|
||||
* Software TLB controls
|
||||
*/
|
||||
class Software_tlb : public Genode::Section_table { };
|
||||
|
||||
#endif /* _SRC__CORE__VEA9X4__SOFTWARE_TLB_H_ */
|
||||
|
20
base-hw/src/platform/_main_helper.h
Normal file
20
base-hw/src/platform/_main_helper.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Martin Stein
|
||||
* \date 2010-09-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__PLATFORM__MAIN_HELPER_H_
|
||||
#define _SRC__PLATFORM__MAIN_HELPER_H_
|
||||
|
||||
static void main_thread_bootstrap() { }
|
||||
|
||||
#endif /* _SRC__PLATFORM__MAIN_HELPER_H_ */
|
||||
|
61
base-hw/src/platform/crt0.s
Normal file
61
base-hw/src/platform/crt0.s
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* \brief Startup code for Genode programs on Cortex A9
|
||||
* \author Martin Stein
|
||||
* \date 2011-10-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
.section .text
|
||||
|
||||
/* ELF entry symbol */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* zero-fill BSS segment but don't pollute thread-entry arguments */
|
||||
.extern _bss_start
|
||||
ldr r4, =_bss_start
|
||||
.extern _bss_end
|
||||
ldr r3, =_bss_end
|
||||
mov r2, #0
|
||||
sub r3, r3, #4
|
||||
1:
|
||||
str r2, [r4]
|
||||
add r4, r4, #4
|
||||
cmp r4, r3
|
||||
bne 1b
|
||||
|
||||
/* fetch thread-entry arguments to their destinations in BSS */
|
||||
ldr r1, =_main_utcb
|
||||
str r0, [r1]
|
||||
|
||||
/* call _main routine */
|
||||
ldr sp, =_main_stack_high
|
||||
.extern _main
|
||||
bl _main
|
||||
1:
|
||||
b 1b
|
||||
|
||||
/* dynamic symbol object handle */
|
||||
.align 3
|
||||
.global __dso_handle
|
||||
__dso_handle: .long 0
|
||||
|
||||
.section .bss
|
||||
|
||||
/* main-thread stack */
|
||||
.align 3
|
||||
.space 64*1024
|
||||
.global _main_stack_high
|
||||
_main_stack_high:
|
||||
|
||||
/* main-thread UTCB-pointer for the Genode thread-API */
|
||||
.align 3
|
||||
.global _main_utcb
|
||||
_main_utcb: .long 0
|
||||
|
123
base-hw/src/platform/genode.ld
Normal file
123
base-hw/src/platform/genode.ld
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* \brief Linker script for Genode programs
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-04-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
ro PT_LOAD;
|
||||
rw PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
_prog_img_beg = .;
|
||||
|
||||
*(.init)
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.fini)
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
. = ALIGN(0x08);
|
||||
|
||||
_ctors_start = .;
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
|
||||
_ctors_end = .;
|
||||
_dtors_start = .;
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
_dtors_end = .;
|
||||
} : ro = 0x90909090
|
||||
|
||||
/* Linux: exception section for uaccess mechanism */
|
||||
__ex_table : { *(__ex_table) }
|
||||
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
_prog_img_data = .;
|
||||
|
||||
.data : {
|
||||
/*
|
||||
* Leave space for parent capability parameters at start of data
|
||||
* section. The protection domain creator is reponsible for storing
|
||||
* sane values here.
|
||||
*/
|
||||
_parent_cap = .;
|
||||
_parent_cap_thread_id = .;
|
||||
LONG(0xffffffff);
|
||||
_parent_cap_local_name = .;
|
||||
LONG(0xffffffff);
|
||||
|
||||
/*
|
||||
* Platform-specific entry for Fiasco.OC.
|
||||
*
|
||||
* PIC-code compiled for Fiasco.OC, needs some PIC-compatible
|
||||
* way to enter the kernel, the fixed address of the kernel
|
||||
* entry code address needs to be found here.
|
||||
*/
|
||||
__l4sys_invoke_indirect = .;
|
||||
LONG(0xeacff000);
|
||||
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
} : rw
|
||||
|
||||
/* exception frames for C++ */
|
||||
.eh_frame : {
|
||||
__eh_frame_start__ = .;
|
||||
KEEP (*(.eh_frame))
|
||||
LONG(0)
|
||||
} : rw
|
||||
|
||||
.init_array : {
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
}
|
||||
|
||||
.gcc_except_table : {
|
||||
KEEP(*(.gcc_except_table))
|
||||
KEEP(*(.gcc_except_table.*))
|
||||
}
|
||||
|
||||
.dynamic : { *(.dynamic) }
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : {
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
}
|
||||
__exidx_end = .;
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab*)
|
||||
} : rw
|
||||
|
||||
.bss : {
|
||||
_bss_start = .;
|
||||
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
|
||||
}
|
||||
_bss_end = .;
|
||||
_prog_img_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.note)
|
||||
*(.note.ABI-tag)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
@ -23,9 +23,11 @@ namespace Genode
|
||||
{
|
||||
enum
|
||||
{
|
||||
/* buses */
|
||||
/* interconnect domains */
|
||||
L4_PER_BASE = 0x48000000,
|
||||
L4_PER_SIZE = 0x01000000,
|
||||
L4_CFG_BASE = 0x4a000000,
|
||||
L4_CFG_SIZE = 0x01000000,
|
||||
|
||||
/* clocks */
|
||||
MPU_DPLL_CLOCK = 200*1000*1000,
|
||||
|
Loading…
Reference in New Issue
Block a user