Initial support for the new 12.x IPC system (#2182)

* Rename CommandAttribute as CommandHIpcAttribute to prepare for 12.x changes

* Implement inital support for TIPC and adds SM command ids

* *Ipc to *ipc

* Missed a ref in last commit...

* CommandAttributeTIpc to CommandAttributeTipc

* Addresses comment and fixes some bugs around

TIPC doesn't have any padding requirements as buffer C isn't a thing
Fix for RegisterService inverting two argument only on TIPC
This commit is contained in:
Mary 2021-04-14 00:01:24 +02:00 committed by GitHub
parent faa654dbaf
commit 0746b83edf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
132 changed files with 1077 additions and 951 deletions

View file

@ -11,7 +11,8 @@ namespace Ryujinx.HLE.HOS.Services
{
abstract class IpcService
{
public IReadOnlyDictionary<int, MethodInfo> Commands { get; }
public IReadOnlyDictionary<int, MethodInfo> HipcCommands { get; }
public IReadOnlyDictionary<int, MethodInfo> TipcCommands { get; }
public ServerBase Server { get; private set; }
@ -22,11 +23,18 @@ namespace Ryujinx.HLE.HOS.Services
public IpcService(ServerBase server = null)
{
Commands = Assembly.GetExecutingAssembly().GetTypes()
HipcCommands = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandAttribute))
.Select(command => (((CommandAttribute)command).Id, methodInfo)))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandHipcAttribute))
.Select(command => (((CommandHipcAttribute)command).Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
TipcCommands = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandTipcAttribute))
.Select(command => (((CommandTipcAttribute)command).Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
Server = server;
@ -53,7 +61,7 @@ namespace Ryujinx.HLE.HOS.Services
_isDomain = false;
}
public void CallMethod(ServiceCtx context)
public void CallHipcMethod(ServiceCtx context)
{
IpcService service = this;
@ -99,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Services
long sfciMagic = context.RequestData.ReadInt64();
int commandId = (int)context.RequestData.ReadInt64();
bool serviceExists = service.Commands.TryGetValue(commandId, out MethodInfo processRequest);
bool serviceExists = service.HipcCommands.TryGetValue(commandId, out MethodInfo processRequest);
if (ServiceConfiguration.IgnoreMissingServices || serviceExists)
{
@ -145,7 +153,48 @@ namespace Ryujinx.HLE.HOS.Services
{
string dbgMessage = $"{service.GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(service, context, dbgMessage);
throw new ServiceNotImplementedException(service, context, dbgMessage, false);
}
}
public void CallTipcMethod(ServiceCtx context)
{
int commandId = (int)context.Request.Type - 0x10;
bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest);
if (ServiceConfiguration.IgnoreMissingServices || serviceExists)
{
ResultCode result = ResultCode.Success;
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
if (serviceExists)
{
Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}");
result = (ResultCode)processRequest.Invoke(this, new object[] { context });
}
else
{
string serviceName;
DummyService dummyService = this as DummyService;
serviceName = (dummyService == null) ? GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write((uint)result);
}
else
{
string dbgMessage = $"{GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(this, context, dbgMessage, true);
}
}