From 1c6e6305eab7a6e98a73d9ba5cdb880ac74d9116 Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Fri, 28 Jun 2019 22:45:31 -0400
Subject: [PATCH] apm: Add getters for performance config and mode

---
 src/core/hle/service/apm/interface.cpp | 70 ++++++++++++++------------
 src/core/hle/service/apm/interface.h   | 12 ++++-
 2 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp
index d058c0245a..b2241366f5 100644
--- a/src/core/hle/service/apm/interface.cpp
+++ b/src/core/hle/service/apm/interface.cpp
@@ -5,43 +5,32 @@
 #include "common/logging/log.h"
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/service/apm/apm.h"
+#include "core/hle/service/apm/controller.h"
 #include "core/hle/service/apm/interface.h"
 
 namespace Service::APM {
 
 class ISession final : public ServiceFramework<ISession> {
 public:
-    ISession() : ServiceFramework("ISession") {
+    ISession(Controller& controller) : ServiceFramework("ISession"), controller(controller) {
         static const FunctionInfo functions[] = {
             {0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
             {1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
+            {2, nullptr, "SetCpuOverclockEnabled"},
         };
         RegisterHandlers(functions);
     }
 
 private:
-    enum class PerformanceConfiguration : u32 {
-        Config1 = 0x00010000,
-        Config2 = 0x00010001,
-        Config3 = 0x00010002,
-        Config4 = 0x00020000,
-        Config5 = 0x00020001,
-        Config6 = 0x00020002,
-        Config7 = 0x00020003,
-        Config8 = 0x00020004,
-        Config9 = 0x00020005,
-        Config10 = 0x00020006,
-        Config11 = 0x92220007,
-        Config12 = 0x92220008,
-    };
-
     void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
         IPC::RequestParser rp{ctx};
 
-        auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
-        u32 config = rp.Pop<u32>();
-        LOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode),
-                    config);
+        const auto mode = rp.PopEnum<PerformanceMode>();
+        const auto config = rp.PopEnum<PerformanceConfiguration>();
+        LOG_DEBUG(Service_APM, "called mode={} config={}", static_cast<u32>(mode),
+                  static_cast<u32>(config));
+
+        controller.SetPerformanceConfiguration(mode, config);
 
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
@@ -50,20 +39,23 @@ private:
     void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
         IPC::RequestParser rp{ctx};
 
-        auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
-        LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode));
+        const auto mode = rp.PopEnum<PerformanceMode>();
+        LOG_DEBUG(Service_APM, "called mode={}", static_cast<u32>(mode));
 
         IPC::ResponseBuilder rb{ctx, 3};
         rb.Push(RESULT_SUCCESS);
-        rb.Push<u32>(static_cast<u32>(PerformanceConfiguration::Config1));
+        rb.PushEnum(controller.GetCurrentPerformanceConfiguration(mode));
     }
+
+    Controller& controller;
 };
 
-APM::APM(std::shared_ptr<Module> apm, const char* name)
-    : ServiceFramework(name), apm(std::move(apm)) {
+APM::APM(std::shared_ptr<Module> apm, Controller& controller, const char* name)
+    : ServiceFramework(name), apm(std::move(apm)), controller(controller) {
     static const FunctionInfo functions[] = {
         {0, &APM::OpenSession, "OpenSession"},
-        {1, nullptr, "GetPerformanceMode"},
+        {1, &APM::GetPerformanceMode, "GetPerformanceMode"},
+        {6, nullptr, "IsCpuOverclockEnabled"},
     };
     RegisterHandlers(functions);
 }
@@ -75,10 +67,17 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ISession>();
+    rb.PushIpcInterface<ISession>(controller);
 }
 
-APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
+void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_APM, "called");
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.PushEnum(controller.GetCurrentPerformanceMode());
+}
+
+APM_Sys::APM_Sys(Controller& controller) : ServiceFramework{"apm:sys"}, controller(controller) {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, nullptr, "RequestPerformanceMode"},
@@ -87,8 +86,8 @@ APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
         {3, nullptr, "GetLastThrottlingState"},
         {4, nullptr, "ClearLastThrottlingState"},
         {5, nullptr, "LoadAndApplySettings"},
-        {6, nullptr, "SetCpuBoostMode"},
-        {7, nullptr, "GetCurrentPerformanceConfiguration"},
+        {6, &APM_Sys::SetCpuBoostMode, "SetCpuBoostMode"},
+        {7, &APM_Sys::GetCurrentPerformanceConfiguration, "GetCurrentPerformanceConfiguration"},
     };
     // clang-format on
 
@@ -102,7 +101,16 @@ void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ISession>();
+    rb.PushIpcInterface<ISession>(controller);
+}
+
+void APM_Sys::GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_APM, "called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(RESULT_SUCCESS);
+    rb.PushEnum(
+        controller.GetCurrentPerformanceConfiguration(controller.GetCurrentPerformanceMode()));
 }
 
 } // namespace Service::APM
diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h
index 773541aa4b..6d5fdf8ef2 100644
--- a/src/core/hle/service/apm/interface.h
+++ b/src/core/hle/service/apm/interface.h
@@ -8,24 +8,32 @@
 
 namespace Service::APM {
 
+class Controller;
+class Module;
+
 class APM final : public ServiceFramework<APM> {
 public:
-    explicit APM(std::shared_ptr<Module> apm, const char* name);
+    explicit APM(std::shared_ptr<Module> apm, Controller& controller, const char* name);
     ~APM() override;
 
 private:
     void OpenSession(Kernel::HLERequestContext& ctx);
+    void GetPerformanceMode(Kernel::HLERequestContext& ctx);
 
     std::shared_ptr<Module> apm;
+    Controller& controller;
 };
 
 class APM_Sys final : public ServiceFramework<APM_Sys> {
 public:
-    explicit APM_Sys();
+    explicit APM_Sys(Controller& controller);
     ~APM_Sys() override;
 
 private:
     void GetPerformanceEvent(Kernel::HLERequestContext& ctx);
+    void GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx);
+
+    Controller& controller;
 };
 
 } // namespace Service::APM