code:
<?xml version="1.0"?>
<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN"
   "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">

<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">

   <head>
      <meta name="dtb:uid" content="http://genode.org/documentation/genode-foundations-15.05.epub"/>
      <meta name="dtb:depth" content="1"/>
      <meta name="dtb:totalPageCount" content="0"/>
      <meta name="dtb:maxPageNumber" content="0"/>
   </head>

   <docTitle>
      <text>Genode OS Framework Foundations</text>
   </docTitle>


code:
Functional specification
########################

This chapter complements the architectural information of Chapters
[Architecture] and [Components] with a thorough description of the
framework's C++ programming interface. The material is partially generated
from the source code, specifically the public header files of the _base_
and _os_ source-code repositories. The location of the headers in either
both repositories depends on role of the respective header. Only if the
interface is fundamentally required by the core component or by the base
framework itself, it is contained in the base repository. Otherwise, the
header is found in the _os_ repository.

Scope of the API
----------------

The Genode API covers
everything needed by Genode to be self-sufficient without any dependency on
3rd-party code. It does not even depend on a C runtime.
It is possible to create components that solely use the raw Genode API, as is
the case for the ones hosted within the _repos/os/_ repository.
Because such components do not rely on any library code except for the
low-complexity Genode base libraries, they are relatively easy to evaluate.
That said, the API must not be mistaken as an application-level API.
It does not present an alternative to established application-level libraries
like the standard C++ library. For example, even though the framework contains
a few utilities for processing strings, those utilities do merely exist to
support the use cases present in Genode.

General conventions
-------------------

The functional specification adheres to the following general conventions:

* Static member functions are called _class functions_. All other member
  functions are called _methods_.

* Both structs and classes are referred to as _classes_. There is no
  distinction between both at the API level.

* Constant functions with no argument and a return value are called
  _accessors_. Technically, they are "getters" but since Genode does not
  have any "setters", accessors are synonymous to "getters". Because those
  functions are so simple, they are listed in the class overview and are not
  described separately.

* Classes that merely inherit other classes are called _sub types_.
  In contrast to the use of a 'typedef', such classes are not mere
  name aliases but represent a new type. The type is compatible to the
  base class but not vice versa. For example, exception types are
  sub types of the 'Exception' class.

* Namespace-wide information is presented with a light yellow background.

* Each non-trivial class is presented in the form of a class diagram on a
  blue-shaded background. The diagram shows the
  public base classes and the list of public class functions and methods.
  If the class is a template, the template arguments are annotated at
  the top-right of corner of the class. If the class represents an
  RPC interface, an information box is attached.
  The methods listed in the diagram can be used as hyperlinks to further
  descriptions if available.

* Method descriptions are presented on a green-shaded background,
  global functions are presented on an orange-shaded background.

* The directory path presented under "Header" sections is a hyperlink to the
  corresponding source code at GitHub.

API primitives
==============

Capability types
~~~~~~~~~~~~~~~~

As described in Section [Capability-based security], inter-component
communication is based on capabilities.
A capability refers to a system-wide unique object identity and can
be delegated among components.
At API level, each capability is associated with the type of the RPC
interface the capability refers to - similar to how a C++ reference refers to
the type of a specific C++ object.

;; internal
;; Genode::Native_capability_tpl<>

; Genode::Capability<>
[raw spec/classes/genode/capability/description]

; XXX typed capabilities
; XXX lifetime of capabilities: mention ref counter

[raw spec/clearpage]

Sessions and connections
~~~~~~~~~~~~~~~~~~~~~~~~

Servers provide their services over session-based communication channels.
A Session type is defined as an abstract interface inherited from the
'Session' base class.

; Genode::Session
[raw spec/classes/genode/session/description]

Each session interface has to provide an implementation of the following
class function that returns the name of the service as constant string.

! static const char *service_name();

This function is used by the framework for the announcement of the
service's root interface at the component's parent. The string returned
by this function corresponds to the service name as used in the
system configuration (Section [System configuration]).

The interaction of a client with a server involves the definition of
session-construction arguments, the request of the session creation
via its parent, the initialization of the matching RPC-client stub
code with the received session capability, the actual use of the
session interface, and the closure of the session.
The 'Connection' template class provides a way to greatly simplify the
handling of session arguments, session creation, and destruction
on the client side. By implementing a service-specific connection
class inherited from 'Connection', session arguments become plain
constructor arguments, session functions can be called directly
on the 'Connection' object, and the session gets properly closed
when destructing the 'Connection'.

; Genode::Connection<>
[raw spec/classes/genode/connection/description]

[raw spec/clearpage]

Dataspace interface
~~~~~~~~~~~~~~~~~~~

The dataspace abstraction described in Section [Dataspaces] is the
fundamental API primitive for representing a container of memory as
provided by core's PD, IO_MEM, or ROM services. Each dataspace is referenced
by a capability that can be passed among components.
Each component with the capability to a dataspace can access the
dataspace's content by attaching the dataspace to the region map of its PD session.
In addition to the use as arguments for region-map operations,
dataspaces provide the following interface.

; XXX Genode::Dataspace_client

; Genode::Dataspace
[raw spec/classes/genode/dataspace/description]

Attached dataspace
------------------

As a utility for handling the common case where a dataspace is attached to the
component's address space as long as a certain object (like a session) exists,
an instance of an 'Attached_dataspace' can be hosted as a member variable.
When destructed, the dataspace will be automatically detached from the
component's address space.

; Genode::Attached_dataspace
[raw spec/classes/genode/attached_dataspace/description]

Component execution environment
===============================

Each component has to provide an implementation of the 'Component' interface
as illustrated by the example given in Section
[Source code and build description].

[raw spec/repos/base/include/base/component.h.overview]

Interface to the component's environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As described in Section [Component creation],
each component consists of a protection domain (PD session), a LOG session,
a ROM session with the component's executable binary,
and a CPU session, from which the main thread is created. These
sessions form the _environment_ of the component, which is represented
by the 'Env' interface class. The environment is provided to the component
as argument to the 'Component::construct' function.

; Genode::Env
[raw spec/classes/genode/env/description]

[raw spec/clearpage]

Parent interface
~~~~~~~~~~~~~~~~

At its creation time, the only communication partner of a component
is its immediate parent. The parent can be reached via interface returned
by 'Env::parent()'.

; XXX Genode::Parent_client

; Genode::Parent
[raw spec/classes/genode/parent/description]

[raw spec/clearpage]

Entrypoint
==========

An entrypoint is a thread that is able to respond to RPC requests and signals.
Each component has at least one initial entrypoint that is created as
part of the component's environment. It can be accessed via the 'Env::ep()'
method.

The 'Entrypoint::manage' and 'Entrypoint::dissolve' methods are used to
associate respectively disassociate signal handlers and RPC objects with the
entrypoint. Under the hood, those operations interact with the component's PD
session in order to bind the component's signal handlers and RPC objects to capabilities.

_Note that the current version of the 'Entrypoint' utilizes the former_
_'Rpc_entrypoint' and 'Signal_receiver' APIs. The entrypoint is designated_
_to eventually replace those APIs. Hence, application code should no longer_
_use the 'Rpc_entrypoint' and 'Signal_receiver' directly._

; Genode::Entrypoint
[raw spec/classes/genode/entrypoint/description]

[raw spec/clearpage]

Region-map interface
====================

A region map represents a (portion of) a virtual memory address space (Section
[Region maps]). By attaching dataspaces to a region map, the content of those
dataspaces becomes visible in the component's virtual address space.
Furthermore, a region map can be used as a dataspace. Thereby, the nesting of
region maps becomes possible. This allows a component to manage portions of
its own virtual address space manually as done for the stack area and linker
area (Section [PD session interface]). The use of region maps as so-called
managed dataspaces makes it even possible to manage portions of the virtual
address space of other components (Section [RM session interface]).

[raw spec/nopagebreak]

; Genode::Region_map
[raw spec/classes/genode/region_map/description]

[raw spec/clearpage]

Session interfaces of the base API
==================================

PD session interface
~~~~~~~~~~~~~~~~~~~~

The protection-domain (PD) service (Section [Protection domains (PD)]) enables
the creation of address spaces that are isolated from each other. Each PD
session corresponds to a protection domain. Each PD session is equipped with
three region maps, one representing the PD's virtual address space, one
for the component's stack area, and one for the component's linker area
designated for shared objects. Of those region maps, only the virtual address
space is needed by application code directly. The stack area and linker area
are used by the framework internally. The PD service is rarely
needed by applications directly but it is internally.

The PD session also represents a resource partition with a budget of
physical memory and capabilities. Within the bounds of its RAM budget, it
allows the client to allocate physical memory in the form of dataspaces.

Analogously, within the bounds of its capability budget, capabilities can be
allocated and associated with a local object or a signal handler. Such a
capability can be passed to another protection domain via an RPC call whereby
the receiving protection domain obtains the right to send messages to the
associated object or to trigger the associated signal handler respectively.
The capability-management operations are not used directly by components at
the API level but are used indirectly via the RPC mechanism described in
Section [Remote procedure calls] and the signalling API described in Section
[Signalling].

; XXX Genode::Pd_session_client

; Genode::Pd_session
[raw spec/classes/genode/pd_session/description]

; Genode::Pd_connection
[raw spec/classes/genode/pd_connection/description]

[raw spec/clearpage]

Attached RAM dataspace
----------------------

The instantiation of an 'Attached_ram_dataspace' object subsumes the tasks of
allocating a dataspaces from the component's PD session and attaching the
dataspace to the component's region map. Furthermore, the reverse operations
are performed during the destruction of an 'Attached_ram_dataspace' object.

; Genode::Attached_ram_dataspace
[raw spec/classes/genode/attached_ram_dataspace/description]

[raw spec/clearpage]

ROM session interface
~~~~~~~~~~~~~~~~~~~~~

