18template <
typename TCpuStates,
typename TLogger = NullLogger>
class SpecRegOps {
35 return "SYSTICK_CALIB";
43 template <SpecialRegisterId SId>
static inline u32 ReadRegister(
const TCpuStates &cpus) {
44 constexpr auto RegId =
static_cast<u8
>(SId);
49 return ReadEpsr(cpus);
51 return ReadXpsr(cpus);
53 return ReadControl(cpus);
56 return cpus.GetSpecialRegisters()[RegId];
62 static inline u32 ReadRegister(
const TCpuStates &cpus,
const SpecialRegisterId ®_id) {
66 return ReadEpsr(cpus);
68 return ReadXpsr(cpus);
70 return ReadControl(cpus);
73 return cpus.GetSpecialRegisters()[
static_cast<u8
>(reg_id)];
79 template <SpecialRegisterId SId>
static inline void WriteRegister(TCpuStates &cpus, u32 value) {
80 constexpr auto RegId =
static_cast<u8
>(SId);
85 return WriteEpsr(cpus, value);
87 return WriteXpsr(cpus, value);
89 return WriteControl(cpus, value);
92 cpus.GetSpecialRegisters()[RegId] = value;
98 static inline void WriteRegister(TCpuStates &cpus,
const SpecialRegisterId ®_id, u32 value) {
102 return WriteEpsr(cpus, value);
104 return WriteXpsr(cpus, value);
106 return WriteControl(cpus, value);
108 const auto rid =
static_cast<u8
>(reg_id);
110 cpus.GetSpecialRegisters()[rid] = value;
114 static inline u32 ReadEpsr(
const TCpuStates &cpus) {
116 auto sys_ctrl = ReadRegister<SpecialRegisterId::kSysCtrl>(cpus);
117 auto BitT = (sys_ctrl & SysCtrlRegister::kTMsk) >> SysCtrlRegister::kTPos;
118 epsr |= BitT << EpsrRegister::kTPos;
121 auto istate = ReadRegister<SpecialRegisterId::kIstate>(cpus);
122 auto it_1_0 = (istate & IstateRegister::kItBit1to0Msk) >> IstateRegister::kItBit0Pos;
123 auto it_7_2 = (istate & IstateRegister::kItBit7to2Msk) >> IstateRegister::kItBit2Pos;
124 epsr |= (it_1_0 << EpsrRegister::kItBit0Pos) | (it_7_2 << EpsrRegister::kItBit2Pos);
128 static inline void WriteEpsr(TCpuStates &cpus, u32 value) {
129 auto sys_ctrl = ReadRegister<SpecialRegisterId::kSysCtrl>(cpus);
130 auto BitT = (value & EpsrRegister::kTMsk) >> EpsrRegister::kTPos;
132 sys_ctrl |= BitT << SysCtrlRegister::kTPos;
133 WriteRegister<SpecialRegisterId::kSysCtrl>(cpus, sys_ctrl);
137 auto it_1_0 = (value & EpsrRegister::kItBit1to0Msk) >> EpsrRegister::kItBit0Pos;
138 auto it_7_2 = (value & EpsrRegister::kItBit7to2Msk) >> EpsrRegister::kItBit2Pos;
139 istate |= (it_1_0 << IstateRegister::kItBit0Pos) | (it_7_2 << IstateRegister::kItBit2Pos);
140 WriteRegister<SpecialRegisterId::kIstate>(cpus, istate);
143 static inline u32 ReadXpsr(
const TCpuStates &cpus) {
145 auto apsr = ReadRegister<SpecialRegisterId::kApsr>(cpus);
148 auto epsr = ReadEpsr(cpus);
151 auto ipsr = ReadRegister<SpecialRegisterId::kIpsr>(cpus);
157 static inline void WriteXpsr(TCpuStates &cpus, u32 value) {
158 static_cast<void>(cpus);
159 static_cast<void>(value);
160 assert(
false &&
"Not implemented");
163 static inline u32 ReadControl(
const TCpuStates &cpus) {
164 const auto sys_ctrl = ReadRegister<SpecialRegisterId::kSysCtrl>(cpus);
165 const auto npriv = (sys_ctrl &
static_cast<u32
>(SysCtrlRegister::kControlNPrivMsk)) >>
166 SysCtrlRegister::kControlNPrivPos;
167 const auto spsel = (sys_ctrl &
static_cast<u32
>(SysCtrlRegister::kControlSpSelMsk)) >>
168 SysCtrlRegister::kControlSpSelPos;
169 const auto fpca = (sys_ctrl &
static_cast<u32
>(SysCtrlRegister::kControlFpcaMsk)) >>
170 SysCtrlRegister::kControlFpcaPos;
173 control |= npriv << ControlRegister::kNPrivPos;
174 control |= spsel << ControlRegister::kSpselPos;
175 control |= fpca << ControlRegister::kFpcaPos;
176 static_cast<void>(cpus);
180 static inline void WriteControl(TCpuStates &cpus, u32 value) {
182 (value &
static_cast<u32
>(ControlRegister::kNPrivMsk)) >> ControlRegister::kNPrivPos;
184 (value &
static_cast<u32
>(ControlRegister::kSpselMsk)) >> ControlRegister::kSpselPos;
187 (value &
static_cast<u32
>(ControlRegister::kFpcaMsk)) >> ControlRegister::kFpcaPos;
189 auto sys_ctrl = ReadRegister<SpecialRegisterId::kSysCtrl>(cpus);
191 sys_ctrl |= npriv << SysCtrlRegister::kControlNPrivPos;
194 sys_ctrl |= spsel << SysCtrlRegister::kControlSpSelPos;
197 sys_ctrl |= fpca << SysCtrlRegister::kControlFpcaPos;
199 WriteRegister<SpecialRegisterId::kSysCtrl>(cpus, sys_ctrl);
203 SpecRegOps() =
delete;
204 ~SpecRegOps() =
delete;
205 SpecRegOps &operator=(
const SpecRegOps &r_src) =
delete;
206 SpecRegOps(SpecRegOps &&r_src) =
delete;
207 SpecRegOps &operator=(SpecRegOps &&r_src) =
delete;
208 SpecRegOps(
const SpecRegOps &r_src) =
delete;