diff options
| author | Ac_K <Acoustik666@gmail.com> | 2023-08-17 14:59:05 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-17 09:59:05 -0300 |
| commit | b0b7843d5c7372db60211255be0edfcb97dcb56d (patch) | |
| tree | 08ddc16f41e3455f66c47d86bba83d7295e1a83c /src/Ryujinx.Horizon/MmNv/Ipc | |
| parent | 6ed613a6e6a66d57d2fdb045d926e42dfcdd3206 (diff) | |
mm: Migrate service in Horizon project (#5580)
* mm: Migrate service in Horizon project
This PR migrate the `mm:u` service to the Horizon project, things were checked by some RE aswell, that's why some vars are renamed, the logic should be the same as before.
Tests are welcome.
* Lock _sessionList instead
* Fix comment
* Fix Session fields order
Diffstat (limited to 'src/Ryujinx.Horizon/MmNv/Ipc')
| -rw-r--r-- | src/Ryujinx.Horizon/MmNv/Ipc/Request.cs | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs b/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs new file mode 100644 index 00000000..9a24c75e --- /dev/null +++ b/src/Ryujinx.Horizon/MmNv/Ipc/Request.cs @@ -0,0 +1,160 @@ +using Ryujinx.Common.Logging; +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.MmNv; +using Ryujinx.Horizon.Sdk.Sf; +using System.Collections.Generic; + +namespace Ryujinx.Horizon.MmNv.Ipc +{ + partial class Request : IRequest + { + private readonly List<Session> _sessionList = new(); + + private uint _uniqueId = 1; + + [CmifCommand(0)] + public Result InitializeOld(Module module, uint fgmPriority, uint autoClearEvent) + { + bool isAutoClearEvent = autoClearEvent != 0; + + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { module, fgmPriority, isAutoClearEvent }); + + Register(module, fgmPriority, isAutoClearEvent); + + return Result.Success; + } + + [CmifCommand(1)] + public Result FinalizeOld(Module module) + { + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { module }); + + lock (_sessionList) + { + _sessionList.Remove(GetSessionByModule(module)); + } + + return Result.Success; + } + + [CmifCommand(2)] + public Result SetAndWaitOld(Module module, uint clockRateMin, int clockRateMax) + { + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { module, clockRateMin, clockRateMax }); + + lock (_sessionList) + { + GetSessionByModule(module)?.SetAndWait(clockRateMin, clockRateMax); + } + + return Result.Success; + } + + [CmifCommand(3)] + public Result GetOld(out uint clockRateActual, Module module) + { + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { module }); + + lock (_sessionList) + { + Session session = GetSessionByModule(module); + + clockRateActual = session == null ? 0 : session.ClockRateMin; + } + + return Result.Success; + } + + [CmifCommand(4)] + public Result Initialize(out uint requestId, Module module, uint fgmPriority, uint autoClearEvent) + { + bool isAutoClearEvent = autoClearEvent != 0; + + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { module, fgmPriority, isAutoClearEvent }); + + requestId = Register(module, fgmPriority, isAutoClearEvent); + + return Result.Success; + } + + [CmifCommand(5)] + public Result Finalize(uint requestId) + { + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { requestId }); + + lock (_sessionList) + { + _sessionList.Remove(GetSessionById(requestId)); + } + + return Result.Success; + } + + [CmifCommand(6)] + public Result SetAndWait(uint requestId, uint clockRateMin, int clockRateMax) + { + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { requestId, clockRateMin, clockRateMax }); + + lock (_sessionList) + { + GetSessionById(requestId)?.SetAndWait(clockRateMin, clockRateMax); + } + + return Result.Success; + } + + [CmifCommand(7)] + public Result Get(out uint clockRateActual, uint requestId) + { + Logger.Stub?.PrintStub(LogClass.ServiceMm, new { requestId }); + + lock (_sessionList) + { + Session session = GetSessionById(requestId); + + clockRateActual = session == null ? 0 : session.ClockRateMin; + } + + return Result.Success; + } + + private Session GetSessionById(uint id) + { + foreach (Session session in _sessionList) + { + if (session.Id == id) + { + return session; + } + } + + return null; + } + + private Session GetSessionByModule(Module module) + { + foreach (Session session in _sessionList) + { + if (session.Module == module) + { + return session; + } + } + + return null; + } + + private uint Register(Module module, uint fgmPriority, bool isAutoClearEvent) + { + lock (_sessionList) + { + // Nintendo ignores the fgm priority as the other services were deprecated. + Session session = new(_uniqueId++, module, isAutoClearEvent); + + _sessionList.Add(session); + + return session.Id; + } + } + } +} |
