ts: Migrate service to Horizon project (#6514)

* ts: Migrate service to Horizon project

This PR migrate the `ts` service (stored in `ptm`) to the Horizon project:
- It stubs all known IPCs.
- IpcServer consts are checked by RE.

Closes #6480

* Fix args
This commit is contained in:
Ac_K 2024-04-05 20:45:43 +02:00 committed by GitHub
parent 05c041feeb
commit 6d28b64312
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 208 additions and 40 deletions

View File

@ -1,39 +0,0 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Ptm.Ts.Types;
namespace Ryujinx.HLE.HOS.Services.Ptm.Ts
{
[Service("ts")]
class IMeasurementServer : IpcService
{
private const uint DefaultTemperature = 42u;
public IMeasurementServer(ServiceCtx context) { }
[CommandCmif(1)]
// GetTemperature(Location location) -> u32
public ResultCode GetTemperature(ServiceCtx context)
{
Location location = (Location)context.RequestData.ReadByte();
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { location });
context.ResponseData.Write(DefaultTemperature);
return ResultCode.Success;
}
[CommandCmif(3)]
// GetTemperatureMilliC(Location location) -> u32
public ResultCode GetTemperatureMilliC(ServiceCtx context)
{
Location location = (Location)context.RequestData.ReadByte();
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { location });
context.ResponseData.Write(DefaultTemperature * 1000);
return ResultCode.Success;
}
}
}

View File

@ -0,0 +1,63 @@
using Ryujinx.Common.Logging;
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
using Ryujinx.Horizon.Sdk.Ts;
using Ryujinx.Horizon.Ts.Ipc;
namespace Ryujinx.Horizon.Ptm.Ipc
{
partial class MeasurementServer : IMeasurementServer
{
// NOTE: Values are randomly choosen.
public const int DefaultTemperature = 42;
public const int MinimumTemperature = 0;
public const int MaximumTemperature = 100;
[CmifCommand(0)] // 1.0.0-16.1.0
public Result GetTemperatureRange(out int minimumTemperature, out int maximumTemperature, Location location)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { location });
minimumTemperature = MinimumTemperature;
maximumTemperature = MaximumTemperature;
return Result.Success;
}
[CmifCommand(1)] // 1.0.0-16.1.0
public Result GetTemperature(out int temperature, Location location)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { location });
temperature = DefaultTemperature;
return Result.Success;
}
[CmifCommand(2)] // 1.0.0-13.2.1
public Result SetMeasurementMode(Location location, byte measurementMode)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { location, measurementMode });
return Result.Success;
}
[CmifCommand(3)] // 1.0.0-13.2.1
public Result GetTemperatureMilliC(out int temperatureMilliC, Location location)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { location });
temperatureMilliC = DefaultTemperature * 1000;
return Result.Success;
}
[CmifCommand(4)] // 8.0.0+
public Result OpenSession(out ISession session, DeviceCode deviceCode)
{
session = new Session(deviceCode);
return Result.Success;
}
}
}

View File

@ -0,0 +1,47 @@
using Ryujinx.Common.Logging;
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Ptm.Ipc;
using Ryujinx.Horizon.Sdk.Sf;
using Ryujinx.Horizon.Sdk.Ts;
namespace Ryujinx.Horizon.Ts.Ipc
{
partial class Session : ISession
{
private readonly DeviceCode _deviceCode;
public Session(DeviceCode deviceCode)
{
_deviceCode = deviceCode;
}
[CmifCommand(0)]
public Result GetTemperatureRange(out int minimumTemperature, out int maximumTemperature)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { _deviceCode });
minimumTemperature = MeasurementServer.MinimumTemperature;
maximumTemperature = MeasurementServer.MaximumTemperature;
return Result.Success;
}
[CmifCommand(2)]
public Result SetMeasurementMode(byte measurementMode)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { _deviceCode, measurementMode });
return Result.Success;
}
[CmifCommand(4)]
public Result GetTemperature(out int temperature)
{
Logger.Stub?.PrintStub(LogClass.ServicePtm, new { _deviceCode });
temperature = MeasurementServer.DefaultTemperature;
return Result.Success;
}
}
}

View File

@ -0,0 +1,44 @@
using Ryujinx.Horizon.Ptm.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Ptm
{
class TsIpcServer
{
private const int MaxSessionsCount = 4;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 1;
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
_serverManager.RegisterObjectForServer(new MeasurementServer(), ServiceName.Encode("ts"), MaxSessionsCount);
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
_sm.Dispose();
}
}
}

View File

@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Ptm
{
class TsMain : IService
{
public static void Main(ServiceTable serviceTable)
{
TsIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@ -0,0 +1,8 @@
namespace Ryujinx.Horizon.Sdk.Ts
{
enum DeviceCode : uint
{
Internal = 0x41000001,
External = 0x41000002,
}
}

View File

@ -0,0 +1,14 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ts
{
interface IMeasurementServer : IServiceObject
{
Result GetTemperatureRange(out int minimumTemperature, out int maximumTemperature, Location location);
Result GetTemperature(out int temperature, Location location);
Result SetMeasurementMode(Location location, byte measurementMode);
Result GetTemperatureMilliC(out int temperatureMilliC, Location location);
Result OpenSession(out ISession session, DeviceCode deviceCode);
}
}

View File

@ -0,0 +1,12 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ts
{
interface ISession : IServiceObject
{
Result GetTemperatureRange(out int minimumTemperature, out int maximumTemperature);
Result GetTemperature(out int temperature);
Result SetMeasurementMode(byte measurementMode);
}
}

View File

@ -1,4 +1,4 @@
namespace Ryujinx.HLE.HOS.Services.Ptm.Ts.Types
namespace Ryujinx.Horizon.Sdk.Ts
{
enum Location : byte
{

View File

@ -11,6 +11,7 @@ using Ryujinx.Horizon.Ngc;
using Ryujinx.Horizon.Ovln;
using Ryujinx.Horizon.Prepo;
using Ryujinx.Horizon.Psc;
using Ryujinx.Horizon.Ptm;
using Ryujinx.Horizon.Sdk.Arp;
using Ryujinx.Horizon.Srepo;
using Ryujinx.Horizon.Usb;
@ -54,6 +55,7 @@ namespace Ryujinx.Horizon
RegisterService<PrepoMain>();
RegisterService<PscMain>();
RegisterService<SrepoMain>();
RegisterService<TsMain>();
RegisterService<UsbMain>();
RegisterService<WlanMain>();