diff --git a/base/include/util/register.h b/base/include/util/register.h index ef7f9fb833..df3a6a81f9 100644 --- a/base/include/util/register.h +++ b/base/include/util/register.h @@ -247,6 +247,36 @@ namespace Genode { return Bits_0::bits(v) | Bits_1::bits(v >> Bits_0::WIDTH); } + + /** + * Override bitset in a given register value + * + * \param T access type of register + * \param reg register value + * \param value new bitset value + */ + template + static inline void set(T & reg, access_t const value) + { + Bits_0::clear(reg); + Bits_1::clear(reg); + Bits_0::set(reg, value); + Bits_1::set(reg, value >> Bits_0::WIDTH); + }; + + /** + * Read bitset from a given register value + * + * \param T access type of register + * \param reg register value + * + * \return bitset value + */ + template + static inline access_t get(T const reg) + { + return Bits_0::get(reg) | (Bits_1::get(reg) << Bits_0::WIDTH); + } }; /** @@ -263,6 +293,7 @@ namespace Genode typedef _BITS_0 Bits_0; typedef _BITS_1 Bits_1; typedef _BITS_2 Bits_2; + typedef Bitset_2 Bits_0_1; enum { WIDTH = Bits_0::BITFIELD_WIDTH + Bits_1::BITFIELD_WIDTH + @@ -282,9 +313,39 @@ namespace Genode template static inline T bits(T const v) { - typedef Bitset_2 Bits_0_1; return Bits_0_1::bits(v) | Bits_2::bits(v >> Bits_0_1::WIDTH); } + + /** + * Override bitset in a given register value + * + * \param T access type of register + * \param reg register value + * \param value new bitset value + */ + template + static inline void set(T & reg, access_t const value) + { + Bits_0::clear(reg); + Bits_1::clear(reg); + Bits_2::clear(reg); + Bits_0_1::set(reg, value); + Bits_2::set(reg, value >> Bits_0_1::WIDTH); + }; + + /** + * Read bitset from a given register value + * + * \param T access type of register + * \param reg register value + * + * \return bitset value + */ + template + static inline access_t get(T const reg) + { + return Bits_0_1::get(reg) | (Bits_2::get(reg) << Bits_0_1::WIDTH); + } }; } diff --git a/base/src/test/util_mmio/main.cc b/base/src/test/util_mmio/main.cc index a0e385eb8b..dd1140c3fe 100644 --- a/base/src/test/util_mmio/main.cc +++ b/base/src/test/util_mmio/main.cc @@ -132,12 +132,11 @@ struct Test_mmio : public Mmio { struct Bits_0 : Bitfield<4, 5> { }; struct Bits_1 : Bitfield<17, 12> { }; - struct Bits_2 : Bitfield<1, 3> { }; }; struct My_bitset_2 : Bitset_2 { }; struct My_bitset_3 : Bitset_3 { }; struct My_bitset_4 : Bitset_2 { }; - struct My_bitset_5 : Bitset_3 { }; + struct My_bitset_5 : Bitset_3 { }; }; @@ -471,9 +470,18 @@ int main() return test_failed(19); /** - * Test 20, bitfield methods of bitsets + * Test 20, bitfield methods at bitsets */ - if (Test_mmio::My_bitset_5::bits(0b110010110) != 0b1100000010001010) { + Test_mmio::Reg_1::access_t bs5 = + Test_mmio::My_bitset_5::bits(0b1011110010110); + if (bs5 != 0b1100000010001010) { + return test_failed(20); + } + if (Test_mmio::My_bitset_5::get(bs5) != 0b110010110) { + return test_failed(20); + } + Test_mmio::My_bitset_5::set(bs5, 0b1011101101001); + if (bs5 != 0b1011000001000100) { return test_failed(20); }