diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index 98df85857..0f3cd41bb 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -15,6 +15,7 @@ using Ryujinx.HLE.HOS.Kernel.Memory;
 using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.HOS.Kernel.Threading;
 using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy;
+using Ryujinx.HLE.HOS.Services.Apm;
 using Ryujinx.HLE.HOS.Services.Arp;
 using Ryujinx.HLE.HOS.Services.Audio.AudioRenderer;
 using Ryujinx.HLE.HOS.Services.Mii;
@@ -53,6 +54,8 @@ namespace Ryujinx.HLE.HOS
 
         public SystemStateMgr State { get; private set; }
 
+        internal PerformanceState PerformanceState { get; private set; }
+
         internal AppletStateMgr AppletState { get; private set; }
 
         internal KSharedMemory HidSharedMem  { get; private set; }
@@ -94,6 +97,8 @@ namespace Ryujinx.HLE.HOS
 
             State = new SystemStateMgr();
 
+            PerformanceState = new PerformanceState();
+
             // Note: This is not really correct, but with HLE of services, the only memory
             // region used that is used is Application, so we can use the other ones for anything.
             KMemoryRegionManager region = KernelContext.MemoryRegions[(int)MemoryRegion.NvServices];
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs
index de2281c23..f131aff85 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/ISystemAppletProxy.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
         // GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
         public ResultCode GetCommonStateGetter(ServiceCtx context)
         {
-            MakeObject(context, new ICommonStateGetter());
+            MakeObject(context, new ICommonStateGetter(context));
 
             return ResultCode.Success;
         }
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs
index a21131638..82e189221 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ICommonStateGetter.cs
@@ -2,17 +2,22 @@ using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
 using Ryujinx.HLE.HOS.Kernel.Common;
 using Ryujinx.HLE.HOS.Kernel.Threading;
-using Ryujinx.HLE.HOS.Services.Apm;
 using System;
 
 namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
 {
     class ICommonStateGetter : IpcService
     {
-        private CpuBoostMode _cpuBoostMode  = CpuBoostMode.Disabled;
-        private bool         _vrModeEnabled = false;
+        private Apm.ManagerServer       apmManagerServer;
+        private Apm.SystemManagerServer apmSystemManagerServer;
 
-        public ICommonStateGetter() { }
+        private bool _vrModeEnabled = false;
+
+        public ICommonStateGetter(ServiceCtx context)
+        {
+            apmManagerServer       = new Apm.ManagerServer(context);
+            apmSystemManagerServer = new Apm.SystemManagerServer(context);
+        }
 
         [Command(0)]
         // GetEventHandle() -> handle<copy>
@@ -58,16 +63,10 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
         }
 
         [Command(6)]
-        // GetPerformanceMode() -> u32
+        // GetPerformanceMode() -> nn::apm::PerformanceMode
         public ResultCode GetPerformanceMode(ServiceCtx context)
         {
-            PerformanceMode mode = context.Device.System.State.DockedMode
-                ? PerformanceMode.Docked
-                : PerformanceMode.Handheld;
-
-            context.ResponseData.Write((int)mode);
-
-            return ResultCode.Success;
+            return (ResultCode)apmManagerServer.GetPerformanceMode(context);
         }
 
         [Command(8)]
@@ -136,12 +135,18 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
                 return ResultCode.InvalidParameters;
             }
 
-            _cpuBoostMode = (CpuBoostMode)cpuBoostMode;
+            apmSystemManagerServer.SetCpuBoostMode((Apm.CpuBoostMode)cpuBoostMode);
 
-            // NOTE: There is a condition variable after the assignment, probably waiting something with apm:sys service (SetCpuBoostMode call?).
-            //       Since we will probably never support CPU boost things, it's not needed to implement more.
+            // TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used. 
 
             return ResultCode.Success;
         }
