1// vi:set ft=cpp: -*- Mode: C++ -*-
2/**
3 * \file
4 * Pager and Io_pager C++ interface.
5 */
6/*
7 * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
8 *
9 * This file is part of TUD:OS and distributed under the terms of the
10 * GNU General Public License 2.
11 * Please see the COPYING-GPL-2 file for details.
12 *
13 * As a special exception, you may use this file as part of a free software
14 * library without restriction.  Specifically, if other files instantiate
15 * templates or use macros or inline functions from this file, or you compile
16 * this file and link it with other files to produce an executable, this
17 * file does not by itself cause the resulting executable to be covered by
18 * the GNU General Public License.  This exception does not however
19 * invalidate any other reasons why the executable file might be covered by
20 * the GNU General Public License.
21 */
22
23#pragma once
24
25#include <l4/sys/capability>
26#include <l4/sys/types.h>
27#include <l4/sys/cxx/ipc_types>
28#include <l4/sys/cxx/ipc_iface>
29
30namespace L4 {
31
32/**
33 * Io_pager interface.
34 *
35 * \note This interface is IA32 specific.
36 *
37 * This class defines the interface for handling IO page faults. IO page
38 * faults happen when a thread tries to access an IO port that it does not
39 * currently have access to.
40 *
41 * Depending on the microkernel's implementation, IO page faults can be
42 * handled in two ways.
43 *
44 * If the microkernel does not support IO page faults, this IO pagefault
45 * interface is not used. Instead, the microkernel sends an exception IPC to
46 * the thread's exception handler (L4::Exception), indicating a #GP (exception
47 * number 13). The exception handler must consult the faulting instruction to
48 * determine the cause of the exception. This is the default in Fiasco.OC.
49 *
50 * In contrast, if the microkernel supports IO page faults, the microkernel
51 * will generate an IO page fault message and send it to the thread's page
52 * fault handler (pager). The page fault handler can implement this interface
53 * to handle the IO page faults.
54 *
55 * \note A program may use this mechanism to implement a lazy IO port access
56 * scheme.
57 *
58 * \note The page fault and exception handlers are set with the
59 * L4::Thread::control interface.
60 */
61class L4_EXPORT Io_pager :
62  public Kobject_0t<Io_pager, L4_PROTO_IO_PAGE_FAULT>
63{
64public:
65  /**
66   * IO page fault protocol message.
67   *
68   * \param      io_pfa  Flex-page describing the faulting IO-port.
69   * \param      pc      Faulting program counter.
70   * \param      rwin    The receive window for a flex-page mapping.
71   * \param[out] fp      Optional: flex-page descriptor to send to the task
72   *                     raising the page fault.
73   *
74   * \return System call message tag; use l4_error() to check for errors.
75   *
76   * IO-port fault messages are usually generated by the kernel and an
77   * IO-page-fault handler needs to be in place to handle such faults
78   * and generate a reply, potentially filling in `fp`.
79   */
80  L4_INLINE_RPC(
81      l4_msgtag_t, io_page_fault, (l4_fpage_t io_pfa, l4_umword_t pc,
82                                   L4::Ipc::Rcv_fpage rwin,
83                                   L4::Ipc::Opt<L4::Ipc::Snd_fpage &> fp));
84
85  typedef L4::Typeid::Rpc_nocode<io_page_fault_t> Rpcs;
86};
87
88/**
89 * Pager interface including the Io_pager interface.
90 *
91 * This class defines the interface for handling page fault IPC. If a thread
92 * causes a page fault, the microkernel synthesises a page fault IPC message
93 * and sends it to the thread's page fault handler (pager). The pager can then
94 * handle the message, for example by establishing a suitable page mapping.
95 *
96 * The page fault handler is set with the L4::Thread::control interface.
97 */
98class L4_EXPORT Pager :
99  public Kobject_t<Pager, Io_pager, L4_PROTO_PAGE_FAULT>
100{
101public:
102  /**
103   * Page-fault protocol message.
104   *
105   * \param      pfa     Faulting address including failure reason: bits [0:2].
106   * \param      pc      Faulting program counter.
107   * \param      rwin    Receive window for a flex-page mapping resolving the
108   *                     page fault.
109   * \param[out] fp      Optional: flex-page descriptor to send to the task
110   *                     raising the page fault.
111   *
112   * \return System call message tag; use l4_error() to check for errors.
113   *
114   * Page-fault messages are usually generated by the kernel and need to
115   * be handled by an appropriate handler function, potentially filling in `fp`
116   * for the reply.
117   *
118   * `pfa` encoding is as shown:
119   *
120   * |       [63/31 .. 3]       | 2 | 1 | 0 |
121   * |:------------------------:|:-:|:-:|:-:|
122   * |            PFA           | X | W | r |
123   *
124   * - __PFA__ Bits 63/31..3 of `pfa` are the page fault address bits 63/31
125   *           to 3, bits 2..0 are masked.
126   * - __X__   Bit 2 of `pfa` if set, indicates a page fault during instruction
127   *           fetch. Note, this bit is implementation-defined and might always
128   *           be clear. Therefore, if this bit is clear it does not imply
129   *           that the page fault is not due to an instruction fetch.
130   * - __W__   Bit 1 of `pfa` is set to 1 for a page fault due to a write
131   *           operation.
132   * - __r__   Bit0: reserved, undefined.
133   */
134  L4_INLINE_RPC(
135      l4_msgtag_t, page_fault, (l4_umword_t pfa, l4_umword_t pc,
136                                L4::Ipc::Rcv_fpage rwin,
137                                L4::Ipc::Opt<L4::Ipc::Snd_fpage &> fp));
138
139  typedef L4::Typeid::Rpc_nocode<page_fault_t> Rpcs;
140};
141
142}
143