The ROM service (Section [Read-only memory (ROM)]) provides access to
ROM modules, e.g., binary data loaded by the boot loader
(core's ROM service described in Section [Access to boot modules (ROM)]).
Each session refers to one ROM module. The module's data is provided to
the client in the form of a dataspace (Section [Dataspaces]).

; Genode::Rom_dataspace
[raw spec/repos/base/include/rom_session/rom_session.h.overview]

; Genode::Rom_session
[raw spec/classes/genode/rom_session/description]

; XXX Genode::Rom_session_client

; Genode::Rom_connection
[raw spec/classes/genode/rom_connection/description]

Attached ROM dataspace
----------------------

By instantiating an 'Attached_rom_dataspace' object, a ROM module is requested
and made visible within the component's address space in a single step.

To accommodate the common use of a ROM session as provider of configuration
data (Section [Component configuration]) or an XML-formatted data model in
a publisher-subscriber scenario [Publishing and subscribing], the
'Attached_rom_dataspace' provides a convenient way to retrieve its content
as an XML node via the 'xml' method.
The method always returns a valid 'Xml_node' even in the event where the
dataspace is invalid or contains no XML. In such cases, the returned XML node
is '<empty/>'. This relieves the caller from handling exceptions that
may occur during XML parsing.

; Genode::Attached_rom_dataspace
[raw spec/classes/genode/attached_rom_dataspace/description]

[raw spec/clearpage]

RM session interface
~~~~~~~~~~~~~~~~~~~~

The region-map (RM) service (Section [Region-map management (RM)]) allows for
the manual creation of region maps that represent (portions of) virtual
address spaces. Components can use this service to manage the virtual memory layout of
so-called managed dataspaces manually. For example, it allows a dataspace
provider to populate the content of dataspaces on demand, depending on the
access patterns produced by the dataspace user.

Note that the RM service is not available on all base platforms.
In particular, it is not supported on Linux.

; XXX Genode::Rm_session_client

; Genode::Rm_session
[raw spec/classes/genode/rm_session/description]

; Genode::Rm_connection
[raw spec/classes/genode/rm_connection/description]

[raw spec/clearpage]

CPU session interface
~~~~~~~~~~~~~~~~~~~~~

The CPU service (Section [Processing-time allocation (CPU)]) provides a
facility for creating and managing threads. A CPU session corresponds to a
CPU-time allocator, from which multiple threads can be allocated.
;
; XXX Genode::Thread_state
; XXX Genode::Thread_state_base
;
; XXX Genode::Cpu_session_client

; Genode::Cpu_session
[raw spec/classes/genode/cpu_session/description]

; Genode::Cpu_connection
[raw spec/classes/genode/cpu_connection/description]

; Genode::Affinity
[raw spec/classes/genode/affinity/description]

[raw spec/clearpage]

Once created, a thread is referred to via a thread capability. This
capability allows for the destruction of the thread via the CPU session,
and provides the 'Cpu_thread' RPC interface to operate on the thread.

; Genode::Cpu_thread
[raw spec/classes/genode/cpu_thread/description]

[raw spec/clearpage]

IO_MEM session interface
~~~~~~~~~~~~~~~~~~~~~~~~

The IO_MEM service
(Section [Access to device resources (IO_MEM, IO_PORT, IRQ)])
enables user-level device drivers to
obtain memory-mapped device resources in the form of dataspaces. Each
IO_MEM session corresponds to the reservation of a physical
address range, for which a dataspace is provided to the client.
The user-level device driver can make the device resource
visible in its address space by attaching the dataspace to
the region map of its own PD session.

; XXX Genode::Io_mem_session_client
; XXX Genode::Io_mem_dataspace
[raw spec/repos/base/include/io_mem_session/io_mem_session.h.overview]

; Genode::Io_mem_session
[raw spec/classes/genode/io_mem_session/description]

; Genode::Io_mem_connection
[raw spec/classes/genode/io_mem_connection/description]

Attached IO_MEM dataspace
-------------------------

An instance of an 'Attached_io_mem_dataspace' represents a locally mapped
memory-mapped I/O range.

; Genode::Attached_io_mem_dataspace
[raw spec/classes/genode/attached_io_mem_dataspace/description]

[raw spec/clearpage]

IO_PORT session interface
~~~~~~~~~~~~~~~~~~~~~~~~~

On the x86 architecture, the IO_PORT service
(Section [Access to device resources (IO_MEM, IO_PORT, IRQ)])
provides access to device I/O ports via an RPC interface. Each IO_PORT session
corresponds to the access right to a port range.

; XXX Genode::Io_port_session_client

; Genode::Io_port_session
[raw spec/classes/genode/io_port_session/description]

; Genode::Io_port_connection
[raw spec/classes/genode/io_port_connection/description]

[raw spec/clearpage]

IRQ session interface
~~~~~~~~~~~~~~~~~~~~~

The IRQ service
(Section [Access to device resources (IO_MEM, IO_PORT, IRQ)])
enables user-level device drivers to serve device interrupts. Each IRQ session
corresponds to an associated interrupt line.

; XXX Genode::Irq_session_client
; XXX Genode::Irq_handler
; XXX Genode::Irq_activation

; XXX Genode::Irq_session
;[raw spec/classes/genode/irq_session/description]

; Genode::Irq_connection
[raw spec/classes/genode/irq_connection/description]

[raw spec/clearpage]

LOG session interface
~~~~~~~~~~~~~~~~~~~~~

For low-level debugging, core provides a simple LOG service
(Section [Logging (LOG)]), which
enables clients to print textual messages. In the LOG output,
each message is tagged with the label of the corresponding client.

; XXX Genode::Log_session_client

; Genode::Log_session
[raw spec/classes/genode/log_session/description]

; Genode::Log_connection
[raw spec/classes/genode/log_connection/description]

[raw spec/clearpage]

;TRACE session interface
;~~~~~~~~~~~~~~~~~~~~~~~
;
;; Genode::Trace::Policy_module
;; Genode::Trace::Buffer
;; Genode::Trace::Policy_id
;; Genode::Trace::Subject_id
;; Genode::Trace::Subject_info
;; Genode::Trace::Logger
;; Genode::Trace::Rpc_call
;; Genode::Trace::Rpc_returned
;; Genode::Trace::Rpc_dispatch
;; Genode::Trace::Rpc_reply
;; Genode::Trace::Signal_submit
;; Genode::Trace::Signal_received
;; Genode::Trace::Session_client
;; Genode::Trace::Session
;; Genode::Trace::Connection
;; Genode::Trace::Simple_buffer
;; Genode::Trace::Partitioned_buffer

OS-level session interfaces
===========================

Report session interface
~~~~~~~~~~~~~~~~~~~~~~~~

Report sessions (Section [Report]) allow a component to propagate internal
state to the outside. The most prominent use case is the realization of
publisher-subscriber communication schemes as discussed in
Section [Publishing and subscribing].

; XXX Report::Session_client

; Report::Session
[raw spec/classes/report/session/description]

; Report::Connection
[raw spec/classes/report/connection/description]

[raw spec/clearpage]

The client-side 'Reporter' is a convenient front end for the use of a
report connection to propagate XML-formed data.

; Genode::Reporter
[raw spec/classes/genode/reporter/description]

The 'Expanding_reporter' further streamlines the generation of reports by
eliminating the burden of handling 'Buffer_exceeded' exceptions as thrown by
the 'Xml_generator' from components that generate reports. Such exceptions are
easy to miss because reports are often small at testing time but become larger
in complex scenarios. Whenever the report exceeds the current buffer size, the
expanding reporter automatically upgrades the report session as needed. Note
that such an upgrade consumes RAM quota. For components that strictly account
RAM consumption to clients, the regular 'Reporter' is preferable. However, in
most cases - where reports are not accounted per client but to the component
itself - the 'Expanding_reporter' should better be used. Besides the builtin
support for growing the report buffer, the expanding reporter alleviates the
need to explicitly enable reports. In contrast to the 'Reporter', it is
implicitly enabled at construction time.

; Genode::Expanding_reporter
[raw spec/classes/genode/expanding_reporter/description]

[raw spec/clearpage]

Terminal and UART session interfaces
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A terminal session (Section [Terminal and UART]) is a bi-directional communication
channel. The UART session interface supplements the terminal
session interface with a facility to parametrize UART configuration
parameters

; XXX Terminal::Session_client

; Terminal::Session
[raw spec/classes/terminal/session/description]

; Terminal::Connection
[raw spec/classes/terminal/connection/description]

; XXX Uart::Session_client

; Uart::Session
[raw spec/classes/uart/session/description]

; Uart::Connection
[raw spec/classes/uart/connection/description]

[raw spec/clearpage]

Event session interface
~~~~~~~~~~~~~~~~~~~~~~~

An event session (Section [Event]) represents a stream of user-input events
from client to server.

; XXX Event::Session_client

; Event::Session
[raw spec/classes/event/session/description]

; Event::Connection
[raw spec/classes/event/connection/description]

[raw spec/clearpage]

Capture session interface
~~~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section

; Framebuffer::Mode
[raw spec/classes/framebuffer/mode/description]

; Capture::Session
; Capture::Session_client
[raw spec/classes/capture/session/description]

; Capture::Connection
; Capture::Connection::Screen
[raw spec/classes/capture/connection/description]

[raw spec/clearpage]

GUI session interface
~~~~~~~~~~~~~~~~~~~~~

The GUI session described in Section [GUI] comprises a virtual framebuffer,
a stream of user-input events, and a so-called view stack, which defines
how portions of the virtual framebuffer are composed on screen.

; Gui::Session
; XXX Gui::Session_client
[raw spec/classes/gui/session/description]

; Gui::Connection
[raw spec/classes/gui/connection/description]

; Framebuffer::Session
; Framebuffer::Session_client
; Framebuffer::Connection
[raw spec/classes/framebuffer/session/description]

; Input::Session
; Input::Session_client
; Input::Connection
[raw spec/classes/input/session/description]

[raw spec/clearpage]

Capture session interface
~~~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section

; XXX Framebuffer::Session_client

; Framebuffer::Mode
[raw spec/classes/framebuffer/mode/description]

; Capture::Session
[raw spec/classes/capture/session/description]

; Capture::Connection
[raw spec/classes/capture/connection/description]

[raw spec/clearpage]

Platform session interface
~~~~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section

; XXX Platform::Device_client

; Platform::Device
[raw spec/classes/platform/device/description]

; XXX Platform::Session_client

; Platform::Session
[raw spec/classes/platform/session/description]

;XXX trivial Platform::Connection
;[raw spec/classes/platform/connection/description]

[raw spec/clearpage]

Block session interface
~~~~~~~~~~~~~~~~~~~~~~~

The block-session interface provides block-device-level access to persistent
storage (Section [Block]). At the client side, the 'Block::Connection'
provides a job interface to issue arbitrary block requests to a server in an
asynchronous fashion. At the server side, the 'Block::Request_stream' API
facilitates the implementation of asynchronously block services such as
block-device drivers. Both client and server share the same notion of a
'Block::Request'.

; Block::Operation
[raw spec/classes/block/operation/description]

; Block::Request
[raw spec/classes/block/request/description]

; XXX description, reference to components section
; Block::Session_client

; Block::Session
; [raw spec/classes/block/session/description]

Client-side block connection
----------------------------

!

; Block::Connection
[raw spec/classes/block/connection/description]

Server-side block-request stream
--------------------------------

To simplify the implementation of robust and scalable block servers, there
exists a server-side block-session front end called block-request stream.
It is designed with the following considerations:

* It anticipates the asynchronous operation of block servers by default.
  Using the API, such servers - in particular block-device drivers - can be
  implemented as state machines triggered by client requests and device
  interrupts.

* It reinforces the memory safety of the server code by not returning any
  pointers or references.

* It relieves the server developers from handling special cases (like a
  congested acknowledgement queue) while being flexible enough to accommodate
  different categories of components like drivers, resource multiplexers
  (part_block), and bump-in-the-wire components in a natural way.

* It naturally supports the batching of requests as well as zero-copy (device
  DMA directly into the client's communication buffer).

The use of the block-request stream API is illustrated by the example at
_os/src/test/block_request_stream/_.

; Block::Request_stream
[raw spec/classes/block/request_stream/description]

[raw spec/clearpage]

Timer session interface
~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section

; XXX Timer::Session_client

; Timer::Session
[raw spec/classes/timer/session/description]

; Timer::Connection
[raw spec/classes/timer/connection/description]

; XXX Genode::Microseconds
; XXX Genode::Milliseconds
; XXX Genode::Duration

The 'Periodic_timeout' and 'One_shot_timeout' classes provide a convenient
API for implementing timeout handlers, following the same pattern as used for
signal handlers (Section [Signalling]).

; Timer::Periodic_timeout
[raw spec/classes/timer/periodic_timeout/description]

; Timer::One_shot_timeout
[raw spec/classes/timer/one_shot_timeout/description]

[raw spec/clearpage]

NIC and uplink session interfaces
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section

; XXX Nic::Session_client

; Nic::Mac_address
;[raw spec/classes/net/mac_address/description]

; Nic::Session
[raw spec/classes/nic/session/description]

; XXX Nic::Session_rpc_object

; Nic::Connection
[raw spec/classes/nic/connection/description]

; Uplink::Session
; Uplink::Session_client
[raw spec/classes/uplink/session/description]

; XXX Uplink::Session_rpc_object

; Uplink::Connection
[raw spec/classes/uplink/connection/description]

[raw spec/clearpage]

Audio-out session interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section

; XXX Audio_out::Signal
; XXX Audio_out::Session_client
; XXX Audio_out::Packet
; XXX Audio_out::Stream
; XXX Audio_out::Session_rpc_object

; Audio_out::Session
[raw spec/classes/audio_out/session/description]

; Audio_out::Connection
[raw spec/classes/audio_out/connection/description]

[raw spec/clearpage]

File-system session interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; XXX description, reference to components section
The file-system session (Section [File system]) interface provides to store
and retrieve data in the form of files organized in a hierarchic directory
structure. Directory operations are performed via a synchronous RPC interface
whereas the actual read and write operations are performed asynchronously
using a packet stream.

; XXX File_system::Session_client

; File_system::File_handle
; File_system::Dir_handle
; File_system::Symlink_handle
[raw spec/repos/os/include/file_system_session/file_system_session.h.overview]

A file-system client issues read or write requests by submitting packet
descriptors to the file-system session's packet stream. Each packet descriptor
contains all parameters of the transaction including the type of operation,
the seek offset, and the length.

; File_system::Packet_descriptor
[raw spec/classes/file_system/packet_descriptor/description]

; XXX File_system::Session_rpc_object

; File_system::Session
[raw spec/classes/file_system/session/description]

; File_system::Connection
[raw spec/classes/file_system/connection/description]

[raw spec/clearpage]

The file-system session's 'status' and 'control' operations use the compound
structures 'Status' and 'Control' as arguments. The format of the data
retrieved by reading a directory node is defined by the 'Directory_entry'.

; File_system::Status
[raw spec/classes/file_system/status/description]

; File_system::Control
[raw spec/classes/file_system/control/description]

; File_system::Directory_entry
[raw spec/classes/file_system/directory_entry/description]

[raw spec/clearpage]

;GPIO session interface
;~~~~~~~~~~~~~~~~~~~~~~
;
;; Gpio::Session_client
;; Gpio::Connection
;; Gpio::Session

;USB session interface
;~~~~~~~~~~~~~~~~~~~~~
;
;; Usb::Session_client
;; Usb::Packet_descriptor
;; Usb::Completion
;; Usb::Session
;; Usb::Session_rpc_object
;; Usb::Connection

;RTC session interface
;~~~~~~~~~~~~~~~~~~~~~
;
;; Rtc::Session_client
;; Rtc::Connection
;; Rtc::Timestamp
;; Rtc::Session

Fundamental types
=================

Integer types
~~~~~~~~~~~~~

Genode provides common integer types in its namespace.
Integer types that can be derived from built-in compiler
types are defined in _base/stdint.h_ and _base/fixed_stdint.h_.
Whereas the former is independent from the machine type, the latter
differs between 32-bit and 64-bit architectures.

[raw spec/repos/base/include/base/stdint.h.overview]

[raw spec/clearpage]
The fixed-width integer types for 32-bit architectures are defined
as follows.

[raw spec/repos/base/include/spec/32bit/base/fixed_stdint.h.overview]

[raw spec/clearpage]
The fixed-width integer types for 64-bit architectures are defined
as follows.

[raw spec/repos/base/include/spec/64bit/base/fixed_stdint.h.overview]

Exception types
~~~~~~~~~~~~~~~

Genode facilitates the use of exceptions to signal errors but it
uses exception types only as textual expression of error code and
for grouping errors. Normally, exceptions do not carry payload.
For code consistency, exception types should inherit from the
'Exception' base class. By convention, exceptions carry no payload.

; Genode::Exception
[raw spec/classes/genode/exception/description]

Exception-less error handling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Genode generally employs C++ exceptions for propagating errors, which is true
to the language. The rationale behind the use of exceptions is given in
Section [Rationale behind using exceptions].

However, as the mechanics of C++ exceptions are built upon a baseline of
functionality like the presence of a memory allocator for allocating exception
headers, no low-level code path involved in memory allocations must depend on
the exception mechanism. With exceptions not being available as a means to
reflect error conditions for those parts of framework, an alternative
error-handling mechanism is required.

Traditional approaches like overloading return values with error codes, or
the use of out parameters to carry return values are error prone.
Genode's 'Attempt' utility provides a safe alternative in the spirit of option
types.

; Genode::Attempt
[raw spec/classes/genode/attempt/description]

Its name reflects is designated use as a carrier for return values. To
illustrate its use, here is slightly abbreviated snippet of Genode's
'Ram_allocator' interface:

! struct Ram_allocator : Interface
! {
!   enum class Alloc_error { OUT_OF_RAM, OUT_OF_CAPS, DENIED };
!
!   using Alloc_result = Attempt<Ram_dataspace_capability, Alloc_error>;
!
!   virtual Alloc_result try_alloc(size_t size) = 0;
!
!   ...
! };

The 'Alloc_error' type models the possible error conditions, which would
normally be represented as exception types. The 'Alloc_result' type describes
the return value of the 'try_alloc' method by using the 'Attempt' utility.
Whenever 'try_alloc' succeeds, the value will hold a capability (referring to
a valid RAM dataspace). Otherwise, it will hold an error value of type
'Alloc_error'.

At the caller side, the 'Attempt' utility is extremely rigid. The caller can
access the value only when providing both a handler for the value and a
handler for the error code. For example, with ram being a reference to a
'Ram_allocator', a call to 'try_alloc' may look like this:

! ram.try_alloc(size).with_result(
!
!   [&] (Ram_dataspace_capability ds) {
!     ...
!   },
!
!   [&] (Alloc_error error) {
!     switch (error) {
!
!     case Alloc_error::OUT_OF_RAM:
!       _request_ram_from_parent(size);
!       break;
!
!     case Alloc_error::OUT_OF_CAPS:
!       _request_caps_from_parent(4);
!       break;
!
!     case Alloc_error::DENIED:
!       ...
!       break;
!     }
!   });

Which of both lambda functions gets called depends on the success of the
'try_alloc' call. The value returned by 'try_alloc' is only reachable by the
code in the scope of the first lambda function. The code within this scope can
rely on the validity of the argument.

By expressing error codes as an enum class, we let the compiler assist us to
cover all possible error cases (using switch). This a is nice benefit over the
use of exceptions, which are unfortunately not covered by function/method
signatures. By using the 'Attempt' utility, we implicitly tie functions together
with their error conditions using C++ types. As another benefit over catch
handlers, the use of switch allows us to share error handing code for
different conditions by grouping case statements.

Note that in the example above, the valid 'ds' object cannot leave the scope of
its lambda function. Sometimes, however, we need to pass a return value along a
chain of callers. This situation is covered by the 'Attempt::convert' method.
Analogously to 'with_result', it takes two lambda functions as arguments. But in
contrast to 'with_result', both lambda functions return a value of the same
type. This naturally confronts the programmer with the question of how to
convert all possible errors to this specific type. If this question cannot be
answered for all error cases, the design of the code is most likely flawed.

C++ supplements
~~~~~~~~~~~~~~~

; Genode::Noncopyable
[raw spec/classes/genode/noncopyable/description]

Data structures
===============

The framework API features a small library of data structures that are
solely exist to support the framework implementation. They have been
designed under the following considerations:

* They should be *as simple as possible* to make them easy to evaluate for
  correctness. Low complexity takes precedence over performance.

* Each data structure provides a *rigid interface* that is targeted at a
  specific use case and does not attempt to be a power tool. For example,
  the 'Fifo' deliberately provides no way to randomly access
  elements, the 'List' merely provides the functionality to remember
  elements but lacks list-manipulation operations.

* Data structures perform no hidden anonymous memory allocations by
  *storing meta data intrusively*. This is precondition for allowing
  resources multiplexers and runtime environments to properly account their
  local memory allocations. Section [Component-local heap partitioning]
  provides the rationale behind the need for full control over memory
  allocations.

[raw spec/clearpage]

List and registry
~~~~~~~~~~~~~~~~~

Most book-keeping tasks in Genode rely on single-connected lists,
which use the 'List' template.

; Genode::List<>
[raw spec/classes/genode/list/description]

; Genode::List_element<>
[raw spec/classes/genode/list_element/description]

Registry
--------

Most commonly, lists are used as containers that solely remember dynamically
created objects. In this use case, the lifetime of the remembered object is
tightly coupled with its presence in the list. The 'Registry' class
template represents a safe wrapper around the raw list that ensures this
presumption and thereby eliminates classes of list-related bugs by
design, e.g., double insertion, missing removal.

An object type to be remembered in a 'Registry' inherits the
'Registry::Element' base class, which takes its registry and a reference to
the object itself as arguments. Thereby, the relationship of the object with
its corresponding registry is fixed at the object's construction time. Once
constructed, it is implicitly part of the registry. The registry provides a
'for_each' method to iterate over its elements. Unlike the traversal of a raw
list, this 'for_each' operation is thread safe. It also supports the safe
destruction of the currently visited object.

; Genode::Registry_base
; Genode::Registry
[raw spec/classes/genode/registry/description]

As an alternative to the use of the 'Registry::Element' base class, the
'Registered' and 'Registered_no_delete' helper templates supplement arbitrary
object types with the ability to become registry elements. They wrap a given
object type in a new type whereby the original type remains untainted by the
fact that its objects are kept in a registry.

; Genode::Registered
[raw spec/classes/genode/registered/description]

; Genode::Registered_no_delete
[raw spec/classes/genode/registered_no_delete/description]

[raw spec/clearpage]

Fifo queue
~~~~~~~~~~

Because the 'List' inserts new list elements at the
list head, it cannot be used for implementing wait queues requiring
first-in-first-out semantics. For such use cases, there exists a
dedicated 'Fifo' template.

; Genode::Fifo<>
[raw spec/classes/genode/fifo/description]

; Genode::Fifo_element<>
[raw spec/classes/genode/fifo_element/description]

[raw spec/clearpage]

AVL tree
~~~~~~~~

For use cases where associative arrays are needed such as allocators, there
is class template for creating AVL trees. The tree-balancing mechanism
is implemented in the 'Avl_node_base' class. The actual 'Avl_node' and
'Avl_tree' classes are tagged with the element type, which ensures that each
AVL tree hosts only one type of elements.

; Genode::Avl_node_base
[raw spec/classes/genode/avl_node_base/description]

; Genode::Avl_node<>
[raw spec/classes/genode/avl_node/description]

; Genode::Avl_tree<>
[raw spec/classes/genode/avl_tree/description]

;XXX is this really interesting for the API?
;To accommodate the common use case for using strings as keys into an
;dictionary, there exists a specialized version of the AVL tree for managing
;pools of strings.
;; Genode::Avl_string_base
;[raw spec/classes/genode/avl_string_base/description]
;
;; Genode::Avl_string<>
;[raw spec/classes/genode/avl_string/description]

[raw spec/clearpage]

ID space
~~~~~~~~

Similar to how the 'Registry' provides a safe wrapper around list's most
common use case, the 'Id_space' covers a prominent use case for AVL trees
in a safeguarded fashion, namely the association of objects with IDs.
Internally, IDs are kept in an AVL tree but that implementation detail remains
hidden from the API. In contrast to a bit allocator, the ID space can be
sparsely populated and does not need to be dimensioned. The lifetime of an ID
is bound to an 'Element' object, which relieves the programmer from manually
allocating/deallocating IDs for objects.

; Genode::Id_space
[raw spec/classes/genode/id_space/description]

Bit array
~~~~~~~~~

Bit arrays are typically used for the allocation of IDs. The 'Bit_array_base'
class operates on a memory buffer specified to its constructor. The
'Bit_array' class template addresses the common case where the ID space
is dimensioned at compile time. It takes the number of bits as arguments
and hosts the memory buffer for storing the bits within the object.

; Genode::Bit_array_base
[raw spec/classes/genode/bit_array_base/description]

; Genode::Bit_array<>
[raw spec/classes/genode/bit_array/description]

[raw spec/clearpage]

;Ring buffer
;~~~~~~~~~~~
;
; Genode::Ring_buffer_unsynchronized
; Genode::Ring_buffer_synchronized
; Genode::Ring_buffer<>

;Handle registry
;~~~~~~~~~~~~~~~
;
;; Genode::Handle<>
;; Genode::Handle_registry<>

;Geometry
;~~~~~~~~
;
;; Genode::Point<>
;; Genode::Area<>
;; Genode::Rect<>
;; Genode::Dirty_rect<>
;
;;; Genode::Flexpage
;;; Genode::Flexpage_iterator

Object lifetime management
==========================

Thread-safe weak pointers
~~~~~~~~~~~~~~~~~~~~~~~~~

Dangling pointers represent one of the most common cause for instabilities
of software written in C or C++. Such a
situation happens when an object disappears while pointers to the object
are still in use. One way to solve this problem is to explicitly notify the
holders of those pointers about the disappearance of the object. But this
would require the object to keep references to those pointer holders, which,
in turn, might disappear as well. Consequently, this approach tends to
become a complex solution, which is prone to deadlocks or race conditions
when multiple threads are involved.

The utilities provided by _base/weak_ptr.h_ implement a more elegant pattern
called "weak pointers" to deal with such situations. An object that might
disappear at any time is represented by the 'Weak_object' class
template. It keeps track of a list of so-called weak pointers pointing
to the object. A weak pointer, in turn, holds privately the pointer to the
object alongside a validity flag. It cannot be used to dereference the
object. For accessing the actual object, a locked pointer must be created
from a weak pointer. If this creation succeeds, the object is guaranteed to
be locked (not destructed) until the locked pointer gets destroyed. If the
object no longer exists, the locked pointer will become invalid. This condition
can (and should) be detected via the 'Locked_ptr::is_valid()' function prior
dereferencing the pointer.

In the event a weak object gets destructed, all weak pointers that point
to the object are automatically invalidated. So a subsequent conversion into
a locked pointer will yield an invalid pointer, which can be detected (in
contrast to a dangling pointer).

To use this mechanism, the destruction of a weak object must be
deferred until no locked pointer points to the object anymore. This is
done by calling the function 'Weak_object::lock_for_destruction()'
at the beginning of the destructor of the to-be-destructed object.
When this function returns, all weak pointers to the object will have been
invalidated. So it is save to destruct and free the object.

; Genode::Weak_object_base
[raw spec/classes/genode/weak_object_base/description]

; Genode::Weak_object<>
[raw spec/classes/genode/weak_object/description]

; Genode::Weak_ptr_base
[raw spec/classes/genode/weak_ptr_base/description]

; Genode::Weak_ptr<>
[raw spec/classes/genode/weak_ptr/description]

; Genode::Locked_ptr_base
[raw spec/classes/genode/locked_ptr_base/description]

; Genode::Locked_ptr<>
[raw spec/classes/genode/locked_ptr/description]

[raw spec/clearpage]

Late and repeated object construction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 'construct_at' utility allows for the
manual placement of objects without the need to have a global placement new
operation nor the need for type-specific new operators.

; construct_at
[raw spec/repos/base/include/util/construct_at.h.overview]

The Genode framework promotes a programming style that largely avoids dynamic
memory allocations. For the most part, higher-level objects aggregate
lower-level objects as class members.
This functional programming style leads to robust programs but it poses a
problem for programs that are expected to adopt their behaviour at runtime.
A way to selectively replace an aggregated object by a
new version with updated constructor arguments is desired. The
'Reconstructible' utility solves this problem by wrapping an object of the
type specified as template argument.
In contrast of a regular object, a 'Reconstructible' object can be
re-constructed any number of times by calling 'construct' with the constructor
arguments. It is accompanied with a so-called 'Constructible' utility, which
leaves the wrapped object unconstructed until 'construct' is called the first
time.

; Genode::Reconstructible<>
[raw spec/classes/genode/reconstructible/description]

; Genode::Constructible<>
[raw spec/classes/genode/constructible/description]

Physical memory allocation
==========================

Throughout Genode, physical memory is allocated in the form of RAM dataspaces
by using the 'Ram_allocator' interface. This interface is implemented by
the PD session and thereby allows a component to use its RAM budget.
The RAM dataspaces allocated from the 'Ram_allocator' interface may serve
as backing store for fine-grained component-local allocators such as the 'Heap'
(Section [Component-local allocators]).

; Genode::Ram_allocator
[raw spec/classes/genode/ram_allocator/description]

Constraining RAM allocations
----------------------------

The operations of the 'Ram_allocator' interface are the basis for Genode's RAM
accounting. In cases where a server needs to allocate RAM on behalf of
its clients, the interface provides a natural hook to track and constrain
the client-specific RAM usage. The 'Constrained_ram_allocator' implements
the interface by forwarding all operations to another 'Ram_allocator'
instance while restricting allocations to a quota limit. Exceeding the
limit results in an 'Out_of_ram' exception.

; Genode::Constrained_ram_allocator
[raw spec/classes/genode/constrained_ram_allocator/description]

Component-local allocators
==========================

Component-local allocators implement the generic 'Deallocator' and 'Allocator'
interfaces. Allocators that operate on address ranges supplement the plain
'Allocator' by implementing the more specific 'Range_allocator' interface.

; Genode::Deallocator
[raw spec/classes/genode/deallocator/description]

; Genode::Allocator
[raw spec/classes/genode/allocator/description]

; Genode::Range_allocator
[raw spec/classes/genode/range_allocator/description]

; Genode::Allocator_guard (deprecated)

[raw spec/clearpage]

Slab allocator
~~~~~~~~~~~~~~

The 'Slab' allocator is tailored for allocating small fixed-size
memory blocks from a big chunk of memory.
For the common use case of using a slab allocator for a certain
type rather than for a known byte size, there exists a typed
slab allocator as a front end of 'Slab'.

; Genode::Slab
[raw spec/classes/genode/slab/description]

; Genode::Tslab<>
[raw spec/classes/genode/tslab/description]

[raw spec/clearpage]

AVL-tree-based best-fit allocator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In contrast to the rather limited slab allocators, 'Allocator_avl'
allows for arbitrary allocations from a list of address regions.
It implements a best-fit allocation strategy, supports arbitrary
alignments, and allocations at specified addresses.

; Genode::Allocator_avl_base
[raw spec/classes/genode/allocator_avl_base/description]

; Genode::Allocator_avl_tpl<>
[raw spec/classes/genode/allocator_avl_tpl/description]

[raw spec/clearpage]

Heap and sliced heap
~~~~~~~~~~~~~~~~~~~~

; Genode::Heap
[raw spec/classes/genode/heap/description]

; Genode::Sliced_heap
[raw spec/classes/genode/sliced_heap/description]

[raw spec/clearpage]

Bit allocator
~~~~~~~~~~~~~

; Genode::Bit_allocator<>
[raw spec/classes/genode/bit_allocator/description]

; XXX should be removed
;; Genode::Synchronized_allocator<>
;; Genode::Synchronized_range_allocator<>

String processing
=================

; explain that this is no application-level string API

Basic string operations
~~~~~~~~~~~~~~~~~~~~~~~

There exists a small set of string-manipulation operations as global functions
in the 'Genode' namespace.

[raw spec/nopagebreak]

[raw spec/repos/base/include/util/string.h.overview]

; XXX ascii_to
;[raw spec/classes/genode/number_of_bytes/description]

[raw spec/clearpage]
To cover the common case of embedding a string buffer as a member variable in
a class, there exists the 'String' class template, which alleviates the
need for C-style arrays in such situations.

The 'String' constructor takes any number of arguments, which will appear
concatenated in the constructed 'String'. Each argument must be printable
as explained in Section [Diagnostic output].

; Genode::String<>
[raw spec/classes/genode/string/description]

There exist a number of printable helper classes that cover typical
use cases for producing formatted text output.

; Genode::Byte_range_ptr
; Genode::Number_of_bytes
; Genode::Cstring

:'Number_of_bytes': wraps an integer value and produces an output
  suffixed with 'K', 'M', or 'G' whenever the value is a multiple
  of a kilobyte, megabyte, or gigabyte.

:'Cstring': wraps a plain C character array to make it printable. There
  exist two constructors. The constructor with one argument expects a
  null-terminated character array. The other constructor takes the
  number of to-be-printed characters as arguments.

:'Hex': wraps an integer value and produces hexadecimal output.

:'Char': produces a character corresponding to the ASCII value the
  wrapped integer argument.

[raw spec/clearpage]

Tokenizing
~~~~~~~~~~

For parsing structured text such as argument strings or XML,
simple tokenizing support is provided via the 'Token' class.

; Genode::Token<>
[raw spec/classes/genode/token/description]

; XXX Genode::Scanner_policy_identifier_with_underline

[raw spec/clearpage]

Diagnostic output
~~~~~~~~~~~~~~~~~

To enable components to produce diagnostic output like errors, warnings, and
log messages, Genode offers a simple 'Output' interface for sequentially
writing single characters or character sequences.

; Genode::Output
[raw spec/classes/genode/output/description]

Functions for generating output for different types are named 'print' and
take an 'Output &' as first argument. The second argument is a 'const &'
to the value to print. Overloads of the 'print' function for commonly
used basic types are provided. Furthermore, there is a function template
that is used if none of the type-specific overloads match. This function
template expects the argument to be an object with a 'print' method. In
contrast to a plain 'print' function overload, such a method is able
to incorporate private state into the output.

[raw spec/repos/base/include/base/output.h.overview]

The component's execution environment provides an implementation of the
'Output' interface that targets a LOG session. This output back end is
offered to the component in the form of the 'log', 'warning', 'error', and
'trace' functions that accept an arbitrary number of arguments that are printed
in a concatenated fashion. Each message is implicitly finalized with a
newline character.

[raw spec/repos/base/include/base/log.h.overview]

; Genode::Buffered_output
; Genode::Log_tsc_probe

[raw spec/clearpage]

Unicode handling
~~~~~~~~~~~~~~~~

The string-handling utilities described in Section [Basic string operations]
operate on ASCII-encoded character strings where each character is encoded as
one byte. It goes without saying that ASCII is unsuitable for user-facing
components that are ultimately expected to support the display of
international characters. The 'Utf8_ptr' utility accommodates such components
with an easy way to extract a sequence of Unicode codepoints from an
UTF-8-encoded string.

; Genode::Codepoint (XXX public member is not visible in the generate description)
;[raw spec/classes/genode/codepoint/description]

; Genode::Utf8_ptr
[raw spec/classes/genode/utf8_ptr/description]

[raw spec/clearpage]

Multi-threading and synchronization
===================================

Threads
~~~~~~~

A thread is created by constructing an object of a class inherited from
'Thread'. The new thread starts its execution at the 'entry' method.
Thereby, each thread runs in the context of its object and
can access context-specific information by accessing its member
variables. This largely alleviates the need for a thread-local storage (TLS)
mechanism.
Threads use a statically allocated stack, which is dimensioned according
to the corresponding constructor argument.

; Genode::Thread
[raw spec/classes/genode/thread/description]

[raw spec/clearpage]

Inter-thread synchronization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Genode provides three inter-thread synchronization primitives, namely 'Mutex',
'Blockade', and 'Semaphore', which model different thread-synchronization
situations. Under the hood, they are based on the same low-level 'Lock'
primitive, which is visible at the API but not recommended for direct use as
it will potentially be removed from the API in a later version.

; Genode::Mutex
[raw spec/classes/genode/mutex/description]

Example of using a 'Mutex'
--------------------------

! Mutex mutex;
! mutex.acquire();
! mutex.release();
!
! {
!   Mutex::Guard guard(mutex) /* acquire() during construction */
! }                           /* release() on guard object destruction */
!
! Mutex::Guard guard(mutex);
! mutex.acquire();            /* <-- cause a warning about the deadlock */

; Genode::Blockade
[raw spec/classes/genode/blockade/description]

; Genode::Lock
; [raw spec/classes/genode/lock/description]

; Genode::Lock_guard<>
; [raw spec/classes/genode/lock_guard/description]

[raw spec/clearpage]

Alongside the mutual exclusion of entering critical sections and the startup
synchronization of threads, producer-consumer relationships between threads
are most common. The 'Semaphore' enables the implementation of this
synchronization scheme.

; Genode::Semaphore
[raw spec/classes/genode/semaphore/description]

[raw spec/clearpage]

To synchronize method calls of an object, the 'Synced_interface' can be
used to equip the class of the called object with thread safety.

; Genode::Synced_interface<>
[raw spec/classes/genode/synced_interface/description]

; Page-fault handling should become private
;; Genode::Pager_object
;; Genode::Pager_activation_base
;; Genode::Pager_entrypoint
;; Genode::Pager_activation<>

Signalling
==========

Section [Asynchronous notifications] provides the high-level
description of the mechanism for the delivery of asynchronous notifications
(signals).
The API defines interfaces for signal transmitters and for the association
of signal handlers with entrypoints.
An entrypoint can be associated with many signal handlers where each
handler usually corresponds to a different signal source.
Each signal handler is addressable via a distinct capability. Those so-called
signal-context capabilities can be delegated across component boundaries
in the same way as RPC-object capabilities.
If a component is in possession of a signal-context capability, it can
trigger the corresponding signal handler by using a so-called signal
transmitter.
The signal transmitter provides fire-and-forget semantics for signal
submission.
Signals serve as mere notifications and cannot carry any payload.

; Genode::Signal
; Genode::Signal_context
; Genode::Signal_receiver

; Genode::Signal_transmitter
[raw spec/classes/genode/signal_transmitter/description]

; Genode::Signal_handler<>
[raw spec/classes/genode/signal_handler/description]

; XXX Genode::Signal_dispatcher_base
; XXX Genode::Signal_rpc_dispatcher_base
; XXX Genode::Signal_dispatcher<>
; XXX Genode::Io_signal_dispatcher<>
; XXX Genode::Signal_rpc_functor<>
; XXX Genode::Signal_rpc_member<>

A 'Signal_handler' object is meant to be hosted as a member of the class that
also contains a member function to be executed upon the arrival of a signal.
Its constructor takes the entrypoint, the signal-handling object, and a
pointer to the handling function as arguments. The following example
illustrates the common pattern of using a 'Signal_handler'.

! class Main
! {
!   ...
!   Entrypoint &_ep;
!   ...
!   void _handle_config();
!
!   Signal_handler<Main> _config_handler =
!     { _ep, *this, &Main::_handle_config };
!   ...
! };

In the example above, the '_config_handler' creates a signal-context
capability for the '_handle_config' method. In fact, the '_config_handler'
is a capability since the 'Signal_handler' is derived from
'Signal_context_capability'. Therefore, the '_config_handler' can be
directly passed as argument to an RPC call for registering a signal
handler at a server.

Remote procedure calls
======================

Section [Synchronous remote procedure calls (RPC)] provides the high-level
description of synchronous remote procedure calls (RPC).

RPC mechanism
~~~~~~~~~~~~~

The RPC mechanism consists of the following header files:

:_base/rpc.h_:
  Contains the basic type definitions and utility macros to declare RPC
  interfaces.

:_base/rpc_args.h_:
  Contains definitions of non-trivial argument types used for transferring
  strings and binary buffers. Its use by RPC interfaces is optional.

:_base/rpc_server.h_:
  Contains the interfaces of the server-side RPC API. In particular, this part
  of the API consists of the 'Rpc_object' class template.

:_base/rpc_client.h_:
  Contains the API support for invoking RPC functions. It is complemented by
  the definitions in _base/capability.h_. The most important elements of the
  client-side RPC API are the 'Capability' class template and 'Rpc_client',
  which is a convenience wrapper around 'Capability'.

Each RPC interface is an abstract C++ interface, supplemented by a few
annotations. For example:

! #include <session/session.h>
! #include <base/rpc.h>
!
! namespace Hello { struct Session; }
!
! struct Hello::Session : Genode::Session
! {
!   static const char *service_name() { return "Hello"; }
!
!   virtual void say_hello() = 0;
!   virtual int add(int a, int b) = 0;
!
!   GENODE_RPC(Rpc_say_hello, void, say_hello);
!   GENODE_RPC(Rpc_add, int, add, int, int);
!   GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
! };

The macros 'GENODE_RPC' and 'GENODE_RPC_INTERFACE' are defined in _base/rpc.h_
and enrich the interface with type information. They are only used at compile
time and have no effect on the run time or the size of the class.
Each RPC function is represented as a type. In the example, the type meta
data of the 'say_hello' function is attached to the 'Rpc_say_hello' type
within the scope of 'Session'. The macro arguments are:

! GENODE_RPC(func_type, ret_type, func_name, arg_type ...)

The 'func_type' argument is an arbitrary type name (except for the type name
'Rpc_functions') used to refer to the RPC function, 'ret_type' is the return
type or 'void', 'func_name' is the name of the server-side function that
implements the RPC function, and the list of 'arg_type' arguments comprises the
RPC function argument types. The 'GENODE_RPC_INTERFACE' macro defines a type
called 'Rpc_functions' that contains the list of the RPC functions provided by
the RPC interface.

Server side
-----------

The implementation of the RPC interface inherits the 'Rpc_object' class
template with the interface type as argument and implements the abstract
RPC interface class.

The server-side RPC dispatching is performed by the compile-time-generated
'dispatch' method of the 'Rpc_object' class template, according to the type
information found in the annotations of the 'Session' interface.

; Genode::Rpc_object_base
[raw spec/classes/genode/rpc_object_base/description]

; Genode::Rpc_object<>
; XXX Genode::Rpc_dispatcher<>
;[raw spec/classes/genode/rpc_object/description]

To make an instance of an RPC object invokable via RPC, it must be associated
with an RPC entrypoint. By passing an RPC object to the 'Entrypoint::manage'
method, a new capability for the RPC object is created. The capability is
tagged with the type of the RPC object.

Most server-side RPC interfaces are session interfaces. In contrast to
plain RPC objects (like a 'Region_map'), all sessions carry a client-provided
budget of RAM and capabilities, and are associated with a client-specific
label. The 'Session_object' class template captures commonalities of
this kind of RPC objects.

; Genode::Session_object
[raw spec/classes/genode/session_object/description]

Client side
-----------

At the client side, a capability can be invoked by the capability's 'call'
method template with the RPC functions type as template argument. The
method arguments correspond to the RPC function arguments.

By convention, the 'Capability::call' method is rarely used directly.
Instead, each RPC interface is accompanied with a client-side implementation
of the abstract interface where each RPC function is implemented by calling
the 'Capability::call' method. This convention is facilitated by the
'Rpc_client' class template.

; Genode::Rpc_client
[raw spec/classes/genode/rpc_client/description]

Using this template, the client-side implementation of the example RPC
interface looks as follows.

! #include <hello_session/hello_session.h>
! #include <base/rpc_client.h>
!
! namespace Hello { struct Session_client; }
!
! struct Hello::Session_client : Genode::Rpc_client<Session>
! {
!   Session_client(Genode::Capability<Session> cap)
!   : Genode::Rpc_client<Session>(cap) { }
!
!   void say_hello()
!   {
!     call<Rpc_say_hello>();
!   }
!
!   int add(int a, int b)
!   {
!     return call<Rpc_add>(a, b);
!   }
! };

For passing RPC arguments and results, the regular C++ type-conversion rules
are in effect. If there is no valid type conversion, or if the number of
arguments is wrong, or if the RPC type annotations are not consistent with the
abstract interface, the error is detected at compile time.

Transferable argument types
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The arguments specified to 'GENODE_RPC' behave mostly as expected for a normal
function call. But there are some notable differences:

:Value types:
  Value types are supported for basic types and plain-old-data types
  (self-sufficient structs or classes). The object data is transferred as such.
  If the type is not self-sufficient (it contains pointers or references), the
  pointers and references are transferred as plain data, most likely
  pointing to the wrong thing in the callee's address space.

:Const references:
  Const references behave like value types. The referenced object is
  transferred to the server and a reference to the server-local copy is passed
  to the server-side function. Note that in contrast to a normal function
  call that takes a reference argument, the size of the referenced object is
  accounted for allocating the message buffer on the client side.

:Non-const references:
  Non-const references are handled similar to const references. In addition the
  server-local copy gets transferred back to the caller so that server-side
  modifications of the object become visible to the client.

:Capabilities:
  Capabilities can be transfered as values, const references, or non-const
  references.

:Variable-length buffers:
  There exists special support for passing binary buffers to RPC functions using
  the 'Rpc_in_buffer' class template provided by _base/rpc_args.h_. The maximum
  size of the buffer must be specified as template argument. An 'Rpc_in_buffer'
  object does not contain a copy of the data passed to the constructor, only a
  pointer to the data. In contrast to a fixed-sized object containing a copy of
  the payload, the RPC framework does not transfer the whole object but only
  the actually used payload.

:Pointers:
  Pointers and const pointers are handled similar to references. The pointed-to
  argument gets transferred and the server-side function is called with a
  pointer to the local copy.

By default, all RPC arguments are input arguments, which are transferred to the
server. The return type of the RPC function, if present, is an output-only
value. To avoid a reference argument from acting as both input- and output
argument, a const reference should be used.

Throwing C++ exceptions across RPC boundaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The propagation of C++ exceptions from the server to the client is supported
by a special variant of the 'GENODE_RPC' macro:

! GENODE_RPC_THROW(func_type, ret_type, func_name,
!                  exc_type_list, arg_type ...)

This macro accepts an additional 'exc_type_list' argument, which is a type
list of exception types. Exception objects are not
transferred as payload. The RPC mechanism propagates solely the information
that the specific exception was raised. Hence, information provided with the
thrown object will be lost when crossing an RPC boundary.

RPC interface inheritance
~~~~~~~~~~~~~~~~~~~~~~~~~

It is possible to extend existing RPC interfaces with additional RPC
functions. Internally, such an RPC interface inheritance is realized by
concatenation of the 'Rpc_functions' type lists of both the base interface
and the derived interface. This use case is supported by a special version of
the 'GENODE_RPC_INTERFACE' macro:

! GENODE_RPC_INTERFACE_INHERIT(base_interface,
!                              rpc_func ...)

Casting capability types
~~~~~~~~~~~~~~~~~~~~~~~~

For typed capabilities, the same type conversion rules apply as for pointers.
In fact, a typed capability pretty much resembles a typed pointer, pointing
to a remote object. Hence, assigning a specialized capability (e.g.,
'Capability<Event::Session>') to a base-typed capability (e.g.,
'Capability<Session>') is always valid. For the opposite case, a static cast
is needed. For capabilities, this cast is supported by
! static_cap_cast<INTERFACE>(cap)

In rare circumstances, mostly in platform-specific base code, a reinterpret
cast for capabilities is required. It allows to convert any capability to
another type:
! reinterpret_cap_cast<INTERFACE>(cap)

Non-virtual RPC interface functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is possible to declare RPC functions using 'GENODE_RPC', which do not
exist as virtual functions in the abstract interface class. In this case, the
function name specified as third argument to 'GENODE_RPC' is of course not
valid for the interface class but an alternative class can be specified as
second argument to the server-side 'Rpc_object'. This way, a server-side
implementation may specify its own class to direct the RPC function to a local
(possibly non-virtual) implementation.

; XXX Genode::Rpc_in_buffer_base
; XXX Genode::Rpc_in_buffer<>

Limitations of the RPC mechanism
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The maximum *number of RPC function arguments* is limited to 7.
If a function requires more arguments, it may be worthwhile to consider
grouping some of them in a compound struct.

[raw spec/clearpage]

Root interface
~~~~~~~~~~~~~~

Each service type is represented as an RPC object implementing
the root interface. The server announces its service type by
providing the service name and the capability of the service's root
interface ('announce' function of the parent interface).
Given the capability to the root interface, the parent is then able
to create and destroy sessions.

; Genode::Root
[raw spec/classes/genode/root/description]

; Genode::Typed_root<>
[raw spec/classes/genode/typed_root/description]

; XXX Genode::Root_client

Because defining root interfaces for services follows a recurring pattern,
there exists default template classes that implement the standard behaviour of
the root interface for services with multiple clients ('Root_component') and
services with a single client ('Static_root').

; Genode::Root_component<>
[raw spec/classes/genode/root_component/description]

; XXX Genode::Single_client
; XXX Genode::Multiple_clients

; Genode::Static_root<>
;[raw spec/classes/genode/static_root/description]

[raw spec/clearpage]

Server-side policy handling
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 'Session_label' and 'Session_policy' utilities aid the implementation
of the server-side policy-selection mechanism described in Section
[Server-side policy selection].

; Genode::Session_label
[raw spec/classes/genode/session_label/description]

; Genode::Session_policy
[raw spec/classes/genode/session_policy/description]

; Should be preserved for internal use
;; Genode::Object_pool<>
;; Genode::Ipc_error
;; Genode::Ipc_marshaller
;; Genode::Ipc_unmarshaller
;; Genode::Ipc_ostream
;; Genode::Ipc_istream
;; Genode::Ipc_client
;; Genode::Ipc_server

[raw spec/clearpage]

Packet stream
~~~~~~~~~~~~~

The 'Packet_stream' is the building block of the asynchronous transfer of bulk
data (Section [Asynchronous bulk transfer - packet streams]).
The public interface consists of
the two class templates 'Packet_stream_source', and 'Packet_stream_sink'.
Both communication parties agree on a policy with regard to the
organization of the communication buffer by specifying the same
'Packet_stream_policy' as template argument.

The communication buffer consists of three parts, a submit queue, an
acknowledgement queue, and a bulk buffer. The submit queue contains
packets generated by the source to be processed by the sink. The
acknowledgement queue contains packets that are processed and acknowledged
by the sink. The bulk buffer contains the actual payload. The assignment
of packets to bulk-buffer regions is performed by the source.

; Genode::Packet_descriptor
[raw spec/classes/genode/packet_descriptor/description]

; Genode::Packet_stream_base
[raw spec/classes/genode/packet_stream_base/description]

; Genode::Packet_stream_source
[raw spec/classes/genode/packet_stream_source/description]

; Genode::Packet_stream_sink
[raw spec/classes/genode/packet_stream_sink/description]

; Genode::Packet_stream_policy
[raw spec/classes/genode/packet_stream_policy/description]

; XXX Genode::Packet_allocator
; XXX Genode::Packet_descriptor_queue<>
; XXX Genode::Packet_descriptor_transmitter<>
; XXX Genode::Packet_descriptor_receiver<>

[raw spec/clearpage]

In client-server scenarios, each client and server can play the role of either
a source or a sink of packets. To ease the use of packet streams in such
scenarios, the classes within the 'Packet_stream_rx' and 'Packet_stream_tx'
namespaces provide ready-to-use building blocks to be aggregated in session
interfaces.

*Data transfer from server to client*

; Packet_stream_rx::Channel
[raw spec/classes/packet_stream_rx/channel/description]

; Packet_stream_rx::Client
[raw spec/classes/packet_stream_rx/client/description]

; XXX Packet_stream_rx::Rpc_object
;[raw spec/classes/packet_stream_rx/rpc_object/description]

[raw spec/clearpage]

*Data transfer from client to server*

; Packet_stream_tx::Channel
[raw spec/classes/packet_stream_tx/channel/description]

; Packet_stream_tx::Client
[raw spec/classes/packet_stream_tx/client/description]

;; Packet_stream_tx::Rpc_object
;[raw spec/classes/packet_stream_tx/rpc_object/description]

XML processing
==============

The configuration concept (Chapter [System configuration] and Section
[Component configuration]) of the framework relies on XML syntax. Hence,
there is the need to process XML-formed data. For parsing XML data, the
'Xml_node' and the accompanying 'Xml_attribute' utilities are provided.
Those utilities operate directly on a text buffer that contains XML
data. There is no conversion step into an internal representation. This approach
alleviates the need for allocating any meta data while extracting information
from XML data. The XML parser is stateless.

Vice versa, the 'Xml_generator' serves as a utility for generating XML
formatted data. The scope of an XML node is represented by a lambda function.
Hence, nested XML nodes can be created by nested lambda functions, which makes
the structure of the XML data immediately apparent in the C++ source code.
As for the 'Xml_node' the 'Xml_generator' does not use any internal
intermediate representation of the XML data. No dynamic memory allocations
are needed while generating XML-formatted output.

A typical component imports parts of its internal state from XML input, most
prominently its configuration. This import is not a one-off operation but may
occur multiple times during the lifetime of the component. Hence, the
component is faced with the challenge of updating its internal data model from
potentially changing XML input. The 'List_model' provides a convenient and
robust formalism to implement such partial model updates.

XML parsing
~~~~~~~~~~~

Genode's XML parser consists of the two classes 'Xml_node' and
'Xml_attribute'. Its primary use case is the provisioning of configuration
information to low-level components. Consequently, it takes the following
considerations into account:

:Low complexity: Because the parser is implicitly used in most components,
  it must not be complex to keep its footprint on the trusted computing base
  as small as possible.

:Free-standing:
  The parser must be able to operate without external dependencies such as
  a C runtime. Otherwise, each Genode-based system would inherit such
  dependencies.

:No dynamic memory allocations:
  The parser should not dynamically allocate memory to be usable in
  resource multiplexers and runtime environments where no anonymous memory
  allocations are allowed (Section [Component-local heap partitioning]).

:Robustness:
  The parser must be robust in the sense that it must not contain buffer
  overflows, infinite loops, memory corruptions, or any other defect that may
  make the program crash.

Other possible goals like expressive error messages, the support for more
general use cases, and even the adherence to standards are deliberately
subordinated.
Given its low complexity, the XML parser cannot satisfy components that need
advanced XML processing such as validating XML data against a DTD or schema,
mutating XML nodes, or using different character encodings.
In such cases, component developers may consider the use of ported 3rd-party
XML parser.

; Genode::Xml_attribute
[raw spec/classes/genode/xml_attribute/description]

; Genode::Xml_node
[raw spec/classes/genode/xml_node/description]

; Genode::Xml_unquoted
[raw spec/classes/genode/xml_unquoted/description]

[raw spec/clearpage]

XML generation
~~~~~~~~~~~~~~

; Genode::Xml_generator
[raw spec/classes/genode/xml_generator/description]

[raw spec/clearpage]

XML-based data models
~~~~~~~~~~~~~~~~~~~~~

The 'List_model' utility eases the implementation of component-internal data
models created and updated from XML. The transformation is defined by the
implementation of the 'Update_policy' interface. As a low-level mechanism,
the list model is not thread safe.

; Genode::List_model
[raw spec/classes/genode/list_model/description]

; Genode::List_model::Update_policy
[raw spec/classes/genode/list_model/update_policy/description]

In some situations, it is convenient to keep a verbatim copy of XML input as
part of the internal data model. As the 'Xml_node' is merely a light-weight
pointer into XML data, it cannot be stored when the underlying XML data is
updated dynamically. Instead, the XML input must be copied into the internal
data model. The 'Buffered_xml' utility takes care of the backing-store
allocation and copying of an existing 'Xml_node'.

; Genode::Buffered_xml
[raw spec/classes/genode/buffered_xml/description]

[raw spec/clearpage]

Component management
====================

; Should be preserved for internal use
;Low-level component creation
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
;The 'Process' class provides a convenient front end for the procedure
;described in Section [Component creation].
;
;; Genode::Elf_binary
;; Genode::Elf_segment
;; Genode::Process

Shared objects
~~~~~~~~~~~~~~

; Genode::Shared_object
[raw spec/classes/genode/shared_object/description]

; Genode::Address_info
[raw spec/classes/genode/address_info/description]

[raw spec/clearpage]

Child management
~~~~~~~~~~~~~~~~

For components that manage a number of child components, each child
is represented by an instance of the 'Child' class.
This instance contains the policy to be applied to the child (for
example, how session requests are routed to services)
and contains the child's execution environment including the
PD session holding the child's RAM and capability quota.

; Genode::Child_policy
[raw spec/classes/genode/child_policy/description]

; Genode::Child
[raw spec/classes/genode/child/description]

; XXX Genode::Slave::Policy
; XXX Genode::Slave::Connection_base
; XXX Genode::Slave::Connection

Composition of subsystems
~~~~~~~~~~~~~~~~~~~~~~~~~

Whereas the 'Child' class aids the sandboxed execution of one child component,
the interplay between such a child with its environment must be implemented
manually, which can quickly become complex. This is where the sandbox API
enters the picture. It makes the full feature set of the init component
available to C++ programs, including the hosting of an arbitrary number of
children, the routing of sessions among them, the balancing of resources, and
dynamic reconfiguration. In addition to the hosting of components, the
sandbox API also allows the program to interact with the sandboxed children by
providing locally implemented services.

A sandbox instance consumes configurations and produces reports, both in the
form of the XML format as known from the init component. An example for
using the API can be found at _repos/os/src/test/sandbox/_.

; Genode::Sandbox
[raw spec/classes/genode/sandbox/description]

[raw spec/clearpage]

; XXX we may go into more detail - or leave this stuff out?
;Session routing
;~~~~~~~~~~~~~~~
;
;The service classes support the management of services
;announced by children or provided locally, and the synchronization
;of service requests with service announcements.
;
; XXX Genode::Client
; XXX Genode::Server
; XXX Genode::Service
; XXX Genode::Local_service
; XXX Genode::Parent_service
; XXX Genode::Async_service
; XXX Genode::Child_service
; XXX Genode::Service_registry

;Session policing
;~~~~~~~~~~~~~~~~
;
; Genode::Child_policy_dynamic_rom_file
; XXX Init::Child_policy_ram_phys
; XXX Init::Child_policy_enforce_labeling
; XXX Init::Child_policy_pd_args
; XXX Init::Child_policy_handle_cpu_priorities
; XXX Init::Child_policy_provide_rom_file
; XXX Init::Child_policy_redirect_rom_file
; XXX Init::Child_config

;; init-specific child implementation is not part of the Genode API
; XXX Init::Child
; XXX Init::Routed_service
; XXX Init::Name_registry

;XXX
;Server API
;==========
;
; Server::Entrypoint

Utilities for user-level device drivers
=======================================

To avoid common implementation bugs in device drivers,
the framework facilitates the declaration of hardware register and bit
layouts in the form of C++ types. By subjecting the device driver's
interaction with the hardware to the to C++ type
system, the consistency of register accesses with the hardware specifications
can be maintained automatically.
Such hardware specifications are declarative and can be cleanly
separated from the program logic of the driver.
The actual driver program is relieved from any intrinsics in the form of
bit-masking operations.

The MMIO access utilities comes in the form of two header files located at
_util/register.h_ and _util/mmio.h_.

Register declarations
~~~~~~~~~~~~~~~~~~~~~

The class templates found in _util/register.h_ provide a means to express
register layouts using C++ types. In a way, these templates make up for
C++'s missing facility to define accurate bitfields.
The following example uses the 'Register' class template to define
a register as well as a bitfield within the register:

! struct Vaporizer : Register<16>
! {
!   struct Enable : Bitfield<2,1> { };
!   struct State  : Bitfield<3,3> {
!     enum{ SOLID = 1, LIQUID = 2, GASSY = 3 };
!   };
!
!   static void     write (access_t value);
!   static access_t read  ();
! };

In the example, 'Vaporizer' is a 16-bit register, which is expressed via the
'Register' template argument. The 'Register' class template allows for
accessing register content at a finer granularity than the whole register
width. To give a specific part of the register a name, the 'Register::Bitfield'
class template is used. It describes a bit region within the range of the
compound register. The bit 2 corresponds to true if the device is enabled and
bits 3 to 5 encode the 'State'. To access the actual register, the methods
'read()' and 'write()' must be provided as back end, which performs the access
of the whole register. Once defined, the 'Vaporizer' offers a handy way to
access the individual parts of the register, for example:

! /* read the whole register content */
! Vaporizer::access_t r = Vaporizer::read();
!
! /* clear a bit field */
! Vaporizer::Enable::clear(r);
!
! /* read a bit field value */
! unsigned old_state = Vaporizer::State::get(r);
!
! /* assign new bit field value */
! Vaporizer::State::set(r, Vaporizer::State::LIQUID);
!
! /* write whole register */
! Vaporizer::write(r);

Bitfields that span multiple registers
--------------------------------------

The register interface of hardware devices may be designed such that
bitfields are not always consecutive in a single register.
For example, values of the HDMI configuration of the Exynos-5 SoC are
scattered over multiple hardware registers.
The problem is best illustrated by the following example of a hypothetical
timer device. The bits of the clock count value are scattered across
two hardware registers, the lower 6 bits of
the 16-bit-wide register 0x2, and two portions of the 32-bit-wide register
0x4. A declaration of those registers would look like this:

! struct Clock_2 : Register<0x2, 16>
! {
!   struct Value : Bitfield<0, 6> { };
! };
!
! struct Clock_1 : Register<0x4, 32>
! {
!   struct Value_2 : Bitfield<2, 13> { };
!   struct Value_1 : Bitfield<18, 7> { };
! };

Writing a clock value needs consecutive write accesses to both registers
with bit shift operations applied to the value:

! write<Clock_1::Value_1>(clk);
! write<Clock_1::Value_2>(clk >> 7);
! write<Clock_2::Value>(clk >> 20);

The new 'Bitset_2' and 'Bitset_3' class templates contained in
_util/register.h_ allow the user to compose a logical bit field from 2 or 3
physical bit fields. The order of the template arguments expresses the order of
physical bits in the logical bit set. Each argument can be a register, a
bit field, or another bit set. The declaration of such a composed bit set for
the example above looks as follows:

! struct Clock : Bitset_3<Clock_1::Value_1,
!                         Clock_1::Value_2,
!                         Clock_2::Value> { };

With this declaration in place, the driver code becomes as simple as:

! write<Clock>(clk);

Under the hood, the framework performs all needed consecutive write operations
on the registers 0x2 and 0x4.

Memory-mapped I/O
~~~~~~~~~~~~~~~~~

The utilities provided by _util/mmio.h_ use the 'Register' template class as
a building block to provide easy-to-use access to memory-mapped I/O registers.
The 'Mmio' class represents a memory-mapped I/O region taking its local base
address as constructor argument. The following example illustrates its use:

! class Timer : Mmio
! {
!   struct Value   : Register<0x0, 32> { };
!   struct Control : Register<0x4, 8> {
!     struct Enable  : Bitfield<0,1> { };
!     struct Irq     : Bitfield<3,1> { };
!     struct Method  : Bitfield<1,2>
!     {
!       enum { ONCE = 1, RELOAD = 2, CYCLE = 3 };
!     };
!   };
!
!   public:
!
!     Timer(addr_t base) : Mmio(base) { }
!
!     void enable();
!     void set_timeout(Value::access_t duration);
!     bool irq_raised();
! };

The memory-mapped timer device consists of two registers: The 32-bit 'Value'
register and the 8-bit 'Control' register. They are located at the MMIO offsets
0x0 and 0x4, respectively. Some parts of the 'Control' register have specific
meanings as expressed by the 'Bitfield' definitions within the 'Control'
struct.

Using these declarations, accessing the individual bits becomes almost a
verbatim description of how the device is used. For example:

! void enable()
! {
!   /* access an individual bitfield */
!   write<Control::Enable>(true);
! }
!
! void set_timeout(Value::access_t duration)
! {
!   /* write complete content of a register */
!   write<Value>(duration);
!
!   /* write all bitfields as one transaction */
!   write<Control>(Control::Enable::bits(1) |
!                  Control::Method::bits(Control::Method::ONCE) |
!                  Control::Irq::bits(0));
! }
!
! bool irq_raised()
! {
!   return read<Control::Irq>();
! }

; describe w/o the generated class descriptions
;; Genode::Register<>
;[raw spec/classes/genode/register/description]
;
;; Genode::Bitset_2<>
;[raw spec/classes/genode/bitset_2/description]
;
;; Genode::Bitset_3<>
;[raw spec/classes/genode/bitset_3/description]
;
;; Genode::Mmio
;[raw spec/classes/genode/mmio/description]

; XXX Genode::Attached_mmio

;;;; Out of scope
; Genode::Array
; Genode::Texture_base
; Genode::Path_base
; Genode::Surface_base
; Genode::Texture<>
; Genode::Path<>
; Genode::Pixel_rgba<>
; Genode::Surface<>
; Component-local VFS
; Genode::Raw
; Genode::String_console
; Genode::Trace::Execution_time
; Genode::Synced_allocator
; Genode::Console
; Genode::Msgbuf_base
; Genode::Msgbuf
; Genode::Local_connection_base
; Genode::Local_connection
; Genode::Io_signal_handler
; Genode::Connection_base
; Genode::Session_state
; Genode::Session_state::Factory
; Genode::Blocking_canceled
; Genode::Rpc_entrypoint
; Genode::Thread_deprecated
; Genode::Cpu_session::Quota
; Genode::Cpu_thread_client
; Genode::Region_map_client
; Genode::Mmio_plain_access
; Genode::Arg
; Genode::Arg_string
; Genode::Register_set_plain_access
; Genode::Register_set
; File_system::Connection_base
; Genode::Xml_node_label_score
; Dither_painter
; Genode::Dynamic_rom_session
; Genode::Timeout_scheduler
; Genode::Static_parent_services
; Genode::Try_parent_service
; Genode::Session_requester
; Genode::Time_source
; Genode::Single_session_service
; Genode::Ram_session_guard
; Genode::Config
; Platform::Abstract_device
; Platform::Client
; Genode::Dither_matrix
; Genode::Color
; Genode::Timer_time_source
; Genode::Timer
; Genode::Quota_guard_untyped
; Genode::Quota_guard
; Genode::Rpc_object::Capability_guard
; Genode::Quota_transfer
; Genode::Dynamic_linker
; Genode::Trace_output
; Block::Session_rpc_object
; Block::Packet_descriptor
; Block::Session_component_base
; Block::Session_component
; Block::Root
; Block::Driver_session_base
; Block::Driver_session
; Block::Driver
; Block::Driver_factory
; Genode::Sandbox::Local_service_base
; Genode::Sandbox::Local_service
; Genode::Directory
; Genode::New_file
; Genode::Root_directory
; Genode::File
; Genode::Readonly_file
; Genode::File_content
; Genode::Watcher
; Genode::Watch_handler
; Pin::Driver
; Pin::Assignment
; Pin::Root
; Pin::Irq_session_component
; Platform::Device_interface
; Platform::Device::Mmio
; Platform::Device::Irq
; Platform::Device::Io_port_range
; Platform::Dma_buffer
; Genode::Truncated
; Genode::Repeated
; Genode::Left_aligned
; Genode::Right_aligned

repo_name: Fhiss/genode