aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/HOS/Services/Apm
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Apm
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Apm')
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs43
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs19
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs45
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs42
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs31
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs25
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs12
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs58
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs28
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs9
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs22
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs8
12 files changed, 342 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs b/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
new file mode 100644
index 00000000..72e39a77
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Apm/IManager.cs
@@ -0,0 +1,43 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ abstract class IManager : IpcService
+ {
+ public IManager(ServiceCtx context) { }
+
+ protected abstract ResultCode OpenSession(out SessionServer sessionServer);
+ protected abstract PerformanceMode GetPerformanceMode();
+ protected abstract bool IsCpuOverclockEnabled();
+
+ [CommandCmif(0)]
+ // OpenSession() -> object<nn::apm::ISession>
+ public ResultCode OpenSession(ServiceCtx context)
+ {
+ ResultCode resultCode = OpenSession(out SessionServer sessionServer);
+
+ if (resultCode == ResultCode.Success)
+ {
+ MakeObject(context, sessionServer);
+ }
+
+ return resultCode;
+ }
+
+ [CommandCmif(1)]
+ // GetPerformanceMode() -> nn::apm::PerformanceMode
+ public ResultCode GetPerformanceMode(ServiceCtx context)
+ {
+ context.ResponseData.Write((uint)GetPerformanceMode());
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(6)] // 7.0.0+
+ // IsCpuOverclockEnabled() -> bool
+ public ResultCode IsCpuOverclockEnabled(ServiceCtx context)
+ {
+ context.ResponseData.Write(IsCpuOverclockEnabled());
+
+ return ResultCode.Success;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs b/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs
new file mode 100644
index 00000000..9620c30a
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Apm/IManagerPrivileged.cs
@@ -0,0 +1,19 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ // NOTE: This service doesn’t exist anymore after firmware 7.0.1. But some outdated homebrew still uses it.
+
+ [Service("apm:p")] // 1.0.0-7.0.1
+ class IManagerPrivileged : IpcService
+ {
+ public IManagerPrivileged(ServiceCtx context) { }
+
+ [CommandCmif(0)]
+ // OpenSession() -> object<nn::apm::ISession>
+ public ResultCode OpenSession(ServiceCtx context)
+ {
+ MakeObject(context, new SessionServer(context));
+
+ return ResultCode.Success;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
new file mode 100644
index 00000000..f828cd17
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Apm/ISession.cs
@@ -0,0 +1,45 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ abstract class ISession : IpcService
+ {
+ 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);
+
+ [CommandCmif(0)]
+ // SetPerformanceConfiguration(nn::apm::PerformanceMode, nn::apm::PerformanceConfiguration)
+ public ResultCode SetPerformanceConfiguration(ServiceCtx context)
+ {
+ PerformanceMode performanceMode = (PerformanceMode)context.RequestData.ReadInt32();
+ PerformanceConfiguration performanceConfiguration = (PerformanceConfiguration)context.RequestData.ReadInt32();
+
+ return SetPerformanceConfiguration(performanceMode, performanceConfiguration);
+ }
+
+ [CommandCmif(1)]
+ // GetPerformanceConfiguration(nn::apm::PerformanceMode) -> nn::apm::PerformanceConfiguration
+ public ResultCode GetPerformanceConfiguration(ServiceCtx context)
+ {
+ PerformanceMode performanceMode = (PerformanceMode)context.RequestData.ReadInt32();
+
+ ResultCode resultCode = GetPerformanceConfiguration(performanceMode, out PerformanceConfiguration performanceConfiguration);
+
+ context.ResponseData.Write((uint)performanceConfiguration);
+
+ return resultCode;
+ }
+
+ [CommandCmif(2)] // 8.0.0+
+ // SetCpuOverclockEnabled(bool)
+ public ResultCode SetCpuOverclockEnabled(ServiceCtx context)
+ {
+ bool enabled = context.RequestData.ReadBoolean();
+
+ SetCpuOverclockEnabled(enabled);
+
+ return ResultCode.Success;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ISystemManager.cs
new file mode 100644
index 00000000..9d2c7b0b
--- /dev/null
+++ b/src/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();
+
+ [CommandCmif(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;
+ }
+
+ [CommandCmif(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;
+ }
+
+ [CommandCmif(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/src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ManagerServer.cs
new file mode 100644
index 00000000..af051934
--- /dev/null
+++ b/src/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/src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs b/src/Ryujinx.HLE/HOS/Services/Apm/PerformanceState.cs
new file mode 100644
index 00000000..d03bf6c7
--- /dev/null
+++ b/src/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/src/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Apm/ResultCode.cs
new file mode 100644
index 00000000..c4499b01
--- /dev/null
+++ b/src/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/src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs b/src/Ryujinx.HLE/HOS/Services/Apm/SessionServer.cs
new file mode 100644
index 00000000..3ef713cf
--- /dev/null
+++ b/src/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/src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs b/src/Ryujinx.HLE/HOS/Services/Apm/SystemManagerServer.cs
new file mode 100644
index 00000000..a6264236
--- /dev/null
+++ b/src/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/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs b/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
new file mode 100644
index 00000000..587142c8
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Apm/Types/CpuBoostMode.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ enum CpuBoostMode
+ {
+ 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/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
new file mode 100644
index 00000000..e8c5752e
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceConfiguration.cs
@@ -0,0 +1,22 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ 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.
+ PerformanceConfiguration3 = 0x00010002, // 1224 | 691.2 | 1600 | Only available for SDEV units.
+ PerformanceConfiguration4 = 0x00020000, // 1020 | 230.4 | 1600 | Only available for SDEV units.
+ PerformanceConfiguration5 = 0x00020001, // 1020 | 307.2 | 1600 |
+ PerformanceConfiguration6 = 0x00020002, // 1224 | 230.4 | 1600 |
+ PerformanceConfiguration7 = 0x00020003, // 1020 | 307 | 1331.2 |
+ PerformanceConfiguration8 = 0x00020004, // 1020 | 384 | 1331.2 |
+ PerformanceConfiguration9 = 0x00020005, // 1020 | 307.2 | 1065.6 |
+ PerformanceConfiguration10 = 0x00020006, // 1020 | 384 | 1065.6 |
+ PerformanceConfiguration11 = 0x92220007, // 1020 | 460.8 | 1600 |
+ PerformanceConfiguration12 = 0x92220008, // 1020 | 460.8 | 1331.2 |
+ PerformanceConfiguration13 = 0x92220009, // 1785 | 768 | 1600 | 7.0.0+
+ PerformanceConfiguration14 = 0x9222000A, // 1785 | 768 | 1331.2 | 7.0.0+
+ PerformanceConfiguration15 = 0x9222000B, // 1020 | 768 | 1600 | 7.0.0+
+ PerformanceConfiguration16 = 0x9222000C // 1020 | 768 | 1331.2 | 7.0.0+
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
new file mode 100644
index 00000000..6d6f9643
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Apm/Types/PerformanceMode.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Apm
+{
+ enum PerformanceMode : uint
+ {
+ Default = 0,
+ Boost = 1
+ }
+} \ No newline at end of file