mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2025-10-03 08:55:51 -05:00
Horizon: Implement arp:r and arp:w services (#5802)
* Horizon: Implement arp:r and arp:w services * Fix formatting * Remove HLE arp services * Revert "Remove HLE arp services" This reverts commit c576fcccadb963db56b96bacabd1c1ac7abfb1ab. * Keep LibHac impl since it's used in bcat * Addresses gdkchan's feedback * ArpApi in PrepoIpcServer and remove LmApi * Fix 2 * Fixes ArpApi init * Fix encoding * Update PrepoService.cs * Fix prepo
This commit is contained in:
@@ -35,5 +35,254 @@ namespace Ryujinx.Horizon.Sdk
|
||||
|
||||
return CmifMessage.ParseResponse(out response, HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize).Memory.Span, false, 0);
|
||||
}
|
||||
|
||||
public static Result SendRequest(
|
||||
out CmifResponse response,
|
||||
int sessionHandle,
|
||||
uint requestId,
|
||||
bool sendPid,
|
||||
scoped ReadOnlySpan<byte> data,
|
||||
ReadOnlySpan<HipcBufferFlags> bufferFlags,
|
||||
ReadOnlySpan<PointerAndSize> buffers)
|
||||
{
|
||||
ulong tlsAddress = HorizonStatic.ThreadContext.TlsAddress;
|
||||
int tlsSize = Api.TlsMessageBufferSize;
|
||||
|
||||
using (var tlsRegion = HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize))
|
||||
{
|
||||
CmifRequestFormat format = new()
|
||||
{
|
||||
DataSize = data.Length,
|
||||
RequestId = requestId,
|
||||
SendPid = sendPid,
|
||||
};
|
||||
|
||||
for (int index = 0; index < bufferFlags.Length; index++)
|
||||
{
|
||||
FormatProcessBuffer(ref format, bufferFlags[index]);
|
||||
}
|
||||
|
||||
CmifRequest request = CmifMessage.CreateRequest(tlsRegion.Memory.Span, format);
|
||||
|
||||
for (int index = 0; index < buffers.Length; index++)
|
||||
{
|
||||
RequestProcessBuffer(ref request, buffers[index], bufferFlags[index]);
|
||||
}
|
||||
|
||||
data.CopyTo(request.Data);
|
||||
}
|
||||
|
||||
Result result = HorizonStatic.Syscall.SendSyncRequest(sessionHandle);
|
||||
|
||||
if (result.IsFailure)
|
||||
{
|
||||
response = default;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return CmifMessage.ParseResponse(out response, HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize).Memory.Span, false, 0);
|
||||
}
|
||||
|
||||
private static void FormatProcessBuffer(ref CmifRequestFormat format, HipcBufferFlags flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isIn = flags.HasFlag(HipcBufferFlags.In);
|
||||
bool isOut = flags.HasFlag(HipcBufferFlags.Out);
|
||||
|
||||
if (flags.HasFlag(HipcBufferFlags.AutoSelect))
|
||||
{
|
||||
if (isIn)
|
||||
{
|
||||
format.InAutoBuffersCount++;
|
||||
}
|
||||
|
||||
if (isOut)
|
||||
{
|
||||
format.OutAutoBuffersCount++;
|
||||
}
|
||||
}
|
||||
else if (flags.HasFlag(HipcBufferFlags.Pointer))
|
||||
{
|
||||
if (isIn)
|
||||
{
|
||||
format.InPointersCount++;
|
||||
}
|
||||
|
||||
if (isOut)
|
||||
{
|
||||
if (flags.HasFlag(HipcBufferFlags.FixedSize))
|
||||
{
|
||||
format.OutFixedPointersCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
format.OutPointersCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags.HasFlag(HipcBufferFlags.MapAlias))
|
||||
{
|
||||
if (isIn && isOut)
|
||||
{
|
||||
format.InOutBuffersCount++;
|
||||
}
|
||||
else if (isIn)
|
||||
{
|
||||
format.InBuffersCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
format.OutBuffersCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RequestProcessBuffer(ref CmifRequest request, PointerAndSize buffer, HipcBufferFlags flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isIn = flags.HasFlag(HipcBufferFlags.In);
|
||||
bool isOut = flags.HasFlag(HipcBufferFlags.Out);
|
||||
|
||||
if (flags.HasFlag(HipcBufferFlags.AutoSelect))
|
||||
{
|
||||
HipcBufferMode mode = HipcBufferMode.Normal;
|
||||
|
||||
if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonSecure))
|
||||
{
|
||||
mode = HipcBufferMode.NonSecure;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonDevice))
|
||||
{
|
||||
mode = HipcBufferMode.NonDevice;
|
||||
}
|
||||
|
||||
if (isIn)
|
||||
{
|
||||
RequestInAutoBuffer(ref request, buffer.Address, buffer.Size, mode);
|
||||
}
|
||||
|
||||
if (isOut)
|
||||
{
|
||||
RequestOutAutoBuffer(ref request, buffer.Address, buffer.Size, mode);
|
||||
}
|
||||
}
|
||||
else if (flags.HasFlag(HipcBufferFlags.Pointer))
|
||||
{
|
||||
if (isIn)
|
||||
{
|
||||
RequestInPointer(ref request, buffer.Address, buffer.Size);
|
||||
}
|
||||
|
||||
if (isOut)
|
||||
{
|
||||
if (flags.HasFlag(HipcBufferFlags.FixedSize))
|
||||
{
|
||||
RequestOutFixedPointer(ref request, buffer.Address, buffer.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestOutPointer(ref request, buffer.Address, buffer.Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags.HasFlag(HipcBufferFlags.MapAlias))
|
||||
{
|
||||
HipcBufferMode mode = HipcBufferMode.Normal;
|
||||
|
||||
if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonSecure))
|
||||
{
|
||||
mode = HipcBufferMode.NonSecure;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(HipcBufferFlags.MapTransferAllowsNonDevice))
|
||||
{
|
||||
mode = HipcBufferMode.NonDevice;
|
||||
}
|
||||
|
||||
if (isIn && isOut)
|
||||
{
|
||||
RequestInOutBuffer(ref request, buffer.Address, buffer.Size, mode);
|
||||
}
|
||||
else if (isIn)
|
||||
{
|
||||
RequestInBuffer(ref request, buffer.Address, buffer.Size, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestOutBuffer(ref request, buffer.Address, buffer.Size, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RequestInAutoBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode)
|
||||
{
|
||||
if (request.ServerPointerSize != 0 && bufferSize <= (ulong)request.ServerPointerSize)
|
||||
{
|
||||
RequestInPointer(ref request, bufferAddress, bufferSize);
|
||||
RequestInBuffer(ref request, 0UL, 0UL, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestInPointer(ref request, 0UL, 0UL);
|
||||
RequestInBuffer(ref request, bufferAddress, bufferSize, mode);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RequestOutAutoBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode)
|
||||
{
|
||||
if (request.ServerPointerSize != 0 && bufferSize <= (ulong)request.ServerPointerSize)
|
||||
{
|
||||
RequestOutPointer(ref request, bufferAddress, bufferSize);
|
||||
RequestOutBuffer(ref request, 0UL, 0UL, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestOutPointer(ref request, 0UL, 0UL);
|
||||
RequestOutBuffer(ref request, bufferAddress, bufferSize, mode);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RequestInBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode)
|
||||
{
|
||||
request.Hipc.SendBuffers[request.SendBufferIndex++] = new HipcBufferDescriptor(bufferAddress, bufferSize, mode);
|
||||
}
|
||||
|
||||
private static void RequestOutBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode)
|
||||
{
|
||||
request.Hipc.ReceiveBuffers[request.RecvBufferIndex++] = new HipcBufferDescriptor(bufferAddress, bufferSize, mode);
|
||||
}
|
||||
|
||||
private static void RequestInOutBuffer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize, HipcBufferMode mode)
|
||||
{
|
||||
request.Hipc.ExchangeBuffers[request.ExchBufferIndex++] = new HipcBufferDescriptor(bufferAddress, bufferSize, mode);
|
||||
}
|
||||
|
||||
private static void RequestInPointer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize)
|
||||
{
|
||||
request.Hipc.SendStatics[request.SendStaticIndex++] = new HipcStaticDescriptor(bufferAddress, (ushort)bufferSize, request.CurrentInPointerId++);
|
||||
request.ServerPointerSize -= (int)bufferSize;
|
||||
}
|
||||
|
||||
private static void RequestOutFixedPointer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize)
|
||||
{
|
||||
request.Hipc.ReceiveList[request.RecvListIndex++] = new HipcReceiveListEntry(bufferAddress, (ushort)bufferSize);
|
||||
request.ServerPointerSize -= (int)bufferSize;
|
||||
}
|
||||
|
||||
private static void RequestOutPointer(ref CmifRequest request, ulong bufferAddress, ulong bufferSize)
|
||||
{
|
||||
RequestOutFixedPointer(ref request, bufferAddress, bufferSize);
|
||||
request.OutPointerSizes[request.OutPointerSizeIndex++] = (ushort)bufferSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user