diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 336593108..d31ab7970 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -239,8 +239,8 @@ ISelfController::ISelfController(std::shared_ptr nvflinger {0, nullptr, "Exit"}, {1, &ISelfController::LockExit, "LockExit"}, {2, &ISelfController::UnlockExit, "UnlockExit"}, - {3, nullptr, "EnterFatalSection"}, - {4, nullptr, "LeaveFatalSection"}, + {3, &ISelfController::EnterFatalSection, "EnterFatalSection"}, + {4, &ISelfController::LeaveFatalSection, "LeaveFatalSection"}, {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"}, {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"}, {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"}, @@ -299,6 +299,30 @@ void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void ISelfController::EnterFatalSection(Kernel::HLERequestContext& ctx) { + ++num_fatal_sections_entered; + LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", num_fatal_sections_entered); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called."); + + // Entry and exit of fatal sections must be balanced. + if (num_fatal_sections_entered == 0) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode{ErrorModule::AM, 512}); + return; + } + + --num_fatal_sections_entered; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 222e6bcde..991b7d47c 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -119,6 +119,8 @@ public: private: void LockExit(Kernel::HLERequestContext& ctx); void UnlockExit(Kernel::HLERequestContext& ctx); + void EnterFatalSection(Kernel::HLERequestContext& ctx); + void LeaveFatalSection(Kernel::HLERequestContext& ctx); void GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx); void SetScreenShotPermission(Kernel::HLERequestContext& ctx); void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx); @@ -135,6 +137,7 @@ private: std::shared_ptr nvflinger; Kernel::EventPair launchable_event; u32 idle_time_detection_extension = 0; + u64 num_fatal_sections_entered = 0; }; class ICommonStateGetter final : public ServiceFramework {