From 758d84db9adf6d4cf72de4c76059f8ab18fd4584 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 26 Mar 2019 15:12:09 -0400 Subject: service/am: Implement EnterFatalSection and LeaveFatalSection These functions act in tandem similar to how a lock or mutex require a balanced lock()/unlock() sequence. EnterFatalSection simply increments a counter for how many times it has been called, while LeaveFatalSection ensures that a previous call to EnterFatalSection has occured. If a previous call has occurred (the counter is not zero), then the counter gets decremented as one would expect. If a previous call has not occurred (the counter is zero), then an error code is returned. --- src/core/hle/service/am/am.cpp | 28 ++++++++++++++++++++++++++-- src/core/hle/service/am/am.h | 3 +++ 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'src') 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 { -- cgit v1.2.3