libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
mem_rw_optional.h
1#pragma once
2
3#include "libmicroemu/internal/bus/mem_access_results.h"
4#include "libmicroemu/types.h"
5#include <cassert>
6#include <type_traits>
7
8namespace libmicroemu::internal {
9
19template <unsigned Id, typename TCpuAccessor, typename TEndianessC> class MemRwOptional {
20public:
21 static constexpr bool kReadOnly = false;
22
26 explicit MemRwOptional(u8 *const buf, const me_size_t buf_size, const me_adr_t vadr_offset)
27 : buf_(buf), vadr_offset_(vadr_offset), buf_size_(buf_size) {}
28
32 virtual ~MemRwOptional() = default;
33
38 MemRwOptional(const MemRwOptional &r_src) = default;
39
44 MemRwOptional &operator=(const MemRwOptional &r_src) = default;
45
50 MemRwOptional(MemRwOptional &&r_src) = default;
51
57
58 template <typename T> ReadResult<T> Read(TCpuAccessor &cpua, me_adr_t vadr) const {
59 // clang-format off
60 static_assert(
61 std::is_same<T, u32>::value ||
62 std::is_same<T, u16>::value ||
63 std::is_same<T, u8>::value,
64 "Read only allows u32, u16 and u8");
65 // clang-format on
66 static_cast<void>(cpua);
67
68 assert(buf_ != nullptr && buf_size_ != 0U);
69
70 const me_adr_t padr = ConvertToPhysicalAdr(vadr);
71 assert(IsPAdrInRange(padr) == true);
72 T val = *reinterpret_cast<const T *>(&buf_[padr]);
73 T cval = TEndianessC::template Convert<T>(val);
74
75 return ReadResult<T>{cval, ReadStatusCode::kOk};
76 }
77
78 template <typename T> WriteResult<T> Write(TCpuAccessor &cpua, me_adr_t vadr, T value) const {
79 // clang-format off
80 static_assert(
81 std::is_same<T, u32>::value ||
82 std::is_same<T, u16>::value ||
83 std::is_same<T, u8>::value,
84 "Write only allows u32, u16 and u8 types");
85 // clang-format on
86 static_cast<void>(cpua);
87
88 assert(buf_ != nullptr && buf_size_ != 0U);
89 const me_adr_t padr = ConvertToPhysicalAdr(vadr);
90 assert(IsPAdrInRange(padr) == true);
91
92 *reinterpret_cast<T *const>(&buf_[padr]) = value;
93
94 return WriteResult<T>{WriteStatusCode::kOk};
95 }
96
97 bool IsVAdrInRange(me_adr_t vadr) const {
98 // if no buffer was assigned always return that this memory has to valid access range
99 if (buf_ == nullptr || buf_size_ == 0U) {
100 return false;
101 }
102
103 const me_adr_t padr = ConvertToPhysicalAdr(vadr);
104 if (IsPAdrInRange(padr) == false) {
105 return false;
106 }
107 return true;
108 }
109
110private:
111 u8 *const buf_{nullptr};
112 const me_adr_t vadr_offset_{0U};
113 const me_size_t buf_size_{0U};
114
115 me_adr_t ConvertToPhysicalAdr(me_adr_t vadr) const { return vadr - vadr_offset_; }
116 bool IsPAdrInRange(me_adr_t padr) const { return padr < buf_size_; }
117};
118
119} // namespace libmicroemu::internal
MemRwOptional & operator=(const MemRwOptional &r_src)=default
Copy assignment operator for MemOpt.
virtual ~MemRwOptional()=default
Destructor.
MemRwOptional(const MemRwOptional &r_src)=default
Copy constructor for MemOpt.
MemRwOptional(MemRwOptional &&r_src)=default
Move constructor for MemOpt.
MemRwOptional & operator=(MemRwOptional &&r_src)=default
Move assignment operator for MemOpt.
MemRwOptional(u8 *const buf, const me_size_t buf_size, const me_adr_t vadr_offset)
Constructor.
Definition mem_rw_optional.h:26
The libmicroemu::internal namespace contains all classes and functions of libmicroemu which are priva...
Definition bkpt_flags.h:6
Definition mem_access_results.h:11
Definition mem_access_results.h:21