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:
parent
faa654dbaf
commit
0746b83edf
132 changed files with 1077 additions and 951 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue