mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-11 06:54:18 +00:00
parent
e272264cb2
commit
d4e435d732
@ -508,6 +508,67 @@ namespace Genode
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
** Access to bitsets **
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read bitset 'T' (composed of 2 parts)
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline typename T::Bitset_2_base::access_t const read()
|
||||||
|
{
|
||||||
|
typedef typename T::Bitset_2_base::Bits_0 Bits_0;
|
||||||
|
typedef typename T::Bitset_2_base::Bits_1 Bits_1;
|
||||||
|
return read<Bits_0>() |
|
||||||
|
(read<Bits_1>() << Bits_0::BITFIELD_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override bitset 'T' (composed of 2 parts)
|
||||||
|
*
|
||||||
|
* \param v value that shall be written
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline void write(typename T::Bitset_2_base::access_t v)
|
||||||
|
{
|
||||||
|
typedef typename T::Bitset_2_base::Bits_0 Bits_0;
|
||||||
|
typedef typename T::Bitset_2_base::Bits_1 Bits_1;
|
||||||
|
write<Bits_0>(v);
|
||||||
|
write<Bits_1>(v >> Bits_0::BITFIELD_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read bitset 'T' (composed of 3 parts)
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline typename T::Bitset_3_base::access_t const read()
|
||||||
|
{
|
||||||
|
typedef typename T::Bitset_3_base::Bits_0 Bits_0;
|
||||||
|
typedef typename T::Bitset_3_base::Bits_1 Bits_1;
|
||||||
|
typedef typename T::Bitset_3_base::Bits_2 Bits_2;
|
||||||
|
return read<Bitset_2<Bits_0, Bits_1> >() |
|
||||||
|
(read<Bits_2>() << (Bits_0::BITFIELD_WIDTH +
|
||||||
|
Bits_1::BITFIELD_WIDTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override bitset 'T' (composed of 3 parts)
|
||||||
|
*
|
||||||
|
* \param v value that shall be written
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline void write(typename T::Bitset_3_base::access_t v)
|
||||||
|
{
|
||||||
|
typedef typename T::Bitset_3_base::Bits_0 Bits_0;
|
||||||
|
typedef typename T::Bitset_3_base::Bits_1 Bits_1;
|
||||||
|
typedef typename T::Bitset_3_base::Bits_2 Bits_2;
|
||||||
|
write<Bitset_2<Bits_0, Bits_1> >(v);
|
||||||
|
write<Bits_2>(v >> (Bits_0::BITFIELD_WIDTH +
|
||||||
|
Bits_1::BITFIELD_WIDTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************
|
/*********************************
|
||||||
** Polling for bitfield states **
|
** Polling for bitfield states **
|
||||||
*********************************/
|
*********************************/
|
||||||
|
@ -20,7 +20,20 @@
|
|||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
namespace Trait {
|
namespace Trait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Round bit width up to an appropriate uint width or 0 if not feasible
|
||||||
|
*/
|
||||||
|
template <unsigned _WIDTH>
|
||||||
|
struct Raise_to_uint_width
|
||||||
|
{
|
||||||
|
enum { WIDTH = _WIDTH < 2 ? 1 :
|
||||||
|
_WIDTH < 9 ? 8 :
|
||||||
|
_WIDTH < 17 ? 16 :
|
||||||
|
_WIDTH < 33 ? 32 :
|
||||||
|
_WIDTH < 65 ? 64 : 0, };
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties of integer types with a given bitwidth
|
* Properties of integer types with a given bitwidth
|
||||||
@ -113,6 +126,7 @@ namespace Genode
|
|||||||
enum {
|
enum {
|
||||||
ACCESS_WIDTH = _ACCESS_WIDTH,
|
ACCESS_WIDTH = _ACCESS_WIDTH,
|
||||||
ACCESS_WIDTH_LOG2 = Trait::Uint_width<ACCESS_WIDTH>::WIDTH_LOG2,
|
ACCESS_WIDTH_LOG2 = Trait::Uint_width<ACCESS_WIDTH>::WIDTH_LOG2,
|
||||||
|
BITFIELD_WIDTH = ACCESS_WIDTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Trait::Uint_width<ACCESS_WIDTH>::Type access_t;
|
typedef typename Trait::Uint_width<ACCESS_WIDTH>::Type access_t;
|
||||||
@ -137,6 +151,7 @@ namespace Genode
|
|||||||
*/
|
*/
|
||||||
SHIFT = _SHIFT,
|
SHIFT = _SHIFT,
|
||||||
WIDTH = _WIDTH,
|
WIDTH = _WIDTH,
|
||||||
|
BITFIELD_WIDTH = WIDTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,6 +213,54 @@ namespace Genode
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitfield that is composed of 2 separate parts
|
||||||
|
*
|
||||||
|
* \param _BITS_X Register, bitfield or/and bitset types the
|
||||||
|
* bitset is composed of. The order of arguments
|
||||||
|
* is also the order of bit significance starting
|
||||||
|
* with the least.
|
||||||
|
*/
|
||||||
|
template <typename _BITS_0, typename _BITS_1>
|
||||||
|
struct Bitset_2
|
||||||
|
{
|
||||||
|
typedef _BITS_0 Bits_0;
|
||||||
|
typedef _BITS_1 Bits_1;
|
||||||
|
enum {
|
||||||
|
WIDTH = Bits_0::BITFIELD_WIDTH +
|
||||||
|
Bits_1::BITFIELD_WIDTH,
|
||||||
|
BITFIELD_WIDTH = WIDTH,
|
||||||
|
ACCESS_WIDTH = Trait::Raise_to_uint_width<WIDTH>::WIDTH,
|
||||||
|
};
|
||||||
|
typedef typename Trait::Uint_width<ACCESS_WIDTH>::Type access_t;
|
||||||
|
typedef Bitset_2<Bits_0, Bits_1> Bitset_2_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitfield that is composed of 3 separate parts
|
||||||
|
*
|
||||||
|
* \param _BITS_X Register, bitfield or/and bitset types the
|
||||||
|
* bitset is composed of. The order of arguments
|
||||||
|
* is also the order of bit significance starting
|
||||||
|
* with the least.
|
||||||
|
*/
|
||||||
|
template <typename _BITS_0, typename _BITS_1, typename _BITS_2>
|
||||||
|
struct Bitset_3
|
||||||
|
{
|
||||||
|
typedef _BITS_0 Bits_0;
|
||||||
|
typedef _BITS_1 Bits_1;
|
||||||
|
typedef _BITS_2 Bits_2;
|
||||||
|
enum {
|
||||||
|
WIDTH = Bits_0::BITFIELD_WIDTH +
|
||||||
|
Bits_1::BITFIELD_WIDTH +
|
||||||
|
Bits_2::BITFIELD_WIDTH,
|
||||||
|
BITFIELD_WIDTH = WIDTH,
|
||||||
|
ACCESS_WIDTH = Trait::Raise_to_uint_width<WIDTH>::WIDTH,
|
||||||
|
};
|
||||||
|
typedef typename Trait::Uint_width<ACCESS_WIDTH>::Type access_t;
|
||||||
|
typedef Bitset_3<Bits_0, Bits_1, Bits_2> Bitset_3_base;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _INCLUDE__UTIL__REGISTER_H_ */
|
#endif /* _INCLUDE__UTIL__REGISTER_H_ */
|
||||||
|
@ -119,6 +119,22 @@ struct Test_mmio : public Mmio
|
|||||||
struct A : Bitfield<3,2> { };
|
struct A : Bitfield<3,2> { };
|
||||||
struct B : Bitfield<30,4> { };
|
struct B : Bitfield<30,4> { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Reg_0 : Register<0x1, 8> { };
|
||||||
|
|
||||||
|
struct Reg_1 : Register<0x2, 16>
|
||||||
|
{
|
||||||
|
struct Bits_0 : Bitfield<1, 3> { };
|
||||||
|
struct Bits_1 : Bitfield<12, 4> { };
|
||||||
|
};
|
||||||
|
struct Reg_2 : Register<0x4, 32>
|
||||||
|
{
|
||||||
|
struct Bits_0 : Bitfield<4, 5> { };
|
||||||
|
struct Bits_1 : Bitfield<17, 12> { };
|
||||||
|
};
|
||||||
|
struct My_bitset_2 : Bitset_2<Reg_1::Bits_0, Reg_0> { };
|
||||||
|
struct My_bitset_3 : Bitset_3<Reg_0, Reg_2::Bits_1, Reg_2::Bits_0> { };
|
||||||
|
struct My_bitset_4 : Bitset_2<My_bitset_2, Reg_2::Bits_0> { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -418,6 +434,39 @@ int main()
|
|||||||
if (compare_mem(mmio_mem, mmio_cmpr_16, sizeof(mmio_mem))) {
|
if (compare_mem(mmio_mem, mmio_cmpr_16, sizeof(mmio_mem))) {
|
||||||
return test_failed(16); }
|
return test_failed(16); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 17, write and read a bitset with 2 parts
|
||||||
|
*/
|
||||||
|
zero_mem(mmio_mem, sizeof(mmio_mem));
|
||||||
|
mmio.write<Test_mmio::My_bitset_2>(0x1234);
|
||||||
|
static uint8_t mmio_cmpr_17[MMIO_SIZE] = {0x00,0x46,0x08,0x00,0x00,0x00,0x00,0x00};
|
||||||
|
if (compare_mem(mmio_mem, mmio_cmpr_17, sizeof(mmio_mem)))
|
||||||
|
return test_failed(17);
|
||||||
|
if (mmio.read<Test_mmio::My_bitset_2>() != 0x234)
|
||||||
|
return test_failed(17);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 18, write and read a bitset with 3 parts
|
||||||
|
*/
|
||||||
|
zero_mem(mmio_mem, sizeof(mmio_mem));
|
||||||
|
mmio.write<Test_mmio::My_bitset_3>(0x12345678);
|
||||||
|
static uint8_t mmio_cmpr_18[MMIO_SIZE] = {0x00,0x78,0x00,0x00,0x30,0x00,0xac,0x08};
|
||||||
|
if (compare_mem(mmio_mem, mmio_cmpr_18, sizeof(mmio_mem)))
|
||||||
|
return test_failed(18);
|
||||||
|
if (mmio.read<Test_mmio::My_bitset_3>() != 0x345678)
|
||||||
|
return test_failed(18);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test 19, write and read a nested bitset
|
||||||
|
*/
|
||||||
|
zero_mem(mmio_mem, sizeof(mmio_mem));
|
||||||
|
mmio.write<Test_mmio::My_bitset_4>(0x5679);
|
||||||
|
static uint8_t mmio_cmpr_19[MMIO_SIZE] = {0x00,0xcf,0x02,0x00,0xa0,0x00,0x00,0x00};
|
||||||
|
if (compare_mem(mmio_mem, mmio_cmpr_19, sizeof(mmio_mem)))
|
||||||
|
return test_failed(19);
|
||||||
|
if (mmio.read<Test_mmio::My_bitset_4>() != 0x5679)
|
||||||
|
return test_failed(19);
|
||||||
|
|
||||||
printf("Test done\n");
|
printf("Test done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user