diff --git a/base/include/util/mmio.h b/base/include/util/mmio.h index 2803af603..05ddfbd6d 100644 --- a/base/include/util/mmio.h +++ b/base/include/util/mmio.h @@ -44,11 +44,12 @@ namespace Genode /** * An integer like region within a MMIO region. * - * \param _OFFSET Offset of the region relative to the base - * of the compound MMIO. - * \param _ACCESS_WIDTH Bit width of the region. + * \param _OFFSET Offset of the region relative to the + * base of the compound MMIO + * \param _ACCESS_WIDTH Bit width of the region, for a list of + * supported widths see 'Genode::Register' * - * \detail See 'Genode::Register' + * \detail See 'Genode::Register' */ template struct Register : public Genode::Register<_ACCESS_WIDTH> @@ -60,14 +61,16 @@ namespace Genode /** * A region within a register - * - * \param _SHIFT Bit shift of the first bit within the compound register + * + * \param _SHIFT Bit shift of the first bit within the + * compound register * \param _WIDTH Bit width of the region * * \detail See 'Genode::Register::Bitfield' */ template - struct Bitfield : public Genode::Register::template Bitfield<_SHIFT, _WIDTH> + struct Bitfield : + public Genode::Register::template Bitfield<_SHIFT, _WIDTH> { /** * Back reference to containing register @@ -79,26 +82,33 @@ namespace Genode /** * An array of successive equally structured regions * - * \param _OFFSET Offset of the first region relative to the base - * of the compound MMIO. - * \param _ACCESS_WIDTH Bit width of a single access, must be at least - * the item width. - * \param _ITEMS How many times the region gets iterated successive + * \param _OFFSET Offset of the first region relative to + * the base of the compound MMIO. + * \param _ACCESS_WIDTH Bit width of a single access, must be at + * least the item width. + * \param _ITEMS How many times the region gets iterated + * successive * \param _ITEM_WIDTH Bit width of a region * - * \detail The array takes all inner structures, wich are covered by an item - * width and iterates them successive. Such structures that are partially - * exceed an item range are read and written also partially. Structures that are - * completely out of the item range are read as '0' and trying to overwrite - * them has no effect. The array is not limited to its access width, it extends to - * the memory region of its successive items. Trying to read out read with an item - * index out of the array range returns '0', trying to write to such indices - * has no effect + * \detail The array takes all inner structures, wich are covered + * by an item width and iterates them successive. Such + * structures that are partially exceed an item range are + * read and written also partially. Structures that are + * completely out of the item range are read as '0' and + * trying to overwrite them has no effect. The array is + * not limited to its access width, it extends to the + * memory region of its successive items. Trying to read + * out read with an item index out of the array range + * returns '0', trying to write to such indices has no + * effect */ - template + template struct Register_array : public Register<_OFFSET, _ACCESS_WIDTH> { - typedef typename Trait::Uint_type<_ACCESS_WIDTH>::template Divisor<_ITEM_WIDTH> Item; + typedef + typename Trait::Uint_type<_ACCESS_WIDTH>::template Divisor<_ITEM_WIDTH> + Item; enum { OFFSET = _OFFSET, @@ -111,7 +121,8 @@ namespace Genode ITEM_MASK = (1 << ITEM_WIDTH) - 1, }; - typedef typename Register::access_t access_t; + typedef typename Register::access_t + access_t; /** * A bitregion within a register array item @@ -119,26 +130,38 @@ namespace Genode * \param _SHIFT Bit shift of the first bit within an item * \param _WIDTH Bit width of the region * - * \detail See 'Genode::Register::Bitfield' + * \detail See 'Genode::Register::Bitfield' */ template - struct Bitfield : public Register::template Bitfield<_SHIFT, _SIZE> + struct Bitfield : + public Register::template Bitfield<_SHIFT, _SIZE> { /** * Back reference to containing register array */ - typedef Register_array Compound_array; + typedef Register_array + Compound_array; }; /** - * Calculate the MMIO-relative offset 'offset' and shift 'shift' - * within the according 'access_t' instance to access item 'index' + * Calculate destination of an array-item access + * + * \param offset Gets overridden with the offset of the + * access type instance, that contains the + * access destination, relative to the MMIO + * base + * \param shift Gets overridden with the shift of the + * destination within the access type instance + * targeted by 'offset' + * \param index Index of the targeted array item */ - static inline void access_dest(off_t & offset, unsigned long & shift, + static inline void access_dest(off_t & offset, + unsigned long & shift, unsigned long const index) { unsigned long const bit_off = index << ITEM_WIDTH_LOG2; - offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2) & ~(sizeof(access_t)-1) ); + offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2) + & ~(sizeof(access_t)-1) ); shift = bit_off - ( offset << BYTE_WIDTH_LOG2 ); offset += OFFSET; } @@ -189,7 +212,8 @@ namespace Genode * Write value to the bitfield 'BITFIELD' */ template - inline void write(typename BITFIELD::Compound_reg::access_t const value); + inline void + write(typename BITFIELD::Compound_reg::access_t const value); /******************************* @@ -200,10 +224,11 @@ namespace Genode * Read the whole item 'index' of the array 'REGISTER_ARRAY' */ template - inline typename REGISTER_ARRAY::access_t read(unsigned long const index) const; + inline typename REGISTER_ARRAY::access_t + read(unsigned long const index) const; /** - * Write 'value' to item 'index' of the array 'REGISTER_ARRAY' + * Write 'value' to item 'index' of the array 'REGISTER_ARRAY' */ template inline void write(typename REGISTER_ARRAY::access_t const value, @@ -215,16 +240,21 @@ namespace Genode *****************************************************/ /** - * Read the bitfield 'ARRAY_BITFIELD' of item 'index' of the compound reg array + * Read the bitfield 'ARRAY_BITFIELD' of item 'index' of the + * compound reg array */ template - inline typename ARRAY_BITFIELD::Compound_array::access_t read(unsigned long const index) const; + inline typename ARRAY_BITFIELD::Compound_array::access_t + read(unsigned long const index) const; /** - * Write 'value' to bitfield 'ARRAY_BITFIELD' of item 'index' of the compound reg array + * Write 'value' to bitfield 'ARRAY_BITFIELD' of item 'index' of + * the compound reg array */ template - inline void write(typename ARRAY_BITFIELD::Compound_array::access_t const value, long unsigned const index); + inline void + write(typename ARRAY_BITFIELD::Compound_array::access_t const value, + long unsigned const index); }; } @@ -304,7 +334,8 @@ void Genode::Mmio::write(typename BITFIELD::Compound_reg::access_t const value) template -typename REGISTER_ARRAY::access_t Genode::Mmio::read(unsigned long const index) const +typename REGISTER_ARRAY::access_t +Genode::Mmio::read(unsigned long const index) const { /** * Handle array overflow @@ -318,14 +349,16 @@ typename REGISTER_ARRAY::access_t Genode::Mmio::read(unsigned long const index) */ if (REGISTER_ARRAY::ITEM_WIDTH == REGISTER_ARRAY::ACCESS_WIDTH) { - offset = REGISTER_ARRAY::OFFSET + (index << REGISTER_ARRAY::ITEM_WIDTH_LOG2); + offset = REGISTER_ARRAY::OFFSET + + (index << REGISTER_ARRAY::ITEM_WIDTH_LOG2); return _read(offset); } else { long unsigned shift; REGISTER_ARRAY::access_dest(offset, shift, index); - return (_read(offset) >> shift) & REGISTER_ARRAY::ITEM_MASK; + return (_read(offset) >> shift) + & REGISTER_ARRAY::ITEM_MASK; } } @@ -347,7 +380,8 @@ void Genode::Mmio::write(typename REGISTER_ARRAY::access_t const value, */ if (REGISTER_ARRAY::ITEM_WIDTH == REGISTER_ARRAY::ACCESS_WIDTH) { - offset = REGISTER_ARRAY::OFFSET + (index << REGISTER_ARRAY::ITEM_WIDTH_LOG2); + offset = REGISTER_ARRAY::OFFSET + + (index << REGISTER_ARRAY::ITEM_WIDTH_LOG2); _write(offset, value); } else { @@ -358,7 +392,9 @@ void Genode::Mmio::write(typename REGISTER_ARRAY::access_t const value, /** * Insert new value into old register value */ - typename REGISTER_ARRAY::access_t new_reg = _read(offset); + typename REGISTER_ARRAY::access_t new_reg = + _read(offset); + new_reg &= ~(REGISTER_ARRAY::ITEM_MASK << shift); new_reg |= (value & REGISTER_ARRAY::ITEM_MASK) << shift; @@ -373,8 +409,9 @@ void Genode::Mmio::write(typename REGISTER_ARRAY::access_t const value, template -void Genode::Mmio::write(typename ARRAY_BITFIELD::Compound_array::access_t const value, - long unsigned const index) +void +Genode::Mmio::write(typename ARRAY_BITFIELD::Compound_array::access_t const value, + long unsigned const index) { typedef typename ARRAY_BITFIELD::Compound_array Register_array; @@ -387,7 +424,8 @@ void Genode::Mmio::write(typename ARRAY_BITFIELD::Compound_array::access_t const template -typename ARRAY_BITFIELD::Compound_array::access_t Genode::Mmio::read(long unsigned const index) const +typename ARRAY_BITFIELD::Compound_array::access_t +Genode::Mmio::read(long unsigned const index) const { typedef typename ARRAY_BITFIELD::Compound_array Array; typedef typename Array::access_t access_t; diff --git a/base/include/util/register.h b/base/include/util/register.h index 06a170725..85cb2b0bc 100644 --- a/base/include/util/register.h +++ b/base/include/util/register.h @@ -1,5 +1,5 @@ /* - * \brief Generic access framework for highly structured memory regions + * \brief Generic accessor framework for highly structured memory regions * \author Martin stein * \date 2011-11-10 */ @@ -21,17 +21,22 @@ namespace Genode namespace Trait { /** - * Get unsigned integer type for a given access width + * Properties of integer types with a given bitwidth */ template struct Uint_type; + /*************************************************************** + ** Provide the integer type and the width as exponent to the ** + ** base of 2 for all supported widths in 'Uint_type' ** + ***************************************************************/ + template <> struct Uint_type<8> { typedef uint8_t Type; enum { WIDTH_LOG2 = 3 }; /** - * Declare dividers of the compound type width + * Access widths, wich are dividers to the compound type width */ template struct Divisor; }; @@ -54,10 +59,16 @@ namespace Genode enum { WIDTH_LOG2 = 6 }; }; - template <> struct Uint_type<8>::Divisor<1> { enum { WIDTH_LOG2 = 0 }; }; - template <> struct Uint_type<8>::Divisor<2> { enum { WIDTH_LOG2 = 1 }; }; - template <> struct Uint_type<8>::Divisor<4> { enum { WIDTH_LOG2 = 2 }; }; - template <> struct Uint_type<8>::Divisor<8> { enum { WIDTH_LOG2 = 3 }; }; + + /******************************************************************** + ** Provide widths as exponents to the base of 2 for all supported ** + ** access widths in 'Uint_type::Divisor' ** + ********************************************************************/ + + template <> struct Uint_type<8>::Divisor<1> { enum { WIDTH_LOG2 = 0 }; }; + template <> struct Uint_type<8>::Divisor<2> { enum { WIDTH_LOG2 = 1 }; }; + template <> struct Uint_type<8>::Divisor<4> { enum { WIDTH_LOG2 = 2 }; }; + template <> struct Uint_type<8>::Divisor<8> { enum { WIDTH_LOG2 = 3 }; }; template <> struct Uint_type<16>::Divisor<16> { enum { WIDTH_LOG2 = 4 }; }; template <> struct Uint_type<32>::Divisor<32> { enum { WIDTH_LOG2 = 5 }; }; template <> struct Uint_type<64>::Divisor<64> { enum { WIDTH_LOG2 = 6 }; }; @@ -69,9 +80,9 @@ namespace Genode * \param _ACCESS_WIDTH Bit width of the region * * \detail The register can contain multiple bitfields. Bitfields - * that are partially exceed the register range are read and - * written also partially. Bitfields that are completely out - * of the register range are read as '0' and trying to + * that are partially exceed the register range are read and + * written also partially. Bitfields that are completely out + * of the register range are read as '0' and trying to * overwrite them has no effect. */ template @@ -87,8 +98,9 @@ namespace Genode /** * A bitregion within a register - * - * \param _SHIFT Bit shift of the first bit within the compound register + * + * \param _SHIFT Bit shift of the first bit within the compound + * register * \param _WIDTH Bit width of the region * * \detail Bitfields are read and written according to their range, @@ -117,17 +129,20 @@ namespace Genode typedef Register Compound_reg; /** - * Get a register value with this bitfield set to 'value' and the rest left zero + * Get a register value with this bitfield set to 'value' and the + * rest left zero * - * \detail Useful to combine successive access to multiple bitfields - * into one operation + * \detail Useful to combine successive access to multiple + * bitfields into one operation */ - static inline access_t bits(access_t const value) { return (value & MASK) << SHIFT; } + static inline access_t bits(access_t const value) { + return (value & MASK) << SHIFT; } /** * Get value of this bitfield from 'reg' */ - static inline access_t get(access_t const reg) { return (reg >> SHIFT) & MASK; } + static inline access_t get(access_t const reg) { + return (reg >> SHIFT) & MASK; } /** * Get registervalue 'reg' with this bitfield set to zero