arm_dynarmic_cp15.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <fmt/format.h>
  5. #include "common/logging/log.h"
  6. #include "core/arm/dynarmic/arm_dynarmic_32.h"
  7. #include "core/arm/dynarmic/arm_dynarmic_cp15.h"
  8. using Callback = Dynarmic::A32::Coprocessor::Callback;
  9. using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord;
  10. using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords;
  11. template <>
  12. struct fmt::formatter<Dynarmic::A32::CoprocReg> {
  13. constexpr auto parse(format_parse_context& ctx) {
  14. return ctx.begin();
  15. }
  16. template <typename FormatContext>
  17. auto format(const Dynarmic::A32::CoprocReg& reg, FormatContext& ctx) {
  18. return format_to(ctx.out(), "cp{}", static_cast<size_t>(reg));
  19. }
  20. };
  21. namespace Core {
  22. static u32 dummy_value;
  23. std::optional<Callback> DynarmicCP15::CompileInternalOperation(bool two, unsigned opc1,
  24. CoprocReg CRd, CoprocReg CRn,
  25. CoprocReg CRm, unsigned opc2) {
  26. LOG_CRITICAL(Core_ARM, "CP15: cdp{} p15, {}, {}, {}, {}, {}", two ? "2" : "", opc1, CRd, CRn,
  27. CRm, opc2);
  28. return {};
  29. }
  30. CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn,
  31. CoprocReg CRm, unsigned opc2) {
  32. if (!two && CRn == CoprocReg::C7 && opc1 == 0 && CRm == CoprocReg::C5 && opc2 == 4) {
  33. // CP15_FLUSH_PREFETCH_BUFFER
  34. // This is a dummy write, we ignore the value written here.
  35. return &dummy_value;
  36. }
  37. if (!two && CRn == CoprocReg::C7 && opc1 == 0 && CRm == CoprocReg::C10) {
  38. switch (opc2) {
  39. case 4:
  40. // CP15_DATA_SYNC_BARRIER
  41. // This is a dummy write, we ignore the value written here.
  42. return &dummy_value;
  43. case 5:
  44. // CP15_DATA_MEMORY_BARRIER
  45. // This is a dummy write, we ignore the value written here.
  46. return &dummy_value;
  47. }
  48. }
  49. if (!two && CRn == CoprocReg::C13 && opc1 == 0 && CRm == CoprocReg::C0 && opc2 == 2) {
  50. // CP15_THREAD_UPRW
  51. return &uprw;
  52. }
  53. LOG_CRITICAL(Core_ARM, "CP15: mcr{} p15, {}, <Rt>, {}, {}, {}", two ? "2" : "", opc1, CRn, CRm,
  54. opc2);
  55. return {};
  56. }
  57. CallbackOrAccessTwoWords DynarmicCP15::CompileSendTwoWords(bool two, unsigned opc, CoprocReg CRm) {
  58. LOG_CRITICAL(Core_ARM, "CP15: mcrr{} p15, {}, <Rt>, <Rt2>, {}", two ? "2" : "", opc, CRm);
  59. return {};
  60. }
  61. CallbackOrAccessOneWord DynarmicCP15::CompileGetOneWord(bool two, unsigned opc1, CoprocReg CRn,
  62. CoprocReg CRm, unsigned opc2) {
  63. if (!two && CRn == CoprocReg::C13 && opc1 == 0 && CRm == CoprocReg::C0) {
  64. switch (opc2) {
  65. case 2:
  66. // CP15_THREAD_UPRW
  67. return &uprw;
  68. case 3:
  69. // CP15_THREAD_URO
  70. return &uro;
  71. }
  72. }
  73. LOG_CRITICAL(Core_ARM, "CP15: mrc{} p15, {}, <Rt>, {}, {}, {}", two ? "2" : "", opc1, CRn, CRm,
  74. opc2);
  75. return {};
  76. }
  77. CallbackOrAccessTwoWords DynarmicCP15::CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) {
  78. LOG_CRITICAL(Core_ARM, "CP15: mrrc{} p15, {}, <Rt>, <Rt2>, {}", two ? "2" : "", opc, CRm);
  79. return {};
  80. }
  81. std::optional<Callback> DynarmicCP15::CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd,
  82. std::optional<u8> option) {
  83. if (option) {
  84. LOG_CRITICAL(Core_ARM, "CP15: mrrc{}{} p15, {}, [...], {}", two ? "2" : "",
  85. long_transfer ? "l" : "", CRd, *option);
  86. } else {
  87. LOG_CRITICAL(Core_ARM, "CP15: mrrc{}{} p15, {}, [...]", two ? "2" : "",
  88. long_transfer ? "l" : "", CRd);
  89. }
  90. return {};
  91. }
  92. std::optional<Callback> DynarmicCP15::CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd,
  93. std::optional<u8> option) {
  94. if (option) {
  95. LOG_CRITICAL(Core_ARM, "CP15: mrrc{}{} p15, {}, [...], {}", two ? "2" : "",
  96. long_transfer ? "l" : "", CRd, *option);
  97. } else {
  98. LOG_CRITICAL(Core_ARM, "CP15: mrrc{}{} p15, {}, [...]", two ? "2" : "",
  99. long_transfer ? "l" : "", CRd);
  100. }
  101. return {};
  102. }
  103. } // namespace Core