core.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <memory>
  5. #include "audio_core/audio_core.h"
  6. #include "common/logging/log.h"
  7. #include "core/arm/arm_interface.h"
  8. #include "core/arm/dynarmic/arm_dynarmic.h"
  9. #include "core/arm/dyncom/arm_dyncom.h"
  10. #include "core/core.h"
  11. #include "core/core_timing.h"
  12. #include "core/gdbstub/gdbstub.h"
  13. #include "core/hle/kernel/kernel.h"
  14. #include "core/hle/kernel/memory.h"
  15. #include "core/hle/kernel/thread.h"
  16. #include "core/hle/service/service.h"
  17. #include "core/hw/hw.h"
  18. #include "core/loader/loader.h"
  19. #include "core/settings.h"
  20. #include "video_core/video_core.h"
  21. namespace Core {
  22. /*static*/ System System::s_instance;
  23. System::ResultStatus System::RunLoop(int tight_loop) {
  24. if (!cpu_core) {
  25. return ResultStatus::ErrorNotInitialized;
  26. }
  27. if (GDBStub::IsServerEnabled()) {
  28. GDBStub::HandlePacket();
  29. // If the loop is halted and we want to step, use a tiny (1) number of instructions to
  30. // execute. Otherwise, get out of the loop function.
  31. if (GDBStub::GetCpuHaltFlag()) {
  32. if (GDBStub::GetCpuStepFlag()) {
  33. GDBStub::SetCpuStepFlag(false);
  34. tight_loop = 1;
  35. } else {
  36. return ResultStatus::Success;
  37. }
  38. }
  39. }
  40. // If we don't have a currently active thread then don't execute instructions,
  41. // instead advance to the next event and try to yield to the next thread
  42. if (Kernel::GetCurrentThread() == nullptr) {
  43. LOG_TRACE(Core_ARM11, "Idling");
  44. CoreTiming::Idle();
  45. CoreTiming::Advance();
  46. PrepareReschedule();
  47. } else {
  48. cpu_core->Run(tight_loop);
  49. }
  50. HW::Update();
  51. Reschedule();
  52. return ResultStatus::Success;
  53. }
  54. System::ResultStatus System::SingleStep() {
  55. return RunLoop(1);
  56. }
  57. System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
  58. if (app_loader) {
  59. app_loader.reset();
  60. }
  61. app_loader = Loader::GetLoader(filepath);
  62. if (!app_loader) {
  63. LOG_CRITICAL(Core, "Failed to obtain loader for %s!", filepath.c_str());
  64. return ResultStatus::ErrorGetLoader;
  65. }
  66. boost::optional<u32> system_mode{app_loader->LoadKernelSystemMode()};
  67. if (!system_mode) {
  68. LOG_CRITICAL(Core, "Failed to determine system mode!");
  69. return ResultStatus::ErrorSystemMode;
  70. }
  71. ResultStatus init_result{Init(emu_window, system_mode.get())};
  72. if (init_result != ResultStatus::Success) {
  73. LOG_CRITICAL(Core, "Failed to initialize system (Error %i)!", init_result);
  74. System::Shutdown();
  75. return init_result;
  76. }
  77. const Loader::ResultStatus load_result{app_loader->Load()};
  78. if (Loader::ResultStatus::Success != load_result) {
  79. LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result);
  80. System::Shutdown();
  81. switch (load_result) {
  82. case Loader::ResultStatus::ErrorEncrypted:
  83. return ResultStatus::ErrorLoader_ErrorEncrypted;
  84. case Loader::ResultStatus::ErrorInvalidFormat:
  85. return ResultStatus::ErrorLoader_ErrorInvalidFormat;
  86. default:
  87. return ResultStatus::ErrorLoader;
  88. }
  89. }
  90. return ResultStatus::Success;
  91. }
  92. void System::PrepareReschedule() {
  93. cpu_core->PrepareReschedule();
  94. reschedule_pending = true;
  95. }
  96. void System::Reschedule() {
  97. if (!reschedule_pending) {
  98. return;
  99. }
  100. reschedule_pending = false;
  101. Kernel::Reschedule();
  102. }
  103. System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
  104. if (cpu_core) {
  105. cpu_core.reset();
  106. }
  107. Memory::Init();
  108. if (Settings::values.use_cpu_jit) {
  109. cpu_core = std::make_unique<ARM_Dynarmic>(USER32MODE);
  110. } else {
  111. cpu_core = std::make_unique<ARM_DynCom>(USER32MODE);
  112. }
  113. CoreTiming::Init();
  114. HW::Init();
  115. Kernel::Init(system_mode);
  116. Service::Init();
  117. AudioCore::Init();
  118. GDBStub::Init();
  119. if (!VideoCore::Init(emu_window)) {
  120. return ResultStatus::ErrorVideoCore;
  121. }
  122. LOG_DEBUG(Core, "Initialized OK");
  123. return ResultStatus::Success;
  124. }
  125. void System::Shutdown() {
  126. GDBStub::Shutdown();
  127. AudioCore::Shutdown();
  128. VideoCore::Shutdown();
  129. Service::Shutdown();
  130. Kernel::Shutdown();
  131. HW::Shutdown();
  132. CoreTiming::Shutdown();
  133. cpu_core.reset();
  134. LOG_DEBUG(Core, "Shutdown OK");
  135. }
  136. } // namespace