[WIP] Add support for events (#60)

* Add support for events, move concept of domains to IpcService

* Support waiting for KThread, remove some test code, other tweaks

* Use move handle on NIFM since I can't test that now, it's better to leave it how it was
This commit is contained in:
gdkchan
2018-03-19 15:58:46 -03:00
committed by GitHub
parent 4940cf0ea5
commit 4314a8f3e5
101 changed files with 1120 additions and 836 deletions

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Acc
{
class IManagerForApplication : IIpcService
class IManagerForApplication : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IManagerForApplication()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Acc
{
class IProfile : IIpcService
class IProfile : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IProfile()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Acc
{
class ServiceAcc : IIpcService
class ServiceAcc : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceAcc()
{

View File

@@ -0,0 +1,7 @@
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
static class AmErr
{
public const int NoMessages = 3;
}
}

View File

@@ -0,0 +1,8 @@
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
enum FocusState
{
InFocus = 1,
OutOfFocus = 2
}
}

View File

@@ -2,15 +2,13 @@ using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using System.IO;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IApplicationFunctions : IIpcService
class IApplicationFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IApplicationFunctions()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IApplicationProxy : IIpcService
class IApplicationProxy : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IApplicationProxy()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IAudioController : IIpcService
class IAudioController : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAudioController()
{

View File

@@ -1,13 +1,16 @@
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.ErrorCode;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class ICommonStateGetter : IIpcService
class ICommonStateGetter : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ICommonStateGetter()
{
@@ -17,37 +20,31 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am
{ 1, ReceiveMessage },
{ 5, GetOperationMode },
{ 6, GetPerformanceMode },
{ 9, GetCurrentFocusState },
{ 9, GetCurrentFocusState }
};
}
private enum FocusState
{
InFocus = 1,
OutOfFocus = 2
}
private enum OperationMode
{
Handheld = 0,
Docked = 1
}
public long GetEventHandle(ServiceCtx Context)
{
Context.ResponseData.Write(0L);
KEvent Event = Context.Process.AppletState.MessageEvent;
int Handle = Context.Process.HandleTable.OpenHandle(Event);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
public long ReceiveMessage(ServiceCtx Context)
{
//Program expects 0xF at 0x17ae70 on puyo sdk,
//otherwise runs on a infinite loop until it reads said value.
//What it means is still unknown.
Context.ResponseData.Write(0xfL);
if (!Context.Process.AppletState.TryDequeueMessage(out MessageInfo Message))
{
return MakeError(ErrorModule.Am, AmErr.NoMessages);
}
return 0; //0x680;
Context.ResponseData.Write((int)Message);
return 0;
}
public long GetOperationMode(ServiceCtx Context)
@@ -66,7 +63,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am
public long GetCurrentFocusState(ServiceCtx Context)
{
Context.ResponseData.Write((byte)FocusState.InFocus);
Context.ResponseData.Write((byte)Context.Process.AppletState.FocusState);
return 0;
}

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IDebugFunctions : IIpcService
class IDebugFunctions : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IDebugFunctions()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IDisplayController : IIpcService
class IDisplayController : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IDisplayController()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class ILibraryAppletCreator : IIpcService
class ILibraryAppletCreator : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ILibraryAppletCreator()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class ISelfController : IIpcService
class ISelfController : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISelfController()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IStorage : IIpcService
class IStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public byte[] Data { get; private set; }

View File

@@ -5,11 +5,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IStorageAccessor : IIpcService
class IStorageAccessor : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private IStorage Storage;

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class IWindowController : IIpcService
class IWindowController : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IWindowController()
{

View File

@@ -0,0 +1,9 @@
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
enum MessageInfo
{
FocusStateChanged = 0xf,
OperationModeChanged = 0x1e,
PerformanceModeChanged = 0x1f
}
}

View File

@@ -0,0 +1,8 @@
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
enum OperationMode
{
Handheld = 0,
Docked = 1
}
}

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Am
{
class ServiceAppletOE : IIpcService
class ServiceAppletOE : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceAppletOE()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Apm
{
class ISession : IIpcService
class ISession : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISession()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Apm
{
class ServiceApm : IIpcService
class ServiceApm : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceApm()
{

View File

@@ -5,11 +5,11 @@ using System.Text;
namespace Ryujinx.Core.OsHle.IpcServices.Aud
{
class IAudioDevice : IIpcService
class IAudioDevice : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IAudioDevice()
{

View File

@@ -7,17 +7,19 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Aud
{
class IAudioOut : IIpcService, IDisposable
class IAudioOut : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private IAalOutput AudioOut;
private KEvent ReleaseEvent;
private int Track;
public IAudioOut(IAalOutput AudioOut, int Track)
public IAudioOut(IAalOutput AudioOut, KEvent ReleaseEvent, int Track)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@@ -32,8 +34,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
{ 8, GetReleasedAudioOutBufferEx }
};
this.AudioOut = AudioOut;
this.Track = Track;
this.AudioOut = AudioOut;
this.ReleaseEvent = ReleaseEvent;
this.Track = Track;
}
public long GetAudioOutState(ServiceCtx Context)
@@ -77,7 +80,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
public long RegisterBufferEvent(ServiceCtx Context)
{
int Handle = Context.Process.HandleTable.OpenHandle(new HEvent());
int Handle = Context.Process.HandleTable.OpenHandle(ReleaseEvent);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
@@ -143,6 +146,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
if (Disposing)
{
AudioOut.CloseTrack(Track);
ReleaseEvent.Dispose();
}
}
}

View File

@@ -1,14 +1,17 @@
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Aud
{
class IAudioRenderer : IIpcService
class IAudioRenderer : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent UpdateEvent;
public IAudioRenderer()
{
@@ -19,6 +22,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
{ 6, StopAudioRenderer },
{ 7, QuerySystemEvent }
};
UpdateEvent = new KEvent();
}
public long RequestUpdateAudioRenderer(ServiceCtx Context)
@@ -41,6 +46,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
Context.Memory.WriteInt32(Position + Offset, 5);
}
//TODO: We shouldn't be signaling this here.
UpdateEvent.Handle.Set();
return 0;
}
@@ -56,11 +64,24 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
public long QuerySystemEvent(ServiceCtx Context)
{
int Handle = Context.Process.HandleTable.OpenHandle(new HEvent());
int Handle = Context.Process.HandleTable.OpenHandle(UpdateEvent);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
return 0;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
UpdateEvent.Dispose();
}
}
}
}

View File

@@ -1,18 +1,17 @@
using ChocolArm64.Memory;
using Ryujinx.Audio;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using System.Text;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Aud
{
class ServiceAudOut : IIpcService
class ServiceAudOut : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceAudOut()
{
@@ -73,9 +72,16 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
Channels = 2;
}
int Track = AudioOut.OpenTrack(SampleRate, Channels, out AudioFormat Format);
KEvent ReleaseEvent = new KEvent();
MakeObject(Context, new IAudioOut(AudioOut, Track));
ReleaseCallback Callback = () =>
{
ReleaseEvent.Handle.Set();
};
int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback, out AudioFormat Format);
MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track));
Context.ResponseData.Write(SampleRate);
Context.ResponseData.Write(Channels);

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Aud
{
class ServiceAudRen : IIpcService
class ServiceAudRen : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceAudRen()
{

View File

@@ -51,11 +51,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd
public Socket Handle;
}
class ServiceBsd : IIpcService
class ServiceBsd : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private List<SocketBsd> Sockets = new List<SocketBsd>();

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Friend
{
class IFriendService : IIpcService
class IFriendService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IFriendService()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Friend
{
class ServiceFriend : IIpcService
class ServiceFriend : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceFriend()
{

View File

@@ -7,13 +7,13 @@ using System.Text;
namespace Ryujinx.Core.OsHle.IpcServices.FspSrv
{
class IDirectory : IIpcService, IDisposable
class IDirectory : IpcService, IDisposable
{
private const int DirectoryEntrySize = 0x310;
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private List<string> DirectoryEntries;

View File

@@ -6,11 +6,11 @@ using System.IO;
namespace Ryujinx.Core.OsHle.IpcServices.FspSrv
{
class IFile : IIpcService, IDisposable
class IFile : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private Stream BaseStream;

View File

@@ -5,15 +5,14 @@ using System.IO;
using System.Text;
using static Ryujinx.Core.OsHle.ErrorCode;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.FspSrv
{
class IFileSystem : IIpcService
class IFileSystem : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private HashSet<string> OpenPaths;

View File

@@ -5,11 +5,11 @@ using System.IO;
namespace Ryujinx.Core.OsHle.IpcServices.FspSrv
{
class IStorage : IIpcService
class IStorage : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private Stream BaseStream;

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.FspSrv
{
class ServiceFspSrv : IIpcService
class ServiceFspSrv : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceFspSrv()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Hid
{
class IActiveApplicationDeviceList : IIpcService
class IActiveApplicationDeviceList : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IActiveApplicationDeviceList()
{

View File

@@ -4,11 +4,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Hid
{
class IAppletResource : IIpcService
class IAppletResource : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private HSharedMem HidSharedMem;

View File

@@ -2,15 +2,13 @@ using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using Ryujinx.Core.Input;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Hid
{
class ServiceHid : IIpcService
class ServiceHid : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceHid()
{

View File

@@ -0,0 +1,151 @@
using Ryujinx.Core.OsHle.Ipc;
using Ryujinx.Core.OsHle.Handles;
using System;
using System.Collections.Generic;
using System.IO;
namespace Ryujinx.Core.OsHle.IpcServices
{
abstract class IpcService : IIpcService
{
public abstract IReadOnlyDictionary<int, ServiceProcessRequest> Commands { get; }
private IdDictionary DomainObjects;
private int SelfId;
private bool IsDomain;
public IpcService()
{
DomainObjects = new IdDictionary();
SelfId = -1;
}
public int ConvertToDomain()
{
if (SelfId == -1)
{
SelfId = DomainObjects.Add(this);
}
IsDomain = true;
return SelfId;
}
public void ConvertToSession()
{
IsDomain = false;
}
public void CallMethod(ServiceCtx Context)
{
IIpcService Service = this;
if (IsDomain)
{
int DomainWord0 = Context.RequestData.ReadInt32();
int DomainObjId = Context.RequestData.ReadInt32();
long Padding = Context.RequestData.ReadInt64();
int DomainCmd = DomainWord0 & 0xff;
if (DomainCmd == 1)
{
Service = GetObject(DomainObjId);
Context.ResponseData.Write(0L);
Context.ResponseData.Write(0L);
}
else if (DomainCmd == 2)
{
Delete(DomainObjId);
Context.ResponseData.Write(0L);
return;
}
else
{
throw new NotImplementedException($"Domain command: {DomainCmd}");
}
}
long SfciMagic = Context.RequestData.ReadInt64();
int CommandId = (int)Context.RequestData.ReadInt64();
if (Service.Commands.TryGetValue(CommandId, out ServiceProcessRequest ProcessRequest))
{
Context.ResponseData.BaseStream.Seek(IsDomain ? 0x20 : 0x10, SeekOrigin.Begin);
Logging.Trace($"{Service.GetType().Name}: {ProcessRequest.Method.Name}");
long Result = ProcessRequest(Context);
if (IsDomain)
{
foreach (int Id in Context.Response.ResponseObjIds)
{
Context.ResponseData.Write(Id);
}
Context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
Context.ResponseData.Write(Context.Response.ResponseObjIds.Count);
}
Context.ResponseData.BaseStream.Seek(IsDomain ? 0x10 : 0, SeekOrigin.Begin);
Context.ResponseData.Write(IpcMagic.Sfco);
Context.ResponseData.Write(Result);
}
else
{
throw new NotImplementedException($"{Service.GetType().Name}: {CommandId}");
}
}
protected static void MakeObject(ServiceCtx Context, IpcService Obj)
{
IpcService Service = Context.Session.Service;
if (Service.IsDomain)
{
Context.Response.ResponseObjIds.Add(Service.Add(Obj));
}
else
{
KSession Session = new KSession(Obj);
int Handle = Context.Process.HandleTable.OpenHandle(Session);
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
}
}
private int Add(IIpcService Obj)
{
return DomainObjects.Add(Obj);
}
private bool Delete(int Id)
{
object Obj = DomainObjects.Delete(Id);
if (Obj is IDisposable DisposableObj)
{
DisposableObj.Dispose();
}
return Obj != null;
}
private IIpcService GetObject(int Id)
{
return DomainObjects.GetData<IIpcService>(Id);
}
}
}

View File

@@ -7,11 +7,11 @@ using System.Text;
namespace Ryujinx.Core.OsHle.IpcServices.Lm
{
class ILogger : IIpcService
class ILogger : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ILogger()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Lm
{
class ServiceLm : IIpcService
class ServiceLm : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceLm()
{
@@ -21,8 +19,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.Lm
public long Initialize(ServiceCtx Context)
{
Context.Session.Initialize();
MakeObject(Context, new ILogger());
return 0;

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Nifm
{
class IGeneralService : IIpcService
class IGeneralService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IGeneralService()
{

View File

@@ -1,13 +1,17 @@
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using System;
using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Nifm
{
class IRequest : IIpcService
class IRequest : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent Event;
public IRequest()
{
@@ -17,9 +21,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.Nifm
{ 1, GetResult },
{ 2, GetSystemEventReadableHandles }
};
Event = new KEvent();
}
// -> i32
public long GetRequestState(ServiceCtx Context)
{
Context.ResponseData.Write(0);
@@ -39,11 +44,25 @@ namespace Ryujinx.Core.OsHle.IpcServices.Nifm
//GetSystemEventReadableHandles() -> (KObject, KObject)
public long GetSystemEventReadableHandles(ServiceCtx Context)
{
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(0xbadcafe);
//FIXME: Is this supposed to return 2 events?
int Handle = Context.Process.HandleTable.OpenHandle(Event);
//Todo: Stub
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
return 0;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
Event.Dispose();
}
}
}
}

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Nifm
{
class ServiceNifm : IIpcService
class ServiceNifm : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceNifm()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Ns
{
class ServiceNs : IIpcService
class ServiceNs : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceNs()
{

View File

@@ -1,4 +1,5 @@
using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using Ryujinx.Core.OsHle.Utilities;
using Ryujinx.Graphics.Gpu;
@@ -7,20 +8,22 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.NvServices
{
class ServiceNvDrv : IIpcService
class ServiceNvDrv : IpcService, IDisposable
{
private delegate long ServiceProcessIoctl(ServiceCtx Context);
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds;
private IdDictionary Fds;
public static GlobalStateTable Fds { get; private set; }
private IdDictionary NvMaps;
private IdDictionary NvMapsById;
public static GlobalStateTable NvMaps { get; private set; }
public static GlobalStateTable NvMapsById { get; private set; }
private KEvent Event;
public ServiceNvDrv()
{
@@ -64,10 +67,15 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
{ ("/dev/nvmap", 0x010e), NvMapIocGetId },
};
Fds = new IdDictionary();
Event = new KEvent();
}
NvMaps = new IdDictionary();
NvMapsById = new IdDictionary();
static ServiceNvDrv()
{
Fds = new GlobalStateTable();
NvMaps = new GlobalStateTable();
NvMapsById = new GlobalStateTable();
}
public long Open(ServiceCtx Context)
@@ -76,7 +84,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, NamePtr);
int Fd = Fds.Add(new NvFd(Name));
int Fd = Fds.Add(Context.Process, new NvFd(Name));
Context.ResponseData.Write(Fd);
Context.ResponseData.Write(0);
@@ -89,7 +97,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
int Fd = Context.RequestData.ReadInt32();
int Cmd = Context.RequestData.ReadInt32() & 0xffff;
NvFd FdData = Fds.GetData<NvFd>(Fd);
NvFd FdData = Fds.GetData<NvFd>(Context.Process, Fd);
long Position = Context.Request.GetSendBuffPtr();
@@ -109,7 +117,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
{
int Fd = Context.RequestData.ReadInt32();
Fds.Delete(Fd);
Fds.Delete(Context.Process, Fd);
Context.ResponseData.Write(0);
@@ -131,7 +139,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
int Fd = Context.RequestData.ReadInt32();
int EventId = Context.RequestData.ReadInt32();
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(0xcafe);
//TODO: Use Fd/EventId, different channels have different events.
int Handle = Context.Process.HandleTable.OpenHandle(Event);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
Context.ResponseData.Write(0);
@@ -203,7 +214,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
return 0;
}
NvMap Map = NvMaps.GetData<NvMap>(Handle);
NvMap Map = NvMaps.GetData<NvMap>(Context.Process, Handle);
if (Map == null)
{
@@ -550,9 +561,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
NvMap Map = new NvMap() { Size = Size };
Map.Handle = NvMaps.Add(Map);
Map.Handle = NvMaps.Add(Context.Process, Map);
Map.Id = NvMapsById.Add(Map);
Map.Id = NvMapsById.Add(Context.Process, Map);
Context.Memory.WriteInt32(Position + 4, Map.Handle);
@@ -567,7 +578,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
int Id = Context.Memory.ReadInt32(Position);
NvMap Map = NvMapsById.GetData<NvMap>(Id);
NvMap Map = NvMapsById.GetData<NvMap>(Context.Process, Id);
if (Map == null)
{
@@ -594,7 +605,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
byte Kind = (byte)Reader.ReadInt64();
long Addr = Reader.ReadInt64();
NvMap Map = NvMaps.GetData<NvMap>(Handle);
NvMap Map = NvMaps.GetData<NvMap>(Context.Process, Handle);
if (Map == null)
{
@@ -620,7 +631,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
int Handle = Reader.ReadInt32();
int Padding = Reader.ReadInt32();
NvMap Map = NvMaps.GetData<NvMap>(Handle);
NvMap Map = NvMaps.GetData<NvMap>(Context.Process, Handle);
if (Map == null)
{
@@ -645,7 +656,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
int Handle = Reader.ReadInt32();
int Param = Reader.ReadInt32();
NvMap Map = NvMaps.GetData<NvMap>(Handle);
NvMap Map = NvMaps.GetData<NvMap>(Context.Process, Handle);
if (Map == null)
{
@@ -675,7 +686,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
int Handle = Context.Memory.ReadInt32(Position + 4);
NvMap Map = NvMaps.GetData<NvMap>(Handle);
NvMap Map = NvMaps.GetData<NvMap>(Context.Process, Handle);
if (Map == null)
{
@@ -689,9 +700,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
return 0;
}
public NvMap GetNvMap(int Handle)
public void Dispose()
{
return NvMaps.GetData<NvMap>(Handle);
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
Event.Dispose();
}
}
}
}

View File

@@ -1,24 +0,0 @@
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
namespace Ryujinx.Core.OsHle.IpcServices
{
static class ObjHelper
{
public static void MakeObject(ServiceCtx Context, object Obj)
{
if (Context.Session is HDomain Dom)
{
Context.Response.ResponseObjIds.Add(Dom.Add(Obj));
}
else
{
HSessionObj HndData = new HSessionObj(Context.Session, Obj);
int VHandle = Context.Process.HandleTable.OpenHandle(HndData);
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(VHandle);
}
}
}
}

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Pctl
{
class IParentalControlService : IIpcService
class IParentalControlService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IParentalControlService()
{

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Pctl
{
class ServicePctl : IIpcService
class ServicePctl : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServicePctl()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Pl
{
class ServicePl : IIpcService
class ServicePl : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServicePl()
{

View File

@@ -0,0 +1,119 @@
using Ryujinx.Core.OsHle.IpcServices.Acc;
using Ryujinx.Core.OsHle.IpcServices.Am;
using Ryujinx.Core.OsHle.IpcServices.Apm;
using Ryujinx.Core.OsHle.IpcServices.Aud;
using Ryujinx.Core.OsHle.IpcServices.Bsd;
using Ryujinx.Core.OsHle.IpcServices.Friend;
using Ryujinx.Core.OsHle.IpcServices.FspSrv;
using Ryujinx.Core.OsHle.IpcServices.Hid;
using Ryujinx.Core.OsHle.IpcServices.Lm;
using Ryujinx.Core.OsHle.IpcServices.Nifm;
using Ryujinx.Core.OsHle.IpcServices.Ns;
using Ryujinx.Core.OsHle.IpcServices.NvServices;
using Ryujinx.Core.OsHle.IpcServices.Pctl;
using Ryujinx.Core.OsHle.IpcServices.Pl;
using Ryujinx.Core.OsHle.IpcServices.Set;
using Ryujinx.Core.OsHle.IpcServices.Sfdnsres;
using Ryujinx.Core.OsHle.IpcServices.Sm;
using Ryujinx.Core.OsHle.IpcServices.Ssl;
using Ryujinx.Core.OsHle.IpcServices.Time;
using Ryujinx.Core.OsHle.IpcServices.Vi;
using System;
namespace Ryujinx.Core.OsHle.IpcServices
{
static class ServiceFactory
{
public static IpcService MakeService(string Name)
{
switch (Name)
{
case "acc:u0":
return new ServiceAcc();
case "aoc:u":
return new ServiceNs();
case "apm":
return new ServiceApm();
case "apm:p":
return new ServiceApm();
case "appletOE":
return new ServiceAppletOE();
case "audout:u":
return new ServiceAudOut();
case "audren:u":
return new ServiceAudRen();
case "bsd:s":
return new ServiceBsd();
case "bsd:u":
return new ServiceBsd();
case "friend:a":
return new ServiceFriend();
case "fsp-srv":
return new ServiceFspSrv();
case "hid":
return new ServiceHid();
case "lm":
return new ServiceLm();
case "nifm:u":
return new ServiceNifm();
case "nvdrv":
return new ServiceNvDrv();
case "nvdrv:a":
return new ServiceNvDrv();
case "pctl:a":
return new ServicePctl();
case "pl:u":
return new ServicePl();
case "set":
return new ServiceSet();
case "set:sys":
return new ServiceSetSys();
case "sfdnsres":
return new ServiceSfdnsres();
case "sm:":
return new ServiceSm();
case "ssl":
return new ServiceSsl();
case "time:s":
return new ServiceTime();
case "time:u":
return new ServiceTime();
case "vi:m":
return new ServiceVi();
case "vi:s":
return new ServiceVi();
case "vi:u":
return new ServiceVi();
}
throw new NotImplementedException(Name);
}
}
}

View File

@@ -5,11 +5,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Set
{
class ServiceSet : IIpcService
class ServiceSet : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceSet()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Set
{
class ServiceSetSys : IIpcService
class ServiceSetSys : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceSetSys()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Sfdnsres
{
class ServiceSfdnsres : IIpcService
class ServiceSfdnsres : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceSfdnsres()
{

View File

@@ -4,11 +4,13 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Sm
{
class ServiceSm : IIpcService
class ServiceSm : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private bool IsInitialized;
public ServiceSm()
{
@@ -23,7 +25,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm
public long Initialize(ServiceCtx Context)
{
Context.Session.Initialize();
IsInitialized = true;
return 0;
}
@@ -31,7 +33,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm
public long GetService(ServiceCtx Context)
{
//Only for kernel version > 3.0.0.
if (!Context.Session.IsInitialized)
if (!IsInitialized)
{
//return SmNotInitialized;
}
@@ -55,7 +57,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm
return 0;
}
HSession Session = new HSession(Context.Process.Services.GetService(Name));
KSession Session = new KSession(ServiceFactory.MakeService(Name));
int Handle = Context.Process.HandleTable.OpenHandle(Session);

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Ssl
{
class ServiceSsl : IIpcService
class ServiceSsl : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceSsl()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Time
{
class ISteadyClock : IIpcService
class ISteadyClock : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISteadyClock()
{

View File

@@ -4,11 +4,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Time
{
class ISystemClock : IIpcService
class ISystemClock : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

View File

@@ -4,11 +4,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Time
{
class ITimeZoneService : IIpcService
class ITimeZoneService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local);

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Time
{
class ServiceTime : IIpcService
class ServiceTime : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceTime()
{

View File

@@ -1,19 +1,17 @@
using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using System.IO;
using static Ryujinx.Core.OsHle.IpcServices.Android.Parcel;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
class IApplicationDisplayService : IIpcService
class IApplicationDisplayService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private IdDictionary Displays;
@@ -145,7 +143,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
string Name = GetDisplayName(Context);
int Handle = Context.Process.HandleTable.OpenHandle(new HEvent());
int Handle = Context.Process.HandleTable.OpenHandle(Context.Ns.Os.VsyncEvent);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);

View File

@@ -1,4 +1,5 @@
using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using Ryujinx.Core.OsHle.IpcServices.Android;
using Ryujinx.Graphics.Gal;
@@ -7,11 +8,13 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
class IHOSBinderDriver : IIpcService, IDisposable
class IHOSBinderDriver : IpcService, IDisposable
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent ReleaseEvent;
private NvFlinger Flinger;
@@ -24,7 +27,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
{ 2, GetNativeHandle }
};
Flinger = new NvFlinger(Renderer);
ReleaseEvent = new KEvent();
Flinger = new NvFlinger(Renderer, ReleaseEvent);
}
public long TransactParcel(ServiceCtx Context)
@@ -56,7 +61,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
int Id = Context.RequestData.ReadInt32();
uint Unk = Context.RequestData.ReadUInt32();
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(0xbadcafe);
int Handle = Context.Process.HandleTable.OpenHandle(ReleaseEvent);
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
return 0;
}
@@ -70,6 +77,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
if (Disposing)
{
ReleaseEvent.Dispose();
Flinger.Dispose();
}
}

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
class IManagerDisplayService : IIpcService
class IManagerDisplayService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IManagerDisplayService()
{

View File

@@ -3,11 +3,11 @@ using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
class ISystemDisplayService : IIpcService
class ISystemDisplayService : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ISystemDisplayService()
{

View File

@@ -1,4 +1,5 @@
using ChocolArm64.Memory;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.IpcServices.NvServices;
using Ryujinx.Graphics.Gal;
using System;
@@ -17,6 +18,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
private Dictionary<(string, int), ServiceProcessParcel> Commands;
private KEvent ReleaseEvent;
private IGalRenderer Renderer;
private const int BufferQueueCount = 0x40;
private const int BufferQueueMask = BufferQueueCount - 1;
@@ -55,8 +60,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
public GbpBuffer Data;
}
private IGalRenderer Renderer;
private BufferEntry[] BufferQueue;
private ManualResetEvent WaitBufferFree;
@@ -69,7 +72,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
private bool KeepRunning;
public NvFlinger(IGalRenderer Renderer)
public NvFlinger(IGalRenderer Renderer, KEvent ReleaseEvent)
{
Commands = new Dictionary<(string, int), ServiceProcessParcel>()
{
@@ -83,8 +86,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
{ ("android.gui.IGraphicBufferProducer", 0xb), GbpDisconnect },
{ ("android.gui.IGraphicBufferProducer", 0xe), GbpPreallocBuffer }
};
this.Renderer = Renderer;
this.Renderer = Renderer;
this.ReleaseEvent = ReleaseEvent;
BufferQueue = new BufferEntry[0x40];
@@ -293,6 +297,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
BufferQueue[Slot].State = BufferState.Free;
ReleaseEvent.Handle.Set();
WaitBufferFree.Set();
return;
@@ -377,6 +383,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
Interlocked.Decrement(ref RenderQueueCount);
ReleaseEvent.Handle.Set();
lock (WaitBufferFree)
{
WaitBufferFree.Set();
@@ -397,9 +405,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
NvMapHandle = BitConverter.ToInt32(RawValue, 0);
}
ServiceNvDrv NvDrv = (ServiceNvDrv)Context.Process.Services.GetService("nvdrv");
return NvDrv.GetNvMap(NvMapHandle);
return ServiceNvDrv.NvMaps.GetData<NvMap>(Context.Process, NvMapHandle);
}
private int GetFreeSlotBlocking(int Width, int Height)

View File

@@ -1,15 +1,13 @@
using Ryujinx.Core.OsHle.Ipc;
using System.Collections.Generic;
using static Ryujinx.Core.OsHle.IpcServices.ObjHelper;
namespace Ryujinx.Core.OsHle.IpcServices.Vi
{
class ServiceVi : IIpcService
class ServiceVi : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public ServiceVi()
{