service/apt: Implement soft reset & CloseApplication
This commit is contained in:
parent
ca701e2610
commit
ad6b140cb0
@ -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);
|
||||||
message_box.exec();
|
if (result != Core::System::ResultStatus::ShutdownRequested)
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +137,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,4 +246,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
|
||||||
|
@ -55,6 +55,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
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,6 +80,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
|
||||||
@ -209,6 +223,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…
Reference in New Issue
Block a user