diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs index 30e3409d..ad27f88f 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 00000000..890c9ac9 --- /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 a82e8a94..8c96c4ad 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 00000000..2041e423 --- /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 0f73f950..2b4a1239 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 00000000..5380d82f --- /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