1// -*- Mode: C++ -*- 2// vim:ft=cpp 3/* 4 * Copyright (C) 2017 Kernkonzept GmbH. 5 * Author(s): Sarah Hoffmann <sarah.hoffmann@kernkonzept.com> 6 * 7 * This file is distributed under the terms of the GNU General Public 8 * License, version 2. Please see the COPYING-GPL-2 file for details. 9 */ 10#pragma once 11 12#include <l4/re/protocols.h> 13#include <l4/sys/capability> 14#include <l4/sys/cxx/ipc_types> 15#include <l4/sys/cxx/ipc_iface> 16 17namespace L4Re 18{ 19 20/** 21 * Interface for memory-like address space accessible via IPC. 22 * 23 * This interface defines methods for indirect access to MMIO regions. 24 * 25 * Memory mapped IO (MMIO) is used by device drivers to control hardware 26 * devices. Access to MMIO regions is assigned to user-level device drivers 27 * via mappings of memory pages. 28 * 29 * However, there are hardware platforms where MMIO regions for different 30 * devices share the same memory page. With respect to security and safety, 31 * it is often not allowed to map a memory page to multiple device drivers 32 * because the driver of one device could then influence operation of another 33 * device, which violates security boundaries. 34 * 35 * A solution to that problem is to implement a third (trusted) component that 36 * gets exclusive access to the shared memory page, and that drivers can 37 * access via IPC with the Mmio_space protocol. This proxy-component can then 38 * enforce an access policy. 39 * 40 * \includefile{l4/re/mmio_space} 41 */ 42struct L4_EXPORT Mmio_space 43: public L4::Kobject_t<Mmio_space, L4::Kobject, L4RE_PROTO_MMIO_SPACE> 44{ 45 /// Actual size of the value to read or write. 46 enum Access_width 47 { 48 Wd_8bit = 0, ///< Value is a byte. 49 Wd_16bit = 1, ///< Value is a 2-byte word. 50 Wd_32bit = 2, ///< Value is a 4-byte word. 51 Wd_64bit = 3 ///< Value is a 8-byte word. 52 }; 53 54 /// Device address. 55 typedef l4_uint64_t Addr; 56 57 /** 58 * Read a value from the given address. 59 * 60 * \param addr Device virtual address to read from. The address 61 * must be aligned relative to the access width. 62 * \param width Access width of value to be read, see #Access_width. 63 * \param[out] value Return value. If width is smaller than 64 bit,the 64 * upper bits are guaranteed to be 0. 65 * 66 * \retval #L4_EOK Success. 67 * \retval -L4_EPERM Insufficient read rights. 68 * \retval -L4_EINVAL Address does not exist or cannot be accessed 69 * with the given width. 70 */ 71 L4_INLINE_RPC(long, mmio_read, (Addr addr, char width, l4_uint64_t *value)); 72 73 /** 74 * Write a value to the given address. 75 * 76 * \param addr Device virtual address to write to. The address 77 * must be aligned relative to the access width. 78 * \param width Access width of value to write, see #Access_width. 79 * \param value Value to write. If width is smaller than 64 bit, 80 * the upper bits are ignored. 81 * 82 * \retval #L4_EOK Success. 83 * \retval -L4_EPERM Insufficient write rights. 84 * \retval -L4_EINVAL Address does not exist or cannot be accessed 85 * with the given width. 86 */ 87 L4_INLINE_RPC(long, mmio_write, (Addr addr, char width, l4_uint64_t value)); 88 89 typedef L4::Typeid::Rpcs<mmio_read_t, mmio_write_t> Rpcs; 90}; 91 92} 93