mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 20:42:56 +01:00
'Reg_array' contains items whose width can be the width of the register storage type at a max. Nethertheless they can be smaller and iterate all subregs that are covered by the item width. The array uses as much successive instances of its storage type as needed. The test 'run/util_mmio' also tests these new features heavily.
80 lines
1.8 KiB
C++
80 lines
1.8 KiB
C++
/*
|
|
* \brief Generic access framework for highly structured memory regions
|
|
* \author Martin stein
|
|
* \date 2011-11-10
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2011-2012 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#ifndef _BASE__INCLUDE__UTIL__REGISTER_H_
|
|
#define _BASE__INCLUDE__UTIL__REGISTER_H_
|
|
|
|
#include <base/stdint.h>
|
|
|
|
namespace Genode
|
|
{
|
|
/**
|
|
* A POD-like highly structured memory region
|
|
*/
|
|
template <typename STORAGE_T>
|
|
struct Register
|
|
{
|
|
typedef STORAGE_T storage_t;
|
|
|
|
/**
|
|
* A bitregion within a register
|
|
*/
|
|
template <unsigned long BIT_SHIFT, unsigned long BIT_SIZE>
|
|
struct Subreg
|
|
{
|
|
enum {
|
|
SHIFT = BIT_SHIFT,
|
|
WIDTH = BIT_SIZE,
|
|
MASK = (1 << WIDTH) - 1,
|
|
REG_MASK = MASK << SHIFT,
|
|
CLEAR_MASK = ~REG_MASK,
|
|
};
|
|
|
|
/**
|
|
* Back reference to containing register
|
|
*/
|
|
typedef Register<storage_t> Compound_reg;
|
|
|
|
/**
|
|
* Get a register value with this subreg set to 'value' and the rest left zero
|
|
*
|
|
* \detail Useful to combine successive access to multiple subregs
|
|
* into one operation
|
|
*/
|
|
static inline storage_t bits(storage_t const value) { return (value & MASK) << SHIFT; }
|
|
|
|
/**
|
|
* Get value of this subreg from 'reg'
|
|
*/
|
|
static inline storage_t get(storage_t const reg) { return (reg >> SHIFT) & MASK; }
|
|
|
|
/**
|
|
* Get registervalue 'reg' with this subreg set to zero
|
|
*/
|
|
static inline void clear(storage_t & reg) { reg &= CLEAR_MASK; }
|
|
|
|
/**
|
|
* Get registervalue 'reg' with this subreg set to 'value'
|
|
*/
|
|
static inline void set(storage_t & reg, storage_t const value = ~0)
|
|
{
|
|
clear(reg);
|
|
reg |= (value & MASK) << SHIFT;
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
#endif /* _BASE__INCLUDE__UTIL__REGISTER_H_ */
|
|
|