mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #3959 from zhaowenlan1779/semi-reset
service/apt: Implement soft reset & CloseApplication
This commit is contained in:
		
						commit
						687e3e74ca
					
				
					 9 changed files with 160 additions and 12 deletions
				
			
		|  | @ -35,6 +35,12 @@ void EmuThread::run() { | ||||||
|                 emit DebugModeLeft(); |                 emit DebugModeLeft(); | ||||||
| 
 | 
 | ||||||
|             Core::System::ResultStatus result = Core::System::GetInstance().RunLoop(); |             Core::System::ResultStatus result = Core::System::GetInstance().RunLoop(); | ||||||
|  |             if (result == Core::System::ResultStatus::ShutdownRequested) { | ||||||
|  |                 // Notify frontend we shutdown
 | ||||||
|  |                 emit ErrorThrown(result, ""); | ||||||
|  |                 // End emulation execution
 | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|             if (result != Core::System::ResultStatus::Success) { |             if (result != Core::System::ResultStatus::Success) { | ||||||
|                 this->SetRunning(false); |                 this->SetRunning(false); | ||||||
|                 emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails()); |                 emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails()); | ||||||
|  |  | ||||||
|  | @ -1400,7 +1400,6 @@ void GMainWindow::UpdateStatusBar() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) { | void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) { | ||||||
|     QMessageBox::StandardButton answer; |  | ||||||
|     QString status_message; |     QString status_message; | ||||||
| 
 | 
 | ||||||
|     QString title, message; |     QString title, message; | ||||||
|  | @ -1435,9 +1434,11 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det | ||||||
|     message_box.setIcon(QMessageBox::Icon::Critical); |     message_box.setIcon(QMessageBox::Icon::Critical); | ||||||
|     QPushButton* continue_button = message_box.addButton(tr("Continue"), QMessageBox::RejectRole); |     QPushButton* continue_button = message_box.addButton(tr("Continue"), QMessageBox::RejectRole); | ||||||
|     QPushButton* abort_button = message_box.addButton(tr("Abort"), QMessageBox::AcceptRole); |     QPushButton* abort_button = message_box.addButton(tr("Abort"), QMessageBox::AcceptRole); | ||||||
|  |     if (result != Core::System::ResultStatus::ShutdownRequested) | ||||||
|         message_box.exec(); |         message_box.exec(); | ||||||
| 
 | 
 | ||||||
|     if (message_box.clickedButton() == abort_button) { |     if (result == Core::System::ResultStatus::ShutdownRequested || | ||||||
|  |         message_box.clickedButton() == abort_button) { | ||||||
|         if (emu_thread) { |         if (emu_thread) { | ||||||
|             ShutdownGame(); |             ShutdownGame(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -77,6 +77,12 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|     HW::Update(); |     HW::Update(); | ||||||
|     Reschedule(); |     Reschedule(); | ||||||
| 
 | 
 | ||||||
|  |     if (reset_requested.exchange(false)) { | ||||||
|  |         Reset(); | ||||||
|  |     } else if (shutdown_requested.exchange(false)) { | ||||||
|  |         return ResultStatus::ShutdownRequested; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return status; |     return status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -132,6 +138,8 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file | ||||||
|     } |     } | ||||||
|     Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table); |     Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table); | ||||||
|     status = ResultStatus::Success; |     status = ResultStatus::Success; | ||||||
|  |     m_emu_window = &emu_window; | ||||||
|  |     m_filepath = filepath; | ||||||
|     return status; |     return status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -241,4 +249,14 @@ void System::Shutdown() { | ||||||
|     LOG_DEBUG(Core, "Shutdown OK"); |     LOG_DEBUG(Core, "Shutdown OK"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void System::Reset() { | ||||||
|  |     // This is NOT a proper reset, but a temporary workaround by shutting down the system and
 | ||||||
|  |     // reloading.
 | ||||||
|  |     // TODO: Properly implement the reset
 | ||||||
|  | 
 | ||||||
|  |     Shutdown(); | ||||||
|  |     // Reload the system with the same setting
 | ||||||
|  |     Load(*m_emu_window, m_filepath); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace Core
 | } // namespace Core
 | ||||||
|  |  | ||||||
|  | @ -59,6 +59,7 @@ public: | ||||||
|                                             /// generic drivers installed
 |                                             /// generic drivers installed
 | ||||||
|         ErrorVideoCore_ErrorBelowGL33,      ///< Error in the video core due to the user not having
 |         ErrorVideoCore_ErrorBelowGL33,      ///< Error in the video core due to the user not having
 | ||||||
|                                             /// OpenGL 3.3 or higher
 |                                             /// OpenGL 3.3 or higher
 | ||||||
|  |         ShutdownRequested,                  ///< Emulated program requested a system shutdown
 | ||||||
|         ErrorUnknown                        ///< Any other error
 |         ErrorUnknown                        ///< Any other error
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -83,6 +84,19 @@ public: | ||||||
|     /// Shutdown the emulated system.
 |     /// Shutdown the emulated system.
 | ||||||
|     void Shutdown(); |     void Shutdown(); | ||||||
| 
 | 
 | ||||||
|  |     /// Shutdown and then load again
 | ||||||
|  |     void Reset(); | ||||||
|  | 
 | ||||||
|  |     /// Request reset of the system
 | ||||||
|  |     void RequestReset() { | ||||||
|  |         reset_requested = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Request shutdown of the system
 | ||||||
|  |     void RequestShutdown() { | ||||||
|  |         shutdown_requested = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Load an executable application. |      * Load an executable application. | ||||||
|      * @param emu_window Reference to the host-system window used for video output and keyboard |      * @param emu_window Reference to the host-system window used for video output and keyboard | ||||||
|  | @ -216,6 +230,12 @@ private: | ||||||
| 
 | 
 | ||||||
|     ResultStatus status = ResultStatus::Success; |     ResultStatus status = ResultStatus::Success; | ||||||
|     std::string status_details = ""; |     std::string status_details = ""; | ||||||
|  |     /// Saved variables for reset
 | ||||||
|  |     EmuWindow* m_emu_window; | ||||||
|  |     std::string m_filepath; | ||||||
|  | 
 | ||||||
|  |     std::atomic<bool> reset_requested; | ||||||
|  |     std::atomic<bool> shutdown_requested; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| inline ARM_Interface& CPU() { | inline ARM_Interface& CPU() { | ||||||
|  |  | ||||||
|  | @ -543,6 +543,65 @@ void Module::Interface::StartLibraryApplet(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.Push(apt->applet_manager->StartLibraryApplet(applet_id, object, buffer)); |     rb.Push(apt->applet_manager->StartLibraryApplet(applet_id, object, buffer)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Module::Interface::CloseApplication(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x27, 1, 4); | ||||||
|  |     u32 parameters_size = rp.Pop<u32>(); | ||||||
|  |     Kernel::SharedPtr<Kernel::Object> object = rp.PopGenericObject(); | ||||||
|  |     std::vector<u8> buffer = rp.PopStaticBuffer(); | ||||||
|  | 
 | ||||||
|  |     LOG_DEBUG(Service_APT, "called"); | ||||||
|  | 
 | ||||||
|  |     Core::System::GetInstance().RequestShutdown(); | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Module::Interface::PrepareToDoApplicationJump(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x31, 4, 0); | ||||||
|  |     u32 flags = rp.Pop<u8>(); | ||||||
|  |     u32 program_id_low = rp.Pop<u32>(); | ||||||
|  |     u32 program_id_high = rp.Pop<u32>(); | ||||||
|  |     Service::FS::MediaType media_type = static_cast<Service::FS::MediaType>(rp.Pop<u8>()); | ||||||
|  | 
 | ||||||
|  |     LOG_WARNING(Service_APT, | ||||||
|  |                 "(STUBBED) called, flags={:08X}, program_id_low={:08X}, program_id_high={:08X}, " | ||||||
|  |                 "media_type={:08X}", | ||||||
|  |                 flags, program_id_low, program_id_high, static_cast<u8>(media_type)); | ||||||
|  | 
 | ||||||
|  |     if (flags == 0x2) { | ||||||
|  |         // It seems that flags 0x2 means jumping to the same application,
 | ||||||
|  |         // and ignore the parameters. This is used in Pokemon main series
 | ||||||
|  |         // to soft reset.
 | ||||||
|  |         application_reset_prepared = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Module::Interface::DoApplicationJump(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x32, 2, 4); | ||||||
|  |     u32 parameter_size = rp.Pop<u32>(); | ||||||
|  |     u32 hmac_size = rp.Pop<u32>(); | ||||||
|  |     std::vector<u8> parameter = rp.PopStaticBuffer(); | ||||||
|  |     std::vector<u8> hmac = rp.PopStaticBuffer(); | ||||||
|  | 
 | ||||||
|  |     LOG_WARNING(Service_APT, "(STUBBED) called"); | ||||||
|  | 
 | ||||||
|  |     if (application_reset_prepared) { | ||||||
|  |         // Reset system
 | ||||||
|  |         Core::System::GetInstance().RequestReset(); | ||||||
|  |     } else { | ||||||
|  |         // After the jump, the application should shutdown
 | ||||||
|  |         // TODO: Actually implement the jump
 | ||||||
|  |         Core::System::GetInstance().RequestShutdown(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Module::Interface::CancelLibraryApplet(Kernel::HLERequestContext& ctx) { | void Module::Interface::CancelLibraryApplet(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040
 |     IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040
 | ||||||
|     bool exiting = rp.Pop<bool>(); |     bool exiting = rp.Pop<bool>(); | ||||||
|  |  | ||||||
|  | @ -409,6 +409,49 @@ public: | ||||||
|          */ |          */ | ||||||
|         void StartLibraryApplet(Kernel::HLERequestContext& ctx); |         void StartLibraryApplet(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|  |         /**
 | ||||||
|  |          * APT::CloseApplication service function | ||||||
|  |          *  Inputs: | ||||||
|  |          *      0 : Command header [0x00270044] | ||||||
|  |          *      1 : Parameters Size | ||||||
|  |          *      2 : 0x0 | ||||||
|  |          *      3 : Handle Parameter | ||||||
|  |          *      4 : (Parameters Size << 14) | 2 | ||||||
|  |          *      5 : void*, Parameters | ||||||
|  |          *  Outputs: | ||||||
|  |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |          */ | ||||||
|  |         void CloseApplication(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * APT::PrepareToDoApplicationJump service function | ||||||
|  |          *  Inputs: | ||||||
|  |          *      0 : Command header [0x00310100] | ||||||
|  |          *      1 : Flags | ||||||
|  |          *      2 : Program ID low | ||||||
|  |          *      3 : Program ID high | ||||||
|  |          *      4 : Media type | ||||||
|  |          *  Outputs: | ||||||
|  |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |          * @param ctx | ||||||
|  |          */ | ||||||
|  |         void PrepareToDoApplicationJump(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * APT::DoApplicationJump service function | ||||||
|  |          *  Inputs: | ||||||
|  |          *      0 : Command header [0x00320084] | ||||||
|  |          *      1 : Parameter Size (capped to 0x300) | ||||||
|  |          *      2 : HMAC Size (capped to 0x20) | ||||||
|  |          *      3 : (Parameter Size << 14) | 2 | ||||||
|  |          *      4 : void*, Parameter | ||||||
|  |          *      5 : (HMAC Size << 14) | 0x802 | ||||||
|  |          *      6 : void*, HMAC | ||||||
|  |          *  Outputs: | ||||||
|  |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |          */ | ||||||
|  |         void DoApplicationJump(Kernel::HLERequestContext& ctx); | ||||||
|  | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * APT::CancelLibraryApplet service function |          * APT::CancelLibraryApplet service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|  | @ -533,6 +576,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         std::shared_ptr<Module> apt; |         std::shared_ptr<Module> apt; | ||||||
|  |         bool application_reset_prepared{}; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt) | ||||||
|         {0x00240044, nullptr, "JumpToApplication"}, |         {0x00240044, nullptr, "JumpToApplication"}, | ||||||
|         {0x002500C0, &APT_A::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"}, |         {0x002500C0, &APT_A::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"}, | ||||||
|         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, |         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, | ||||||
|         {0x00270044, nullptr, "CloseApplication"}, |         {0x00270044, &APT_A::CloseApplication, "CloseApplication"}, | ||||||
|         {0x00280044, &APT_A::CloseLibraryApplet, "CloseLibraryApplet"}, |         {0x00280044, &APT_A::CloseLibraryApplet, "CloseLibraryApplet"}, | ||||||
|         {0x00290044, nullptr, "CloseSystemApplet"}, |         {0x00290044, nullptr, "CloseSystemApplet"}, | ||||||
|         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, |         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, | ||||||
|  | @ -58,8 +58,8 @@ APT_A::APT_A(std::shared_ptr<Module> apt) | ||||||
|         {0x002E0044, nullptr, "LeaveHomeMenu"}, |         {0x002E0044, nullptr, "LeaveHomeMenu"}, | ||||||
|         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, |         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, | ||||||
|         {0x00300044, nullptr, "LeaveResidentApplet"}, |         {0x00300044, nullptr, "LeaveResidentApplet"}, | ||||||
|         {0x00310100, nullptr, "PrepareToDoApplicationJump"}, |         {0x00310100, &APT_A::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"}, | ||||||
|         {0x00320084, nullptr, "DoApplicationJump"}, |         {0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"}, | ||||||
|         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, |         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, | ||||||
|         {0x00340084, nullptr, "SendDeliverArg"}, |         {0x00340084, nullptr, "SendDeliverArg"}, | ||||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, |         {0x00350080, nullptr, "ReceiveDeliverArg"}, | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ APT_S::APT_S(std::shared_ptr<Module> apt) | ||||||
|         {0x00240044, nullptr, "JumpToApplication"}, |         {0x00240044, nullptr, "JumpToApplication"}, | ||||||
|         {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, |         {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, | ||||||
|         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, |         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, | ||||||
|         {0x00270044, nullptr, "CloseApplication"}, |         {0x00270044, &APT_S::CloseApplication, "CloseApplication"}, | ||||||
|         {0x00280044, nullptr, "CloseLibraryApplet"}, |         {0x00280044, nullptr, "CloseLibraryApplet"}, | ||||||
|         {0x00290044, nullptr, "CloseSystemApplet"}, |         {0x00290044, nullptr, "CloseSystemApplet"}, | ||||||
|         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, |         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, | ||||||
|  | @ -58,8 +58,8 @@ APT_S::APT_S(std::shared_ptr<Module> apt) | ||||||
|         {0x002E0044, nullptr, "LeaveHomeMenu"}, |         {0x002E0044, nullptr, "LeaveHomeMenu"}, | ||||||
|         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, |         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, | ||||||
|         {0x00300044, nullptr, "LeaveResidentApplet"}, |         {0x00300044, nullptr, "LeaveResidentApplet"}, | ||||||
|         {0x00310100, nullptr, "PrepareToDoApplicationJump"}, |         {0x00310100, &APT_S::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"}, | ||||||
|         {0x00320084, nullptr, "DoApplicationJump"}, |         {0x00320084, &APT_S::DoApplicationJump, "DoApplicationJump"}, | ||||||
|         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, |         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, | ||||||
|         {0x00340084, nullptr, "SendDeliverArg"}, |         {0x00340084, nullptr, "SendDeliverArg"}, | ||||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, |         {0x00350080, nullptr, "ReceiveDeliverArg"}, | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ APT_U::APT_U(std::shared_ptr<Module> apt) | ||||||
|         {0x00240044, nullptr, "JumpToApplication"}, |         {0x00240044, nullptr, "JumpToApplication"}, | ||||||
|         {0x002500C0, &APT_U::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"}, |         {0x002500C0, &APT_U::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"}, | ||||||
|         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, |         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, | ||||||
|         {0x00270044, nullptr, "CloseApplication"}, |         {0x00270044, &APT_U::CloseApplication, "CloseApplication"}, | ||||||
|         {0x00280044, &APT_U::CloseLibraryApplet, "CloseLibraryApplet"}, |         {0x00280044, &APT_U::CloseLibraryApplet, "CloseLibraryApplet"}, | ||||||
|         {0x00290044, nullptr, "CloseSystemApplet"}, |         {0x00290044, nullptr, "CloseSystemApplet"}, | ||||||
|         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, |         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, | ||||||
|  | @ -58,8 +58,8 @@ APT_U::APT_U(std::shared_ptr<Module> apt) | ||||||
|         {0x002E0044, nullptr, "LeaveHomeMenu"}, |         {0x002E0044, nullptr, "LeaveHomeMenu"}, | ||||||
|         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, |         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, | ||||||
|         {0x00300044, nullptr, "LeaveResidentApplet"}, |         {0x00300044, nullptr, "LeaveResidentApplet"}, | ||||||
|         {0x00310100, nullptr, "PrepareToDoApplicationJump"}, |         {0x00310100, &APT_U::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"}, | ||||||
|         {0x00320084, nullptr, "DoApplicationJump"}, |         {0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"}, | ||||||
|         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, |         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, | ||||||
|         {0x00340084, nullptr, "SendDeliverArg"}, |         {0x00340084, nullptr, "SendDeliverArg"}, | ||||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, |         {0x00350080, nullptr, "ReceiveDeliverArg"}, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue