armstate.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/swap.h"
  5. #include "common/logging/log.h"
  6. #include "core/memory.h"
  7. #include "core/arm/skyeye_common/armstate.h"
  8. #include "core/arm/skyeye_common/vfp/vfp.h"
  9. #include "core/gdbstub/gdbstub.h"
  10. ARMul_State::ARMul_State(PrivilegeMode initial_mode)
  11. {
  12. Reset();
  13. ChangePrivilegeMode(initial_mode);
  14. }
  15. void ARMul_State::ChangePrivilegeMode(u32 new_mode)
  16. {
  17. if (Mode == new_mode)
  18. return;
  19. if (new_mode != USERBANK) {
  20. switch (Mode) {
  21. case SYSTEM32MODE: // Shares registers with user mode
  22. case USER32MODE:
  23. Reg_usr[0] = Reg[13];
  24. Reg_usr[1] = Reg[14];
  25. break;
  26. case IRQ32MODE:
  27. Reg_irq[0] = Reg[13];
  28. Reg_irq[1] = Reg[14];
  29. Spsr[IRQBANK] = Spsr_copy;
  30. break;
  31. case SVC32MODE:
  32. Reg_svc[0] = Reg[13];
  33. Reg_svc[1] = Reg[14];
  34. Spsr[SVCBANK] = Spsr_copy;
  35. break;
  36. case ABORT32MODE:
  37. Reg_abort[0] = Reg[13];
  38. Reg_abort[1] = Reg[14];
  39. Spsr[ABORTBANK] = Spsr_copy;
  40. break;
  41. case UNDEF32MODE:
  42. Reg_undef[0] = Reg[13];
  43. Reg_undef[1] = Reg[14];
  44. Spsr[UNDEFBANK] = Spsr_copy;
  45. break;
  46. case FIQ32MODE:
  47. Reg_firq[0] = Reg[13];
  48. Reg_firq[1] = Reg[14];
  49. Spsr[FIQBANK] = Spsr_copy;
  50. break;
  51. }
  52. switch (new_mode) {
  53. case USER32MODE:
  54. Reg[13] = Reg_usr[0];
  55. Reg[14] = Reg_usr[1];
  56. Bank = USERBANK;
  57. break;
  58. case IRQ32MODE:
  59. Reg[13] = Reg_irq[0];
  60. Reg[14] = Reg_irq[1];
  61. Spsr_copy = Spsr[IRQBANK];
  62. Bank = IRQBANK;
  63. break;
  64. case SVC32MODE:
  65. Reg[13] = Reg_svc[0];
  66. Reg[14] = Reg_svc[1];
  67. Spsr_copy = Spsr[SVCBANK];
  68. Bank = SVCBANK;
  69. break;
  70. case ABORT32MODE:
  71. Reg[13] = Reg_abort[0];
  72. Reg[14] = Reg_abort[1];
  73. Spsr_copy = Spsr[ABORTBANK];
  74. Bank = ABORTBANK;
  75. break;
  76. case UNDEF32MODE:
  77. Reg[13] = Reg_undef[0];
  78. Reg[14] = Reg_undef[1];
  79. Spsr_copy = Spsr[UNDEFBANK];
  80. Bank = UNDEFBANK;
  81. break;
  82. case FIQ32MODE:
  83. Reg[13] = Reg_firq[0];
  84. Reg[14] = Reg_firq[1];
  85. Spsr_copy = Spsr[FIQBANK];
  86. Bank = FIQBANK;
  87. break;
  88. case SYSTEM32MODE: // Shares registers with user mode.
  89. Reg[13] = Reg_usr[0];
  90. Reg[14] = Reg_usr[1];
  91. Bank = SYSTEMBANK;
  92. break;
  93. }
  94. // Set the mode bits in the APSR
  95. Cpsr = (Cpsr & ~Mode) | new_mode;
  96. Mode = new_mode;
  97. }
  98. }
  99. // Performs a reset
  100. void ARMul_State::Reset()
  101. {
  102. VFPInit(this);
  103. // Set stack pointer to the top of the stack
  104. Reg[13] = 0x10000000;
  105. Reg[15] = 0;
  106. Cpsr = INTBITS | SVC32MODE;
  107. Mode = SVC32MODE;
  108. Bank = SVCBANK;
  109. ResetMPCoreCP15Registers();
  110. NresetSig = HIGH;
  111. NfiqSig = HIGH;
  112. NirqSig = HIGH;
  113. NtransSig = (Mode & 3) ? HIGH : LOW;
  114. abortSig = LOW;
  115. NumInstrs = 0;
  116. Emulate = RUN;
  117. }
  118. // Resets certain MPCore CP15 values to their ARM-defined reset values.
  119. void ARMul_State::ResetMPCoreCP15Registers()
  120. {
  121. // c0
  122. CP15[CP15_MAIN_ID] = 0x410FB024;
  123. CP15[CP15_TLB_TYPE] = 0x00000800;
  124. CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111;
  125. CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001;
  126. CP15[CP15_DEBUG_FEATURE_0] = 0x00000002;
  127. CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103;
  128. CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302;
  129. CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000;
  130. CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000;
  131. CP15[CP15_ISA_FEATURE_0] = 0x00100011;
  132. CP15[CP15_ISA_FEATURE_1] = 0x12002111;
  133. CP15[CP15_ISA_FEATURE_2] = 0x11221011;
  134. CP15[CP15_ISA_FEATURE_3] = 0x01102131;
  135. CP15[CP15_ISA_FEATURE_4] = 0x00000141;
  136. // c1
  137. CP15[CP15_CONTROL] = 0x00054078;
  138. CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F;
  139. CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000;
  140. // c2
  141. CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000;
  142. CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000;
  143. CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000;
  144. // c3
  145. CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000;
  146. // c7
  147. CP15[CP15_PHYS_ADDRESS] = 0x00000000;
  148. // c9
  149. CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0;
  150. // c10
  151. CP15[CP15_TLB_LOCKDOWN] = 0x00000000;
  152. CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4;
  153. CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0;
  154. // c13
  155. CP15[CP15_PID] = 0x00000000;
  156. CP15[CP15_CONTEXT_ID] = 0x00000000;
  157. CP15[CP15_THREAD_UPRW] = 0x00000000;
  158. CP15[CP15_THREAD_URO] = 0x00000000;
  159. CP15[CP15_THREAD_PRW] = 0x00000000;
  160. // c15
  161. CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000;
  162. CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000;
  163. CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000;
  164. CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000;
  165. CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
  166. }
  167. static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type)
  168. {
  169. if (GDBStub::g_server_enabled && GDBStub::CheckBreakpoint(address, type)) {
  170. LOG_DEBUG(Debug, "Found memory breakpoint @ %08x", address);
  171. GDBStub::Break(true);
  172. }
  173. }
  174. u8 ARMul_State::ReadMemory8(u32 address) const
  175. {
  176. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
  177. return Memory::Read8(address);
  178. }
  179. u16 ARMul_State::ReadMemory16(u32 address) const
  180. {
  181. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
  182. u16 data = Memory::Read16(address);
  183. if (InBigEndianMode())
  184. data = Common::swap16(data);
  185. return data;
  186. }
  187. u32 ARMul_State::ReadMemory32(u32 address) const
  188. {
  189. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
  190. u32 data = Memory::Read32(address);
  191. if (InBigEndianMode())
  192. data = Common::swap32(data);
  193. return data;
  194. }
  195. u64 ARMul_State::ReadMemory64(u32 address) const
  196. {
  197. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
  198. u64 data = Memory::Read64(address);
  199. if (InBigEndianMode())
  200. data = Common::swap64(data);
  201. return data;
  202. }
  203. void ARMul_State::WriteMemory8(u32 address, u8 data)
  204. {
  205. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
  206. Memory::Write8(address, data);
  207. }
  208. void ARMul_State::WriteMemory16(u32 address, u16 data)
  209. {
  210. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
  211. if (InBigEndianMode())
  212. data = Common::swap16(data);
  213. Memory::Write16(address, data);
  214. }
  215. void ARMul_State::WriteMemory32(u32 address, u32 data)
  216. {
  217. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
  218. if (InBigEndianMode())
  219. data = Common::swap32(data);
  220. Memory::Write32(address, data);
  221. }
  222. void ARMul_State::WriteMemory64(u32 address, u64 data)
  223. {
  224. CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
  225. if (InBigEndianMode())
  226. data = Common::swap64(data);
  227. Memory::Write64(address, data);
  228. }
  229. // Reads from the CP15 registers. Used with implementation of the MRC instruction.
  230. // Note that since the 3DS does not have the hypervisor extensions, these registers
  231. // are not implemented.
  232. u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const
  233. {
  234. // Unprivileged registers
  235. if (crn == 13 && opcode_1 == 0 && crm == 0)
  236. {
  237. if (opcode_2 == 2)
  238. return CP15[CP15_THREAD_UPRW];
  239. if (opcode_2 == 3)
  240. return CP15[CP15_THREAD_URO];
  241. }
  242. if (InAPrivilegedMode())
  243. {
  244. if (crn == 0 && opcode_1 == 0)
  245. {
  246. if (crm == 0)
  247. {
  248. if (opcode_2 == 0)
  249. return CP15[CP15_MAIN_ID];
  250. if (opcode_2 == 1)
  251. return CP15[CP15_CACHE_TYPE];
  252. if (opcode_2 == 3)
  253. return CP15[CP15_TLB_TYPE];
  254. if (opcode_2 == 5)
  255. return CP15[CP15_CPU_ID];
  256. }
  257. else if (crm == 1)
  258. {
  259. if (opcode_2 == 0)
  260. return CP15[CP15_PROCESSOR_FEATURE_0];
  261. if (opcode_2 == 1)
  262. return CP15[CP15_PROCESSOR_FEATURE_1];
  263. if (opcode_2 == 2)
  264. return CP15[CP15_DEBUG_FEATURE_0];
  265. if (opcode_2 == 4)
  266. return CP15[CP15_MEMORY_MODEL_FEATURE_0];
  267. if (opcode_2 == 5)
  268. return CP15[CP15_MEMORY_MODEL_FEATURE_1];
  269. if (opcode_2 == 6)
  270. return CP15[CP15_MEMORY_MODEL_FEATURE_2];
  271. if (opcode_2 == 7)
  272. return CP15[CP15_MEMORY_MODEL_FEATURE_3];
  273. }
  274. else if (crm == 2)
  275. {
  276. if (opcode_2 == 0)
  277. return CP15[CP15_ISA_FEATURE_0];
  278. if (opcode_2 == 1)
  279. return CP15[CP15_ISA_FEATURE_1];
  280. if (opcode_2 == 2)
  281. return CP15[CP15_ISA_FEATURE_2];
  282. if (opcode_2 == 3)
  283. return CP15[CP15_ISA_FEATURE_3];
  284. if (opcode_2 == 4)
  285. return CP15[CP15_ISA_FEATURE_4];
  286. }
  287. }
  288. if (crn == 1 && opcode_1 == 0 && crm == 0)
  289. {
  290. if (opcode_2 == 0)
  291. return CP15[CP15_CONTROL];
  292. if (opcode_2 == 1)
  293. return CP15[CP15_AUXILIARY_CONTROL];
  294. if (opcode_2 == 2)
  295. return CP15[CP15_COPROCESSOR_ACCESS_CONTROL];
  296. }
  297. if (crn == 2 && opcode_1 == 0 && crm == 0)
  298. {
  299. if (opcode_2 == 0)
  300. return CP15[CP15_TRANSLATION_BASE_TABLE_0];
  301. if (opcode_2 == 1)
  302. return CP15[CP15_TRANSLATION_BASE_TABLE_1];
  303. if (opcode_2 == 2)
  304. return CP15[CP15_TRANSLATION_BASE_CONTROL];
  305. }
  306. if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
  307. return CP15[CP15_DOMAIN_ACCESS_CONTROL];
  308. if (crn == 5 && opcode_1 == 0 && crm == 0)
  309. {
  310. if (opcode_2 == 0)
  311. return CP15[CP15_FAULT_STATUS];
  312. if (opcode_2 == 1)
  313. return CP15[CP15_INSTR_FAULT_STATUS];
  314. }
  315. if (crn == 6 && opcode_1 == 0 && crm == 0)
  316. {
  317. if (opcode_2 == 0)
  318. return CP15[CP15_FAULT_ADDRESS];
  319. if (opcode_2 == 1)
  320. return CP15[CP15_WFAR];
  321. }
  322. if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
  323. return CP15[CP15_PHYS_ADDRESS];
  324. if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
  325. return CP15[CP15_DATA_CACHE_LOCKDOWN];
  326. if (crn == 10 && opcode_1 == 0)
  327. {
  328. if (crm == 0 && opcode_2 == 0)
  329. return CP15[CP15_TLB_LOCKDOWN];
  330. if (crm == 2)
  331. {
  332. if (opcode_2 == 0)
  333. return CP15[CP15_PRIMARY_REGION_REMAP];
  334. if (opcode_2 == 1)
  335. return CP15[CP15_NORMAL_REGION_REMAP];
  336. }
  337. }
  338. if (crn == 13 && crm == 0)
  339. {
  340. if (opcode_2 == 0)
  341. return CP15[CP15_PID];
  342. if (opcode_2 == 1)
  343. return CP15[CP15_CONTEXT_ID];
  344. if (opcode_2 == 4)
  345. return CP15[CP15_THREAD_PRW];
  346. }
  347. if (crn == 15)
  348. {
  349. if (opcode_1 == 0 && crm == 12)
  350. {
  351. if (opcode_2 == 0)
  352. return CP15[CP15_PERFORMANCE_MONITOR_CONTROL];
  353. if (opcode_2 == 1)
  354. return CP15[CP15_CYCLE_COUNTER];
  355. if (opcode_2 == 2)
  356. return CP15[CP15_COUNT_0];
  357. if (opcode_2 == 3)
  358. return CP15[CP15_COUNT_1];
  359. }
  360. if (opcode_1 == 5 && opcode_2 == 2)
  361. {
  362. if (crm == 5)
  363. return CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS];
  364. if (crm == 6)
  365. return CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS];
  366. if (crm == 7)
  367. return CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE];
  368. }
  369. if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
  370. return CP15[CP15_TLB_DEBUG_CONTROL];
  371. }
  372. }
  373. LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
  374. return 0;
  375. }
  376. // Write to the CP15 registers. Used with implementation of the MCR instruction.
  377. // Note that since the 3DS does not have the hypervisor extensions, these registers
  378. // are not implemented.
  379. void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
  380. {
  381. if (InAPrivilegedMode())
  382. {
  383. if (crn == 1 && opcode_1 == 0 && crm == 0)
  384. {
  385. if (opcode_2 == 0)
  386. CP15[CP15_CONTROL] = value;
  387. else if (opcode_2 == 1)
  388. CP15[CP15_AUXILIARY_CONTROL] = value;
  389. else if (opcode_2 == 2)
  390. CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value;
  391. }
  392. else if (crn == 2 && opcode_1 == 0 && crm == 0)
  393. {
  394. if (opcode_2 == 0)
  395. CP15[CP15_TRANSLATION_BASE_TABLE_0] = value;
  396. else if (opcode_2 == 1)
  397. CP15[CP15_TRANSLATION_BASE_TABLE_1] = value;
  398. else if (opcode_2 == 2)
  399. CP15[CP15_TRANSLATION_BASE_CONTROL] = value;
  400. }
  401. else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
  402. {
  403. CP15[CP15_DOMAIN_ACCESS_CONTROL] = value;
  404. }
  405. else if (crn == 5 && opcode_1 == 0 && crm == 0)
  406. {
  407. if (opcode_2 == 0)
  408. CP15[CP15_FAULT_STATUS] = value;
  409. else if (opcode_2 == 1)
  410. CP15[CP15_INSTR_FAULT_STATUS] = value;
  411. }
  412. else if (crn == 6 && opcode_1 == 0 && crm == 0)
  413. {
  414. if (opcode_2 == 0)
  415. CP15[CP15_FAULT_ADDRESS] = value;
  416. else if (opcode_2 == 1)
  417. CP15[CP15_WFAR] = value;
  418. }
  419. else if (crn == 7 && opcode_1 == 0)
  420. {
  421. if (crm == 0 && opcode_2 == 4)
  422. {
  423. CP15[CP15_WAIT_FOR_INTERRUPT] = value;
  424. }
  425. else if (crm == 4 && opcode_2 == 0)
  426. {
  427. // NOTE: Not entirely accurate. This should do permission checks.
  428. CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value);
  429. }
  430. else if (crm == 5)
  431. {
  432. if (opcode_2 == 0)
  433. CP15[CP15_INVALIDATE_INSTR_CACHE] = value;
  434. else if (opcode_2 == 1)
  435. CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value;
  436. else if (opcode_2 == 2)
  437. CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value;
  438. else if (opcode_2 == 6)
  439. CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value;
  440. else if (opcode_2 == 7)
  441. CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value;
  442. }
  443. else if (crm == 6)
  444. {
  445. if (opcode_2 == 0)
  446. CP15[CP15_INVALIDATE_DATA_CACHE] = value;
  447. else if (opcode_2 == 1)
  448. CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
  449. else if (opcode_2 == 2)
  450. CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
  451. }
  452. else if (crm == 7 && opcode_2 == 0)
  453. {
  454. CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value;
  455. }
  456. else if (crm == 10)
  457. {
  458. if (opcode_2 == 0)
  459. CP15[CP15_CLEAN_DATA_CACHE] = value;
  460. else if (opcode_2 == 1)
  461. CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value;
  462. else if (opcode_2 == 2)
  463. CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value;
  464. }
  465. else if (crm == 14)
  466. {
  467. if (opcode_2 == 0)
  468. CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value;
  469. else if (opcode_2 == 1)
  470. CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value;
  471. else if (opcode_2 == 2)
  472. CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value;
  473. }
  474. }
  475. else if (crn == 8 && opcode_1 == 0)
  476. {
  477. if (crm == 5)
  478. {
  479. if (opcode_2 == 0)
  480. CP15[CP15_INVALIDATE_ITLB] = value;
  481. else if (opcode_2 == 1)
  482. CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value;
  483. else if (opcode_2 == 2)
  484. CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value;
  485. else if (opcode_2 == 3)
  486. CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value;
  487. }
  488. else if (crm == 6)
  489. {
  490. if (opcode_2 == 0)
  491. CP15[CP15_INVALIDATE_DTLB] = value;
  492. else if (opcode_2 == 1)
  493. CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value;
  494. else if (opcode_2 == 2)
  495. CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value;
  496. else if (opcode_2 == 3)
  497. CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value;
  498. }
  499. else if (crm == 7)
  500. {
  501. if (opcode_2 == 0)
  502. CP15[CP15_INVALIDATE_UTLB] = value;
  503. else if (opcode_2 == 1)
  504. CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value;
  505. else if (opcode_2 == 2)
  506. CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value;
  507. else if (opcode_2 == 3)
  508. CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value;
  509. }
  510. }
  511. else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
  512. {
  513. CP15[CP15_DATA_CACHE_LOCKDOWN] = value;
  514. }
  515. else if (crn == 10 && opcode_1 == 0)
  516. {
  517. if (crm == 0 && opcode_2 == 0)
  518. {
  519. CP15[CP15_TLB_LOCKDOWN] = value;
  520. }
  521. else if (crm == 2)
  522. {
  523. if (opcode_2 == 0)
  524. CP15[CP15_PRIMARY_REGION_REMAP] = value;
  525. else if (opcode_2 == 1)
  526. CP15[CP15_NORMAL_REGION_REMAP] = value;
  527. }
  528. }
  529. else if (crn == 13 && opcode_1 == 0 && crm == 0)
  530. {
  531. if (opcode_2 == 0)
  532. CP15[CP15_PID] = value;
  533. else if (opcode_2 == 1)
  534. CP15[CP15_CONTEXT_ID] = value;
  535. else if (opcode_2 == 3)
  536. CP15[CP15_THREAD_URO] = value;
  537. else if (opcode_2 == 4)
  538. CP15[CP15_THREAD_PRW] = value;
  539. }
  540. else if (crn == 15)
  541. {
  542. if (opcode_1 == 0 && crm == 12)
  543. {
  544. if (opcode_2 == 0)
  545. CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value;
  546. else if (opcode_2 == 1)
  547. CP15[CP15_CYCLE_COUNTER] = value;
  548. else if (opcode_2 == 2)
  549. CP15[CP15_COUNT_0] = value;
  550. else if (opcode_2 == 3)
  551. CP15[CP15_COUNT_1] = value;
  552. }
  553. else if (opcode_1 == 5)
  554. {
  555. if (crm == 4)
  556. {
  557. if (opcode_2 == 2)
  558. CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value;
  559. else if (opcode_2 == 4)
  560. CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value;
  561. }
  562. else if (crm == 5 && opcode_2 == 2)
  563. {
  564. CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value;
  565. }
  566. else if (crm == 6 && opcode_2 == 2)
  567. {
  568. CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value;
  569. }
  570. else if (crm == 7 && opcode_2 == 2)
  571. {
  572. CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value;
  573. }
  574. }
  575. else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
  576. {
  577. CP15[CP15_TLB_DEBUG_CONTROL] = value;
  578. }
  579. }
  580. }
  581. // Unprivileged registers
  582. if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
  583. {
  584. CP15[CP15_FLUSH_PREFETCH_BUFFER] = value;
  585. }
  586. else if (crn == 7 && opcode_1 == 0 && crm == 10)
  587. {
  588. if (opcode_2 == 4)
  589. CP15[CP15_DATA_SYNC_BARRIER] = value;
  590. else if (opcode_2 == 5)
  591. CP15[CP15_DATA_MEMORY_BARRIER] = value;
  592. }
  593. else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
  594. {
  595. CP15[CP15_THREAD_UPRW] = value;
  596. }
  597. }