genode/repos/base/include/util/mmio.h
Martin Stein 442c24420d mmio: separate MMIO access and register logic
By separating the plain MMIO access implementation from the generic bit
and offset logic of registers, we can now use the latter also with other
types of register access like I2C. The register and MMIO front-ends have
not changed due to the separation.

Ref #2196
2017-03-15 12:24:42 +01:00

96 lines
1.9 KiB
C++

/*
* \brief Type-safe, fine-grained access to a continuous MMIO region
* \author Martin stein
* \date 2011-10-26
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__UTIL__MMIO_H_
#define _INCLUDE__UTIL__MMIO_H_
/* Genode includes */
#include <util/register_set.h>
namespace Genode {
class Mmio_plain_access;
class Mmio;
}
/**
* Plain access implementation for MMIO
*/
class Genode::Mmio_plain_access
{
friend Register_set_plain_access;
public:
/**
* FIXME We keep this public only to stay interface compatible
* but the value should be accessible only through an
* accessor.
*/
addr_t const base;
private:
/**
* Write '_ACCESS_T' typed 'value' to MMIO base + 'offset'
*/
template <typename ACCESS_T>
inline void _write(off_t const offset, ACCESS_T const value)
{
addr_t const dst = base + offset;
*(ACCESS_T volatile *)dst = value;
}
/**
* Read '_ACCESS_T' typed from MMIO base + 'offset'
*/
template <typename ACCESS_T>
inline ACCESS_T _read(off_t const &offset) const
{
addr_t const dst = base + offset;
ACCESS_T const value = *(ACCESS_T volatile *)dst;
return value;
}
public:
/**
* Constructor
*
* \param base base address of targeted MMIO region
*/
Mmio_plain_access(addr_t const base) : base(base) { }
};
/**
* Type-safe, fine-grained access to a continuous MMIO region
*
* For further details refer to the documentation of the 'Register_set' class.
*/
struct Genode::Mmio : Mmio_plain_access, Register_set<Mmio_plain_access>
{
/**
* Constructor
*
* \param base base address of targeted MMIO region
*/
Mmio(addr_t const base)
:
Mmio_plain_access(base),
Register_set(*static_cast<Mmio_plain_access *>(this)) { }
};
#endif /* _INCLUDE__UTIL__MMIO_H_ */