diff --git a/CMakeLists.txt b/CMakeLists.txt index a107da8..aec08ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(CPPREG_API_HEADERS register/Mask.h register/Overflow.h register/Register.h + register/RegisterPack.h register/ShadowValue.h register/Traits.h) diff --git a/register/Register.h b/register/Register.h index b98ca27..a964acd 100644 --- a/register/Register.h +++ b/register/Register.h @@ -124,120 +124,6 @@ namespace cppreg { }; - //! Register pack base implementation. - /** - * @tparam PackBase Base address to use for the pack memory. - * @tparam PackByteSize Size in bytes of the memory region for the pack. - */ - template < - Address_t PackBase, - std::uint32_t PackByteSize - > struct RegisterPack { - - //! Type alias for byte array. - using mem_array_t = std::array; - - //! Base address. - constexpr static const Address_t pack_base = PackBase; - - //! Pack size in bytes. - constexpr static const std::uint32_t size_in_bytes = PackByteSize; - - //! Reference to the byte array. - /** - * This is explicitly defined below. - */ - static mem_array_t& _mem_array; - - }; - - //! RegisterPack byte array reference definition. - template < - Address_t PackBase, - std::uint32_t PackByteSize - > - typename RegisterPack::mem_array_t& - RegisterPack::_mem_array = - *( - reinterpret_cast< - RegisterPack::mem_array_t* const - >(RegisterPack::pack_base) - ); - - - //! Packed register implementation. - /** - * @tparam RegisterPack Pack to which the register belongs. - * @tparam RegWidth Register total width in bits. - * @tparam OffsetInPack Register offset in the pack in bytes. - * @tparam reset Register reset value (0x0 if unknown). - * @tparam shadow Boolean flag to enable shadow value (enabled if `true`). - * - * This implementation is intended to be used when defining a register - * that belongs to a type. - */ - template < - typename RegisterPack, - Width_t RegWidth, - std::uint32_t OffsetInPack, - typename RegisterType::type ResetValue = 0x0, - bool UseShadow = false - > - struct PackedRegister : - Register< - RegisterPack::pack_base + OffsetInPack * 8, - RegWidth, - ResetValue, - UseShadow - > { - - //! Register type. - using base_reg = Register< - RegisterPack::pack_base + OffsetInPack * 8, - RegWidth, - ResetValue, - UseShadow - >; - - //! Memory modifier. - /** - * @return A reference to the writable register memory. - */ - static typename base_reg::MMIO_t& rw_mem_device() { - return RegisterPack::_mem_array[OffsetInPack]; - }; - - //! Memory accessor. - /** - * @return A reference to the read-only register memory. - */ - static const typename base_reg::MMIO_t& ro_mem_device() { - return RegisterPack::_mem_array[OffsetInPack]; - }; - - // Safety check to detect if are overflowing the pack. - static_assert((OffsetInPack + (RegWidth / 8u)) <= - RegisterPack::size_in_bytes, - "packed register is overflowing the pack"); - - }; - - - //! Pack indexing structure. - /** - * @tparam T List of types (registers or fields) to index. - * - * This can be used to conveniently map indices over packed registers. - * The order in the variadic parameter pack will define the indexing - * (starting at zero). - */ - template - struct PackIndexing { - template - using regs = typename std::tuple_element>::type; - }; - - } diff --git a/register/RegisterPack.h b/register/RegisterPack.h new file mode 100644 index 0000000..e99bb5d --- /dev/null +++ b/register/RegisterPack.h @@ -0,0 +1,158 @@ +//! Register pack implementation. +/** + * @file RegisterPack.h + * @author Nicolas Clauvelin (nclauvelin@sendyne.com) + * @copyright Copyright 2010-2018 Sendyne Corp. All rights reserved. + * + * This header provides the definitions related to register implementation. + */ + + +#include "Register.h" + + +#ifndef CPPREG_REGISTERPACK_H +#define CPPREG_REGISTERPACK_H + + +//! cppreg namespace. +namespace cppreg { + + + //! Register pack base implementation. + /** + * @tparam PackBase Base address to use for the pack memory. + * @tparam PackByteSize Size in bytes of the memory region for the pack. + */ + template < + Address_t PackBase, + std::uint32_t PackByteSize + > struct RegisterPack { + + //! Type alias for byte array. + using mem_array_t = std::array; + + //! Base address. + constexpr static const Address_t pack_base = PackBase; + + //! Pack size in bytes. + constexpr static const std::uint32_t size_in_bytes = PackByteSize; + + //! Reference to the byte array. + /** + * This is explicitly defined below. + */ + static mem_array_t& _mem_array; + + }; + + //! RegisterPack byte array reference definition. + template < + Address_t PackBase, + std::uint32_t PackByteSize + > + typename RegisterPack::mem_array_t& + RegisterPack::_mem_array = + *( + reinterpret_cast< + RegisterPack::mem_array_t* const + >(RegisterPack::pack_base) + ); + + + //! Packed register implementation. + /** + * @tparam RegisterPack Pack to which the register belongs. + * @tparam RegWidth Register total width in bits. + * @tparam OffsetInPack Register offset in the pack in bytes. + * @tparam reset Register reset value (0x0 if unknown). + * @tparam shadow Boolean flag to enable shadow value (enabled if `true`). + * + * This implementation is intended to be used when defining a register + * that belongs to a type. + */ + template < + typename RegisterPack, + Width_t RegWidth, + std::uint32_t OffsetInPack, + typename RegisterType::type ResetValue = 0x0, + bool UseShadow = false + > + struct PackedRegister : + Register< + RegisterPack::pack_base + OffsetInPack * 8, + RegWidth, + ResetValue, + UseShadow + > { + + //! Register type. + using base_reg = Register< + RegisterPack::pack_base + OffsetInPack * 8, + RegWidth, + ResetValue, + UseShadow + >; + + //! Memory modifier. + /** + * @return A reference to the writable register memory. + */ + static typename base_reg::MMIO_t& rw_mem_device() { + return RegisterPack::_mem_array[OffsetInPack]; + }; + + //! Memory accessor. + /** + * @return A reference to the read-only register memory. + */ + static const typename base_reg::MMIO_t& ro_mem_device() { + return RegisterPack::_mem_array[OffsetInPack]; + }; + + // Safety check to detect if are overflowing the pack. + static_assert((OffsetInPack + (RegWidth / 8u)) <= + RegisterPack::size_in_bytes, + "packed register is overflowing the pack"); + + }; + + + //! Pack indexing structure. + /** + * @tparam T List of types (registers or fields) to index. + * + * This can be used to conveniently map indices over packed registers. + * The order in the variadic parameter pack will define the indexing + * (starting at zero). + */ + template + struct PackIndexing { + template + using regs = typename std::tuple_element>::type; + }; + + + //! Template for loop implementation. + template + struct for_loop { + template