diff --git a/single/cppreg-all.h b/single/cppreg-all.h index 4b23096..a677303 100644 --- a/single/cppreg-all.h +++ b/single/cppreg-all.h @@ -34,17 +34,17 @@ namespace cppreg { (mask == type_mask::value) && (offset == 0u); template inline static T read( - const MMIO_t* const mmio_device, + const MMIO_t& mmio_device, typename std::enable_if::type = nullptr ) noexcept { - return static_cast((*mmio_device & mask) >> offset); + return static_cast((mmio_device & mask) >> offset); }; template inline static T read( - const MMIO_t* const mmio_device, + const MMIO_t& mmio_device, typename std::enable_if::type = nullptr ) noexcept { - return static_cast(*mmio_device); + return static_cast(mmio_device); }; }; template @@ -53,21 +53,21 @@ namespace cppreg { (mask == type_mask::value) && (offset == 0u); template inline static void write( - MMIO_t* const mmio_device, + MMIO_t& mmio_device, T value, typename std::enable_if::type = nullptr ) noexcept { - *mmio_device = static_cast( - (*mmio_device & ~mask) | ((value << offset) & mask) + mmio_device = static_cast( + (mmio_device & ~mask) | ((value << offset) & mask) ); }; template inline static void write( - MMIO_t* const mmio_device, + MMIO_t& mmio_device, T value, typename std::enable_if::type = nullptr ) noexcept { - *mmio_device = value; + mmio_device = value; }; }; template @@ -76,66 +76,66 @@ namespace cppreg { (mask == type_mask::value) && (offset == 0u); template inline static void write( - MMIO_t* const mmio_device, + MMIO_t& mmio_device, typename std::enable_if::type = nullptr ) noexcept { - *mmio_device = static_cast( - (*mmio_device & ~mask) | ((value << offset) & mask) + mmio_device = static_cast( + (mmio_device & ~mask) | ((value << offset) & mask) ); }; template inline static void write( - MMIO_t* const mmio_device, + MMIO_t& mmio_device, typename std::enable_if::type = nullptr ) noexcept { - *mmio_device = value; + mmio_device = value; }; }; struct read_only { template - inline static T read(const MMIO_t* const mmio_device) noexcept { + inline static T read(const MMIO_t& mmio_device) noexcept { return RegisterRead::read(mmio_device); }; }; struct read_write : read_only { template - inline static void write(MMIO_t* const mmio_device, + inline static void write(MMIO_t& mmio_device, const T value) noexcept { RegisterWrite::write(mmio_device, value); }; template - inline static void write(MMIO_t* const mmio_device) noexcept { + inline static void write(MMIO_t& mmio_device) noexcept { RegisterWriteConstant ::write(mmio_device); }; template - inline static void set(MMIO_t* const mmio_device) + inline static void set(MMIO_t& mmio_device) noexcept { RegisterWriteConstant ::write(mmio_device); }; template - inline static void clear(MMIO_t* const mmio_device) + inline static void clear(MMIO_t& mmio_device) noexcept { RegisterWriteConstant ::write(mmio_device); }; template - inline static void toggle(MMIO_t* const mmio_device) + inline static void toggle(MMIO_t& mmio_device) noexcept { - *mmio_device = static_cast((*mmio_device) ^ mask); + mmio_device = static_cast((mmio_device) ^ mask); }; }; struct write_only { template - inline static void write(MMIO_t* const mmio_device, + inline static void write(MMIO_t& mmio_device, const T value) noexcept { RegisterWrite::value, 0u>::write( mmio_device, ((value << offset) & mask) ); }; template - inline static void write(MMIO_t* const mmio_device) noexcept { + inline static void write(MMIO_t& mmio_device) noexcept { RegisterWriteConstant< MMIO_t, T, type_mask::value, 0u, ((value << offset) & mask) > @@ -200,20 +200,14 @@ namespace cppreg { #ifndef CPPREG_SHADOWVALUE_H #define CPPREG_SHADOWVALUE_H namespace cppreg { - template - struct Shadow { - constexpr static const bool use_shadow = false; + template struct Shadow : std::false_type {}; + template + struct Shadow : std::true_type { + static typename Register::type shadow_value; }; template - struct Shadow { - static typename Register::type value; - constexpr static const bool use_shadow = true; - }; - template - typename Register::type Shadow::value = + typename Register::type Shadow::shadow_value = Register::reset; - template - constexpr const bool Shadow::use_shadow; } #endif @@ -230,7 +224,7 @@ namespace cppreg { public: using base_type = typename Register::type; private: - static_assert(!Register::shadow::use_shadow, + static_assert(!Register::shadow::value, "merge write is not available for shadow value register"); constexpr static const base_type _accumulated_value = ((value << offset) & mask); @@ -244,8 +238,8 @@ namespace cppreg { MergeWrite_tmpl operator=(MergeWrite_tmpl) = delete; MergeWrite_tmpl(MergeWrite_tmpl&&) = delete; inline void done() const && noexcept { - typename Register::MMIO_t* const mmio_device = - Register::rw_mem_pointer(); + typename Register::MMIO_t& mmio_device = + Register::rw_mem_device(); RegisterWriteConstant< typename Register::MMIO_t, typename Register::type, @@ -295,8 +289,8 @@ namespace cppreg { MergeWrite& operator=(const MergeWrite&) = delete; MergeWrite& operator=(MergeWrite&&) = delete; inline void done() const && noexcept { - typename Register::MMIO_t* const mmio_device = - Register::rw_mem_pointer(); + typename Register::MMIO_t& mmio_device = + Register::rw_mem_device(); RegisterWrite< typename Register::MMIO_t, base_type, @@ -317,7 +311,7 @@ namespace cppreg { base_type, F::mask, F::offset - >(&_accumulated_value, value); + >(_accumulated_value, value); return std::move( MergeWrite @@ -325,7 +319,7 @@ namespace cppreg { ); }; private: - static_assert(!Register::shadow::use_shadow, + static_assert(!Register::shadow::value, "merge write is not available for shadow value register"); constexpr MergeWrite() : _accumulated_value(0u) {}; constexpr MergeWrite(const base_type v) : _accumulated_value(v) {}; @@ -351,11 +345,11 @@ namespace cppreg { constexpr static const Width_t size = RegWidth; constexpr static const type reset = ResetValue; using shadow = Shadow; - static MMIO_t* rw_mem_pointer() { - return reinterpret_cast(base_address); + static MMIO_t& rw_mem_device() { + return *(reinterpret_cast(base_address)); }; - static const MMIO_t* ro_mem_pointer() { - return reinterpret_cast(base_address); + static const MMIO_t& ro_mem_device() { + return *(reinterpret_cast(base_address)); }; template inline static MergeWrite @@ -387,6 +381,53 @@ namespace cppreg { static_assert(RegWidth != 0u, "defining a Register type of width 0u is not allowed"); }; + template < + Address_t PackBase, + std::uint32_t PackByteSize + > struct RegisterPack { + using mem_array_t = std::array; + constexpr static const Address_t pack_base = PackBase; + constexpr static const std::uint32_t size_in_bytes = PackByteSize; + static mem_array_t& _mem_array; + }; + 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) + ); + template < + typename RegisterPack, + Width_t RegWidth, + std::uint32_t OffsetInPack + > + struct PackedRegister : + Register { + using base_reg = Register< + RegisterPack::pack_base + OffsetInPack * 8, RegWidth + >; + static typename base_reg::MMIO_t& rw_mem_device() { + return RegisterPack::_mem_array[OffsetInPack]; + }; + static const typename base_reg::MMIO_t& ro_mem_device() { + return RegisterPack::_mem_array[OffsetInPack]; + }; + static_assert((OffsetInPack + (RegWidth / 8u)) <= + RegisterPack::size_in_bytes, + "packed register is overflowing the pack"); + }; + template + struct PackIndexing { + template + using type = typename std::tuple_element>::type; + template + using regs = typename std::tuple_element>::type; + }; } #endif @@ -410,7 +451,7 @@ namespace cppreg { constexpr static const type mask = make_shifted_mask(width, offset); constexpr static const bool has_shadow = - parent_register::shadow::use_shadow; + parent_register::shadow::value; template struct check_overflow { constexpr static const bool result = @@ -422,7 +463,7 @@ namespace cppreg { }; inline static type read() noexcept { return policy::template read( - parent_register::ro_mem_pointer() + parent_register::ro_mem_device() ); }; template @@ -430,7 +471,7 @@ namespace cppreg { write(const typename std::enable_if::type value) noexcept { policy::template write( - parent_register::rw_mem_pointer(), + parent_register::rw_mem_device(), value ); }; @@ -439,10 +480,10 @@ namespace cppreg { write(const typename std::enable_if::type value) noexcept { RegisterWrite - ::write(&parent_register::shadow::value, value); + ::write(parent_register::shadow::shadow_value, value); policy::template write::value, 0u>( - parent_register::rw_mem_pointer(), - parent_register::shadow::value + parent_register::rw_mem_device(), + parent_register::shadow::shadow_value ); }; template @@ -455,7 +496,7 @@ namespace cppreg { >::type write() noexcept { policy::template write( - parent_register::rw_mem_pointer() + parent_register::rw_mem_device() ); }; template @@ -471,15 +512,15 @@ namespace cppreg { }; inline static void set() noexcept { policy::template - set(parent_register::rw_mem_pointer()); + set(parent_register::rw_mem_device()); }; inline static void clear() noexcept { policy::template - clear(parent_register::rw_mem_pointer()); + clear(parent_register::rw_mem_device()); }; inline static void toggle() noexcept { policy::template - toggle(parent_register::rw_mem_pointer()); + toggle(parent_register::rw_mem_device()); }; inline static bool is_set() noexcept { return (Field::read() == (mask >> offset));