11#include <l4/cxx/type_traits>
71template<
unsigned MAX_BITS = 32 >
85struct Register_block_base<16> : Register_block_base<8>
104#undef REGBLK_READ_TEMPLATE
105#undef REGBLK_WRITE_TEMPLATE
107template<
typename CHILD>
108struct Register_block_modify_mixin
110 template<
typename T >
111 T modify(T clear_bits, T set_bits,
l4_addr_t reg)
const
113 CHILD
const *c =
static_cast<CHILD
const *
>(
this);
114 T r = (c->template read<T>(reg) & ~clear_bits) | set_bits;
115 c->template write<T>(r, reg);
119 template<
typename T >
121 {
return this->
template modify<T>(T(0), set_bits, reg); }
123 template<
typename T >
124 T clear(T clear_bits,
l4_addr_t reg)
const
125 {
return this->
template modify<T>(clear_bits, T(0), reg); }
129#define REGBLK_READ_TEMPLATE(sz) \
130 template< typename T > \
131 typename cxx::enable_if<sizeof(T) == (sz / 8), T>::type read(l4_addr_t reg) const \
133 union X { T t; l4_uint##sz##_t v; } m; \
134 m.v = _b->do_read_##sz (reg); \
138#define REGBLK_WRITE_TEMPLATE(sz) \
139 template< typename T > \
140 void write(T value, l4_addr_t reg, typename cxx::enable_if<sizeof(T) == (sz / 8), T>::type = T()) const \
142 union X { T t; l4_uint##sz##_t v; } m; \
144 _b->do_write_##sz(m.v, reg); \
155template<
typename BLOCK >
156class Register_block_tmpl
157:
public Register_block_modify_mixin<Register_block_tmpl<BLOCK> >
163 Register_block_tmpl(BLOCK *blk) : _b(blk) {}
164 Register_block_tmpl() =
default;
166 operator BLOCK * ()
const {
return _b; }
168 REGBLK_READ_TEMPLATE(8)
169 REGBLK_WRITE_TEMPLATE(8)
170 REGBLK_READ_TEMPLATE(16)
171 REGBLK_WRITE_TEMPLATE(16)
172 REGBLK_READ_TEMPLATE(32)
173 REGBLK_WRITE_TEMPLATE(32)
174 REGBLK_READ_TEMPLATE(64)
175 REGBLK_WRITE_TEMPLATE(64)
179#undef REGBLK_READ_TEMPLATE
180#undef REGBLK_WRITE_TEMPLATE
182namespace __Type_helper {
183 template<
unsigned>
struct Unsigned;
184 template<>
struct Unsigned<8> {
typedef l4_uint8_t type; };
185 template<>
struct Unsigned<16> {
typedef l4_uint16_t type; };
186 template<>
struct Unsigned<32> {
typedef l4_uint32_t type; };
187 template<>
struct Unsigned<64> {
typedef l4_uint64_t type; };
200template<
unsigned BITS,
typename BLOCK >
201class Ro_register_tmpl
208 typedef typename __Type_helper::Unsigned<BITS>::type value_type;
210 Ro_register_tmpl(BLOCK
const &blk,
unsigned offset) : _b(blk), _o(offset) {}
211 Ro_register_tmpl() =
default;
217 operator value_type ()
const
236template<
unsigned BITS,
typename BLOCK >
237class Register_tmpl :
public Ro_register_tmpl<BITS, BLOCK>
240 typedef typename Ro_register_tmpl<BITS, BLOCK>::value_type value_type;
242 Register_tmpl(BLOCK
const &blk,
unsigned offset)
243 : Ro_register_tmpl<BITS, BLOCK>(blk, offset)
246 Register_tmpl() =
default;
274 value_type
set(value_type set_bits)
290 value_type
clear(value_type clear_bits)
308 value_type
modify(value_type clear_bits, value_type set_bits)
326 typename BLOCK = Register_block_tmpl<
327 Register_block_base<MAX_BITS>
333 template<
unsigned B,
typename BLK >
friend class Register_block;
334 template<
unsigned B,
typename BLK >
friend class Ro_register_block;
339 Register_block() =
default;
340 Register_block(Block
const &blk) : _b(blk) {}
341 Register_block &operator = (Block
const &blk)
342 { _b = blk;
return *
this; }
344 template<
unsigned BITS >
345 Register_block(Register_block<BITS> blk) : _b(blk._b) {}
356 template<
unsigned BITS >
375 template<
unsigned BITS >
400 typename BLOCK = Register_block_tmpl<
401 Register_block_base<MAX_BITS>
const
404class Ro_register_block
407 template<
unsigned B,
typename BLK >
friend class Ro_register_block;
412 Ro_register_block() =
default;
413 Ro_register_block(BLOCK
const &blk) : _b(blk) {}
415 template<
unsigned BITS >
419 typedef Ro_register Register;
427 {
return Ro_register(this->_b, offset); }
435 template<
unsigned BITS >
454template<
typename BASE,
unsigned MAX_BITS = 32 >
457#define REGBLK_IMPL_RW_TEMPLATE(sz, ...) \
458 l4_uint##sz##_t do_read_##sz(l4_addr_t reg) const override \
459 { return static_cast<BASE const *>(this)->template read<l4_uint##sz##_t>(reg); } \
461 void do_write_##sz(l4_uint##sz##_t value, l4_addr_t reg) override \
462 { static_cast<BASE*>(this)->template write<l4_uint##sz##_t>(value, reg); }
465template<
typename BASE >
468 REGBLK_IMPL_RW_TEMPLATE(8);
471template<
typename BASE >
474 REGBLK_IMPL_RW_TEMPLATE(8);
475 REGBLK_IMPL_RW_TEMPLATE(16);
478template<
typename BASE >
479struct Register_block_impl<BASE, 32> :
public Register_block_base<32>
481 REGBLK_IMPL_RW_TEMPLATE(8);
482 REGBLK_IMPL_RW_TEMPLATE(16);
483 REGBLK_IMPL_RW_TEMPLATE(32);
486template<
typename BASE >
489 REGBLK_IMPL_RW_TEMPLATE(8);
490 REGBLK_IMPL_RW_TEMPLATE(16);
491 REGBLK_IMPL_RW_TEMPLATE(32);
492 REGBLK_IMPL_RW_TEMPLATE(64);
495#undef REGBLK_IMPL_RW_TEMPLATE
Handles a reference to a register block of the given maximum access width.
Ro_register operator[](unsigned offset) const
Read only access to register at offset offset.
Register_tmpl< BITS, Block > r(unsigned offset)
Read/write access to register at offset offset.
Ro_register_tmpl< BITS, Block > r(unsigned offset) const
Read only access to register at offset offset.
Single hardware register inside a Register_block_base interface.
value_type clear(value_type clear_bits)
clears bits in clear_bits in the hardware register.
value_type modify(value_type clear_bits, value_type set_bits)
clears bits in clear_bits and sets bits in set_bits in the hardware register.
value_type set(value_type set_bits)
set bits in set_bits in the hardware register.
void write(value_type val)
write val into the hardware register.
Register_tmpl & operator=(value_type val)
write val into the hardware register.
Ro_register operator[](unsigned offset) const
Read only access to register at offset offset.
Ro_register_tmpl< BITS, Block > r(unsigned offset) const
Read only access to register at offset offset.
Single read only register inside a Register_block_base interface.
value_type read() const
read the value from the hardware register.
unsigned long l4_addr_t
Address type.
unsigned char l4_uint8_t
Unsigned 8bit value.
unsigned int l4_uint32_t
Unsigned 32bit value.
unsigned short int l4_uint16_t
Unsigned 16bit value.
unsigned long long l4_uint64_t
Unsigned 64bit value.
Common L4 ABI Data Types.
Abstract register block interface.
Implementation helper for register blocks.