armstate.cpp 20 KB

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