aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs118
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/ResultCode.cs12
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs24
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs35
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs12
-rw-r--r--Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs20
7 files changed, 227 insertions, 2 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs b/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs
index b4aebc7e..15625fc2 100644
--- a/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs
+++ b/Ryujinx.HLE/HOS/Services/Spl/IGeneralInterface.cs
@@ -1,13 +1,127 @@
-namespace Ryujinx.HLE.HOS.Services.Sm
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.FileSystem.Content;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Services.Spl.Types;
+
+namespace Ryujinx.HLE.HOS.Services.Spl
{
[Service("spl:")]
[Service("spl:es")]
[Service("spl:fs")]
[Service("spl:manu")]
[Service("spl:mig")]
- [Service("spl:ssl")]
+ [Service("spl:ssl")]
class IGeneralInterface : IpcService
{
public IGeneralInterface(ServiceCtx context) { }
+
+ [CommandHipc(0)]
+ // GetConfig(u32 config_item) -> u64 config_value
+ public ResultCode GetConfig(ServiceCtx context)
+ {
+ ConfigItem configItem = (ConfigItem)context.RequestData.ReadUInt32();
+
+ // NOTE: Nintendo explicitly blacklists package2 hash here, amusingly.
+ // This is not blacklisted in safemode, but we're never in safe mode...
+ if (configItem == ConfigItem.Package2Hash)
+ {
+ return ResultCode.InvalidArguments;
+ }
+
+ // TODO: This should call svcCallSecureMonitor using arg 0xC3000002.
+ // Since it's currently not implemented we can use a private method for now.
+ SmcResult result = SmcGetConfig(context, out ulong configValue, configItem);
+
+ // Nintendo has some special handling here for hardware type/is_retail.
+ if (result == SmcResult.InvalidArgument)
+ {
+ switch (configItem)
+ {
+ case ConfigItem.HardwareType:
+ configValue = (ulong)HardwareType.Icosa;
+ result = SmcResult.Success;
+ break;
+ case ConfigItem.HardwareState:
+ configValue = (ulong)HardwareState.Development;
+ result = SmcResult.Success;
+ break;
+ default:
+ break;
+ }
+ }
+
+ context.ResponseData.Write(configValue);
+
+ return (ResultCode)((int)result << 9) | ResultCode.ModuleId;
+ }
+
+ private SmcResult SmcGetConfig(ServiceCtx context, out ulong configValue, ConfigItem configItem)
+ {
+ configValue = default;
+
+ SystemVersion version = context.Device.System.ContentManager.GetCurrentFirmwareVersion();
+ MemorySize memorySize = context.Device.Configuration.MemoryConfiguration.ToKernelMemorySize();
+
+ switch (configItem)
+ {
+ case ConfigItem.DisableProgramVerification:
+ configValue = 0;
+ break;
+ case ConfigItem.DramId:
+ if (memorySize == MemorySize.MemorySize8GB)
+ {
+ configValue = (ulong)DramId.IowaSamsung8GB;
+ }
+ else if (memorySize == MemorySize.MemorySize6GB)
+ {
+ configValue = (ulong)DramId.IcosaSamsung6GB;
+ }
+ else
+ {
+ configValue = (ulong)DramId.IcosaSamsung4GB;
+ }
+ break;
+ case ConfigItem.SecurityEngineInterruptNumber:
+ return SmcResult.NotImplemented;
+ case ConfigItem.FuseVersion:
+ return SmcResult.NotImplemented;
+ case ConfigItem.HardwareType:
+ configValue = (ulong)HardwareType.Icosa;
+ break;
+ case ConfigItem.HardwareState:
+ configValue = (ulong)HardwareState.Production;
+ break;
+ case ConfigItem.IsRecoveryBoot:
+ configValue = 0;
+ break;
+ case ConfigItem.DeviceId:
+ return SmcResult.NotImplemented;
+ case ConfigItem.BootReason:
+ // This was removed in firmware 4.0.0.
+ return SmcResult.InvalidArgument;
+ case ConfigItem.MemoryMode:
+ configValue = (ulong)context.Device.Configuration.MemoryConfiguration;
+ break;
+ case ConfigItem.IsDevelopmentFunctionEnabled:
+ configValue = 0;
+ break;
+ case ConfigItem.KernelConfiguration:
+ return SmcResult.NotImplemented;
+ case ConfigItem.IsChargerHiZModeEnabled:
+ return SmcResult.NotImplemented;
+ case ConfigItem.QuestState:
+ return SmcResult.NotImplemented;
+ case ConfigItem.RegulatorType:
+ return SmcResult.NotImplemented;
+ case ConfigItem.DeviceUniqueKeyGeneration:
+ return SmcResult.NotImplemented;
+ case ConfigItem.Package2Hash:
+ return SmcResult.NotImplemented;
+ default:
+ return SmcResult.InvalidArgument;
+ }
+
+ return SmcResult.Success;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Spl/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Spl/ResultCode.cs
new file mode 100644
index 00000000..4f61998a
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Spl/ResultCode.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.HOS.Services.Spl
+{
+ enum ResultCode
+ {
+ ModuleId = 26,
+ ErrorCodeShift = 9,
+
+ Success = 0,
+
+ InvalidArguments = (101 << ErrorCodeShift) | ModuleId
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs b/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs
new file mode 100644
index 00000000..f08bbeaa
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Spl/Types/ConfigItem.cs
@@ -0,0 +1,24 @@
+namespace Ryujinx.HLE.HOS.Services.Spl.Types
+{
+ enum ConfigItem
+ {
+ // Standard config items.
+ DisableProgramVerification = 1,
+ DramId = 2,
+ SecurityEngineInterruptNumber = 3,
+ FuseVersion = 4,
+ HardwareType = 5,
+ HardwareState = 6,
+ IsRecoveryBoot = 7,
+ DeviceId = 8,
+ BootReason = 9,
+ MemoryMode = 10,
+ IsDevelopmentFunctionEnabled = 11,
+ KernelConfiguration = 12,
+ IsChargerHiZModeEnabled = 13,
+ QuestState = 14,
+ RegulatorType = 15,
+ DeviceUniqueKeyGeneration = 16,
+ Package2Hash = 17
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs b/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs
new file mode 100644
index 00000000..4e1d1f0e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Spl/Types/DramId.cs
@@ -0,0 +1,35 @@
+namespace Ryujinx.HLE.HOS.Services.Spl.Types
+{
+ enum DramId
+ {
+ IcosaSamsung4GB,
+ IcosaHynix4GB,
+ IcosaMicron4GB,
+ IowaHynix1y4GB,
+ IcosaSamsung6GB,
+ HoagHynix1y4GB,
+ AulaHynix1y4GB,
+ IowaX1X2Samsung4GB,
+ IowaSansung4GB,
+ IowaSamsung8GB,
+ IowaHynix4GB,
+ IowaMicron4GB,
+ HoagSamsung4GB,
+ HoagSamsung8GB,
+ HoagHynix4GB,
+ HoagMicron4GB,
+ IowaSamsung4GBY,
+ IowaSamsung1y4GBX,
+ IowaSamsung1y8GBX,
+ HoagSamsung1y4GBX,
+ IowaSamsung1y4GBY,
+ IowaSamsung1y8GBY,
+ AulaSamsung1y4GB,
+ HoagSamsung1y8GBX,
+ AulaSamsung1y4GBX,
+ IowaMicron1y4GB,
+ HoagMicron1y4GB,
+ AulaMicron1y4GB,
+ AulaSamsung1y8GBX
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs b/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs
new file mode 100644
index 00000000..414d0f11
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareState.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.Services.Spl.Types
+{
+ enum HardwareState
+ {
+ Development,
+ Production
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs b/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs
new file mode 100644
index 00000000..491eb943
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Spl/Types/HardwareType.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.HOS.Services.Spl.Types
+{
+ enum HardwareType
+ {
+ Icosa,
+ Copper,
+ Hoag,
+ Iowa,
+ Calcio,
+ Aula
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs b/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs
new file mode 100644
index 00000000..d5f424a6
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Spl/Types/SmcResult.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.HLE.HOS.Services.Spl.Types
+{
+ enum SmcResult
+ {
+ Success = 0,
+ NotImplemented = 1,
+ InvalidArgument = 2,
+ Busy = 3,
+ NoAsyncOperation = 4,
+ InvalidAsyncOperation = 5,
+ NotPermitted = 6,
+ NotInitialized = 7,
+
+ PsciSuccess = 0,
+ PsciNotSupported = -1,
+ PsciInvalidParameters = -2,
+ PsciDenied = -3,
+ PsciAlreadyOn = -4
+ }
+} \ No newline at end of file