From 33dc4c9ce40165795da884eaa684f16e8b643799 Mon Sep 17 00:00:00 2001 From: Ac_K Date: Wed, 29 Sep 2021 01:03:35 +0200 Subject: [PATCH] clkrst: Stub/Implement IClkrstManager and IClkrstSession calls (#2692) This PR stubs and implements some clkrst call because they are used to overclock the Switch hardware and it's pointless in our case as we emulate the system. Everything was done checked by RE. Fixes #2686 --- Ryujinx.Common/Logging/LogClass.cs | 1 + .../Clkrst/ClkrstManager/IClkrstSession.cs | 62 ++++++++++++ .../HOS/Services/Pcv/Clkrst/IClkrstManager.cs | 50 +++++++++- Ryujinx.HLE/HOS/Services/Pcv/ResultCode.cs | 12 +++ .../Pcv/Rtc/{IUnknown1.cs => IRtcManager.cs} | 4 +- .../HOS/Services/Pcv/Types/DeviceCode.cs | 94 +++++++++++++++++++ 6 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs create mode 100644 Ryujinx.HLE/HOS/Services/Pcv/ResultCode.cs rename Ryujinx.HLE/HOS/Services/Pcv/Rtc/{IUnknown1.cs => IRtcManager.cs} (51%) create mode 100644 Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs index 30e3409d1..ad27f88f3 100644 --- a/Ryujinx.Common/Logging/LogClass.cs +++ b/Ryujinx.Common/Logging/LogClass.cs @@ -49,6 +49,7 @@ namespace Ryujinx.Common.Logging ServiceNv, ServiceOlsc, ServicePctl, + ServicePcv, ServicePl, ServicePrepo, ServicePsm, diff --git a/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs b/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs new file mode 100644 index 000000000..890c9ac97 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/ClkrstManager/IClkrstSession.cs @@ -0,0 +1,62 @@ +using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Pcv.Types; +using System.Linq; + +namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager +{ + class IClkrstSession : IpcService + { + private DeviceCode _deviceCode; + private uint _unknown; + private uint _clockRate; + + private DeviceCode[] allowedDeviceCodeTable = new DeviceCode[] + { + DeviceCode.Cpu, DeviceCode.Gpu, DeviceCode.Disp1, DeviceCode.Disp2, + DeviceCode.Tsec, DeviceCode.Mselect, DeviceCode.Sor1, DeviceCode.Host1x, + DeviceCode.Vic, DeviceCode.Nvenc, DeviceCode.Nvjpg, DeviceCode.Nvdec, + DeviceCode.Ape, DeviceCode.AudioDsp, DeviceCode.Emc, DeviceCode.Dsi, + DeviceCode.SysBus, DeviceCode.XusbSs, DeviceCode.XusbHost, DeviceCode.XusbDevice, + DeviceCode.Gpuaux, DeviceCode.Pcie, DeviceCode.Apbdma, DeviceCode.Sdmmc1, + DeviceCode.Sdmmc2, DeviceCode.Sdmmc4 + }; + + public IClkrstSession(DeviceCode deviceCode, uint unknown) + { + _deviceCode = deviceCode; + _unknown = unknown; + } + + [CommandHipc(7)] + // SetClockRate(u32 hz) + public ResultCode SetClockRate(ServiceCtx context) + { + if (!allowedDeviceCodeTable.Contains(_deviceCode)) + { + return ResultCode.InvalidArgument; + } + + _clockRate = context.RequestData.ReadUInt32(); + + Logger.Stub?.PrintStub(LogClass.ServicePcv, new { _clockRate }); + + return ResultCode.Success; + } + + [CommandHipc(8)] + // GetClockRate() -> u32 hz + public ResultCode GetClockRate(ServiceCtx context) + { + if (!allowedDeviceCodeTable.Contains(_deviceCode)) + { + return ResultCode.InvalidArgument; + } + + context.ResponseData.Write(_clockRate); + + Logger.Stub?.PrintStub(LogClass.ServicePcv, new { _clockRate }); + + return ResultCode.Success; + } + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs b/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs index a82e8a94f..8c96c4ad9 100644 --- a/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs +++ b/Ryujinx.HLE/HOS/Services/Pcv/Clkrst/IClkrstManager.cs @@ -1,9 +1,57 @@ -namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel.Common; +using Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager; +using Ryujinx.HLE.HOS.Services.Pcv.Types; +using System; + +namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst { [Service("clkrst")] // 8.0.0+ [Service("clkrst:i")] // 8.0.0+ class IClkrstManager : IpcService { + private int _moduleStateTableEventHandle = 0; + public IClkrstManager(ServiceCtx context) { } + + [CommandHipc(0)] + // OpenSession(u32 device_code, u32 unk) -> object + public ResultCode OpenSession(ServiceCtx context) + { + DeviceCode deviceCode = (DeviceCode)context.RequestData.ReadUInt32(); + uint unknown = context.RequestData.ReadUInt32(); + + // TODO: Service checks the deviceCode and the unk value. + + MakeObject(context, new IClkrstSession(deviceCode, unknown)); + + return ResultCode.Success; + } + + [CommandHipc(4)] + // GetModuleStateTableEvent() -> handle + public ResultCode GetModuleStateTableEvent(ServiceCtx context) + { + if (_moduleStateTableEventHandle == 0) + { + if (context.Process.HandleTable.GenerateHandle(context.Device.System.IirsSharedMem, out _moduleStateTableEventHandle) != KernelResult.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_moduleStateTableEventHandle); + + return ResultCode.Success; + } + + [CommandHipc(5)] + // GetModuleStateTableMaxCount() -> u32 max_count + public ResultCode GetModuleStateTableMaxCount(ServiceCtx context) + { + context.ResponseData.Write(26u); + + return ResultCode.Success; + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Pcv/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Pcv/ResultCode.cs new file mode 100644 index 000000000..2041e423e --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Pcv/ResultCode.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.HLE.HOS.Services.Pcv +{ + enum ResultCode + { + ModuleId = 30, + ErrorCodeShift = 9, + + Success = 0, + + InvalidArgument = (5 << ErrorCodeShift) | ModuleId + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IUnknown1.cs b/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs similarity index 51% rename from Ryujinx.HLE/HOS/Services/Pcv/Rtc/IUnknown1.cs rename to Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs index 0f73f9501..2b4a1239c 100644 --- a/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IUnknown1.cs +++ b/Ryujinx.HLE/HOS/Services/Pcv/Rtc/IRtcManager.cs @@ -1,8 +1,8 @@ namespace Ryujinx.HLE.HOS.Services.Pcv.Rtc { [Service("rtc")] // 8.0.0+ - class IUnknown1 : IpcService + class IRtcManager : IpcService { - public IUnknown1(ServiceCtx context) { } + public IRtcManager(ServiceCtx context) { } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs b/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs new file mode 100644 index 000000000..5380d82fb --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Pcv/Types/DeviceCode.cs @@ -0,0 +1,94 @@ +namespace Ryujinx.HLE.HOS.Services.Pcv.Types +{ + enum DeviceCode + { + Cpu = 0x40000001, + Gpu = 0x40000002, + I2s1 = 0x40000003, + I2s2 = 0x40000004, + I2s3 = 0x40000005, + Pwm = 0x40000006, + I2c1 = 0x02000001, + I2c2 = 0x02000002, + I2c3 = 0x02000003, + I2c4 = 0x02000004, + I2c5 = 0x02000005, + I2c6 = 0x02000006, + Spi1 = 0x07000000, + Spi2 = 0x07000001, + Spi3 = 0x07000002, + Spi4 = 0x07000003, + Disp1 = 0x40000011, + Disp2 = 0x40000012, + Isp = 0x40000013, + Vi = 0x40000014, + Sdmmc1 = 0x40000015, + Sdmmc2 = 0x40000016, + Sdmmc3 = 0x40000017, + Sdmmc4 = 0x40000018, + Owr = 0x40000019, + Csite = 0x4000001A, + Tsec = 0x4000001B, + Mselect = 0x4000001C, + Hda2codec2x = 0x4000001D, + Actmon = 0x4000001E, + I2cSlow = 0x4000001F, + Sor1 = 0x40000020, + Sata = 0x40000021, + Hda = 0x40000022, + XusbCoreHostSrc = 0x40000023, + XusbFalconSrc = 0x40000024, + XusbFsSrc = 0x40000025, + XusbCoreDevSrc = 0x40000026, + XusbSsSrc = 0x40000027, + UartA = 0x03000001, + UartB = 0x35000405, + UartC = 0x3500040F, + UartD = 0x37000001, + Host1x = 0x4000002C, + Entropy = 0x4000002D, + SocTherm = 0x4000002E, + Vic = 0x4000002F, + Nvenc = 0x40000030, + Nvjpg = 0x40000031, + Nvdec = 0x40000032, + Qspi = 0x40000033, + ViI2c = 0x40000034, + Tsecb = 0x40000035, + Ape = 0x40000036, + AudioDsp = 0x40000037, + AudioUart = 0x40000038, + Emc = 0x40000039, + Plle = 0x4000003A, + PlleHwSeq = 0x4000003B, + Dsi = 0x4000003C, + Maud = 0x4000003D, + Dpaux1 = 0x4000003E, + MipiCal = 0x4000003F, + UartFstMipiCal = 0x40000040, + Osc = 0x40000041, + SysBus = 0x40000042, + SorSafe = 0x40000043, + XusbSs = 0x40000044, + XusbHost = 0x40000045, + XusbDevice = 0x40000046, + Extperiph1 = 0x40000047, + Ahub = 0x40000048, + Hda2hdmicodec = 0x40000049, + Gpuaux = 0x4000004A, + UsbD = 0x4000004B, + Usb2 = 0x4000004C, + Pcie = 0x4000004D, + Afi = 0x4000004E, + PciExClk = 0x4000004F, + PExUsbPhy = 0x40000050, + XUsbPadCtl = 0x40000051, + Apbdma = 0x40000052, + Usb2TrkClk = 0x40000053, + XUsbIoPll = 0x40000054, + XUsbIoPllHwSeq = 0x40000055, + Cec = 0x40000056, + Extperiph2 = 0x40000057, + OscClk = 0x40000080 + } +} \ No newline at end of file