mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
codezero: remove support from Genode (fix #1668)
This commit is contained in:
parent
7898113f99
commit
acc46f70b7
2
README
2
README
@ -13,7 +13,7 @@ the project's official website:
|
||||
[http://genode.org/documentation/general-overview]
|
||||
|
||||
The current implementation can be compiled for 8 different kernels: Linux,
|
||||
L4ka::Pistachio, L4/Fiasco, OKL4, NOVA, Fiasco.OC, Codezero, and a custom
|
||||
L4ka::Pistachio, L4/Fiasco, OKL4, NOVA, Fiasco.OC, seL4, and a custom
|
||||
kernel for running Genode directly on ARM-based hardware. Whereas the Linux
|
||||
version serves us as development vehicle and enables us to rapidly develop the
|
||||
generic parts of the system, the actual target platforms of the framework are
|
||||
|
@ -359,9 +359,9 @@ Platforms
|
||||
:Evaluation of MP scheduling models on different Genode base platforms:
|
||||
|
||||
Several of Genode's supported base platforms come with multi-processor
|
||||
support, i.e., Linux, NOVA, L4ka::Pistachio, Codezero, and Fiasco.OC. Each of
|
||||
support, i.e., Linux, NOVA, L4ka::Pistachio, and Fiasco.OC. Each of
|
||||
these kernels follows a different approach for utilizing multiple CPUs. For
|
||||
example, Linux and Codezero manage the association of threads with CPUs
|
||||
example, Linux manages the association of threads with CPUs
|
||||
largely transparent for user-level programs. In contrast, NOVA makes the use
|
||||
of multiple CPUs explicit and constraints the modes of IPC interaction of
|
||||
threads running on different CPUs. Furthermore, kernels differ with regard to
|
||||
|
@ -169,7 +169,6 @@ different time sources. Time sources are either hardware timers, a time source
|
||||
provided by the kernel, or a pseudo time source (busy):
|
||||
|
||||
:'nova': NOVA kernel semaphores as time source
|
||||
:'codezero': busy time source
|
||||
:'okl4_x86': PIT as time source
|
||||
:'foc': IPC timeout as time source
|
||||
:'fiasco': IPC timeout as time source
|
||||
|
@ -57,10 +57,6 @@ but build upon of each other:
|
||||
L4/Fiasco kernel developed at University of Technology Dresden.
|
||||
See [http://genode.org/documentation/platforms/fiasco]
|
||||
|
||||
:'codezero':
|
||||
Codezero microkernel developed by B-Labs
|
||||
See [http://genode.org/documentation/platforms/codezero]
|
||||
|
||||
:'sel4':
|
||||
seL4 microkernel developed at NICTA/General Dynamics
|
||||
See[https://sel4.systems/]
|
||||
|
@ -1,25 +0,0 @@
|
||||
#
|
||||
# \brief Download and prepare the Codezero kernel
|
||||
# \author Norman Feske
|
||||
# \date 2011-08-05
|
||||
#
|
||||
|
||||
VERBOSE ?= @
|
||||
ECHO := @echo
|
||||
|
||||
#
|
||||
# Print help information by default
|
||||
#
|
||||
help::
|
||||
|
||||
prepare:
|
||||
$(VERBOSE)../../tool/ports/prepare_port codezero
|
||||
|
||||
help::
|
||||
$(ECHO)
|
||||
$(ECHO) "Prepare the codezero base repository"
|
||||
$(ECHO)
|
||||
$(ECHO) "--- available commands ---"
|
||||
$(ECHO) "prepare - checkout upstream source codes"
|
||||
$(ECHO) "clean - remove upstream source codes"
|
||||
$(ECHO)
|
@ -1,3 +0,0 @@
|
||||
This repository contains the port of Genode to the Codezero microkernel
|
||||
For instructions about using Genode with Codezero, please refer to
|
||||
'doc/codezero.txt'.
|
@ -1,240 +0,0 @@
|
||||
#
|
||||
# Automatically generated, don't edit
|
||||
#
|
||||
# Generated on: furnace
|
||||
# At: Fri, 05 Aug 2011 21:48:00 +0000
|
||||
# Linux version 2.6.32-33-generic (buildd@rothera) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #70-Ubuntu SMP Thu Jul 7 21:09:46 UTC 2011
|
||||
|
||||
#
|
||||
# Codezero Microkernel Configurator
|
||||
#
|
||||
|
||||
#
|
||||
# Main architecture
|
||||
#
|
||||
CONFIG_ARCH_ARM=y
|
||||
|
||||
|
||||
#
|
||||
# ARM Architecture Configuration
|
||||
#
|
||||
|
||||
#
|
||||
# ARM Platform Type
|
||||
#
|
||||
CONFIG_PLATFORM_PB926=y
|
||||
CONFIG_PLATFORM_PBA9=n
|
||||
CONFIG_PLATFORM_BEAGLE=n
|
||||
CONFIG_PLATFORM_EB=n
|
||||
|
||||
|
||||
#
|
||||
# ARM Processor Type
|
||||
#
|
||||
CONFIG_CPU_ARM926=y
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Generic Processor Properties
|
||||
#
|
||||
CONFIG_ICACHE_DISABLE=n
|
||||
CONFIG_DCACHE_DISABLE=n
|
||||
|
||||
|
||||
#
|
||||
# Generic Kernel Properties
|
||||
#
|
||||
CONFIG_PREEMPT_DISABLE=n
|
||||
CONFIG_DEBUG_ACCOUNTING=n
|
||||
CONFIG_DEBUG_SPINLOCKS=n
|
||||
CONFIG_SCHED_TICKS=1000
|
||||
|
||||
|
||||
#
|
||||
# Toolchain Prefix
|
||||
#
|
||||
CONFIG_TOOLCHAIN_USERSPACE="arm-none-linux-gnueabi-"
|
||||
CONFIG_TOOLCHAIN_KERNEL="arm-none-eabi-"
|
||||
|
||||
|
||||
#
|
||||
# Container Setup
|
||||
#
|
||||
CONFIG_CAPABILITIES=n
|
||||
CONFIG_CONTAINERS=1
|
||||
|
||||
#
|
||||
# Container 0 Parameters
|
||||
#
|
||||
|
||||
#
|
||||
# Container 0 Type
|
||||
#
|
||||
CONFIG_CONT0_TYPE_BAREMETAL=y
|
||||
CONFIG_CONT0_TYPE_POSIX=n
|
||||
CONFIG_CONT0_TYPE_LINUX=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Options
|
||||
#
|
||||
CONFIG_CONT0_OPT_NAME="empty0"
|
||||
|
||||
#
|
||||
# Baremetal Project Type
|
||||
#
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_EMPTY=y
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_HELLO_WORLD=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_THREADS_DEMO=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_TEST_SUITE=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_UART_SERVICE=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_TIMER_SERVICE=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_KMI_SERVICE=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_MUTEX_DEMO=n
|
||||
CONFIG_CONT0_BAREMETAL_PROJ_IPC_DEMO=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Pager Linker Parameters
|
||||
#
|
||||
CONFIG_CONT0_PAGER_LMA=0x41000
|
||||
CONFIG_CONT0_PAGER_VMA=0x100000
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Pager Physical Memory Regions (Capabilities)
|
||||
#
|
||||
CONFIG_CONT0_PAGER_PHYSMEM_REGIONS=1
|
||||
CONFIG_CONT0_PAGER_PHYS0_START=0x41000
|
||||
CONFIG_CONT0_PAGER_PHYS0_END=0x4000000
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Pager Virtual Memory Regions (Capabilities)
|
||||
#
|
||||
CONFIG_CONT0_PAGER_VIRTMEM_REGIONS=1
|
||||
CONFIG_CONT0_PAGER_VIRT0_START=0x0
|
||||
CONFIG_CONT0_PAGER_VIRT0_END=0x50000000
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Pager Capabilities
|
||||
#
|
||||
|
||||
#
|
||||
# Container 0 Thread Pool Capability
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_THREADPOOL_USE=y
|
||||
CONFIG_CONT0_PAGER_CAP_THREADPOOL_SIZE=64
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Space Pool Capability
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_SPACEPOOL_USE=y
|
||||
CONFIG_CONT0_PAGER_CAP_SPACEPOOL_SIZE=64
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Mutex Pool Capability
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_MUTEXPOOL_USE=y
|
||||
CONFIG_CONT0_PAGER_CAP_MUTEXPOOL_SIZE=100
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Map Pool Capability
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_MAPPOOL_USE=y
|
||||
CONFIG_CONT0_PAGER_CAP_MAPPOOL_SIZE=800
|
||||
|
||||
|
||||
#
|
||||
# Container 0 IPC Capability
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_IPC_USE=y
|
||||
CONFIG_CONT0_PAGER_CAP_IPC_TARGET_CURRENT_CONTAINER=y
|
||||
CONFIG_CONT0_PAGER_CAP_IPC_TARGET_CURRENT_PAGER_SPACE=n
|
||||
CONFIG_CONT0_PAGER_CAP_IPC_TARGET_OTHER_CONTAINER=n
|
||||
CONFIG_CONT0_PAGER_CAP_IPC_TARGET_OTHER_PAGER=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 IRQ Control Capability
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_IRQCTRL_USE=y
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Custom Capability 0 Parameters
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_CUSTOM0_USE=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Custom Capability 1 Parameters
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_CUSTOM1_USE=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Custom Capability 2 Parameters
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_CUSTOM2_USE=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Custom Capability 3 Parameters
|
||||
#
|
||||
CONFIG_CONT0_PAGER_CAP_CUSTOM3_USE=n
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Global Capabilities
|
||||
#
|
||||
|
||||
#
|
||||
# Container 0 IPC Capability
|
||||
#
|
||||
CONFIG_CONT0_CAP_IPC_USE=y
|
||||
CONFIG_CONT0_CAP_IPC_TARGET_CURRENT_CONTAINER=y
|
||||
CONFIG_CONT0_CAP_IPC_TARGET_CURRENT_PAGER_SPACE=n
|
||||
CONFIG_CONT0_CAP_IPC_TARGET_OTHER_CONTAINER=n
|
||||
CONFIG_CONT0_CAP_IPC_TARGET_OTHER_PAGER=n
|
||||
|
||||
|
||||
#
|
||||
# Container 0 Mutex Pool Capability
|
||||
#
|
||||
CONFIG_CONT0_CAP_MUTEXPOOL_USE=y
|
||||
CONFIG_CONT0_CAP_MUTEXPOOL_SIZE=100
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Derived symbols
|
||||
#
|
||||
CONFIG_CONT3_START_PC_ADDR=0xd0000000
|
||||
CONFIG_DEBUG_PERFMON_KERNEL=n
|
||||
CONFIG_CONT1_PAGER_LOAD_ADDR=0x1100000
|
||||
CONFIG_CONT2_START_PC_ADDR=0xc0000000
|
||||
CONFIG_CONT2_PAGER_VIRT_ADDR=0xc0000000
|
||||
CONFIG_RAM_BASE_PLAT=0
|
||||
CONFIG_CONT2_PAGER_LOAD_ADDR=0x2100000
|
||||
CONFIG_CONT1_PAGER_VIRT_ADDR=0xb0000000
|
||||
CONFIG_CONT3_PAGER_LOAD_ADDR=0x3100000
|
||||
CONFIG_SUBARCH_V5=y
|
||||
CONFIG_SUBARCH_V7=n
|
||||
CONFIG_SUBARCH_V6=n
|
||||
CONFIG_CONT0_PAGER_LOAD_ADDR=0x41000
|
||||
CONFIG_CONT0_PAGER_VIRT_ADDR=0x100000
|
||||
CONFIG_CONT3_PAGER_VIRT_ADDR=0xd0000000
|
||||
CONFIG_CONT0_START_PC_ADDR=0x100000
|
||||
CONFIG_CONT1_START_PC_ADDR=0xb0000000
|
||||
#
|
||||
# That's all, folks!
|
@ -1,274 +0,0 @@
|
||||
|
||||
==================================
|
||||
Genode on the Codezero microkernel
|
||||
==================================
|
||||
|
||||
|
||||
Norman Feske
|
||||
|
||||
|
||||
Codezero is a microkernel primarily targeted at ARM-based embedded systems.
|
||||
It is developed by the British company B-Labs.
|
||||
|
||||
:B-Labs website:
|
||||
|
||||
[http://b-labs.com]
|
||||
|
||||
The Codezero kernel was first made publicly available in summer 2009. The
|
||||
latest version, documentation, and community resources are available at the
|
||||
project website:
|
||||
|
||||
:Codezero project website:
|
||||
|
||||
[http://l4dev.org]
|
||||
|
||||
As highlighted by the name of the project website, the design of the kernel is
|
||||
closely related to the family of L4 microkernels. In short, the kernel provides
|
||||
a minimalistic set of functionality for managing address spaces, threads, and
|
||||
communication between threads, but leaves complicated policy and device access
|
||||
to user-level components.
|
||||
|
||||
|
||||
Using Genode with Codezero
|
||||
##########################
|
||||
|
||||
For using Codezero, please ensure to have Git, SCons, and Python installed as
|
||||
these tools are required for downloading and building the kernel. Furthermore,
|
||||
you will need to install the tool chain for ARM. For instructions on how to
|
||||
download and install the tool chain, please refer to:
|
||||
|
||||
:[http://genode.org/download/tool-chain]:
|
||||
Genode tool-chain
|
||||
|
||||
To download the Codezero kernel and integrate it with Genode, issue
|
||||
|
||||
! make prepare
|
||||
|
||||
from the 'base-codezero/' directory. The Codezero kernel is fully supported by
|
||||
Genode's run mechanism. Therefore, you can run Genode scenarios using Qemu
|
||||
directly from the build directory. For a quick test, let's create a build
|
||||
directory for Codezero on the VersatilePB926 platform using Genode's
|
||||
'create_builddir' tool:
|
||||
|
||||
! <genode-dir>/tool/create_builddir codezero_vpb926 BUILD_DIR=<build_dir>
|
||||
|
||||
To execute the graphical Genode demo, change to the new created build directory
|
||||
and issue:
|
||||
|
||||
! make run/demo
|
||||
|
||||
|
||||
Characteristics of the kernel
|
||||
#############################
|
||||
|
||||
To put Codezero in relation to other L4 kernels, here is a quick summary on the
|
||||
most important design aspects as implemented with the version 0.3, and on how
|
||||
our port of Genode relates to them:
|
||||
|
||||
* In the line of the original L4 interface, the kernel uses global name spaces
|
||||
for kernel objects such as threads and address spaces.
|
||||
|
||||
* For the interaction between a user thread and the kernel, the concept of
|
||||
user-level thread-control blocks (UTCB) is used. A UTCB is a small
|
||||
thread-specific region in the thread's virtual address space, which is
|
||||
always mapped. Hence the access to the UTCB can never raise a page fault,
|
||||
which makes it perfect for the kernel to access system-call arguments,
|
||||
in particular IPC payload copied from/to user threads. In contrast to other
|
||||
L4 kernels, the location of UTCBs within the virtual address space is managed
|
||||
by the user land.
|
||||
|
||||
On Genode, core keeps track of the UTCB locations for all user threads.
|
||||
This way, the physical backing store for the UTCB can be properly accounted
|
||||
to the corresponding protection domain.
|
||||
|
||||
* The kernel provides three kinds of synchronous inter-process communication
|
||||
(IPC): Short IPC carries payload in CPU registers only. Full IPC copies
|
||||
message payload via the UTCBs of the communicating parties. Extended IPC
|
||||
transfers a variable-sized message from/to arbitrary locations of the
|
||||
sender/receiver address spaces. During an extended IPC, page fault may
|
||||
occur.
|
||||
|
||||
Genode solely relies on extended IPC, leaving the other IPC mechanisms to
|
||||
future optimizations.
|
||||
|
||||
* The scheduling of threads is based on hard priorities. Threads with the
|
||||
same priority are executed in a round-robin fashion. The kernel supports
|
||||
time-slice-based preemption.
|
||||
|
||||
Genode does not support Codezero priorities yet.
|
||||
|
||||
* The original L4 interface leaves open the question on how to manage
|
||||
and account kernel resources such as the memory used for page tables.
|
||||
Codezero makes the accounting of such resources explicit, enables the
|
||||
user-land to manage them in a responsible way, and prevent kernel-resource
|
||||
denial-of-service problems.
|
||||
|
||||
* In contrast to the original L4.v2 and L4.x0 interfaces, the kernel provides
|
||||
no time source in the form of IPC timeouts to the user land. A time source
|
||||
must be provided by a user-space timer driver. Genode employs such a timer
|
||||
services on all platforms so that it is not effected by this limitation.
|
||||
|
||||
In several ways, Codezero goes beyond the known L4 interfaces. The most
|
||||
noticeable addition is the support for so-called containers. A container is
|
||||
similar to a virtual machine. It is an execution environment that holds a set
|
||||
of physical resources such as RAM and devices. The number of containers and the
|
||||
physical resources assigned to them is static and is to be defined at build
|
||||
time. The code executed inside a container can be roughly classified into two
|
||||
cases. First, there are static programs that require strong isolation from the
|
||||
rest of the system but no classical operating-system infrastructure, for
|
||||
example special-purpose telecommunication stacks or cryptographic functionality
|
||||
of an embedded device. Second, there a kernel-like workload, which use the L4
|
||||
interface to substructure the container into address spaces, for example a
|
||||
paravirtualized Linux kernel that uses Codezero address spaces to protect Linux
|
||||
processes. Genode runs inside a container and facilitates Codezero's L4
|
||||
interface to implement its multi-server architecture.
|
||||
|
||||
|
||||
Behind the scenes
|
||||
#################
|
||||
|
||||
The 'make prepare' mechanism checks out the kernel source code from the
|
||||
upstream Git repository to 'base-codezero/contrib'. When building the kernel
|
||||
from within a Genode build directory via 'make kernel', this directory won't be
|
||||
touched by the Genode build system. Instead, a snapshot of the 'contrib'
|
||||
directory is taken to '<build-dir>/kernel/codezero'. This is the place where
|
||||
the Codezero configuration and build processes are executed. By working with a
|
||||
build-directory-local snapshot, we ensure that the source tree remains
|
||||
untouched at all times. After having taken the snapshot, the Codezero kernel is
|
||||
configured using a configuration template specific for the hardware platform.
|
||||
The configuration comes in the form of a CML file located at
|
||||
'base-codezero/config/'. There is one CML file per supported platform named
|
||||
'<platform>.cml'. The configured Codezero build directory will reside at
|
||||
'<build-dir>/kernel/codezero/build/'. Finally, the Codezero build system is
|
||||
invoked to build the kernel.
|
||||
|
||||
The two stages of building Codezero
|
||||
===================================
|
||||
|
||||
The Codezero build system always performs the compilation of the kernel and the
|
||||
so-called containers as well as the integration of all these components into a
|
||||
final ELF image as one operation. When building just the kernel via 'make
|
||||
kernel', the final image will contain the default container0 that comes with
|
||||
the Codezero distribution. For integrating Genode into the final image, the
|
||||
content of the container0 must be replaced by the Genode binaries followed by
|
||||
another execution of 'kernel/codezero/build.py'. Now, the single-image will be
|
||||
re-created, including the Genode binaries. When using Genode's run mechanism,
|
||||
these steps are automated for you. For reference, please review the Codezero
|
||||
run environment at 'base-codezero/run/env'.
|
||||
|
||||
By first building the kernel with Codezero's default container ('make kernel')
|
||||
and later replacing the container's content with Genode binaries, we
|
||||
optimize the work flow for building Genode components. The kernel is compiled
|
||||
only once, but the (quick) re-linking of the final image is done every time a
|
||||
run script is executed.
|
||||
|
||||
In the run environment, you will see that we forcefully remove a file called
|
||||
'cinfo.c' from the build-directory-local snapshot of the Codezero source tree.
|
||||
This file is generated automatically by the Codezero build system and linked
|
||||
against the kernel. It contains the parameters of the containers executed on
|
||||
the kernel. Because we change the content of container0 each time when
|
||||
executing a run script, those parameter change. So we have to enforce to
|
||||
re-generation of the 'cinfo.c' file.
|
||||
|
||||
How Genode ROM modules are passed into the final image
|
||||
======================================================
|
||||
|
||||
The Codezero build system picks up any ELF files residing the container's
|
||||
directory wheres the file called 'main.elf' is considered to be the roottask
|
||||
(in Codezero speak called pager) of the container. For Genode, 'main.elf'
|
||||
corresponds to the core executable. All other boot modules are merged into an
|
||||
ELF file, which we merely use as a container for these binary data. This ELF
|
||||
file is linked such that it gets loaded directly after the core image (this is
|
||||
how core finds the boot modules). The process of archiving all boot modules
|
||||
into the single ELF file is automated via the 'base-codezero/tool/gen_romfs'
|
||||
tool. In the container's directory, the merged file is called 'modules.elf'.
|
||||
|
||||
Adapting the source code of the kernel
|
||||
======================================
|
||||
|
||||
For debugging and development you might desire to change the kernel code
|
||||
at times. You can safely do so within the 'base-codezero/contrib/' directory.
|
||||
When issuing the next 'make kernel' from the Genode build directory, your
|
||||
changes will be picked up. However, when working with run scripts, the kernel
|
||||
is not revisited each time. The kernel gets built only once if the
|
||||
'<build-dir>/kernel' directory does not exist, yet. If you work on the kernel
|
||||
source tree and wish to conveniently test the kernel with a run script, use
|
||||
|
||||
! make kernel run/<run-script>
|
||||
|
||||
This way, you make sure to rebuild the kernel prior executing the steps
|
||||
described in the run script.
|
||||
|
||||
Tweaking the kernel configuration
|
||||
=================================
|
||||
|
||||
The kernel configuration can be tweaked within '<build-dir>/kernel/codezero'.
|
||||
Just change to this directory and issue './build.py -C'. The next time you
|
||||
build the kernel via 'make kernel' your configuration will be applied.
|
||||
If you want to conserve your custom configuration, just copy the file
|
||||
'<build-dir>/kernel/codezero/build/config.cml'.
|
||||
|
||||
Parameters of 'vpb926.cml' explained
|
||||
====================================
|
||||
|
||||
The default configuration for the VersatilePB926 platform as found at
|
||||
'base-codzero/config/vpb926.cml' is paramaterized as follows:
|
||||
|
||||
:Default pager parameters:
|
||||
! 0x41000 Pager LMA
|
||||
! 0x100000 Pager VMA
|
||||
These values are important because they are currently hard-wired in the
|
||||
linker script used by Genode. If you need to adopt these values, make
|
||||
sure to also update the Genode linker script located at
|
||||
'base-codezero/src/platform/genode.ld'.
|
||||
|
||||
:Physical Memory Regions:
|
||||
! 1 Number of Physical Regions
|
||||
! 0x41000 Physical Region 0 Start Address
|
||||
! 0x4000000 Physical Region 0 End Address
|
||||
We only use 64MB of memory. The physical memory between 0 and 0x41000 is
|
||||
used by the kernel.
|
||||
|
||||
:Virtual Memory Regions:
|
||||
! 1 Number of Virtual Regions
|
||||
! 0x0 Virtual Region 0 Start Address
|
||||
! 0x50000000 Virtual Region 0 End Address
|
||||
It is important to choose the end address such that the virtual memory
|
||||
covers the thread context area. The context area is defined at
|
||||
'base/include/base/thread.h'.
|
||||
|
||||
|
||||
Limitations
|
||||
###########
|
||||
|
||||
At the current stage, the Genode version for Codezero is primarily geared
|
||||
towards the developers of Codezero as a workload to stress their kernel. It
|
||||
still has a number of limitations that would affect the real-world use:
|
||||
|
||||
* Because the only platform supported out of the box by the official Codezero
|
||||
source tree is the ARM-based Versatilebp board, Genode is currently tied to
|
||||
this hardware platform.
|
||||
|
||||
* The current timer driver at 'os/src/drivers/timer/codezero/' is a dummy
|
||||
driver that just yields the CPU time instead of blocking. Is is not
|
||||
suitable as time source.
|
||||
|
||||
* The PL110 framebuffer driver at 'os/src/drivers/framebuffer/pl110/'
|
||||
does only support the LCD display as provided by Qemu but it is not tested on
|
||||
real hardware.
|
||||
|
||||
* Even though Codezero provides priority-based scheduling, Genode does not
|
||||
allow assigning priorities to Codezero processes, yet.
|
||||
|
||||
As always, these limitations will be addressed as needed.
|
||||
|
||||
|
||||
Thanks
|
||||
######
|
||||
|
||||
We want to thank the main developer of Codezero Bahadir Balban for his great
|
||||
responsiveness to our feature requests and questions. Without his help, the
|
||||
porting effort would have taken much more effort. We hope that our framework
|
||||
will be of value to the Codezero community.
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
SPECS = genode
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* \brief Atomic operations for ARM on codezero
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__ARM__CPU__ATOMIC_H_
|
||||
#define _INCLUDE__ARM__CPU__ATOMIC_H_
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Atomic compare and exchange
|
||||
*
|
||||
* This function compares the value at dest with cmp_val.
|
||||
* If both values are equal, dest is set to new_val. If
|
||||
* both values are different, the value at dest remains
|
||||
* unchanged.
|
||||
*
|
||||
* \return 1 if the value was successfully changed to new_val,
|
||||
* 0 if cmp_val and the value at dest differ.
|
||||
*/
|
||||
int cmpxchg(volatile int *dest, int cmp_val, int new_val);
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__ARM__CPU__ATOMIC_H_ */
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* \brief IPC message buffer
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__IPC_MSGBUF_H_
|
||||
#define _INCLUDE__BASE__IPC_MSGBUF_H_
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* IPC message buffer layout
|
||||
*/
|
||||
class Msgbuf_base
|
||||
{
|
||||
protected:
|
||||
|
||||
size_t _size;
|
||||
char _msg_start[]; /* symbol marks start of message */
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Begin of actual message buffer
|
||||
*/
|
||||
char buf[];
|
||||
|
||||
/**
|
||||
* Return size of message buffer
|
||||
*/
|
||||
inline size_t size() const { return _size; };
|
||||
|
||||
/**
|
||||
* Return address of message buffer
|
||||
*/
|
||||
inline void *addr() { return &_msg_start[0]; };
|
||||
|
||||
} __attribute__((aligned(4)));
|
||||
|
||||
/**
|
||||
* Instance of IPC message buffer with specified buffer size
|
||||
*/
|
||||
template <unsigned BUF_SIZE>
|
||||
class Msgbuf : public Msgbuf_base
|
||||
{
|
||||
public:
|
||||
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
Msgbuf() { _size = BUF_SIZE; }
|
||||
|
||||
} __attribute__((aligned(4)));
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__IPC_MSGBUF_H_ */
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* \brief Dummy definitions for native types used for compiling unit tests
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
#define _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
|
||||
#include <base/native_capability.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Codezero {
|
||||
|
||||
struct l4_mutex;
|
||||
|
||||
enum { NILTHREAD = -1 };
|
||||
}
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
typedef int Dst;
|
||||
|
||||
static bool valid(Dst tid) { return tid != Codezero::NILTHREAD; }
|
||||
static Dst invalid() { return Codezero::NILTHREAD; }
|
||||
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
|
||||
};
|
||||
|
||||
typedef Cap_dst_policy::Dst Native_thread_id;
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
Native_thread_id l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to the
|
||||
* physical thread object, which is going to be destroyed on
|
||||
* destruction of the 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Empty UTCB type expected by the thread library
|
||||
*
|
||||
* On this kernel, UTCBs are not placed within the the context area. Each
|
||||
* thread can request its own UTCB pointer using the kernel interface.
|
||||
* However, we use the 'Native_utcb' member of the thread context to
|
||||
* hold thread-specific data, i.e. the running lock used by the lock
|
||||
* implementation.
|
||||
*/
|
||||
struct Native_utcb
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Prevent construction
|
||||
*
|
||||
* A UTCB is never constructed, it is backed by zero-initialized memory.
|
||||
*/
|
||||
Native_utcb();
|
||||
|
||||
/**
|
||||
* Backing store for per-thread running lock
|
||||
*
|
||||
* The size of this member must equal 'sizeof(Codezero::l4_mutex)'.
|
||||
* Unfortunately, we cannot include the Codezero headers here.
|
||||
*/
|
||||
int _running_lock;
|
||||
|
||||
public:
|
||||
|
||||
Codezero::l4_mutex *running_lock() {
|
||||
return (Codezero::l4_mutex *)&_running_lock; }
|
||||
};
|
||||
|
||||
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
||||
typedef int Native_connection_state;
|
||||
|
||||
struct Native_config
|
||||
{
|
||||
/**
|
||||
* Thread-context area configuration.
|
||||
*/
|
||||
static constexpr addr_t context_area_virtual_base() {
|
||||
return 0x40000000UL; }
|
||||
static constexpr addr_t context_area_virtual_size() {
|
||||
return 0x10000000UL; }
|
||||
|
||||
/**
|
||||
* Size of virtual address region holding the context of one thread
|
||||
*/
|
||||
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
|
||||
};
|
||||
|
||||
struct Native_pd_args { };
|
||||
}
|
||||
|
||||
|
||||
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* \brief Aggregate Codezero syscall bindings
|
||||
* \author Norman Feske
|
||||
* \date 2010-02-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__CODEZERO__SYSCALLS_H_
|
||||
#define _INCLUDE__CODEZERO__SYSCALLS_H_
|
||||
|
||||
/*
|
||||
* Codezero headers happen to include the compiler's 'stdarg.h'. If this
|
||||
* happened within the 'Codezero' namespace below, we would not be able to
|
||||
* include 'stdarg.h' later on into the root namespace (stdarg's include guards
|
||||
* would prevent this. Therefore, we make sure to include the file into the
|
||||
* root namespace prior processing any Codezero headers.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace Codezero { extern "C" {
|
||||
|
||||
/* make Codezero includes happy */
|
||||
extern char *strncpy(char *dest, const char *src, __SIZE_TYPE__);
|
||||
extern void *memcpy(void *dest, const void *src, __SIZE_TYPE__);
|
||||
|
||||
/*
|
||||
* Work around the problem of C++ keywords being used as
|
||||
* argument names in the Codezero API headers.
|
||||
*/
|
||||
#define new _new_
|
||||
#define virtual _virtual_
|
||||
#define printf(A, ...)
|
||||
|
||||
#include <l4lib/macros.h>
|
||||
#include <l4lib/arch/arm/syscalls.h>
|
||||
#include <l4lib/arch/arm/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/mutex.h>
|
||||
#include <l4/api/thread.h>
|
||||
#include <l4/api/irq.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include <l4/lib/list.h> /* needed for capability.h */
|
||||
#include <l4/generic/capability.h>
|
||||
#include <l4/generic/cap-types.h>
|
||||
#include <l4/arch/arm/exception.h>
|
||||
#include <l4/arch/arm/io.h>
|
||||
|
||||
#undef new
|
||||
#undef virtual
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#undef printf
|
||||
|
||||
/*
|
||||
* Turn '#define cacheable' (as defined in the codezero headers) into an enum
|
||||
* value. Otherwise, the define will conflict with variables named 'cacheable'.
|
||||
*/
|
||||
enum { _codezero_cacheable = cacheable /* #define value */ };
|
||||
#undef cacheable
|
||||
enum { cacheable = _codezero_cacheable };
|
||||
|
||||
} }
|
||||
|
||||
namespace Codezero {
|
||||
|
||||
/**
|
||||
* Return thread ID of the calling thread
|
||||
*/
|
||||
inline int thread_myself()
|
||||
{
|
||||
struct task_ids ids = { 0, 0, 0 };
|
||||
l4_getid(&ids);
|
||||
return ids.tid;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__CODEZERO__SYSCALLS_H_ */
|
@ -1 +0,0 @@
|
||||
REP_INC_DIR += include/codezero/dummies
|
@ -1,11 +0,0 @@
|
||||
CODEZERO_DIR := $(call select_from_ports,codezero)/src/kernel/codezero
|
||||
|
||||
LIBL4_DIR = $(CODEZERO_DIR)/conts/userlibs/libl4
|
||||
|
||||
INC_DIR += $(CODEZERO_DIR)/conts/userlibs/libc/include
|
||||
|
||||
SRC_C += $(notdir $(wildcard $(LIBL4_DIR)/src/arch/arm/v5/*.c))
|
||||
SRC_S += $(notdir $(wildcard $(LIBL4_DIR)/src/arch/arm/v5/*.S))
|
||||
|
||||
vpath %.c $(LIBL4_DIR)/src/arch/arm/v5
|
||||
vpath %.S $(LIBL4_DIR)/src/arch/arm/v5
|
@ -1,3 +0,0 @@
|
||||
LIBS += l4_arm_v5
|
||||
|
||||
include $(REP_DIR)/lib/mk/l4.inc
|
@ -1,33 +0,0 @@
|
||||
#
|
||||
# \brief Portions of base library shared by core and non-core processes
|
||||
# \author Norman Feske
|
||||
# \date 2013-02-14
|
||||
#
|
||||
|
||||
LIBS += cxx syscall startup
|
||||
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
SRC_CC += allocator/slab.cc
|
||||
SRC_CC += allocator/allocator_avl.cc
|
||||
SRC_CC += heap/heap.cc heap/sliced_heap.cc
|
||||
SRC_CC += console/console.cc
|
||||
SRC_CC += child/child.cc
|
||||
SRC_CC += process/process.cc
|
||||
SRC_CC += elf/elf_binary.cc
|
||||
SRC_CC += lock/lock.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread.cc thread/myself.cc thread/thread_bootstrap.cc thread/trace.cc
|
||||
SRC_CC += thread/context_allocator.cc env/utcb.cc
|
||||
SRC_CC += lock/cmpxchg.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
INC_DIR += $(REP_DIR)/include/codezero/dummies
|
||||
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
@ -1,14 +0,0 @@
|
||||
SRC_CC += console/log_console.cc
|
||||
SRC_CC += cpu/cache.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
|
||||
SRC_CC += thread/thread_start.cc
|
||||
SRC_CC += irq/platform.cc
|
||||
|
||||
INC_DIR += $(BASE_DIR)/src/base/env
|
||||
INC_DIR += $(REP_DIR)/include/codezero/dummies
|
||||
|
||||
LIBS += base-common
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
@ -1,3 +0,0 @@
|
||||
ifeq ($(filter-out $(SPECS),platform_vpb926),)
|
||||
CODEZERO_CML = $(REP_DIR)/config/vpb926.cml
|
||||
endif
|
@ -1,51 +0,0 @@
|
||||
CODEZERO_DIR := $(call select_from_ports,codezero)/src/kernel/codezero
|
||||
|
||||
LIBL4_DIR = $(CODEZERO_DIR)/conts/userlibs/libl4
|
||||
|
||||
SRC_C += init.c irq.c mutex.c
|
||||
SRC_C += arch/arm/exregs.c
|
||||
SRC_S += $(addprefix arch/arm/,syscalls.S new_thread.S)
|
||||
SRC_C += $(addprefix lib/,addr.c bit.c idpool.c)
|
||||
SRC_C += $(addprefix lib/thread/,init.c thread.c)
|
||||
SRC_C += $(addprefix lib/cap/,cap.c read.c)
|
||||
|
||||
#
|
||||
# Dummies
|
||||
#
|
||||
SRC_C += dummy.c
|
||||
|
||||
INC_DIR += $(CODEZERO_DIR)/conts/userlibs/libc/include
|
||||
INC_DIR += $(CODEZERO_DIR)/conts/userlibs/libmem/include
|
||||
INC_DIR += $(CODEZERO_DIR)/conts/userlibs/libmem
|
||||
|
||||
vpath % $(LIBL4_DIR)/src
|
||||
vpath %.c $(REP_DIR)/src/lib/syscall
|
||||
|
||||
#
|
||||
# The libl4 source files uses macros defined in macros.h but do not
|
||||
# explicitly include the 'macros.h' header file.
|
||||
#
|
||||
CC_OPT += -include $(LIBL4_DIR)/include/l4lib/macros.h
|
||||
|
||||
#
|
||||
# Resolve conflicts with built-in functions
|
||||
#
|
||||
CC_OPT += -fno-builtin-pow
|
||||
|
||||
#
|
||||
# During the compilation of the libl4 file 'thread.c', the 'l4id_t' type
|
||||
# is used without prior inclusion of 'types.h'. Furthermore, 'types.h'
|
||||
# has a wrong include guard, so we take care of this problem using a
|
||||
# wrapper.
|
||||
#
|
||||
CC_OPT_lib_thread_thread += -include fix_include_types.h
|
||||
CC_OPT_arch_arm_exregs += -include fix_include_types.h
|
||||
|
||||
lib/thread/thread.o arch/arm/exregs.o: fix_include_types.h
|
||||
|
||||
fix_include_types.h:
|
||||
@echo "#include <l4lib/arch/arm/types.h>" > $@
|
||||
@echo "#define __L4LIB_ARM_TYPES_H___" >> $@
|
||||
|
||||
CC_OPT += -std=gnu99
|
||||
|
@ -1,5 +0,0 @@
|
||||
SRC_CC = core_printf.cc
|
||||
INC_DIR += $(REP_DIR)/src/base/console/pl011
|
||||
INC_DIR += $(REP_DIR)/include/codezero/dummies
|
||||
|
||||
vpath core_printf.cc $(BASE_DIR)/src/base/console
|
@ -1,33 +0,0 @@
|
||||
#
|
||||
# Create prerequisites for building Genode for Codezero
|
||||
#
|
||||
|
||||
#
|
||||
# Execute the rules in this file only at the second build stage when we know
|
||||
# about the complete build settings, e.g., the 'CROSS_DEV_PREFIX'.
|
||||
#
|
||||
ifeq ($(called_from_lib_mk),yes)
|
||||
|
||||
include $(REP_DIR)/lib/mk/codezero_cml.inc
|
||||
|
||||
all: $(BUILD_BASE_DIR)/include/l4/config.h
|
||||
|
||||
$(BUILD_BASE_DIR)/include/l4/config.h: $(CODEZERO_CML)
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)$(CODEZERO_DIR)/tools/cml2header.py -i $^ -o $@
|
||||
|
||||
#
|
||||
# Codezero's 'macros.h' includes the file "config.h", expected to be located in
|
||||
# the same directory (using #include "config.h"). However, 'config.h' is
|
||||
# generated into the source tree by the Codezero configuration system. Since we
|
||||
# do not want to pollute the source tree, we create a shadow copy of 'macros.h'
|
||||
# in the same directory as our generated 'config.h'.
|
||||
#
|
||||
all: $(BUILD_BASE_DIR)/include/l4/macros.h
|
||||
|
||||
$(BUILD_BASE_DIR)/include/l4/macros.h: $(CODEZERO_DIR)/include/l4/macros.h
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)ln -s $^ $@
|
||||
|
||||
endif
|
||||
|
@ -1,5 +0,0 @@
|
||||
include $(BASE_DIR)/lib/mk/startup.inc
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/codezero/dummies
|
||||
|
||||
vpath crt0.s $(BASE_DIR)/src/platform/arm
|
@ -1,39 +0,0 @@
|
||||
#
|
||||
# Specifics for the Codezero kernel API
|
||||
#
|
||||
|
||||
CODEZERO_DIR := $(call select_from_ports,codezero)/src/kernel/codezero
|
||||
|
||||
#
|
||||
# Convert path to absolute directory
|
||||
#
|
||||
absdir = $(shell readlink -f $(1))
|
||||
|
||||
#
|
||||
# Headers generated within the build directory
|
||||
# (see 'lib/mk/platform.mk')
|
||||
#
|
||||
INC_DIR += $(BUILD_BASE_DIR)/include
|
||||
|
||||
#
|
||||
# Codezero headers
|
||||
#
|
||||
INC_DIR += $(CODEZERO_DIR)/include
|
||||
INC_DIR += $(CODEZERO_DIR)/conts/userlibs/libl4/include
|
||||
INC_DIR += $(CODEZERO_DIR)/conts/userlibs/libdev/uart/include
|
||||
|
||||
#
|
||||
# Allow programs to test for the Codezero kernel
|
||||
#
|
||||
# This is needed by the 'pl050/irq_handler.h' to handle the interrupt semantics
|
||||
# of Codezero.
|
||||
#
|
||||
CC_OPT += -D__CODEZERO__
|
||||
|
||||
#
|
||||
# Clean rules for removing the side effects of building the platform
|
||||
#
|
||||
clean_includes:
|
||||
$(VERBOSE)rm -rf $(BUILD_BASE_DIR)/include
|
||||
|
||||
cleanall: clean_includes
|
@ -1,13 +0,0 @@
|
||||
#
|
||||
# Specifics for Codezero on ARM
|
||||
#
|
||||
SPECS += codezero
|
||||
|
||||
#
|
||||
# Linker options specific for ARM
|
||||
#
|
||||
LD_TEXT_ADDR ?= 0x02000000
|
||||
|
||||
CC_OPT += -D__ARCH__=arm
|
||||
|
||||
include $(call select_from_repositories,mk/spec-codezero.mk)
|
@ -1,9 +0,0 @@
|
||||
#
|
||||
# Specifics for Codezero on ARMv5
|
||||
#
|
||||
|
||||
SPECS += codezero_arm
|
||||
|
||||
CC_OPT += -D__SUBARCH__=v5
|
||||
|
||||
include $(call select_from_repositories,mk/spec-codezero_arm.mk)
|
@ -1,6 +0,0 @@
|
||||
SPECS += codezero_arm_v5 platform_vpb926
|
||||
|
||||
CC_OPT += -D__PLATFORM__=pb926
|
||||
|
||||
include $(call select_from_repositories,mk/spec-codezero_arm_v5.mk)
|
||||
include $(call select_from_repositories,mk/spec-platform_vpb926.mk)
|
@ -1,67 +0,0 @@
|
||||
This directory contains patches of the Codezero kernel that are needed for the
|
||||
integration with Genode. Furthermore, some patches address issues with recent
|
||||
tool chains not yet supported by the official Codezero verison.
|
||||
|
||||
:binutils-2.21.patch:
|
||||
|
||||
The GNU assembler of binutils-2.21 complains with an error that was ignored
|
||||
by previous binutils versions:
|
||||
|
||||
"Error: .size expression for ... does not evaluate to a constant"
|
||||
|
||||
This error seems to occur if the argument of 'BEGIN_PROC' does not match
|
||||
the argument of 'END_PROC'. The patch fixes such inconsistencies in the
|
||||
code.
|
||||
|
||||
:gcc_shared_enabled.patch:
|
||||
|
||||
Codezero expect the tool chain to be used for the kernel to not support
|
||||
shared libraries. This is the case for Codesourcery's arm-non-eabi
|
||||
tool chain. Such tool chains use to incorporate both libgcc and libgcc_eh
|
||||
into the single libgcc.a library. In contrast, for tool chains built with
|
||||
'--enable-shared', libgcc does not contain the functions of libgcc_eh. Hence,
|
||||
one symbol called '__aeabi_unwind_cpp_pr0' referenced by libgcc and normally
|
||||
provided by libgcc_eh remains unresolved. There are two possible solutions
|
||||
for this problem: We could link libgcc_eh to the 'final.elf' image as
|
||||
expected by libgcc. However, this way, we will need to implement the
|
||||
the environment expected by libgcc_eh. For Codezero, this is pointless
|
||||
because no C++ is used. The second option is to provide a dummy symbol
|
||||
for '__aeabi_unwind_cpp_pr0' just to make the linker happy. This patch
|
||||
adds such a dummy symbol to 'loader/main.c'.
|
||||
|
||||
:libc_search_dir.patch:
|
||||
|
||||
The userlibs are build with w/o '-nostdinc'. Consequently, the standard
|
||||
search paths of the tool chain are used. Because the user land is
|
||||
normally build with the Codesourcery tool chain 'arm-none-linux-gnueabi',
|
||||
the complete glibc headers (that come with the tool chain) end up in
|
||||
the default search path. Coincidentally, the userlibs SConstruct file
|
||||
misses to supply the Codezero libc headers, which goes undetected because
|
||||
headers such as 'stdio.h' are silently taken from the tool chain's libc.
|
||||
This patch supplies Codezero's libc include-search path for building
|
||||
the userlibs. This enables the userlibs to be built with tool chains
|
||||
that do not come with a complete libc.
|
||||
|
||||
:scons-2.0.1.patch:
|
||||
|
||||
SCons 2.0.1 complains about the 'build_dir' argument being renamed to
|
||||
'variant_dir'. This patch renames the argument where needed for building
|
||||
the kernel and the default container.
|
||||
|
||||
:set_fixed_pager.patch:
|
||||
|
||||
At some point, Codezero abandoned the facility to define the pager for a
|
||||
given thread via the exregs system call. Instead, the kernel hard-wires the
|
||||
creator of the thread as the thread's pager. This is conflicting with
|
||||
Genode's way of creating and paging threads. On the current version of Genode
|
||||
for Codezero, all threads are paged by one thread (thread 3 happens to be the
|
||||
global pager) within core. As a work-around to Codezero's current limitation,
|
||||
we define thread 3 to be the pager of all threads.
|
||||
|
||||
:gcc_4_6_1_fixes.patch:
|
||||
|
||||
Version 4.6.1 of GCC is more picky about dead code than previous versions and
|
||||
warns about unused variables. Because Codezero is build with the '-Werror'
|
||||
flag, these warnings cause the kernel build to fail. The patch fixes those
|
||||
warnings by removing the variables in question.
|
||||
|
@ -1,27 +0,0 @@
|
||||
--- src/kernel/codezero/src/arch/arm/vectors.S
|
||||
+++ src/kernel/codezero/src/arch/arm/vectors.S
|
||||
@@ -503,7 +503,7 @@ BEGIN_PROC(arm_irq_exception_basic)
|
||||
mov lr, pc
|
||||
ldr pc, =do_irq
|
||||
ldmfd sp!, {r0-r3, pc}^
|
||||
-END_PROC(arm_irq_exception)
|
||||
+END_PROC(arm_irq_exception_basic)
|
||||
|
||||
/* Minimal IRQ state saved on irq stack right after irq vector enters: */
|
||||
#define IRQ_R0 0
|
||||
--- src/kernel/codezero/conts/userlibs/libc/src/arch-arm/memcpy.S
|
||||
+++ src/kernel/codezero/conts/userlibs/libc/src/arch-arm/memcpy.S
|
||||
@@ -57,4 +57,4 @@ BEGIN_PROC(memcpy)
|
||||
bne last
|
||||
1:
|
||||
pop {r0, r4 - r11, pc}
|
||||
-END_PROC(_memcpy)
|
||||
+END_PROC(memcpy)
|
||||
--- src/kernel/codezero/conts/userlibs/libc/src/arch-arm/memset.S
|
||||
+++ src/kernel/codezero/conts/userlibs/libc/src/arch-arm/memset.S
|
||||
@@ -65,4 +65,4 @@ BEGIN_PROC(memset)
|
||||
bne end
|
||||
|
||||
ldmfd sp!, {r4 - r11, pc}
|
||||
-END_PROC(_memset)
|
||||
+END_PROC(memset)
|
@ -1,166 +0,0 @@
|
||||
--- src/kernel/codezero/src/api/map.c
|
||||
+++ src/kernel/codezero/src/api/map.c
|
||||
@@ -78,6 +78,6 @@ int sys_unmap(unsigned long virtual, unsigned long npages, unsigned int tid)
|
||||
retval = ret;
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
--- src/kernel/codezero/src/api/thread.c
|
||||
+++ src/kernel/codezero/src/api/thread.c
|
||||
@@ -497,7 +497,7 @@ out_err:
|
||||
*/
|
||||
int sys_thread_control(unsigned int flags, struct task_ids *ids)
|
||||
{
|
||||
- struct ktcb *task = 0, *pager = 0;
|
||||
+ struct ktcb *task = 0;
|
||||
int err, ret = 0;
|
||||
|
||||
if ((err = check_access((unsigned long)ids, sizeof(*ids),
|
||||
@@ -508,8 +508,6 @@ int sys_thread_control(unsigned int flags, struct task_ids *ids)
|
||||
if (!(task = tcb_find(ids->tid)))
|
||||
return -ESRCH;
|
||||
|
||||
- pager = task->pager;
|
||||
-
|
||||
/*
|
||||
* Caller may operate on a thread if it shares
|
||||
* the same address space with that thread's pager
|
||||
--- src/kernel/codezero/src/arch/arm/mapping-common.c
|
||||
+++ src/kernel/codezero/src/arch/arm/mapping-common.c
|
||||
@@ -313,12 +313,11 @@ int check_mapping(unsigned long vaddr, unsigned long size,
|
||||
int remove_mapping_space(struct address_space *space, unsigned long vaddr)
|
||||
{
|
||||
pmd_table_t *pmd_table;
|
||||
- int pgd_i, pmd_i;
|
||||
+ int pmd_i;
|
||||
pmd_t *pmd;
|
||||
unsigned int pmd_type, pte_type;
|
||||
|
||||
vaddr = page_align(vaddr);
|
||||
- pgd_i = PGD_INDEX(vaddr);
|
||||
pmd_i = PMD_INDEX(vaddr);
|
||||
|
||||
/*
|
||||
--- src/kernel/codezero/src/glue/arm/init.c
|
||||
+++ src/kernel/codezero/src/glue/arm/init.c
|
||||
@@ -68,8 +68,6 @@ void print_sections(void)
|
||||
/* The kip is non-standard, using 0xBB to indicate mine for now ;-) */
|
||||
void kip_init()
|
||||
{
|
||||
- struct utcb **utcb_ref;
|
||||
-
|
||||
/*
|
||||
* TODO: Adding utcb size might be useful
|
||||
*/
|
||||
@@ -86,9 +84,6 @@ void kip_init()
|
||||
|
||||
kip_init_syscalls();
|
||||
|
||||
- /* KIP + 0xFF0 is pointer to UTCB segment start address */
|
||||
- utcb_ref = (struct utcb **)((unsigned long)&kip + UTCB_KIP_OFFSET);
|
||||
-
|
||||
add_boot_mapping(virt_to_phys(&kip), USER_KIP_PAGE, PAGE_SIZE,
|
||||
MAP_USR_RO);
|
||||
printk("%s: Kernel built on %s, %s\n", __KERNELNAME__,
|
||||
--- src/kernel/codezero/loader/libs/elf/src/elf.c
|
||||
+++ src/kernel/codezero/loader/libs/elf/src/elf.c
|
||||
@@ -339,16 +339,12 @@ elf_loadFile(void *elfFile, bool phys)
|
||||
{
|
||||
int i;
|
||||
int num_pheaders;
|
||||
- int pheader_offset;
|
||||
- int pheader_type;
|
||||
if (elf_checkFile(elfFile) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
num_pheaders = elf_getNumProgramHeaders(elfFile);
|
||||
- pheader_offset = elf_getProgramHeaderOffset(elfFile, 0);
|
||||
//printf("Number of program headers: %d\n", num_pheaders);
|
||||
- //printf("Program header offset of first header from file beginning: 0x%p\n",pheader_offset);
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
@@ -373,8 +369,6 @@ elf_loadFile(void *elfFile, bool phys)
|
||||
// printf("This section's size in file: %p\n", len);
|
||||
src = (uint64_t) (uintptr_t) elfFile + elf_getProgramHeaderOffset(elfFile, i);
|
||||
// printf("Elf program header offset: %p\n", src);
|
||||
- pheader_type = elf_getProgramHeaderType(elfFile, i);
|
||||
- // printf("Elf program header type: %p\n", pheader_type);
|
||||
// Comment
|
||||
printf("Copying to range from 0x%x to 0x%x of size: 0x%x\n", (unsigned int)dest, (unsigned int)dest + (unsigned int)len, (unsigned int)len);
|
||||
memcpy((void*) (uintptr_t) dest, (void*) (uintptr_t) src, len);
|
||||
--- src/kernel/codezero/loader/libs/elf/src/elf32.c
|
||||
+++ src/kernel/codezero/loader/libs/elf/src/elf32.c
|
||||
@@ -248,7 +248,6 @@ elf32_fprintf(FILE *f, struct Elf32_Header *file, int size, const char *name, in
|
||||
struct Elf32_Shdr *sections;
|
||||
unsigned numSections;
|
||||
int i, r;
|
||||
- char *str_table;
|
||||
|
||||
fprintf(f, "Found an elf32 file called \"%s\" located "
|
||||
"at address 0x%p\n", name, file);
|
||||
@@ -307,7 +306,6 @@ elf32_fprintf(FILE *f, struct Elf32_Header *file, int size, const char *name, in
|
||||
}
|
||||
}
|
||||
if (flags & ELF_PRINT_SECTIONS) {
|
||||
- str_table = elf32_getSegmentStringTable(file);
|
||||
|
||||
printf("Section Headers:\n");
|
||||
printf(" [Nr] Name Type Addr Off\n");
|
||||
--- src/kernel/codezero/src/generic/capability.c
|
||||
+++ src/kernel/codezero/src/generic/capability.c
|
||||
@@ -403,7 +403,7 @@ struct capability *cap_match_mem(struct capability *cap,
|
||||
{
|
||||
struct sys_map_args *args = args_ptr;
|
||||
struct ktcb *target = args->task;
|
||||
- unsigned long long start, end, pfn_point;
|
||||
+ unsigned long long start, pfn_point;
|
||||
unsigned long pfn;
|
||||
unsigned int perms;
|
||||
|
||||
@@ -415,7 +415,6 @@ struct capability *cap_match_mem(struct capability *cap,
|
||||
|
||||
/* Long long range check to avoid overflow */
|
||||
start = cap->start;
|
||||
- end = cap->end;
|
||||
pfn_point = pfn;
|
||||
if (start > pfn_point || cap->end < pfn_point + args->npages)
|
||||
return 0;
|
||||
--- src/kernel/codezero/loader/main.c
|
||||
+++ src/kernel/codezero/loader/main.c
|
||||
@@ -26,7 +26,6 @@ int load_elf_image(unsigned long **entry, void *filebuf);
|
||||
int load_container_image(void *cont_section)
|
||||
{
|
||||
struct Elf32_Header *elf_header = (struct Elf32_Header *)cont_section;
|
||||
- struct Elf32_Shdr *sect_header;
|
||||
int nsect;
|
||||
int nimgs = 0;
|
||||
unsigned long *image_entry;
|
||||
@@ -36,7 +35,6 @@ int load_container_image(void *cont_section)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- sect_header = elf32_getSectionTable(elf_header);
|
||||
nsect = elf32_getNumSections(elf_header);
|
||||
|
||||
for (int i = 0; i < nsect; i++) {
|
||||
@@ -59,7 +57,6 @@ int load_container_image(void *cont_section)
|
||||
int load_container_images(unsigned long start, unsigned long end)
|
||||
{
|
||||
struct Elf32_Header *elf_header = (struct Elf32_Header *)start;
|
||||
- struct Elf32_Shdr *sect_header;
|
||||
int nsect = 0;
|
||||
int nconts = 0;
|
||||
|
||||
@@ -68,7 +65,6 @@ int load_container_images(unsigned long start, unsigned long end)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- sect_header = elf32_getSectionTable(elf_header);
|
||||
nsect = elf32_getNumSections(elf_header);
|
||||
|
||||
for (int i = 0; i < nsect; i++) {
|
@ -1,8 +0,0 @@
|
||||
--- src/kernel/codezero/loader/main.c
|
||||
+++ src/kernel/codezero/loader/main.c
|
||||
@@ -135,3 +135,5 @@ int main(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+
|
||||
+asm(".global __aeabi_unwind_cpp_pr0; __aeabi_unwind_cpp_pr0:");
|
@ -1,19 +0,0 @@
|
||||
--- src/kernel/codezero/conts/userlibs/SConstruct
|
||||
+++ src/kernel/codezero/conts/userlibs/SConstruct
|
||||
@@ -11,6 +11,7 @@ PROJRELROOT = '../..'
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from scripts.config.config_invoke import *
|
||||
+from scripts.config.projpaths import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
@@ -28,7 +29,7 @@ env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
ASFLAGS = ['-D__ASSEMBLY__', '-march=' + gcc_arch_flag],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = 'gcc', # libgcc.a - Required for division routines.
|
||||
- CPPPATH = KERNEL_HEADERS,
|
||||
+ CPPPATH = [KERNEL_HEADERS, LIBC_INCLUDE],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
# Set the build directory for this source tree
|
@ -1,91 +0,0 @@
|
||||
--- src/kernel/codezero/src/drivers/SConscript
|
||||
+++ src/kernel/codezero/src/drivers/SConscript
|
||||
@@ -8,24 +8,24 @@ src_local = []
|
||||
objs = []
|
||||
|
||||
objs += SConscript("uart/pl011/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'pl011'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'pl011'))
|
||||
|
||||
objs += SConscript("timer/sp804/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'timer'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'timer'))
|
||||
|
||||
objs += SConscript("irq/pl190/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'vic'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'vic'))
|
||||
|
||||
objs += SConscript("irq/gic/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'gic'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'gic'))
|
||||
|
||||
objs += SConscript("irq/omap3/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'omap/intc'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'omap/intc'))
|
||||
|
||||
objs += SConscript("uart/omap/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'omap/uart'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'omap/uart'))
|
||||
|
||||
objs += SConscript("timer/omap/SConscript", exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = join(bdir, 'omap/timer'))
|
||||
+ duplicate=0, variant_dir = join(bdir, 'omap/timer'))
|
||||
|
||||
Return('objs')
|
||||
--- src/kernel/codezero/conts/baremetal/empty/SConstruct
|
||||
+++ src/kernel/codezero/conts/baremetal/empty/SConstruct
|
||||
@@ -48,7 +48,7 @@ env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
- duplicate=0, build_dir = builddir)
|
||||
+ duplicate=0, variant_dir = builddir)
|
||||
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
--- src/kernel/codezero/SConstruct
|
||||
+++ src/kernel/codezero/SConstruct
|
||||
@@ -71,35 +71,35 @@ env = Environment(CC = config.toolchain_kernel + 'gcc',
|
||||
objects = []
|
||||
objects += SConscript('src/generic/SConscript',
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, 'generic'))
|
||||
+ variant_dir = join(builddir, 'generic'))
|
||||
|
||||
objects += SConscript(join(join('src/glue', arch), 'SConscript'),
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, join('glue',arch)))
|
||||
+ variant_dir = join(builddir, join('glue',arch)))
|
||||
|
||||
objects += SConscript(join(join('src/arch', arch), 'SConscript'),
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, join('arch', arch)))
|
||||
+ variant_dir = join(builddir, join('arch', arch)))
|
||||
|
||||
objects += SConscript(join(join('src/arch', arch), join(subarch, 'SConscript')),
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, join(join('arch',arch), subarch)))
|
||||
+ variant_dir = join(builddir, join(join('arch',arch), subarch)))
|
||||
|
||||
objects += SConscript('src/lib/SConscript',
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, 'lib'))
|
||||
+ variant_dir = join(builddir, 'lib'))
|
||||
|
||||
objects += SConscript('src/api/SConscript',
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, 'api'))
|
||||
+ variant_dir = join(builddir, 'api'))
|
||||
|
||||
objects += SConscript('src/drivers/SConscript',
|
||||
exports = { 'env' : env, 'bdir' : 'driver/'}, duplicate = 0,
|
||||
- build_dir = join(builddir, 'driver'))
|
||||
+ variant_dir = join(builddir, 'driver'))
|
||||
|
||||
objects += SConscript(join(join('src/platform', platform), 'SConscript'),
|
||||
exports = { 'env' : env }, duplicate = 0,
|
||||
- build_dir = join(builddir, join('platform', platform)))
|
||||
+ variant_dir = join(builddir, join('platform', platform)))
|
||||
|
||||
|
||||
# Add builders for generating kernel linker scripts
|
@ -1,11 +0,0 @@
|
||||
--- src/kernel/codezero/include/l4/generic/tcb.h
|
||||
+++ src/kernel/codezero/include/l4/generic/tcb.h
|
||||
@@ -70,7 +70,7 @@ struct task_ids {
|
||||
|
||||
struct container;
|
||||
|
||||
-#define tcb_pagerid(tcb) ((tcb)->pager->tid)
|
||||
+#define tcb_pagerid(tcb) 4
|
||||
|
||||
#define space_is_pager(tcb) \
|
||||
((tcb)->space->spid == (tcb)->pager->space->spid)
|
@ -1 +0,0 @@
|
||||
fb29b6a49c1e6ee759e034da8a59cf66b7ed74ef
|
@ -1,9 +0,0 @@
|
||||
LICENSE := GPLv3
|
||||
VERSION := git
|
||||
DOWNLOADS := codezero.git
|
||||
|
||||
URL(codezero) := https://github.com/nfeske/codezero.git
|
||||
REV(codezero) := 6fa4884a5a1cf6207372f69ae01e5faa6d5a39c8
|
||||
DIR(codezero) := src/kernel/codezero
|
||||
|
||||
PATCHES := $(wildcard $(REP_DIR)/patches/*.patch)
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* \brief Console backend for PL011 UART on Codezero
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-03
|
||||
*
|
||||
* This code assumes a PL011 UART as provided by 'qemu -M versatilepb'. Prior
|
||||
* executing this code, the kernel already initialized the UART to print some
|
||||
* startup message. So we can skip the UART initialization here. The kernel
|
||||
* maps the UART registers to the magic address PL011_BASE when starting mm0.
|
||||
* So we can just start using the device without any precautions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/console.h>
|
||||
|
||||
/* codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
/**
|
||||
* Base address of default-mapped UART device
|
||||
*
|
||||
* defined in 'l4/arch/arm/io.h'
|
||||
*/
|
||||
enum { PL011_BASE = USERSPACE_CONSOLE_VBASE };
|
||||
|
||||
/**
|
||||
* UART registers
|
||||
*/
|
||||
enum { PL011_REG_UARTDR = PL011_BASE + 0x00 };
|
||||
enum { PL011_REG_UARTFR = PL011_BASE + 0x18 };
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if UART is ready to transmit a character
|
||||
*/
|
||||
static bool pl011_tx_ready()
|
||||
{
|
||||
enum { PL011_TX_FIFO_FULL = 1 << 5 };
|
||||
return !(*((volatile unsigned *)PL011_REG_UARTFR) & PL011_TX_FIFO_FULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output character to serial port
|
||||
*/
|
||||
static void pl011_out_char(uint8_t c)
|
||||
{
|
||||
/* wait until serial port is ready */
|
||||
while (!pl011_tx_ready());
|
||||
|
||||
/* output character */
|
||||
*((volatile unsigned int *)PL011_REG_UARTDR) = c;
|
||||
}
|
||||
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Core_console : public Console
|
||||
{
|
||||
protected:
|
||||
|
||||
void _out_char(char c) {
|
||||
if(c == '\n')
|
||||
pl011_out_char('\r');
|
||||
pl011_out_char(c);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* \brief Support for exceptions libsupc++
|
||||
* \author Norman Feske
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2006-07-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
extern "C" char __eh_frame_start__[]; /* from linker script */
|
||||
extern "C" void __register_frame (const void *begin); /* from libgcc_eh */
|
||||
|
||||
/*
|
||||
* This symbol is set by Genode's dynamic linker (ldso) during binary setup.
|
||||
* After setup, the symbol will point to the actual implementation of
|
||||
* 'dl_iterate_phdr', which is located within the linker. 'dl_iterate_phdr'
|
||||
* iterates through all (linker loaded) binaries and shared libraries. This
|
||||
* function has to be implemented in order to support C++ exceptions within
|
||||
* shared libraries.
|
||||
* Return values of dl_iterate_phdr (gcc 4.2.4):
|
||||
* < 0 = error
|
||||
* 0 = continue program header iteration
|
||||
* > 0 = stop iteration (no errors occured)
|
||||
*
|
||||
* See also: man dl_iterate_phdr
|
||||
*/
|
||||
int (*genode__dl_iterate_phdr) (int (*callback) (void *info, unsigned long size, void *data), void *data) = 0;
|
||||
|
||||
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size, void *data), void *data) __attribute__((weak));
|
||||
extern "C" int dl_iterate_phdr(int (*callback) (void *info, unsigned long size, void *data), void *data)
|
||||
{
|
||||
if (!genode__dl_iterate_phdr)
|
||||
return -1;
|
||||
|
||||
return genode__dl_iterate_phdr(callback, data);
|
||||
}
|
||||
|
||||
extern "C" void raise()
|
||||
{
|
||||
PDBG("raise called - not implemented\n");
|
||||
}
|
||||
|
||||
void init_exception_handling()
|
||||
{
|
||||
// __register_frame(__eh_frame_start__);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief Functions required for using the arm-none-linux-gnueabi tool chain
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
extern "C" int raise(int sig)
|
||||
{
|
||||
PWRN("raise - not yet implemented");
|
||||
return 0;
|
||||
}
|
30
repos/base-codezero/src/base/env/utcb.cc
vendored
30
repos/base-codezero/src/base/env/utcb.cc
vendored
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* \brief Helper functions UTCB access on Codezero
|
||||
* \author Norman Feske
|
||||
* \date 2012-03-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
Genode::Native_utcb *Genode::Thread_base::utcb()
|
||||
{
|
||||
/*
|
||||
* If 'utcb' is called on the object returned by 'myself',
|
||||
* the 'this' pointer may be NULL (if the calling thread is
|
||||
* the main thread). Therefore we handle this special case
|
||||
* here.
|
||||
*/
|
||||
if (this == 0) return 0;
|
||||
|
||||
return &_context->utcb;
|
||||
}
|
||||
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* \brief Codezero implementation of the IPC API
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/ipc.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/blocking.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
enum { verbose_ipc = false };
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_ostream **
|
||||
*****************/
|
||||
|
||||
void Ipc_ostream::_send()
|
||||
{
|
||||
if (verbose_ipc)
|
||||
PDBG("thread %d sends IPC to %d, write_offset=%d",
|
||||
thread_myself(), _dst.dst(), _write_offset);
|
||||
|
||||
umword_t snd_size = min(_write_offset, (unsigned)L4_IPC_EXTENDED_MAX_SIZE);
|
||||
|
||||
*(umword_t *)_snd_msg->addr() = _dst.local_name();
|
||||
|
||||
int ret = l4_send_extended(_dst.dst(), L4_IPC_TAG_SYNC_EXTENDED,
|
||||
snd_size, _snd_msg->addr());
|
||||
if (ret < 0)
|
||||
PERR("l4_send_extended (to thread %d) returned ret=%d",
|
||||
_dst.dst(), ret);
|
||||
|
||||
_write_offset = sizeof(umword_t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg)
|
||||
:
|
||||
Ipc_marshaller((char *)snd_msg->addr(), snd_msg->size()),
|
||||
_snd_msg(snd_msg), _dst(dst)
|
||||
{
|
||||
_write_offset = sizeof(umword_t);
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Ipc_istream **
|
||||
*****************/
|
||||
|
||||
void Ipc_istream::_wait()
|
||||
{
|
||||
umword_t *rcv_buf = (umword_t *)_rcv_msg->addr();
|
||||
umword_t rcv_size = min(_rcv_msg->size(), (unsigned)L4_IPC_EXTENDED_MAX_SIZE);
|
||||
|
||||
if (verbose_ipc)
|
||||
PDBG("thread %d waits for IPC from %d, rcv_buf at %p, rcv_size=%d",
|
||||
dst(), _rcv_cs, rcv_buf, (int)rcv_size);
|
||||
|
||||
int ret = l4_receive_extended(_rcv_cs, rcv_size, rcv_buf);
|
||||
if (ret < 0)
|
||||
PERR("l4_receive_extended (from any) returned ret=%d", ret);
|
||||
|
||||
if (verbose_ipc)
|
||||
PDBG("thread %d received IPC from %d",
|
||||
dst(), l4_get_sender());
|
||||
|
||||
_read_offset = sizeof(umword_t);
|
||||
}
|
||||
|
||||
|
||||
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
|
||||
:
|
||||
Ipc_unmarshaller((char *)rcv_msg->addr(), rcv_msg->size()),
|
||||
Native_capability(thread_myself(), 0),
|
||||
_rcv_msg(rcv_msg)
|
||||
{
|
||||
_rcv_cs = L4_ANYTHREAD;
|
||||
_read_offset = sizeof(umword_t);
|
||||
}
|
||||
|
||||
|
||||
Ipc_istream::~Ipc_istream() { }
|
||||
|
||||
|
||||
/****************
|
||||
** Ipc_client **
|
||||
****************/
|
||||
|
||||
void Ipc_client::_call()
|
||||
{
|
||||
#warning l4_sendrecv_extended is not yet implemented in l4lib/arch/syslib.h
|
||||
_send();
|
||||
_rcv_cs = Ipc_ostream::_dst.dst();
|
||||
_wait();
|
||||
_rcv_cs = L4_ANYTHREAD;
|
||||
|
||||
_write_offset = _read_offset = sizeof(umword_t);
|
||||
}
|
||||
|
||||
|
||||
Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg,
|
||||
Msgbuf_base *rcv_msg, unsigned short)
|
||||
: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0)
|
||||
{ }
|
||||
|
||||
|
||||
/****************
|
||||
** Ipc_server **
|
||||
****************/
|
||||
|
||||
void Ipc_server::_prepare_next_reply_wait()
|
||||
{
|
||||
/* now we have a request to reply */
|
||||
_reply_needed = true;
|
||||
|
||||
/* leave space for return value at the beginning of the msgbuf */
|
||||
_write_offset = 2*sizeof(umword_t);
|
||||
|
||||
/* receive buffer offset */
|
||||
_read_offset = sizeof(umword_t);
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_wait()
|
||||
{
|
||||
/* wait for new server request */
|
||||
try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
|
||||
|
||||
/* define destination of next reply */
|
||||
Ipc_ostream::_dst = Native_capability(l4_get_sender(), badge());
|
||||
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_reply()
|
||||
{
|
||||
try { _send(); } catch (Ipc_error) { }
|
||||
|
||||
_prepare_next_reply_wait();
|
||||
}
|
||||
|
||||
|
||||
void Ipc_server::_reply_wait()
|
||||
{
|
||||
if (_reply_needed)
|
||||
_reply();
|
||||
|
||||
_wait();
|
||||
}
|
||||
|
||||
|
||||
Ipc_server::Ipc_server(Msgbuf_base *snd_msg,
|
||||
Msgbuf_base *rcv_msg)
|
||||
:
|
||||
Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg),
|
||||
_reply_needed(false)
|
||||
{ }
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* \brief Codezero-specific implementation of cmpxchg
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <cpu/atomic.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/lock.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
static bool mutex_initialized;
|
||||
static Codezero::l4_mutex mutex;
|
||||
|
||||
int Genode::cmpxchg(volatile int *dest, int cmp_val, int new_val)
|
||||
{
|
||||
if (!mutex_initialized) {
|
||||
Codezero::l4_mutex_init(&mutex);
|
||||
mutex_initialized = true;
|
||||
}
|
||||
|
||||
int ret = Codezero::l4_mutex_lock(&mutex);
|
||||
if (ret < 0)
|
||||
mutex_initialized = false;
|
||||
|
||||
bool result = false;
|
||||
if (*dest == cmp_val) {
|
||||
*dest = new_val;
|
||||
result = true;
|
||||
}
|
||||
|
||||
ret = Codezero::l4_mutex_unlock(&mutex);
|
||||
if (ret < 0)
|
||||
mutex_initialized = false;
|
||||
|
||||
return result;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* \brief Helper functions for the Lock implementation
|
||||
* \author Norman Feske
|
||||
* \date 2010-04-20
|
||||
*
|
||||
* For documentation about the interface, please revisit the 'base-pistachio'
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
extern Genode::Native_thread_id main_thread_tid;
|
||||
extern Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
static inline void thread_yield()
|
||||
{
|
||||
Codezero::l4_thread_switch(-1);
|
||||
}
|
||||
|
||||
|
||||
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Codezero::l4_mutex *running_lock = thread_base ?
|
||||
thread_base->utcb()->running_lock() :
|
||||
&main_thread_running_lock;
|
||||
Codezero::l4_mutex_unlock(running_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline void thread_switch_to(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Genode::Native_thread_id tid = thread_base ?
|
||||
thread_base->tid().l4id :
|
||||
main_thread_tid;
|
||||
Codezero::l4_thread_switch(tid);
|
||||
}
|
||||
|
||||
|
||||
static inline void thread_stop_myself()
|
||||
{
|
||||
Genode::Thread_base *myself = Genode::Thread_base::myself();
|
||||
Codezero::l4_mutex *running_lock = myself ?
|
||||
myself->utcb()->running_lock() :
|
||||
&main_thread_running_lock;
|
||||
Codezero::l4_mutex_lock(running_lock);
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* \brief Thread bootstrap code
|
||||
* \author Christian Prochaska
|
||||
* \author Martin Stein
|
||||
* \date 2013-02-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
/* initialize codezero environment */
|
||||
Codezero::__l4_init();
|
||||
|
||||
/* provide kernel identification of thread through temporary environment */
|
||||
main_thread_tid = Codezero::thread_myself();
|
||||
}
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/****************************
|
||||
** Codezero libl4 support **
|
||||
****************************/
|
||||
|
||||
/*
|
||||
* Unfortunately, the function 'exregs_print_registers' in 'exregs.c' refers to
|
||||
* 'memset'. Because we do not want to link core against a C library, we have to
|
||||
* resolve this function here.
|
||||
*/
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n) __attribute__((weak));
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n)
|
||||
{
|
||||
return Genode::memset(s, c, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Same problem as for 'memset'. The 'printf' symbol is referenced from
|
||||
* 'mutex.c' and 'exregs.c' of Codezero's libl4.
|
||||
*/
|
||||
extern "C" int printf(const char *format, ...) __attribute__((weak));
|
||||
extern "C" int printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
Genode::vprintf(format, list);
|
||||
va_end(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
Codezero::l4_mutex_init(utcb()->running_lock());
|
||||
Codezero::l4_mutex_lock(utcb()->running_lock()); /* block on first mutex lock */
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(size_t, Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
|
||||
/* adjust values whose computation differs for a main thread */
|
||||
_tid.l4id = main_thread_tid;
|
||||
_thread_cap = Genode::env()->parent()->main_thread_cap();
|
||||
|
||||
/* get first mutex lock (normally done by _thread_bootstrap) */
|
||||
Codezero::l4_mutex_init(utcb()->running_lock());
|
||||
Codezero::l4_mutex_lock(utcb()->running_lock());
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* \brief NOVA-specific implementation of the Thread API
|
||||
* \author Norman Feske
|
||||
* \date 2010-01-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Entry point entered by new threads
|
||||
*/
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
Thread_base::myself()->_thread_bootstrap();
|
||||
Thread_base::myself()->entry();
|
||||
Thread_base::myself()->_join_lock.unlock();
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
_cpu_session->kill_thread(_thread_cap);
|
||||
env()->rm_session()->remove_client(_pager_cap);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* if no cpu session is given, use it from the environment */
|
||||
if (!_cpu_session)
|
||||
_cpu_session = env()->cpu_session();
|
||||
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
|
||||
_thread_cap = _cpu_session->create_thread(WEIGHT, buf);
|
||||
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
|
||||
/* create new pager object and assign it to the new thread */
|
||||
_pager_cap = env()->rm_session()->add_client(_thread_cap);
|
||||
_cpu_session->set_pager(_thread_cap, _pager_cap);
|
||||
|
||||
/* register initial IP and SP at core */
|
||||
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
Codezero::l4_mutex_unlock(utcb()->running_lock());
|
||||
_cpu_session->cancel_blocking(_thread_cap);
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* \brief Core-local RM session
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_rm_session.h>
|
||||
#include <platform.h>
|
||||
#include <map_local.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Rm_session::Local_addr
|
||||
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
off_t offset, bool use_local_addr,
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
auto lambda = [&] (Dataspace_component *ds) -> Local_addr {
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
if (size == 0)
|
||||
size = ds->size();
|
||||
|
||||
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
|
||||
size_t num_pages = page_rounded_size >> get_page_size_log2();
|
||||
|
||||
if (use_local_addr) {
|
||||
PERR("Parameter 'use_local_addr' not supported within core");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
PERR("Parameter 'offset' not supported within core");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* allocate range in core's virtual address space */
|
||||
void *virt_addr;
|
||||
if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) {
|
||||
PERR("Could not allocate virtual address range in core of size %zd\n",
|
||||
page_rounded_size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages)) {
|
||||
PERR("core-local memory mapping failed virt=%lx, phys=%lx\n",
|
||||
(addr_t)virt_addr, ds->phys_addr());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return virt_addr;
|
||||
};
|
||||
return _ds_ep->apply(ds_cap, lambda);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific parts of cores CPU-service
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread_cap)
|
||||
{
|
||||
PERR("%s: Not implemented", __PRETTY_FUNCTION__);
|
||||
return Ram_dataspace_capability();
|
||||
}
|
||||
|
||||
|
||||
Cpu_session::Quota Cpu_session_component::quota() { return Quota(); }
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* \brief Core-local region manager session
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_
|
||||
#define _CORE__INCLUDE__CORE_RM_SESSION_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <dataspace_component.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Core_rm_session : public Rm_session
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint *_ds_ep;
|
||||
|
||||
public:
|
||||
|
||||
Core_rm_session(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { }
|
||||
|
||||
Local_addr attach(Dataspace_capability ds_cap, size_t size = 0,
|
||||
off_t offset = 0, bool use_local_addr = false,
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false);
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
Pager_capability add_client(Thread_capability) {
|
||||
return Pager_capability(); }
|
||||
|
||||
void remove_client(Pager_capability) { }
|
||||
|
||||
void fault_handler(Signal_context_capability) { }
|
||||
|
||||
State state() { return State(); }
|
||||
|
||||
Dataspace_capability dataspace() { return Dataspace_capability(); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */
|
@ -1,166 +0,0 @@
|
||||
/*
|
||||
* \brief Dummy pager support for Genode
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__IPC_PAGER_H_
|
||||
#define _CORE__INCLUDE__IPC_PAGER_H_
|
||||
|
||||
#include <base/cache.h>
|
||||
#include <base/ipc.h>
|
||||
#include <base/stdint.h>
|
||||
#include <base/native_types.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Mapping
|
||||
{
|
||||
private:
|
||||
|
||||
addr_t _from_phys_addr;
|
||||
addr_t _to_virt_addr;
|
||||
size_t _num_pages;
|
||||
bool _writeable;
|
||||
|
||||
enum { PAGE_SIZE_LOG2 = 12 };
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||
Cache_attribute const cacheability, bool io_mem,
|
||||
unsigned l2size = PAGE_SIZE_LOG2,
|
||||
bool rw = true)
|
||||
:
|
||||
_from_phys_addr(src_addr),
|
||||
_to_virt_addr(dst_addr),
|
||||
_num_pages(1 << (l2size - PAGE_SIZE_LOG2)),
|
||||
_writeable(rw)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Construct invalid mapping
|
||||
*/
|
||||
Mapping() : _num_pages(0) { }
|
||||
|
||||
/**
|
||||
* Prepare map operation
|
||||
*
|
||||
* No preparations are needed on Codezero because all mapping
|
||||
* originate from the physical address space.
|
||||
*/
|
||||
void prepare_map_operation() { }
|
||||
|
||||
addr_t from_phys() const { return _from_phys_addr; }
|
||||
addr_t to_virt() const { return _to_virt_addr; }
|
||||
size_t num_pages() const { return _num_pages; }
|
||||
bool writeable() const { return _writeable; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Special paging server class
|
||||
*/
|
||||
class Ipc_pager
|
||||
{
|
||||
private:
|
||||
|
||||
Native_thread_id _last; /* faulted thread */
|
||||
addr_t _pf_addr; /* page-fault address */
|
||||
addr_t _pf_ip; /* instruction pointer of faulter */
|
||||
bool _pf_write; /* true on write fault */
|
||||
|
||||
Mapping _reply_mapping;
|
||||
|
||||
// protected:
|
||||
//
|
||||
// /**
|
||||
// * Wait for pagefault
|
||||
// */
|
||||
// void _wait();
|
||||
//
|
||||
// /**
|
||||
// * Send page-fault reply and wait for next page fault
|
||||
// */
|
||||
// void _reply_and_wait();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Wait for a new page fault received as short message IPC
|
||||
*/
|
||||
void wait_for_fault();
|
||||
|
||||
/**
|
||||
* Reply current page-fault and wait for a new one
|
||||
*/
|
||||
void reply_and_wait_for_fault();
|
||||
|
||||
/**
|
||||
* Request instruction pointer of current page fault
|
||||
*/
|
||||
addr_t fault_ip() { return _pf_ip; }
|
||||
|
||||
/**
|
||||
* Request fault address of current page fault
|
||||
*/
|
||||
addr_t fault_addr() { return _pf_addr; }
|
||||
|
||||
/**
|
||||
* Set parameters for next reply
|
||||
*/
|
||||
void set_reply_mapping(Mapping m) { _reply_mapping = m; }
|
||||
|
||||
/**
|
||||
* Set destination for next reply
|
||||
*/
|
||||
void set_reply_dst(Native_capability pager_object) {
|
||||
_last = pager_object.local_name(); }
|
||||
|
||||
/**
|
||||
* Answer call without sending a mapping
|
||||
*
|
||||
* This function is used to acknowledge local calls from one of
|
||||
* core's region-manager sessions.
|
||||
*/
|
||||
void acknowledge_wakeup();
|
||||
|
||||
/**
|
||||
* Returns true if the last request was send from a core thread
|
||||
*/
|
||||
bool request_from_core() { return true; }
|
||||
|
||||
/**
|
||||
* Return badge for faulting thread
|
||||
*/
|
||||
unsigned long badge() const { return _last; }
|
||||
|
||||
/**
|
||||
* Return true if page fault was a write fault
|
||||
*/
|
||||
bool is_write_fault() const { return _pf_write; }
|
||||
|
||||
/**
|
||||
* Return true if last fault was an exception
|
||||
*/
|
||||
bool is_exception() const
|
||||
{
|
||||
/*
|
||||
* Reflection of exceptions is not supported on this platform.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__IPC_PAGER_H_ */
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* \brief Core-local mapping
|
||||
* \author Norman Feske
|
||||
* \date 2010-02-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__MAP_LOCAL_H_
|
||||
#define _CORE__INCLUDE__MAP_LOCAL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <util.h>
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Map physical pages to core-local virtual address range
|
||||
*
|
||||
* On Codezero, mappings originate from the physical address space.
|
||||
*
|
||||
* \param from_phys physical source address
|
||||
* \param to_virt core-local destination address
|
||||
* \param num_pages number of pages to map
|
||||
*
|
||||
* \return true on success
|
||||
*/
|
||||
inline bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
int res = l4_map((void *)from_phys, (void *)to_virt,
|
||||
num_pages, MAP_USR_RW, thread_myself());
|
||||
if (res < 0) {
|
||||
PERR("l4_map phys 0x%lx -> 0x%lx returned %d", from_phys, to_virt, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool unmap_local(addr_t virt_addr, size_t num_pages)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
int res = l4_unmap((void *)virt_addr, num_pages, thread_myself());
|
||||
if (res < 0) {
|
||||
PERR("l4_unmap returned %d", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__MAP_LOCAL_H_ */
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* \brief Platform interface
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* local includes */
|
||||
#include <platform_generic.h>
|
||||
#include <core_mem_alloc.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform : public Platform_generic
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Core_mem_allocator::Phys_allocator Phys_allocator;
|
||||
|
||||
Core_mem_allocator _core_mem_alloc; /* core-accessible memory */
|
||||
Phys_allocator _io_mem_alloc; /* MMIO allocator */
|
||||
Phys_allocator _io_port_alloc; /* I/O port allocator */
|
||||
Phys_allocator _irq_alloc; /* IRQ allocator */
|
||||
Rom_fs _rom_fs; /* ROM file system */
|
||||
|
||||
/**
|
||||
* Virtual address range usable by non-core processes
|
||||
*/
|
||||
addr_t _vm_base;
|
||||
size_t _vm_size;
|
||||
|
||||
int _init_rom_fs();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
|
||||
/********************************
|
||||
** Generic platform interface **
|
||||
********************************/
|
||||
|
||||
Range_allocator *ram_alloc() { return _core_mem_alloc.phys_alloc(); }
|
||||
Range_allocator *io_mem_alloc() { return &_io_mem_alloc; }
|
||||
Range_allocator *io_port_alloc() { return &_io_port_alloc; }
|
||||
Range_allocator *irq_alloc() { return &_irq_alloc; }
|
||||
Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); }
|
||||
Range_allocator *core_mem_alloc() { return &_core_mem_alloc; }
|
||||
addr_t vm_start() const { return _vm_base; }
|
||||
size_t vm_size() const { return _vm_size; }
|
||||
Rom_fs *rom_fs() { return &_rom_fs; }
|
||||
|
||||
void wait_for_exit();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* \brief Protection-domain facility
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_PD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
#include <address_space.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
class Platform_pd : public Address_space
|
||||
{
|
||||
private:
|
||||
|
||||
enum { MAX_THREADS_PER_PD = 32 };
|
||||
enum { UTCB_VIRT_BASE = 0x30000000 };
|
||||
enum { UTCB_AREA_SIZE = MAX_THREADS_PER_PD*sizeof(struct Codezero::utcb) };
|
||||
|
||||
unsigned _space_id;
|
||||
|
||||
bool utcb_in_use[MAX_THREADS_PER_PD];
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Platform_pd(bool core);
|
||||
Platform_pd(Allocator * md_alloc, char const *,
|
||||
signed pd_id = -1, bool create = true);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_pd();
|
||||
|
||||
/**
|
||||
* Register quota donation at allocator guard
|
||||
*/
|
||||
void upgrade_ram_quota(size_t ram_quota) { }
|
||||
|
||||
/**
|
||||
* Bind thread to protection domain
|
||||
*
|
||||
* \return 0 on success or
|
||||
* -1 if thread ID allocation failed.
|
||||
*/
|
||||
int bind_thread(Platform_thread *thread);
|
||||
|
||||
/**
|
||||
* Unbind thread from protection domain
|
||||
*
|
||||
* Free the thread's slot and update thread object.
|
||||
*/
|
||||
void unbind_thread(Platform_thread *thread);
|
||||
|
||||
/**
|
||||
* Assign parent interface to protection domain
|
||||
*/
|
||||
int assign_parent(Native_capability parent) { return 0; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Address-space interface **
|
||||
*****************************/
|
||||
|
||||
void flush(addr_t, size_t) { PDBG("not implemented"); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */
|
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
#define _CORE__INCLUDE__PLATFORM_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread_state.h>
|
||||
#include <base/native_types.h>
|
||||
|
||||
/* core includes */
|
||||
#include <pager.h>
|
||||
#include <address_space.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_pd;
|
||||
class Platform_thread
|
||||
{
|
||||
private:
|
||||
|
||||
friend class Platform_pd;
|
||||
|
||||
enum { PD_NAME_MAX_LEN = 64 };
|
||||
|
||||
unsigned _tid; /* global codezero thread ID */
|
||||
unsigned _space_id;
|
||||
Weak_ptr<Address_space> _address_space;
|
||||
addr_t _utcb;
|
||||
char _name[PD_NAME_MAX_LEN];
|
||||
Pager_object *_pager;
|
||||
|
||||
/**
|
||||
* Assign physical thread ID and UTCB address to thread
|
||||
*
|
||||
* This function is called from 'Platform_pd::bind_thread'.
|
||||
*/
|
||||
void _assign_physical_thread(unsigned tid, unsigned space_id,
|
||||
addr_t utcb,
|
||||
Weak_ptr<Address_space> address_space)
|
||||
{
|
||||
_tid = tid; _space_id = space_id; _utcb = utcb;
|
||||
_address_space = address_space;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
enum { THREAD_INVALID = -1 }; /* invalid thread number */
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_thread(size_t, const char *name = 0, unsigned priority = 0,
|
||||
addr_t utcb = 0, int thread_id = THREAD_INVALID);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Platform_thread();
|
||||
|
||||
/**
|
||||
* Start thread
|
||||
*
|
||||
* \param ip instruction pointer to start at
|
||||
* \param sp stack pointer to use
|
||||
* \param cpu_no target cpu
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread could not be started
|
||||
*/
|
||||
int start(void *ip, void *sp, unsigned int cpu_no = 0);
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause();
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
*/
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
/**
|
||||
* Return the address space to which the thread is bound
|
||||
*/
|
||||
Weak_ptr<Address_space> address_space();
|
||||
|
||||
|
||||
/************************
|
||||
** Accessor functions **
|
||||
************************/
|
||||
|
||||
/**
|
||||
* Set pager capability
|
||||
*/
|
||||
Pager_object *pager(Pager_object *pager) const { return _pager; }
|
||||
void pager(Pager_object *pager) { _pager = pager; }
|
||||
Pager_object *pager() { return _pager; }
|
||||
|
||||
/**
|
||||
* Return identification of thread when faulting
|
||||
*/
|
||||
unsigned long pager_object_badge() const { return _tid; }
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
*/
|
||||
void affinity(Affinity::Location) { }
|
||||
|
||||
/**
|
||||
* Get the executing CPU for this thread
|
||||
*/
|
||||
Affinity::Location affinity() const { return Affinity::Location(); }
|
||||
|
||||
/**
|
||||
* Get thread name
|
||||
*/
|
||||
const char *name() const { return "noname"; }
|
||||
|
||||
|
||||
/***********************
|
||||
** Codezero specific **
|
||||
***********************/
|
||||
|
||||
addr_t utcb() const { return _utcb; }
|
||||
|
||||
/**
|
||||
* Set CPU quota of the thread to 'quota'
|
||||
*/
|
||||
void quota(size_t const quota) { /* not supported*/ }
|
||||
|
||||
/**
|
||||
* Return execution time consumed by the thread
|
||||
*/
|
||||
unsigned long long execution_time() const { return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* \brief Core-internal utilities
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__UTIL_H_
|
||||
#define _CORE__INCLUDE__UTIL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
constexpr size_t get_page_size_log2() { return 12; }
|
||||
constexpr size_t get_page_size() { return 1 << get_page_size_log2(); }
|
||||
constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); }
|
||||
inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); }
|
||||
inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); }
|
||||
|
||||
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
|
||||
inline size_t constrain_map_size_log2(size_t size_log2) { return get_page_size_log2(); }
|
||||
|
||||
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
|
||||
Rm_session::Fault_type pf_type,
|
||||
unsigned long faulter_badge)
|
||||
{
|
||||
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg,
|
||||
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ",
|
||||
(void *)pf_addr, (void *)pf_ip,
|
||||
faulter_badge);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__UTIL_H_ */
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* \brief Implementation of the IO_MEM session interface
|
||||
* \author Norman Feske
|
||||
* \date 2009-03-29
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <io_mem_session_component.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Io_mem_session_component::_unmap_local(addr_t base, size_t size)
|
||||
{ }
|
||||
|
||||
|
||||
addr_t Io_mem_session_component::_map_local(addr_t base, size_t size)
|
||||
{ return 0; }
|
@ -1,134 +0,0 @@
|
||||
/*
|
||||
* \brief Implementation of IRQ session component
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <irq_root.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
bool Irq_object::_associate() { return true; }
|
||||
|
||||
|
||||
void Irq_object::_wait_for_irq()
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
/* block for IRQ */
|
||||
int ret = l4_irq_control(IRQ_CONTROL_WAIT, 0, _irq);
|
||||
if (ret < 0)
|
||||
PWRN("l4_irq_control(IRQ_CONTROL_WAIT) returned %d", ret);
|
||||
}
|
||||
|
||||
|
||||
void Irq_object::start()
|
||||
{
|
||||
::Thread_base::start();
|
||||
_sync_bootup.lock();
|
||||
}
|
||||
|
||||
|
||||
void Irq_object::entry()
|
||||
{
|
||||
if (!_associate()) {
|
||||
PERR("Could not associate with IRQ 0x%x", _irq);
|
||||
return;
|
||||
}
|
||||
|
||||
/* thread is up and ready */
|
||||
_sync_bootup.unlock();
|
||||
|
||||
/* wait for first ack_irq */
|
||||
_sync_ack.lock();
|
||||
|
||||
using namespace Codezero;
|
||||
|
||||
/* attach thread to IRQ when first called */
|
||||
int ret = l4_irq_control(IRQ_CONTROL_REGISTER, 0, _irq);
|
||||
if (ret < 0) {
|
||||
PERR("l4_irq_control(IRQ_CONTROL_REGISTER) returned %d", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
||||
_wait_for_irq();
|
||||
|
||||
if (!_sig_cap.valid())
|
||||
continue;
|
||||
|
||||
Genode::Signal_transmitter(_sig_cap).submit(1);
|
||||
|
||||
_sync_ack.lock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Irq_object::Irq_object(unsigned irq)
|
||||
:
|
||||
Thread<4096>("irq"),
|
||||
_sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
|
||||
_irq(irq)
|
||||
{ }
|
||||
|
||||
|
||||
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
|
||||
const char *args)
|
||||
:
|
||||
_irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
|
||||
_irq_alloc(irq_alloc),
|
||||
_irq_object(_irq_number)
|
||||
{
|
||||
long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
|
||||
if (msi)
|
||||
throw Root::Unavailable();
|
||||
|
||||
if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).is_error()) {
|
||||
PERR("Unavailable IRQ 0x%x requested", _irq_number);
|
||||
throw Root::Unavailable();
|
||||
}
|
||||
|
||||
_irq_object.start();
|
||||
}
|
||||
|
||||
|
||||
Irq_session_component::~Irq_session_component()
|
||||
{
|
||||
PERR("Not yet implemented.");
|
||||
}
|
||||
|
||||
|
||||
void Irq_session_component::ack_irq()
|
||||
{
|
||||
_irq_object.ack_irq();
|
||||
}
|
||||
|
||||
|
||||
void Irq_session_component::sigh(Genode::Signal_context_capability cap)
|
||||
{
|
||||
_irq_object.sigh(cap);
|
||||
}
|
||||
|
||||
|
||||
Genode::Irq_session::Info Irq_session_component::info()
|
||||
{
|
||||
/* no MSI support */
|
||||
return { .type = Genode::Irq_session::Info::Type::INVALID };
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* \brief Pager support for Codezero
|
||||
* \author Norman Feske
|
||||
* \date 2010-02-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <pager.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <ipc_pager.h>
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
enum { verbose_page_faults = false };
|
||||
|
||||
|
||||
/************************
|
||||
** Page-fault utility **
|
||||
************************/
|
||||
|
||||
class Fault
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type { READ, WRITE, EXEC, UNKNOWN };
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Translate Codezero page-fault information to generic fault type
|
||||
*
|
||||
* \param sr status
|
||||
* \param pte page-table entry
|
||||
*/
|
||||
static Type _fault_type(umword_t sr, umword_t pte)
|
||||
{
|
||||
if (is_prefetch_abort(sr))
|
||||
return EXEC;
|
||||
|
||||
if ((pte & PTE_PROT_MASK) == (__MAP_USR_RO & PTE_PROT_MASK))
|
||||
return WRITE;
|
||||
|
||||
return READ;
|
||||
}
|
||||
|
||||
Type _type;
|
||||
umword_t _addr;
|
||||
umword_t _ip;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param kdata Codezero-specific page-fault information
|
||||
*/
|
||||
Fault(struct fault_kdata const &kdata)
|
||||
:
|
||||
_type(_fault_type(kdata.fsr, kdata.pte)),
|
||||
_addr(_type == EXEC ? kdata.faulty_pc : kdata.far),
|
||||
_ip(kdata.faulty_pc)
|
||||
{ }
|
||||
|
||||
Type type() const { return _type; }
|
||||
umword_t addr() const { return _addr; }
|
||||
umword_t ip() const { return _ip; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Print page-fault information in a human-readable form
|
||||
*/
|
||||
inline void print_page_fault(Fault &fault, int from)
|
||||
{
|
||||
printf("page (%s%s%s) fault from %d at pf_addr=%lx, pf_ip=%lx\n",
|
||||
fault.type() == Fault::READ ? "r" : "-",
|
||||
fault.type() == Fault::WRITE ? "w" : "-",
|
||||
fault.type() == Fault::EXEC ? "x" : "-",
|
||||
from, fault.addr(), fault.ip());
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** IPC pager **
|
||||
***************/
|
||||
|
||||
void Ipc_pager::wait_for_fault()
|
||||
{
|
||||
for (;;) {
|
||||
int ret = l4_receive(L4_ANYTHREAD);
|
||||
|
||||
if (ret < 0) {
|
||||
PERR("pager: l4_received returned ret=%d", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
umword_t tag = l4_get_tag();
|
||||
int faulter_tid = l4_get_sender();
|
||||
|
||||
if (tag != L4_IPC_TAG_PFAULT) {
|
||||
PWRN("got an unexpected IPC from %d", faulter_tid);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* copy fault information from message registers */
|
||||
struct fault_kdata fault_kdata;
|
||||
for (unsigned i = 0; i < sizeof(fault_kdata_t)/sizeof(umword_t); i++)
|
||||
((umword_t *)&fault_kdata)[i] = read_mr(MR_UNUSED_START + i);
|
||||
|
||||
Fault fault(fault_kdata);
|
||||
|
||||
if (verbose_page_faults)
|
||||
print_page_fault(fault, faulter_tid);
|
||||
|
||||
/* determine corresponding page in our own address space */
|
||||
_pf_addr = fault.addr();
|
||||
_pf_write = fault.type() == Fault::WRITE;
|
||||
_pf_ip = fault.ip();
|
||||
_last = faulter_tid;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ipc_pager::reply_and_wait_for_fault()
|
||||
{
|
||||
/* install mapping */
|
||||
umword_t flags = _reply_mapping.writeable() ? MAP_USR_RW
|
||||
: MAP_USR_RO;
|
||||
|
||||
/*
|
||||
* XXX: remove heuristics for mapping device registers.
|
||||
*/
|
||||
if (_reply_mapping.from_phys() == 0x10120000 /* LCD */
|
||||
|| _reply_mapping.from_phys() == 0x10006000 /* keyboard */
|
||||
|| _reply_mapping.from_phys() == 0x10007000) /* mouse */
|
||||
flags = MAP_USR_IO;
|
||||
|
||||
int ret = l4_map((void *)_reply_mapping.from_phys(),
|
||||
(void *)_reply_mapping.to_virt(),
|
||||
_reply_mapping.num_pages(), flags, _last);
|
||||
|
||||
/* wake up faulter if mapping succeeded */
|
||||
if (ret < 0)
|
||||
PERR("l4_map returned %d, putting thread %d to sleep", ret, _last);
|
||||
else
|
||||
acknowledge_wakeup();
|
||||
|
||||
/* wait for next page fault */
|
||||
wait_for_fault();
|
||||
}
|
||||
|
||||
|
||||
void Ipc_pager::acknowledge_wakeup()
|
||||
{
|
||||
enum { SUCCESS = 0 };
|
||||
l4_set_sender(_last);
|
||||
l4_ipc_return(SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** Pager entrypoint **
|
||||
**********************/
|
||||
|
||||
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
|
||||
{
|
||||
return Untyped_capability(_tid.l4id, badge);
|
||||
}
|
@ -1,302 +0,0 @@
|
||||
/*
|
||||
* \brief Platform interface implementation
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_parent.h>
|
||||
#include <platform.h>
|
||||
#include <map_local.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum { verbose_boot_info = true };
|
||||
|
||||
/*
|
||||
* Memory-layout information provided by the linker script
|
||||
*/
|
||||
|
||||
/* virtual address range consumed by core's program image */
|
||||
extern unsigned _prog_img_beg, _prog_img_end;
|
||||
|
||||
/* physical address range occupied by core */
|
||||
extern addr_t _vma_start, _lma_start;
|
||||
|
||||
|
||||
/**************************
|
||||
** Boot-module handling **
|
||||
**************************/
|
||||
|
||||
/**
|
||||
* Scan ROM module image for boot modules
|
||||
*
|
||||
* By convention, the boot modules start at the page after core's BSS segment.
|
||||
*/
|
||||
int Platform::_init_rom_fs()
|
||||
{
|
||||
/**
|
||||
* Format of module meta-data as found in the ROM module image
|
||||
*/
|
||||
struct Module
|
||||
{
|
||||
long name; /* physical address of null-terminated string */
|
||||
long base; /* physical address of module data */
|
||||
long size; /* size of module data in bytes */
|
||||
};
|
||||
|
||||
/* find base address of ROM module image */
|
||||
addr_t phys_base = round_page((addr_t)&_prog_img_end);
|
||||
|
||||
/* map the first page of the image containing the module meta data */
|
||||
class Out_of_virtual_memory_during_rom_fs_init { };
|
||||
void *virt_base = 0;
|
||||
if (!_core_mem_alloc.virt_alloc()->alloc(get_page_size(), &virt_base))
|
||||
throw Out_of_virtual_memory_during_rom_fs_init();
|
||||
|
||||
if (!map_local(phys_base, (addr_t)virt_base, 1)) {
|
||||
PERR("map_local failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* remove page containing module infos from physical memory allocator */
|
||||
_core_mem_alloc.phys_alloc()->remove_range(phys_base, get_page_size());
|
||||
|
||||
/* validate the presence of a ROM image by checking the magic cookie */
|
||||
const char cookie[4] = {'G', 'R', 'O', 'M'};
|
||||
for (size_t i = 0; i < sizeof(cookie); i++)
|
||||
if (cookie[i] != ((char *)virt_base)[i]) {
|
||||
PERR("could not detect ROM modules");
|
||||
return -2;
|
||||
}
|
||||
|
||||
printf("detected ROM module image at 0x%p\n", (void *)phys_base);
|
||||
|
||||
/* detect overly large meta data, we only support 4K */
|
||||
addr_t end_of_header = ((long *)virt_base)[1];
|
||||
size_t header_size = end_of_header - (long)phys_base;
|
||||
if (header_size > get_page_size()) {
|
||||
PERR("ROM fs module header exceeds %d bytes", get_page_size());
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* start of module list */
|
||||
Module *module = (Module *)((addr_t)virt_base + 2*sizeof(long));
|
||||
|
||||
/*
|
||||
* Interate over module list and populate core's ROM file system with
|
||||
* 'Rom_module' objects.
|
||||
*/
|
||||
for (; module->name; module++) {
|
||||
|
||||
/* convert physical address of module name to core-local address */
|
||||
char *name = (char *)(module->name - phys_base + (addr_t)virt_base);
|
||||
|
||||
printf("ROM module \"%s\" at physical address 0x%p, size=%zd\n",
|
||||
name, (void *)module->base, (size_t)module->size);
|
||||
|
||||
Rom_module *rom_module = new (core_mem_alloc())
|
||||
Rom_module(module->base, module->size, name);
|
||||
|
||||
_rom_fs.insert(rom_module);
|
||||
|
||||
/* remove module from physical memory allocator */
|
||||
_core_mem_alloc.phys_alloc()->remove_range(module->base, round_page(module->size));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************
|
||||
** Support for core memory management **
|
||||
****************************************/
|
||||
|
||||
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
|
||||
addr_t phys_addr,
|
||||
unsigned size)
|
||||
{
|
||||
return map_local(phys_addr, virt_addr, size / get_page_size());
|
||||
}
|
||||
|
||||
|
||||
bool Core_mem_allocator::Mapped_mem_allocator::_unmap_local(addr_t virt_addr,
|
||||
unsigned size)
|
||||
{
|
||||
return unmap_local(virt_addr, size / get_page_size());
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
** Platform interface **
|
||||
************************/
|
||||
|
||||
Platform::Platform() :
|
||||
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
||||
_irq_alloc(core_mem_alloc()), _vm_base(0), _vm_size(0)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
/* init core UTCB */
|
||||
static char main_utcb[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
|
||||
static struct exregs_data exregs;
|
||||
exregs_set_utcb(&exregs, (unsigned long)&main_utcb[0]);
|
||||
l4_exchange_registers(&exregs, thread_myself());
|
||||
|
||||
/* error handling is futile at this point */
|
||||
|
||||
/* read number of capabilities */
|
||||
int num_caps;
|
||||
int ret;
|
||||
if ((ret = l4_capability_control(CAP_CONTROL_NCAPS,
|
||||
0, &num_caps)) < 0) {
|
||||
PERR("l4_capability_control(CAP_CONTROL_NCAPS) returned %d", ret);
|
||||
class Could_not_obtain_num_of_capabilities { };
|
||||
throw Could_not_obtain_num_of_capabilities();
|
||||
}
|
||||
|
||||
struct capability cap_array[num_caps];
|
||||
|
||||
if (verbose_boot_info)
|
||||
printf("allocated cap array[%d] of size %d on stack\n",
|
||||
num_caps, sizeof(cap_array));
|
||||
|
||||
/* read all capabilities */
|
||||
if ((ret = l4_capability_control(CAP_CONTROL_READ,
|
||||
0, cap_array)) < 0) {
|
||||
PERR("l4_capability_control(CAP_CONTROL_READ) returned %d", ret);
|
||||
class Read_caps_failed { };
|
||||
throw Read_caps_failed();
|
||||
}
|
||||
|
||||
/* initialize core allocators */
|
||||
bool phys_mem_defined = false;
|
||||
addr_t dev_mem_base = 0;
|
||||
for (int i = 0; i < num_caps; i++) {
|
||||
struct capability *cap = &cap_array[i];
|
||||
|
||||
addr_t base = cap->start << get_page_size_log2(),
|
||||
size = cap->size << get_page_size_log2();
|
||||
|
||||
if (verbose_boot_info)
|
||||
printf("cap type=%x, rtype=%x, base=%lx, size=%lx\n",
|
||||
cap_type(cap), cap_rtype(cap), base, size);
|
||||
|
||||
switch (cap_type(cap)) {
|
||||
|
||||
case CAP_TYPE_MAP_VIRTMEM:
|
||||
|
||||
/*
|
||||
* Use first non-UTCB virtual address range as default
|
||||
* virtual memory range usable for all processes.
|
||||
*/
|
||||
if (_vm_size == 0) {
|
||||
|
||||
/* exclude page at virtual address 0 */
|
||||
if (base == 0 && size >= get_page_size()) {
|
||||
base += get_page_size();
|
||||
size -= get_page_size();
|
||||
}
|
||||
|
||||
_vm_base = base;
|
||||
_vm_size = size;
|
||||
|
||||
/* add range as free range to core's virtual address allocator */
|
||||
_core_mem_alloc.virt_alloc()->add_range(base, size);
|
||||
break;
|
||||
}
|
||||
|
||||
PWRN("ignoring additional virtual address range [%lx,%lx)",
|
||||
base, base + size);
|
||||
break;
|
||||
|
||||
case CAP_TYPE_MAP_PHYSMEM:
|
||||
|
||||
/*
|
||||
* We interpret the first physical memory resource that is bigger
|
||||
* than typical device resources as RAM.
|
||||
*/
|
||||
enum { RAM_SIZE_MIN = 16*1024*1024 };
|
||||
if (!phys_mem_defined && size > RAM_SIZE_MIN) {
|
||||
_core_mem_alloc.phys_alloc()->add_range(base, size);
|
||||
phys_mem_defined = true;
|
||||
dev_mem_base = base + size;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAP_TYPE_IPC:
|
||||
case CAP_TYPE_UMUTEX:
|
||||
case CAP_TYPE_IRQCTRL:
|
||||
case CAP_TYPE_QUANTITY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addr_t core_virt_beg = trunc_page((addr_t)&_prog_img_beg),
|
||||
core_virt_end = round_page((addr_t)&_prog_img_end);
|
||||
size_t core_size = core_virt_end - core_virt_beg;
|
||||
|
||||
printf("core image:\n");
|
||||
printf(" virtual address range [%08lx,%08lx) size=0x%zx\n",
|
||||
core_virt_beg, core_virt_end, core_size);
|
||||
printf(" physically located at 0x%08lx\n", _lma_start);
|
||||
|
||||
/* remove core image from core's virtual address allocator */
|
||||
_core_mem_alloc.virt_alloc()->remove_range(core_virt_beg, core_size);
|
||||
|
||||
/* preserve context area in core's virtual address space */
|
||||
_core_mem_alloc.virt_alloc()->raw()->remove_range(Native_config::context_area_virtual_base(),
|
||||
Native_config::context_area_virtual_size());
|
||||
|
||||
/* remove used core memory from physical memory allocator */
|
||||
_core_mem_alloc.phys_alloc()->remove_range(_lma_start, core_size);
|
||||
|
||||
/* remove magically mapped UART from core virtual memory */
|
||||
_core_mem_alloc.virt_alloc()->remove_range(USERSPACE_CONSOLE_VBASE, get_page_size());
|
||||
|
||||
/* add boot modules to ROM fs */
|
||||
if (_init_rom_fs() < 0) {
|
||||
PERR("initialization of romfs failed - halt.");
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* initialize interrupt allocator */
|
||||
_irq_alloc.add_range(0, 255);
|
||||
|
||||
/* regard physical addresses higher than memory area as MMIO */
|
||||
_io_mem_alloc.add_range(dev_mem_base, 0x80000000 - dev_mem_base);
|
||||
|
||||
/*
|
||||
* Print statistics about allocator initialization
|
||||
*/
|
||||
printf("VM area at [%08lx,%08lx)\n", _vm_base, _vm_base + _vm_size);
|
||||
|
||||
if (verbose_boot_info) {
|
||||
printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
|
||||
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
|
||||
printf(":io_mem_alloc: "); _io_mem_alloc.raw()->dump_addr_tree();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Platform::wait_for_exit()
|
||||
{
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Core_parent::exit(int exit_value) { }
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* \brief Protection-domain facility
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_pd.h>
|
||||
#include <platform.h>
|
||||
#include <util.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
/***************************
|
||||
** Public object members **
|
||||
***************************/
|
||||
|
||||
int Platform_pd::bind_thread(Platform_thread *thread)
|
||||
{
|
||||
/* allocate new thread at the kernel */
|
||||
struct task_ids ids = { 1, _space_id, TASK_ID_INVALID };
|
||||
int ret = l4_thread_control(THREAD_CREATE | TC_SHARE_SPACE, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control returned %d, tid=%d\n", ret, ids.tid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate UTCB for new thread */
|
||||
int utcb_idx;
|
||||
for (utcb_idx = 0; utcb_idx < MAX_THREADS_PER_PD; utcb_idx++)
|
||||
if (!utcb_in_use[utcb_idx]) break;
|
||||
|
||||
if (utcb_idx == MAX_THREADS_PER_PD) {
|
||||
PERR("UTCB allocation failed");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* mark UTCB as being in use */
|
||||
utcb_in_use[utcb_idx] = true;
|
||||
|
||||
/* map UTCB area for the first thread of a new PD */
|
||||
if (utcb_idx == 0) {
|
||||
void *utcb_phys = 0;
|
||||
if (!platform()->ram_alloc()->alloc(UTCB_AREA_SIZE, &utcb_phys)) {
|
||||
PERR("could not allocate physical pages for UTCB");
|
||||
return -3;
|
||||
}
|
||||
|
||||
ret = l4_map(utcb_phys, (void *)UTCB_VIRT_BASE,
|
||||
UTCB_AREA_SIZE/get_page_size(), MAP_USR_RW, ids.tid);
|
||||
if (ret < 0) {
|
||||
PERR("UTCB mapping into new PD failed, ret=%d", ret);
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
addr_t utcb_addr = UTCB_VIRT_BASE + utcb_idx*sizeof(struct utcb);
|
||||
thread->_assign_physical_thread(ids.tid, _space_id, utcb_addr,
|
||||
this->Address_space::weak_ptr());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform_pd::unbind_thread(Platform_thread *thread)
|
||||
{
|
||||
/* find UTCB index of thread */
|
||||
unsigned utcb_idx;
|
||||
for (utcb_idx = 0; utcb_idx < MAX_THREADS_PER_PD; utcb_idx++)
|
||||
if (thread->utcb() == UTCB_VIRT_BASE + utcb_idx*sizeof(struct utcb))
|
||||
break;
|
||||
|
||||
if (utcb_idx == MAX_THREADS_PER_PD) {
|
||||
PWRN("could not find UTCB index of thread");
|
||||
return;
|
||||
}
|
||||
|
||||
utcb_in_use[utcb_idx] = false;
|
||||
|
||||
PWRN("not fully implemented");
|
||||
}
|
||||
|
||||
|
||||
Platform_pd::Platform_pd(bool core)
|
||||
{
|
||||
PWRN("not yet implemented");
|
||||
}
|
||||
|
||||
|
||||
Platform_pd::Platform_pd(Allocator * md_alloc, char const *,
|
||||
signed pd_id, bool create)
|
||||
: _space_id(TASK_ID_INVALID)
|
||||
{
|
||||
_space_id = TASK_ID_INVALID;
|
||||
|
||||
/* mark all UTCBs of the new PD as free */
|
||||
for (int i = 0; i < MAX_THREADS_PER_PD; i++)
|
||||
utcb_in_use[i] = false;
|
||||
|
||||
struct task_ids ids = { TASK_ID_INVALID, TASK_ID_INVALID, TASK_ID_INVALID };
|
||||
|
||||
int ret = l4_thread_control(THREAD_CREATE | TC_NEW_SPACE, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control(THREAD_CREATE | TC_NEW_SPACE) returned %d", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set space ID to valid value to indicate success */
|
||||
_space_id = ids.spid;
|
||||
}
|
||||
|
||||
|
||||
Platform_pd::~Platform_pd()
|
||||
{
|
||||
/* invalidate weak pointers to this object */
|
||||
Address_space::lock_for_destruction();
|
||||
|
||||
PWRN("not yet implemented");
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* \brief Thread facility
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no)
|
||||
{
|
||||
Native_thread_id pager = _pager ? _pager->cap().dst() : THREAD_INVALID;
|
||||
|
||||
/* setup thread context */
|
||||
struct exregs_data exregs;
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_stack(&exregs, (unsigned long)sp);
|
||||
exregs_set_pc (&exregs, (unsigned long)ip);
|
||||
exregs_set_pager(&exregs, pager);
|
||||
exregs_set_utcb (&exregs, _utcb);
|
||||
|
||||
int ret = l4_exchange_registers(&exregs, _tid);
|
||||
if (ret < 0) {
|
||||
printf("l4_exchange_registers returned ret=%d\n", ret);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* start execution */
|
||||
struct task_ids ids = { _tid, _space_id, _tid };
|
||||
ret = l4_thread_control(THREAD_RUN, &ids);
|
||||
if (ret < 0) {
|
||||
printf("Error: l4_thread_control(THREAD_RUN) returned %d\n", ret);
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (verbose_thread_start)
|
||||
printf("core started thread \"%s\" with ID %d inside space ID %d\n",
|
||||
_name, _tid, _space_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::pause()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::resume()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::cancel_blocking()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
Weak_ptr<Address_space> Platform_thread::address_space()
|
||||
{
|
||||
return _address_space;
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(size_t, const char *name, unsigned, addr_t,
|
||||
int thread_id)
|
||||
: _tid(THREAD_INVALID)
|
||||
{
|
||||
strncpy(_name, name, sizeof(_name));
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::~Platform_thread()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* \brief Export RAM dataspace as shared memory object (dummy)
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
/* core includes */
|
||||
#include <ram_session_component.h>
|
||||
#include <platform.h>
|
||||
#include <map_local.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { }
|
||||
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { }
|
||||
|
||||
void Ram_session_component::_clear_ds (Dataspace_component *ds)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
/*
|
||||
* Map dataspace core-locally, memset, unmap dataspace
|
||||
*/
|
||||
|
||||
size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask();
|
||||
size_t num_pages = page_rounded_size >> get_page_size_log2();
|
||||
|
||||
/* allocate range in core's virtual address space */
|
||||
void *virt_addr;
|
||||
if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) {
|
||||
PERR("Could not allocate virtual address range in core of size %zd\n",
|
||||
page_rounded_size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* map the dataspace's physical pages to corresponding virtual addresses */
|
||||
if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages)) {
|
||||
PERR("core-local memory mapping failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(virt_addr, 0, ds->size());
|
||||
|
||||
/* unmap dataspace from core */
|
||||
if (!unmap_local((addr_t)virt_addr, num_pages)) {
|
||||
PERR("could not unmap %zd pages from virtual address range at %p",
|
||||
num_pages, virt_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* free core's virtual address space */
|
||||
platform()->region_alloc()->free(virt_addr, page_rounded_size);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* \brief RM-session implementation
|
||||
* \author Norman Feske
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <rm_session_component.h>
|
||||
#include <util.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
|
||||
{
|
||||
l4_unmap((void *)virt_base, size >> get_page_size_log2(), badge());
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
TARGET = core
|
||||
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
|
||||
SRC_CC += cap_session_component.cc \
|
||||
context_area.cc \
|
||||
core_mem_alloc.cc \
|
||||
core_rm_session.cc \
|
||||
cpu_session_component.cc \
|
||||
cpu_session_support.cc \
|
||||
dataspace_component.cc \
|
||||
dump_alloc.cc \
|
||||
io_mem_session_component.cc \
|
||||
io_mem_session_support.cc \
|
||||
irq_session_component.cc \
|
||||
main.cc \
|
||||
pager.cc \
|
||||
pager_ep.cc \
|
||||
pager_object.cc \
|
||||
pd_session_component.cc \
|
||||
platform.cc \
|
||||
platform_pd.cc \
|
||||
platform_services.cc \
|
||||
platform_thread.cc \
|
||||
ram_session_component.cc \
|
||||
ram_session_support.cc \
|
||||
rm_session_component.cc \
|
||||
rm_session_support.cc \
|
||||
rom_session_component.cc \
|
||||
signal_session_component.cc \
|
||||
signal_source_component.cc \
|
||||
thread_start.cc \
|
||||
trace_session_component.cc
|
||||
|
||||
LIBS += core_printf base-common
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(GEN_CORE_DIR)/include \
|
||||
$(REP_DIR)/include/codezero/dummies \
|
||||
$(BASE_DIR)/src/base/thread
|
||||
|
||||
include $(GEN_CORE_DIR)/version.inc
|
||||
|
||||
vpath main.cc $(GEN_CORE_DIR)
|
||||
vpath ram_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath rom_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath cap_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath cpu_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath pd_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath rm_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
|
||||
vpath platform_services.cc $(GEN_CORE_DIR)
|
||||
vpath signal_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath signal_source_component.cc $(GEN_CORE_DIR)
|
||||
vpath trace_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath dataspace_component.cc $(GEN_CORE_DIR)
|
||||
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
|
||||
vpath dump_alloc.cc $(GEN_CORE_DIR)
|
||||
vpath context_area.cc $(GEN_CORE_DIR)
|
||||
vpath pager_ep.cc $(GEN_CORE_DIR)
|
||||
vpath pager_object.cc $(GEN_CORE_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/core
|
@ -1,4 +0,0 @@
|
||||
include $(PRG_DIR)/target.inc
|
||||
|
||||
LD_TEXT_ADDR = 0x100000
|
||||
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* \brief Implementation of Thread API interface for core
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
|
||||
/**
|
||||
* Create and start new thread
|
||||
*
|
||||
* \param space_no space ID in which the new thread will be executed
|
||||
* \param sp initial stack pointer
|
||||
* \param ip initial instruction pointer
|
||||
* \return new thread ID, or
|
||||
* negative error code
|
||||
*/
|
||||
inline int create_thread(unsigned space_no,
|
||||
void *sp, void *ip,
|
||||
int pager_tid = 1)
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
struct task_ids ids = { 1U, space_no, TASK_ID_INVALID };
|
||||
|
||||
/* allocate new thread at the kernel */
|
||||
unsigned long flags = THREAD_CREATE | TC_SHARE_SPACE | TC_SHARE_GROUP;
|
||||
int ret = l4_thread_control(flags, &ids);
|
||||
if (ret < 0) {
|
||||
PERR("l4_thread_control returned %d, spid=%d\n",
|
||||
ret, ids.spid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long utcb_base_addr = (unsigned long)l4_get_utcb();
|
||||
|
||||
/* calculate utcb address of new thread */
|
||||
unsigned long new_utcb = utcb_base_addr + ids.tid*sizeof(struct utcb);
|
||||
|
||||
/* setup thread context */
|
||||
struct exregs_data exregs;
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_stack(&exregs, (unsigned long)sp);
|
||||
exregs_set_pc (&exregs, (unsigned long)ip);
|
||||
exregs_set_pager(&exregs, pager_tid);
|
||||
exregs_set_utcb (&exregs, new_utcb);
|
||||
|
||||
ret = l4_exchange_registers(&exregs, ids.tid);
|
||||
if (ret < 0) {
|
||||
printf("l4_exchange_registers returned ret=%d\n", ret);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* start execution */
|
||||
ret = l4_thread_control(THREAD_RUN, &ids);
|
||||
if (ret < 0) {
|
||||
printf("Error: l4_thread_control(THREAD_RUN) returned %d\n", ret);
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* return new thread ID allocated by the kernel */
|
||||
return ids.tid;
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
Thread_base::myself()->_thread_bootstrap();
|
||||
Thread_base::myself()->entry();
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform()->core_mem_alloc())
|
||||
Platform_thread(0, _context->name);
|
||||
|
||||
_tid.l4id = create_thread(1, stack_top(), (void *)&_thread_start);
|
||||
|
||||
if (_tid.l4id < 0)
|
||||
PERR("create_thread returned %d", _tid.l4id);
|
||||
|
||||
if (verbose_thread_start)
|
||||
printf("core started local thread \"%s\" with ID %d\n",
|
||||
_context->name, _tid.l4id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
PWRN("not implemented");
|
||||
}
|
||||
|
||||
|
@ -1,71 +0,0 @@
|
||||
TARGET = codezero
|
||||
|
||||
CODEZERO_DIR := $(call select_from_ports,codezero)/src/kernel/codezero
|
||||
|
||||
include $(REP_DIR)/lib/mk/codezero_cml.inc
|
||||
|
||||
TOOL_CHAIN_DIR = $(dir $(CROSS_DEV_PREFIX))
|
||||
CODEZERO_DST_DIR = $(BUILD_BASE_DIR)/kernel/codezero
|
||||
CODEZERO_BUILD_DIR = $(CODEZERO_DST_DIR)/build
|
||||
|
||||
.PHONY: $(TARGET)
|
||||
|
||||
MIRROR_COPY := conts/baremetal/empty conts/userlibs \
|
||||
build.py include SConstruct src loader
|
||||
|
||||
MIRROR_SYMLINK := scripts tools
|
||||
|
||||
update_copy = $(VERBOSE)tar c -C $(CODEZERO_DIR) $(MIRROR_COPY) | tar x -C $(CODEZERO_DST_DIR)
|
||||
|
||||
ifneq ($(VERBOSE),)
|
||||
CODEZERO_STDOUT := > /dev/null
|
||||
endif
|
||||
|
||||
#
|
||||
# Environment variables passed to the Codezero build system
|
||||
#
|
||||
BUILD_ENV = PATH=$(dir $(CROSS_DEV_PREFIX)):$$PATH
|
||||
|
||||
#
|
||||
# Local copy of the CML file used for supplying the configuration
|
||||
# to the Codezero build system.
|
||||
#
|
||||
LOCAL_CONFIG_CML := $(shell pwd)/config.cml
|
||||
|
||||
$(TARGET): $(CODEZERO_BUILD_DIR)
|
||||
$(MSG_BUILD)kernel
|
||||
$(update_copy)
|
||||
$(VERBOSE)cd $(CODEZERO_DST_DIR); $(BUILD_ENV) ./build.py $(CODEZERO_STDOUT)
|
||||
|
||||
#
|
||||
# Mirror the parts of the Codezero source tree that are relevant for building
|
||||
# the kernel
|
||||
#
|
||||
$(CODEZERO_DST_DIR): $(CODEZERO_DIR)
|
||||
$(VERBOSE)test -d $@ || mkdir -p $@
|
||||
$(VERBOSE)for d in $(MIRROR_SYMLINK); do ln -sf $(realpath $^)/$$d $@/$$d; done
|
||||
|
||||
$(CODEZERO_BUILD_DIR): $(CODEZERO_DST_DIR) $(CODEZERO_CML)
|
||||
$(update_copy)
|
||||
$(VERBOSE)cp $(CODEZERO_CML) $(LOCAL_CONFIG_CML)
|
||||
@#
|
||||
@# Create copy of the CML config in the local build directory to update
|
||||
@# the tool chain parameters according to the CROSS_DEV_PREFIX configured
|
||||
@# for Genode.
|
||||
@#
|
||||
$(VERBOSE)sed -i "/TOOLCHAIN_USERSPACE/s/\".*\"/\"$(notdir $(CROSS_DEV_PREFIX))\"/" $(LOCAL_CONFIG_CML)
|
||||
$(VERBOSE)sed -i "/TOOLCHAIN_KERNEL/s/\".*\"/\"$(notdir $(CROSS_DEV_PREFIX))\"/" $(LOCAL_CONFIG_CML)
|
||||
$(VERBOSE)cd $(CODEZERO_DST_DIR); $(BUILD_ENV) ./build.py -C -b -f $(LOCAL_CONFIG_CML) $(CODEZERO_STDOUT)
|
||||
|
||||
clean cleanall: clean_codezero
|
||||
|
||||
#
|
||||
# Make sure to execute the 'clean_codezero' rule prior the generic clean
|
||||
# rule in 'prg.mk' because the generic rule will attempt to remove $(TARGET)
|
||||
# file, which is a directory in our case.
|
||||
#
|
||||
clean_prg_objects: clean_codezero
|
||||
|
||||
clean_codezero:
|
||||
$(VERBOSE)rm -f $(LOCAL_CONFIG_CML)
|
||||
$(VERBOSE)rm -rf $(CODEZERO_DST_DIR)
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* \brief Dummies for Codezeros libmem (used by libl4)
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2011-05-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
void *mem_cache_zalloc(void *cache){ return 0; }
|
||||
void *mem_cache_alloc(void *cache){ return 0; }
|
||||
void *mem_cache_init(void *start, int cache_size, int struct_size,
|
||||
unsigned int alignment) { return 0; }
|
||||
int mem_cache_free(void *cache, void *addr) { return 0; }
|
||||
|
||||
void *kmalloc(int size) { return 0; }
|
||||
|
||||
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* \brief Linker script for Genode programs
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-04-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* values taken from Codezero's mm0 linker script */
|
||||
/*physical_base = 0x00208000;*/
|
||||
/*virtual_base = 0xe0000000;*/
|
||||
/*offset = virtual_base - physical_base;*/
|
||||
|
||||
/*
|
||||
* Addresses correspond to the linker script generated by
|
||||
* the Codezero build system.
|
||||
*/
|
||||
vma_start = 0x100000;
|
||||
lma_start = 0x41000;
|
||||
offset = vma_start - lma_start;
|
||||
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
ro PT_LOAD;
|
||||
rw PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = vma_start;
|
||||
|
||||
.text : AT (ADDR(.text) - offset) {
|
||||
/* begin of program image (link address) */
|
||||
_prog_img_beg = .;
|
||||
|
||||
*(.text.crt0)
|
||||
*(.init)
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.fini)
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
. = ALIGN(0x08);
|
||||
|
||||
_ctors_start = .;
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
|
||||
_ctors_end = .;
|
||||
_dtors_start = .;
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
_dtors_end = .;
|
||||
} : ro = 0x0
|
||||
|
||||
/* Linux: exception section for uaccess mechanism */
|
||||
__ex_table : { *(__ex_table) }
|
||||
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
_prog_img_data = .;
|
||||
|
||||
.data : AT (ADDR(.data) - offset) {
|
||||
/*
|
||||
* Leave space for parent capability parameters at start of data
|
||||
* section. The protection domain creator is reponsible for storing
|
||||
* sane values here.
|
||||
*/
|
||||
_parent_cap = .;
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
_vma_start = .;
|
||||
LONG(vma_start);
|
||||
_lma_start = .;
|
||||
LONG(lma_start);
|
||||
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
} : rw
|
||||
|
||||
/* exception frames for C++ */
|
||||
.eh_frame : {
|
||||
__eh_frame_start__ = .;
|
||||
KEEP (*(.eh_frame))
|
||||
LONG(0)
|
||||
} : rw
|
||||
|
||||
.init_array : {
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
|
||||
.gcc_except_table : { KEEP(*(.gcc_except_table)) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : {
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
}
|
||||
__exidx_end = .;
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab*)
|
||||
} : rw
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
.bss : AT (ADDR(.bss) - offset) {
|
||||
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
|
||||
}
|
||||
|
||||
/* end of program image -- must be after last section */
|
||||
_prog_img_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.note)
|
||||
*(.note.ABI-tag)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os, re, getopt, sys
|
||||
from stat import ST_SIZE
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
verbose = 0
|
||||
|
||||
|
||||
# return address of 4K page following the spefified address
|
||||
def round_page(addr):
|
||||
page_size = 0x1000
|
||||
return (addr + page_size) & ~(page_size - 1)
|
||||
|
||||
|
||||
def first_free_addr_after_program(elf, cross_prefix = ""):
|
||||
try:
|
||||
objdump = cross_prefix + "objdump"
|
||||
objdump_output = Popen([objdump, "-p", elf],
|
||||
stdout=PIPE).communicate()[0]
|
||||
except OSError:
|
||||
print "Error: execution of " + objdump + " failed, invalid cross-tool prefix?"
|
||||
exit(3)
|
||||
|
||||
#
|
||||
# The output of 'objdump -p' contains the list of program segments. Each
|
||||
# segment has two lines of text, the first containing the 'vaddr' value and
|
||||
# the latter containing the 'memsz' value. For each line, we match for both
|
||||
# 'vaddr' and 'memsz' fields. When observing a line with a 'memsz' field,
|
||||
# we know that the previous line contained the corresponding 'vaddr' and
|
||||
# that the end address of the segment is the sum of the current 'vaddr'
|
||||
# and 'memsz' values.
|
||||
#
|
||||
max_end_addr = 0
|
||||
for line in objdump_output.splitlines():
|
||||
match_vaddr = re.compile(".*vaddr (0x[0-9a-f]*).*").match(line)
|
||||
match_memsz = re.compile(".*memsz (0x[0-9a-f]*).*").match(line)
|
||||
if (match_vaddr):
|
||||
vaddr = int(match_vaddr.group(1), 0)
|
||||
if (match_memsz):
|
||||
memsz = int(match_memsz.group(1), 0)
|
||||
max_end_addr = max(max_end_addr, vaddr + memsz)
|
||||
|
||||
# align the first free address at the next page boundary
|
||||
return round_page(max_end_addr)
|
||||
|
||||
|
||||
def generate_modules_asm(modules):
|
||||
"""
|
||||
Generate assembly code aggregating boot-module data from specified files.
|
||||
The generated assembly code looks as follows:
|
||||
|
||||
/*
|
||||
* The ELF image consists only of a data section. At file offset 0, there
|
||||
* is a magic cookie that core validates when accessing the ROM fs. It is
|
||||
* followed by the end address of the meta data.
|
||||
*/
|
||||
.section .data
|
||||
.string "GROM" /* magic cookie used by core to identify a ROM fs image*/
|
||||
.long header_end /* end of ROM fs meta data */
|
||||
|
||||
/*
|
||||
* Each module is represented by a struct of 3 long values. The first
|
||||
* value is pointer to the module name. A null-pointer marks the end of
|
||||
* the module list.
|
||||
*/
|
||||
.long mod1_name /* pointer to the null-terminated module name */
|
||||
.long mod1_start /* pointer to the module data */
|
||||
.long mod1_end - mod1_start /* size of the module data */
|
||||
|
||||
.long 0
|
||||
|
||||
/*
|
||||
* For each module, there exists a null-terminated string labeled with
|
||||
* 'mod<index>_name' referenced by the module list above.
|
||||
*/
|
||||
mod1_name:
|
||||
.string "name of data module"
|
||||
.byte 0
|
||||
|
||||
header_end:
|
||||
|
||||
/*
|
||||
* The data of each module must be aligned at a page boundary to enable
|
||||
* the mapping of individual modules to different address spaces.
|
||||
*/
|
||||
.align 4096
|
||||
mod1_start: .incbin "data"
|
||||
mod1_end:
|
||||
"""
|
||||
|
||||
asm_src = ""
|
||||
|
||||
# header
|
||||
asm_src += ".section .data\nmodule_list:\n"
|
||||
asm_src += ".ascii \"GROM\"\n"
|
||||
asm_src += ".long header_end\n"
|
||||
|
||||
# module list
|
||||
i = 1
|
||||
for module in modules:
|
||||
asm_src += ".long mod" + str(i) + "_name\n"
|
||||
asm_src += ".long mod" + str(i) + "_start\n"
|
||||
asm_src += ".long mod" + str(i) + "_end - mod" + str(i) + "_start\n"
|
||||
i = i + 1
|
||||
asm_src += ".long 0\n"
|
||||
|
||||
# module names
|
||||
i = 1
|
||||
for module in modules:
|
||||
asm_src += "mod" + str(i) + "_name: .string \"" + os.path.split(module)[1] + "\"; .byte 0\n"
|
||||
i = i + 1
|
||||
|
||||
asm_src += "header_end:\n"
|
||||
|
||||
# module data
|
||||
i = 1
|
||||
for module in modules:
|
||||
asm_src += ".p2align 12,0\n"
|
||||
asm_src += "mod" + str(i) + "_start: .incbin \"" + module + "\"; "
|
||||
asm_src += "mod" + str(i) + "_end:\n"
|
||||
i = i + 1
|
||||
|
||||
return asm_src
|
||||
|
||||
instructions = """
|
||||
usage: gen_romfs [-v] [-p <cross-prefix>] -c <core-elf> -o <output> [modules ...]
|
||||
|
||||
Generates Genode ROM file system as ELF file loadable into a Codezero container
|
||||
|
||||
-c|--core ELF binary of Genode's core
|
||||
-o|--output name of ELF image to generate
|
||||
-p|--prefix cross toolchain prefix
|
||||
-v|--verbose print details about generated ROM file systemn
|
||||
"""
|
||||
|
||||
def usage():
|
||||
print instructions
|
||||
|
||||
def user_error(message):
|
||||
print "Error: " + message
|
||||
usage
|
||||
sys.exit(2)
|
||||
|
||||
# default values for command-line arguments
|
||||
cross_prefix = ""
|
||||
core_elf = ""
|
||||
dst_elf = ""
|
||||
|
||||
# parse command line arguments
|
||||
try:
|
||||
opts, modules = getopt.getopt(sys.argv[1:],
|
||||
"c:o:p:v",
|
||||
["core=", "output=", "prefix=", "verbose"])
|
||||
except getopt.GetoptError:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
for opt, arg in opts:
|
||||
if opt in ("-c", "--core"):
|
||||
core_elf = arg
|
||||
elif opt in ("-o", "--output"):
|
||||
dst_elf = arg
|
||||
elif opt in ("-p", "--prefix"):
|
||||
cross_prefix = arg
|
||||
elif opt in ("-v", "--verbose"):
|
||||
verbose = 1
|
||||
else:
|
||||
user_error("invalid argument \"" + arg + "\"")
|
||||
|
||||
# validate arguments
|
||||
if (core_elf == ""): user_error("no core binary specified")
|
||||
if (len(modules) == 0): user_error("no modules specified")
|
||||
if (dst_elf == ""): user_error("no output file spefied")
|
||||
|
||||
# determine destination address of the modules ELF image
|
||||
modules_start_addr = first_free_addr_after_program(core_elf, cross_prefix)
|
||||
|
||||
if (verbose):
|
||||
print "module address: " + hex(modules_start_addr)
|
||||
|
||||
# generate assembly code aggregating the module data
|
||||
asm_src = generate_modules_asm(modules)
|
||||
|
||||
if (verbose):
|
||||
print "generated assember code:"
|
||||
for line in asm_src.splitlines():
|
||||
print " " + line
|
||||
|
||||
# invoke assembler and linker through the gcc front end
|
||||
gcc_cmd = [cross_prefix + "gcc",
|
||||
"-nostdlib",
|
||||
"-x", "assembler",
|
||||
"-Wl,--entry=0",
|
||||
"-Wl,--section-start=.data=" + hex(modules_start_addr),
|
||||
"-o", dst_elf,
|
||||
"-"]
|
||||
|
||||
if (verbose):
|
||||
print "gcc command line:"
|
||||
print " " + ' '.join(gcc_cmd)
|
||||
|
||||
Popen(gcc_cmd, stdin=PIPE).communicate(asm_src)[0]
|
@ -56,7 +56,7 @@ namespace Genode {
|
||||
/**
|
||||
* Prepare map operation
|
||||
*
|
||||
* No preparations are needed on Codezero because all mapping
|
||||
* No preparations are needed on seL4 because all mapping
|
||||
* originate from the physical address space.
|
||||
*/
|
||||
void prepare_map_operation() { }
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* \brief Memory barrier
|
||||
* \author Martin Stein
|
||||
* \date 2014-11-12
|
||||
*
|
||||
* The memory barrier prevents memory accesses from being reordered in such a
|
||||
* way that accesses to the guarded resource get outside the guarded stage. As
|
||||
* cmpxchg() defines the start of the guarded stage it also represents an
|
||||
* effective memory barrier.
|
||||
*
|
||||
* Note, we assume a compiler-memory barrier is sufficient on ARMv5.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 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_V5__CPU__MEMORY_BARRIER_H_
|
||||
#define _INCLUDE__ARM_V5__CPU__MEMORY_BARRIER_H_
|
||||
|
||||
namespace Genode {
|
||||
|
||||
static inline void memory_barrier()
|
||||
{
|
||||
asm volatile ("" ::: "memory");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__ARM_V5__CPU__MEMORY_BARRIER_H_ */
|
@ -4,7 +4,7 @@
|
||||
* \date 2011-03-07
|
||||
*
|
||||
* This file is a generic variant of the Native_capability, which is
|
||||
* suitable many platforms such as Fiasco, Pistachio, OKL4, Linux, Codezero,
|
||||
* suitable many platforms such as Fiasco, Pistachio, OKL4, Linux,
|
||||
* and some more.
|
||||
*/
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
SPECS += arm
|
||||
|
||||
# add repository relative include paths
|
||||
REP_INC_DIR += include/arm_v5
|
||||
|
||||
#
|
||||
# Configure target CPU
|
||||
#
|
||||
CC_MARCH += -march=armv5
|
||||
|
||||
include $(call select_from_repositories,mk/spec-arm.mk)
|
@ -1,18 +0,0 @@
|
||||
REP_INC_DIR += include/platform/vpb926
|
||||
|
||||
#
|
||||
# Enable peripherals of the platform
|
||||
#
|
||||
SPECS += pl050 pl11x pl011 ps2 framebuffer
|
||||
|
||||
#
|
||||
# Pull in CPU specifics
|
||||
#
|
||||
SPECS += arm_v5
|
||||
|
||||
#
|
||||
# Add device parameters to include search path
|
||||
#
|
||||
REP_INC_DIR += include/platform/vpb926
|
||||
|
||||
include $(call select_from_repositories,mk/spec-arm_v5.mk)
|
@ -516,7 +516,7 @@ void Rm_session_component::detach(Local_addr local_addr)
|
||||
* This is the case for Fiasco, Pistachio, and NOVA. On those
|
||||
* kernels, the unmap operation must be issued for each leaf
|
||||
* dataspace the managed dataspace is composed of. For kernels with
|
||||
* support for directed unmap (OKL4 or Codezero), unmap can be
|
||||
* support for directed unmap (OKL4), unmap can be
|
||||
* simply applied for the contiguous virtual address region in the
|
||||
* client.
|
||||
*/
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* \brief PL011 UART definitions for the Versatile Platform Baseboard 926
|
||||
* \author Christian Helmuth
|
||||
* \date 2011-11-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__VPB926__PL011_DEFS_H_
|
||||
#define _INCLUDE__PLATFORM__VPB926__PL011_DEFS_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
#warning pl011 untested on vpb926
|
||||
|
||||
enum {
|
||||
|
||||
/** Number of UARTs */
|
||||
PL011_NUM = 4,
|
||||
|
||||
/**
|
||||
* MMIO regions
|
||||
*/
|
||||
PL011_PHYS0 = 0x101f1000, /* base for UART 0 */
|
||||
PL011_PHYS1 = 0x101f2000, /* base for UART 1 */
|
||||
PL011_PHYS2 = 0x101f3000, /* base for UART 2 */
|
||||
PL011_PHYS3 = 0x10009000, /* base for UART 3 */
|
||||
PL011_SIZE = 0x1000, /* size of each MMIO region */
|
||||
|
||||
/**
|
||||
* Interrupt lines
|
||||
*/
|
||||
/* FIXME find correct vectors */
|
||||
PL011_IRQ0 = 12, /* UART 0 on primary */
|
||||
PL011_IRQ1 = 13, /* UART 1 on primary */
|
||||
PL011_IRQ2 = 14, /* UART 2 on primary */
|
||||
PL011_IRQ3 = 6, /* UART 3 on secondary */
|
||||
|
||||
/**
|
||||
* UART baud rate configuration (precalculated)
|
||||
*
|
||||
* div = 24000000 / 16 / baud rate
|
||||
* IBRD = floor(div)
|
||||
* FBRD = floor((div - IBRD) * 64 + 0.5)
|
||||
*/
|
||||
/* FIXME calculate correct / check values */
|
||||
PL011_IBRD_115200 = 13, PL011_FBRD_115200 = 1,
|
||||
PL011_IBRD_19200 = 78, PL011_FBRD_19200 = 8,
|
||||
PL011_IBRD_9600 = 156, PL011_FBRD_9600 = 16,
|
||||
};
|
||||
|
||||
|
||||
static struct Pl011_uart {
|
||||
Genode::addr_t mmio_base;
|
||||
Genode::size_t mmio_size;
|
||||
int irq_number;
|
||||
} pl011_uart[PL011_NUM] = {
|
||||
{ PL011_PHYS0, PL011_SIZE, PL011_IRQ0 },
|
||||
{ PL011_PHYS1, PL011_SIZE, PL011_IRQ1 },
|
||||
{ PL011_PHYS2, PL011_SIZE, PL011_IRQ2 },
|
||||
{ PL011_PHYS3, PL011_SIZE, PL011_IRQ3 },
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__VPB926__PL011_DEFS_H_ */
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* \brief PL050 PS/2 controller definitions for the VersatilePB platform
|
||||
* \author Norman Feske
|
||||
* \date 2010-03-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__VERSATILEPB__PL050_DEFS_H_
|
||||
#define _INCLUDE__PLATFORM__VERSATILEPB__PL050_DEFS_H_
|
||||
|
||||
enum {
|
||||
PL050_KEYBD_PHYS = 0x10006000, PL050_KEYBD_SIZE = 0x1000,
|
||||
PL050_MOUSE_PHYS = 0x10007000, PL050_MOUSE_SIZE = 0x1000,
|
||||
|
||||
/**
|
||||
* Interrupt lines
|
||||
*/
|
||||
SIC_IRQ_OFFSET = 31,
|
||||
PL050_KEYBD_SIC_IRQ = 3,
|
||||
PL050_MOUSE_SIC_IRQ = 4,
|
||||
|
||||
PL050_KEYBD_IRQ = SIC_IRQ_OFFSET + PL050_KEYBD_SIC_IRQ,
|
||||
PL050_MOUSE_IRQ = SIC_IRQ_OFFSET + PL050_MOUSE_SIC_IRQ,
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__VERSATILEPB__PL050_DEFS_H_ */
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* \brief PL110 display controller definitions for the VersatilePB platform
|
||||
* \author Norman Feske
|
||||
* \date 2010-03-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__VERSATILEPB__PL11X_DEFS_H_
|
||||
#define _INCLUDE__PLATFORM__VERSATILEPB__PL11X_DEFS_H_
|
||||
|
||||
enum {
|
||||
PL11X_LCD_PHYS = 0x10120000,
|
||||
PL11X_LCD_SIZE = 0x1000,
|
||||
|
||||
/**
|
||||
* Offsets of LCD control register offsets (in 32bit words)
|
||||
*/
|
||||
PL11X_REG_TIMING0 = 0,
|
||||
PL11X_REG_TIMING1 = 1,
|
||||
PL11X_REG_TIMING2 = 2,
|
||||
PL11X_REG_TIMING3 = 3,
|
||||
PL11X_REG_UPBASE = 4,
|
||||
PL11X_REG_LPBASE = 5,
|
||||
PL11X_REG_IMSC = 6,
|
||||
PL11X_REG_CTRL = 7,
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__VERSATILEPB__PL11X_DEFS_H_ */
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* \brief SP810 System Controller.
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__PLATFORM__VPB926__SP810_DEFS_H_
|
||||
#define _INCLUDE__PLATFORM__VPB926__SP810_DEFS_H_
|
||||
|
||||
enum {
|
||||
|
||||
SP810_PHYS = 0x10000000,
|
||||
SP810_SIZE = 0x1000,
|
||||
|
||||
SP810_REG_ID = 0x0,
|
||||
SP810_REG_OSCCLCD = 0x1c,
|
||||
SP810_REG_LOCK = 0x20,
|
||||
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PLATFORM__VPB926__SP810_DEFS_H_ */
|
@ -1,13 +0,0 @@
|
||||
include $(REP_DIR)/lib/mk/timer.inc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/drivers/timer/include_periodic
|
||||
|
||||
#
|
||||
# Supply dummy includes to prevent warning about missing string.h and stdio.h,
|
||||
# which are included by Codezero's headers.
|
||||
#
|
||||
REP_INC_DIR += include/codezero/dummies
|
||||
|
||||
SRC_CC += platform_timer.cc
|
||||
vpath platform_timer.cc $(REP_DIR)/src/drivers/timer/codezero
|
||||
|
@ -1,7 +0,0 @@
|
||||
TARGET = fb_drv
|
||||
REQUIRES = pl11x platform_vpb926
|
||||
SRC_CC = main.cc video_memory.cc
|
||||
LIBS = base
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
vpath %.cc $(PRG_DIR)/..
|
@ -35,14 +35,6 @@ class Irq_handler
|
||||
{
|
||||
_irq.ack_irq();
|
||||
|
||||
#ifdef __CODEZERO__
|
||||
/*
|
||||
* (Re-)enable device interrupt because Codezero tends to
|
||||
* disable it in its IRQ handler.
|
||||
*/
|
||||
_channel->enable_irq();
|
||||
#endif
|
||||
|
||||
/* check for pending PS/2 input */
|
||||
while (_input_driver.event_pending())
|
||||
_input_driver.handle_event();
|
||||
|
@ -1 +0,0 @@
|
||||
/* dummy, needed for including Codezero API headers */
|
@ -1 +0,0 @@
|
||||
/* dummy, needed for including Codezero API headers */
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* \brief Dummy platform-timer implementation
|
||||
* \author Norman Feske
|
||||
* \date 2009-11-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
/* local includes */
|
||||
#include "timer_session_component.h"
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
using namespace Codezero;
|
||||
|
||||
|
||||
unsigned long Platform_timer::max_timeout() { return 1000; }
|
||||
|
||||
|
||||
unsigned long Platform_timer::curr_time() const
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
return _curr_time_usec;
|
||||
}
|
||||
|
||||
|
||||
void Platform_timer::_usleep(unsigned long usecs)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
l4_thread_switch(L4_NILTHREAD);
|
||||
_curr_time_usec += 1000;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
REPOSITORIES = $(GENODE_DIR)/repos/base-codezero
|
||||
|
||||
##
|
||||
## Kernel-specific run tool configuration
|
||||
##
|
||||
|
||||
RUN_OPT = --include boot_dir/codezero \
|
||||
--include power_on/qemu --include log/qemu
|
@ -26,7 +26,6 @@ usage:
|
||||
@echo " 'okl4_x86'"
|
||||
@echo " 'nova_x86_32'"
|
||||
@echo " 'nova_x86_64'"
|
||||
@echo " 'codezero_vpb926'"
|
||||
@echo " 'hw_panda'"
|
||||
@echo " 'hw_pbxa9'"
|
||||
@echo " 'hw_imx53_qsb'"
|
||||
@ -174,9 +173,6 @@ $(PLATFORM):: $(BUILD_DIR)/Makefile
|
||||
#
|
||||
# Platform-specific dependencies
|
||||
#
|
||||
codezero_vpb926::
|
||||
@echo "SPECS += codezero_platform_vpb926" > $(BUILD_DIR)/etc/specs.conf
|
||||
|
||||
foc_x86_32::
|
||||
@echo "SPECS = genode foc_x86_32" > $(BUILD_DIR)/etc/specs.conf
|
||||
@echo "SPECS += acpi" >> $(BUILD_DIR)/etc/specs.conf
|
||||
|
@ -1,65 +0,0 @@
|
||||
|
||||
|
||||
##
|
||||
# Return location of prebuilt mirror of codezero source tree
|
||||
#
|
||||
proc kernel_dir { } { return [pwd]/kernel/codezero }
|
||||
|
||||
|
||||
##
|
||||
# Return container directory where the Genode binaries should be copied to
|
||||
#
|
||||
proc container_dir { } { return [kernel_dir]/build/cont0/empty0 }
|
||||
|
||||
|
||||
##
|
||||
# Return location of 'gen_romfs' tool
|
||||
#
|
||||
proc gen_romfs { } { return "[genode_dir]/repos/base-codezero/tool/gen_romfs" }
|
||||
|
||||
|
||||
##
|
||||
# Print and execute shell command
|
||||
#
|
||||
proc exec_sh { command } {
|
||||
puts "$command"
|
||||
exec sh -c $command
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Populate boot directory with binaries on codezero
|
||||
#
|
||||
proc run_boot_dir {binaries} {
|
||||
|
||||
if {![file exists kernel]} { build kernel }
|
||||
|
||||
copy_and_strip_genode_binaries_to_run_dir $binaries
|
||||
|
||||
# the codezero build system expects that the pager binary is named 'main.elf'
|
||||
exec cp [run_dir]/genode/core [container_dir]/main.elf
|
||||
|
||||
# obtain list of modules
|
||||
set modules [glob [run_dir]/genode/*]
|
||||
|
||||
# remove core from list of modules
|
||||
set core_idx [lsearch -exact $modules [run_dir]/genode/core]
|
||||
set modules [lreplace $modules $core_idx $core_idx]
|
||||
|
||||
# generate elf image containing the boot modules
|
||||
exec_sh "[gen_romfs] -p [cross_dev_prefix] -c [run_dir]/genode/core -o [container_dir]/modules.elf $modules"
|
||||
|
||||
set tool_chain_dir [file dirname [cross_dev_prefix]]
|
||||
set prepend_path ""
|
||||
if {[file isdirectory $tool_chain_dir]} {
|
||||
set prepend_path $tool_chain_dir }
|
||||
|
||||
# force re-generation of 'cinfo.c', which depends on the container content
|
||||
exec_sh "rm -f [kernel_dir]/src/generic/cinfo.c"
|
||||
|
||||
# rebuild codezero, linking the new container content
|
||||
exec_sh "cd [kernel_dir]; PATH=$prepend_path:\$PATH ./build.py"
|
||||
|
||||
# copy result to [run_dir]/image.elf (to be picked up by spawn_qemu)
|
||||
exec_sh "cp [kernel_dir]/build/final.elf [run_dir]/image.elf"
|
||||
}
|
Loading…
Reference in New Issue
Block a user