+
+        [Command(91)] // 7.0.0+
+        // GetCurrentPerformanceConfiguration() -> nn::apm::PerformanceConfiguration
+        public ResultCode GetCurrentPerformanceConfiguration(ServiceCtx context)
+        {
+            return (ResultCode)apmSystemManagerServer.GetCurrentPerformanceConfiguration(context);
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs
index 3d3287d07..700886fd7 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/IApplicationProxy.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService
         // GetCommonStateGetter() -> object<nn::am::service::ICommonStateGetter>
         public ResultCode GetCommonStateGetter(ServiceCtx context)
         {
-            MakeObject(context, new ICommonStateGetter());
+            MakeObject(context, new ICommonStateGetter(context));
 
             return ResultCode.Success;
         }
diff --git a/Ryujinx.HLE/HOS/Services/Apm/IManager.cs b/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
index 19fbcd44b..ae1cfba81 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
@@ -1,15 +1,41 @@
 namespace Ryujinx.HLE.HOS.Services.Apm
 {
-    [Service("apm")] // 8.0.0+
-    class IManager : IpcService
+    abstract class IManager : IpcService
     {
         public IManager(ServiceCtx context) { }
 
+        protected abstract ResultCode OpenSession(out SessionServer sessionServer);
+        protected abstract PerformanceMode GetPerformanceMode();
+        protected abstract bool IsCpuOverclockEnabled();
+
         [Command(0)]
         // OpenSession() -> object<nn::apm::ISession>
         public ResultCode OpenSession(ServiceCtx context)
         {
-            MakeObject(context, new ISession());
+            ResultCode resultCode = OpenSession(out SessionServer sessionServer);
+
+            if (resultCode == ResultCode.Success)
+            {
+                MakeObject(context, sessionServer);
+            }
+
+            return resultCode;
+        }
+
+        [Command(1)]
+        // GetPerformanceMode() -> nn::apm::PerformanceMode
+        public ResultCode GetPerformanceMode(ServiceCtx context)
+        {
+            context.ResponseData.Write((uint)GetPerformanceMode());
+
+            return ResultCode.Success;
+        }
+
+        [Command(6)] // 7.0.0+
+        // IsCpuOverclockEnabled() -> bool
+        public ResultCode IsCpuOverclockEnabled(ServiceCtx context)
+        {
+            context.ResponseData.Write(IsCpuOverclockEnabled());
 
             return ResultCode.Success;
         }
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ISession.cs b/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
index a979af766..95bdf35d3 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
@@ -1,30 +1,43 @@
-using Ryujinx.Common.Logging;
-
 namespace Ryujinx.HLE.HOS.Services.Apm
 {
-    class ISession : IpcService
+    abstract class ISession : IpcService
     {
-        public ISession() { }
+        public ISession(ServiceCtx context) { }
+
+        protected abstract ResultCode SetPerformanceConfiguration(PerformanceMode performanceMode, PerformanceConfiguration performanceConfiguration);
+        protected abstract ResultCode GetPerformanceConfiguration(PerformanceMode performanceMode, out PerformanceConfiguration performanceConfiguration);
+        protected abstract void SetCpuOverclockEnabled(bool enabled);
 
         [Command(0)]
         // SetPerformanceConfiguration(nn::apm::PerformanceMode, nn::apm::PerformanceConfiguration)
         public ResultCode SetPerformanceConfiguration(ServiceCtx context)
         {
-            PerformanceMode          perfMode   = (PerformanceMode)context.RequestData.ReadInt32();
-            PerformanceConfiguration perfConfig = (PerformanceConfiguration)context.RequestData.ReadInt32();
+            PerformanceMode          performanceMode          = (PerformanceMode)context.RequestData.ReadInt32();
+            PerformanceConfiguration performanceConfiguration = (PerformanceConfiguration)context.RequestData.ReadInt32();
 
-            return ResultCode.Success;
+            return SetPerformanceConfiguration(performanceMode, performanceConfiguration);
         }
 
         [Command(1)]
         // GetPerformanceConfiguration(nn::apm::PerformanceMode) -> nn::apm::PerformanceConfiguration
         public ResultCode GetPerformanceConfiguration(ServiceCtx context)
         {
-            PerformanceMode perfMode = (PerformanceMode)context.RequestData.ReadInt32();
+            PerformanceMode performanceMode = (PerformanceMode)context.RequestData.ReadInt32();
 
-            context.ResponseData.Write((uint)PerformanceConfiguration.PerformanceConfiguration1);
+            ResultCode resultCode = GetPerformanceConfiguration(performanceMode, out PerformanceConfiguration performanceConfiguration);
 
-            Logger.Stub?.PrintStub(LogClass.ServiceApm);
+            context.ResponseData.Write((uint)performanceConfiguration);
+
+            return resultCode;
+        }
+
+        [Command(2)] // 8.0.0+
+        // SetCpuOverclockEnabled(bool)
+        public ResultCode SetCpuOverclockEnabled(ServiceCtx context)
+        {
+            bool enabled = context.RequestData.ReadBoolean();
+
+            SetCpuOverclockEnabled(enabled);
 
             return ResultCode.Success;
         }
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs b/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs
new file mode 100644
index 000000000..f7b2f450f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs
@@ -0,0 +1,42 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+    abstract class ISystemManager : IpcService
+    {
+        public ISystemManager(ServiceCtx context) { }
+
+        protected abstract void RequestPerformanceMode(PerformanceMode performanceMode);
+        internal abstract void SetCpuBoostMode(CpuBoostMode cpuBoostMode);
+        protected abstract PerformanceConfiguration GetCurrentPerformanceConfiguration();
+
+        [Command(0)]
+        // RequestPerformanceMode(nn::apm::PerformanceMode)
+        public ResultCode RequestPerformanceMode(ServiceCtx context)
+        {
+            RequestPerformanceMode((PerformanceMode)context.RequestData.ReadInt32());
+
+            // NOTE: This call seems to overclock the system related to the PerformanceMode, since we emulate it, it's fine to do nothing instead.
+
+            return ResultCode.Success;
+        }
+
+        [Command(6)] // 7.0.0+
+        // SetCpuBoostMode(nn::apm::CpuBootMode)
+        public ResultCode SetCpuBoostMode(ServiceCtx context)
+        {
+            SetCpuBoostMode((CpuBoostMode)context.RequestData.ReadUInt32());
+
+            // NOTE: This call seems to overclock the system related to the CpuBoostMode, since we emulate it, it's fine to do nothing instead.
+
+            return ResultCode.Success;
+        }
+
+        [Command(7)] // 7.0.0+
+        // GetCurrentPerformanceConfiguration() -> nn::apm::PerformanceConfiguration
+        public ResultCode GetCurrentPerformanceConfiguration(ServiceCtx context)
+        {
+            context.ResponseData.Write((uint)GetCurrentPerformanceConfiguration());
+
+            return ResultCode.Success;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs b/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs
new file mode 100644
index 000000000..af0519344
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs
@@ -0,0 +1,31 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+    [Service("apm")]
+    [Service("apm:am")] // 8.0.0+
+    class ManagerServer : IManager
+    {
+        private readonly ServiceCtx _context;
+
+        public ManagerServer(ServiceCtx context) : base(context)
+        {
+            _context = context;
+        }
+
+        protected override ResultCode OpenSession(out SessionServer sessionServer)
+        {
+            sessionServer = new SessionServer(_context);
+
+            return ResultCode.Success;
+        }
+
+        protected override PerformanceMode GetPerformanceMode()
+        {
+            return _context.Device.System.PerformanceState.PerformanceMode;
+        }
+
+        protected override bool IsCpuOverclockEnabled()
+        {
+            return _context.Device.System.PerformanceState.CpuOverclockEnabled;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs b/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs
new file mode 100644
index 000000000..d03bf6c72
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs
@@ -0,0 +1,25 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+    class PerformanceState
+    {
+        public PerformanceState() { }
+
+        public bool CpuOverclockEnabled = false;
+
+        public PerformanceMode PerformanceMode = PerformanceMode.Default;
+        public CpuBoostMode    CpuBoostMode    = CpuBoostMode.Disabled;
+
+        public PerformanceConfiguration DefaultPerformanceConfiguration = PerformanceConfiguration.PerformanceConfiguration7;
+        public PerformanceConfiguration BoostPerformanceConfiguration   = PerformanceConfiguration.PerformanceConfiguration8;
+
+        public PerformanceConfiguration GetCurrentPerformanceConfiguration(PerformanceMode performanceMode)
+        {
+            return performanceMode switch
+            {
+                PerformanceMode.Default => DefaultPerformanceConfiguration,
+                PerformanceMode.Boost   => BoostPerformanceConfiguration,
+                _                       => PerformanceConfiguration.PerformanceConfiguration7
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs
new file mode 100644
index 000000000..c4499b014
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+    enum ResultCode
+    {
+        ModuleId       = 148,
+        ErrorCodeShift = 9,
+
+        Success = 0,
+
+        InvalidParameters = (1 << ErrorCodeShift) | ModuleId
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs b/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs
new file mode 100644
index 000000000..3ef713cf3
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs
@@ -0,0 +1,58 @@
+using Ryujinx.Common.Logging;
+
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+    class SessionServer : ISession
+    {
+        private readonly ServiceCtx _context;
+
+        public SessionServer(ServiceCtx context) : base(context) 
+        {
+            _context = context;
+        }
+
+        protected override ResultCode SetPerformanceConfiguration(PerformanceMode performanceMode, PerformanceConfiguration performanceConfiguration)
+        {
+            if (performanceMode > PerformanceMode.Boost)
+            {
+                return ResultCode.InvalidParameters;
+            }
+
+            switch (performanceMode)
+            {
+                case PerformanceMode.Default:
+                    _context.Device.System.PerformanceState.DefaultPerformanceConfiguration = performanceConfiguration;
+                    break;
+                case PerformanceMode.Boost:
+                    _context.Device.System.PerformanceState.BoostPerformanceConfiguration = performanceConfiguration;
+                    break;
+                default:
+                    Logger.Error?.Print(LogClass.ServiceApm, $"PerformanceMode isn't supported: {performanceMode}");
+                    break;
+            }
+
+            return ResultCode.Success;
+        }
+
+        protected override ResultCode GetPerformanceConfiguration(PerformanceMode performanceMode, out PerformanceConfiguration performanceConfiguration)
+        {
+            if (performanceMode > PerformanceMode.Boost)
+            {
+                performanceConfiguration = 0;
+
+                return ResultCode.InvalidParameters;
+            }
+
+            performanceConfiguration = _context.Device.System.PerformanceState.GetCurrentPerformanceConfiguration(performanceMode);
+
+            return ResultCode.Success;
+        }
+
+        protected override void SetCpuOverclockEnabled(bool enabled)
+        {
+            _context.Device.System.PerformanceState.CpuOverclockEnabled = enabled;
+
+            // NOTE: This call seems to overclock the system, since we emulate it, it's fine to do nothing instead.
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs b/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs
new file mode 100644
index 000000000..a62642360
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs
@@ -0,0 +1,28 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+    [Service("apm:sys")]
+    class SystemManagerServer : ISystemManager
+    {
+        private readonly ServiceCtx _context;
+
+        public SystemManagerServer(ServiceCtx context) : base(context)
+        {
+            _context = context;
+        }
+
+        protected override void RequestPerformanceMode(PerformanceMode performanceMode)
+        {
+            _context.Device.System.PerformanceState.PerformanceMode = performanceMode;
+        }
+
+        internal override void SetCpuBoostMode(CpuBoostMode cpuBoostMode)
+        {
+            _context.Device.System.PerformanceState.CpuBoostMode = cpuBoostMode;
+        }
+
+        protected override PerformanceConfiguration GetCurrentPerformanceConfiguration()
+        {
+            return _context.Device.System.PerformanceState.GetCurrentPerformanceConfiguration(_context.Device.System.PerformanceState.PerformanceMode);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs b/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
index a4c87d3cc..587142c83 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
@@ -2,8 +2,8 @@
 {
     enum CpuBoostMode
     {
-        Disabled = 0,
-        Mode1    = 1, // Use PerformanceConfiguration13 and PerformanceConfiguration14, or PerformanceConfiguration15 and PerformanceConfiguration16
-        Mode2    = 2  // Use PerformanceConfiguration15 and PerformanceConfiguration16.
+        Disabled      = 0,
+        BoostCPU      = 1, // Uses PerformanceConfiguration13 and PerformanceConfiguration14, or PerformanceConfiguration15 and PerformanceConfiguration16
+        ConservePower = 2  // Uses PerformanceConfiguration15 and PerformanceConfiguration16.
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
index e42edebcc..e8c5752e4 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
@@ -1,6 +1,6 @@
 namespace Ryujinx.HLE.HOS.Services.Apm
 {
-    enum PerformanceConfiguration : uint         // Clocks are all in MHz.
+    enum PerformanceConfiguration : uint  // Clocks are all in MHz.
     {                                            // CPU  | GPU   | RAM    | NOTE
         PerformanceConfiguration1  = 0x00010000, // 1020 | 384   | 1600   | Only available while docked.
         PerformanceConfiguration2  = 0x00010001, // 1020 | 768   | 1600   | Only available while docked.
diff --git a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
index a7a0dfad2..6d6f9643e 100644
--- a/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
+++ b/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
@@ -1,8 +1,8 @@
 namespace Ryujinx.HLE.HOS.Services.Apm
 {
-    enum PerformanceMode
+    enum PerformanceMode : uint
     {
-        Handheld = 0,
-        Docked   = 1
+        Default = 0,
+        Boost   = 1
     }
 }
\ No newline at end of file