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
				
			
		|  | @ -77,6 +77,12 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | |||
|     HW::Update(); | ||||
|     Reschedule(); | ||||
| 
 | ||||
|     if (reset_requested.exchange(false)) { | ||||
|         Reset(); | ||||
|     } else if (shutdown_requested.exchange(false)) { | ||||
|         return ResultStatus::ShutdownRequested; | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
|     status = ResultStatus::Success; | ||||
|     m_emu_window = &emu_window; | ||||
|     m_filepath = filepath; | ||||
|     return status; | ||||
| } | ||||
| 
 | ||||
|  | @ -241,4 +249,14 @@ void System::Shutdown() { | |||
|     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
 | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ public: | |||
|                                             /// generic drivers installed
 | ||||
|         ErrorVideoCore_ErrorBelowGL33,      ///< Error in the video core due to the user not having
 | ||||
|                                             /// OpenGL 3.3 or higher
 | ||||
|         ShutdownRequested,                  ///< Emulated program requested a system shutdown
 | ||||
|         ErrorUnknown                        ///< Any other error
 | ||||
|     }; | ||||
| 
 | ||||
|  | @ -83,6 +84,19 @@ public: | |||
|     /// Shutdown the emulated system.
 | ||||
|     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. | ||||
|      * @param emu_window Reference to the host-system window used for video output and keyboard | ||||
|  | @ -216,6 +230,12 @@ private: | |||
| 
 | ||||
|     ResultStatus status = ResultStatus::Success; | ||||
|     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() { | ||||
|  |  | |||
|  | @ -543,6 +543,65 @@ void Module::Interface::StartLibraryApplet(Kernel::HLERequestContext& ctx) { | |||
|     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) { | ||||
|     IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040
 | ||||
|     bool exiting = rp.Pop<bool>(); | ||||
|  |  | |||
|  | @ -409,6 +409,49 @@ public: | |||
|          */ | ||||
|         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 | ||||
|          *  Inputs: | ||||
|  | @ -533,6 +576,7 @@ public: | |||
| 
 | ||||
|     private: | ||||
|         std::shared_ptr<Module> apt; | ||||
|         bool application_reset_prepared{}; | ||||
|     }; | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt) | |||
|         {0x00240044, nullptr, "JumpToApplication"}, | ||||
|         {0x002500C0, &APT_A::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"}, | ||||
|         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, | ||||
|         {0x00270044, nullptr, "CloseApplication"}, | ||||
|         {0x00270044, &APT_A::CloseApplication, "CloseApplication"}, | ||||
|         {0x00280044, &APT_A::CloseLibraryApplet, "CloseLibraryApplet"}, | ||||
|         {0x00290044, nullptr, "CloseSystemApplet"}, | ||||
|         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, | ||||
|  | @ -58,8 +58,8 @@ APT_A::APT_A(std::shared_ptr<Module> apt) | |||
|         {0x002E0044, nullptr, "LeaveHomeMenu"}, | ||||
|         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, | ||||
|         {0x00300044, nullptr, "LeaveResidentApplet"}, | ||||
|         {0x00310100, nullptr, "PrepareToDoApplicationJump"}, | ||||
|         {0x00320084, nullptr, "DoApplicationJump"}, | ||||
|         {0x00310100, &APT_A::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"}, | ||||
|         {0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"}, | ||||
|         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, | ||||
|         {0x00340084, nullptr, "SendDeliverArg"}, | ||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ APT_S::APT_S(std::shared_ptr<Module> apt) | |||
|         {0x00240044, nullptr, "JumpToApplication"}, | ||||
|         {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, | ||||
|         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, | ||||
|         {0x00270044, nullptr, "CloseApplication"}, | ||||
|         {0x00270044, &APT_S::CloseApplication, "CloseApplication"}, | ||||
|         {0x00280044, nullptr, "CloseLibraryApplet"}, | ||||
|         {0x00290044, nullptr, "CloseSystemApplet"}, | ||||
|         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, | ||||
|  | @ -58,8 +58,8 @@ APT_S::APT_S(std::shared_ptr<Module> apt) | |||
|         {0x002E0044, nullptr, "LeaveHomeMenu"}, | ||||
|         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, | ||||
|         {0x00300044, nullptr, "LeaveResidentApplet"}, | ||||
|         {0x00310100, nullptr, "PrepareToDoApplicationJump"}, | ||||
|         {0x00320084, nullptr, "DoApplicationJump"}, | ||||
|         {0x00310100, &APT_S::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"}, | ||||
|         {0x00320084, &APT_S::DoApplicationJump, "DoApplicationJump"}, | ||||
|         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, | ||||
|         {0x00340084, nullptr, "SendDeliverArg"}, | ||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ APT_U::APT_U(std::shared_ptr<Module> apt) | |||
|         {0x00240044, nullptr, "JumpToApplication"}, | ||||
|         {0x002500C0, &APT_U::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"}, | ||||
|         {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, | ||||
|         {0x00270044, nullptr, "CloseApplication"}, | ||||
|         {0x00270044, &APT_U::CloseApplication, "CloseApplication"}, | ||||
|         {0x00280044, &APT_U::CloseLibraryApplet, "CloseLibraryApplet"}, | ||||
|         {0x00290044, nullptr, "CloseSystemApplet"}, | ||||
|         {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, | ||||
|  | @ -58,8 +58,8 @@ APT_U::APT_U(std::shared_ptr<Module> apt) | |||
|         {0x002E0044, nullptr, "LeaveHomeMenu"}, | ||||
|         {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, | ||||
|         {0x00300044, nullptr, "LeaveResidentApplet"}, | ||||
|         {0x00310100, nullptr, "PrepareToDoApplicationJump"}, | ||||
|         {0x00320084, nullptr, "DoApplicationJump"}, | ||||
|         {0x00310100, &APT_U::PrepareToDoApplicationJump, "PrepareToDoApplicationJump"}, | ||||
|         {0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"}, | ||||
|         {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, | ||||
|         {0x00340084, nullptr, "SendDeliverArg"}, | ||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue