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