aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Ipc
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Ipc')
-rw-r--r--Ryujinx.HLE/HOS/Ipc/IpcHandleDesc.cs61
-rw-r--r--Ryujinx.HLE/HOS/Ipc/IpcMessage.cs163
-rw-r--r--Ryujinx.HLE/HOS/Ipc/IpcRecvListBuffDesc.cs8
3 files changed, 115 insertions, 117 deletions
diff --git a/Ryujinx.HLE/HOS/Ipc/IpcHandleDesc.cs b/Ryujinx.HLE/HOS/Ipc/IpcHandleDesc.cs
index e6ed4613..c7ef7e9c 100644
--- a/Ryujinx.HLE/HOS/Ipc/IpcHandleDesc.cs
+++ b/Ryujinx.HLE/HOS/Ipc/IpcHandleDesc.cs
@@ -1,3 +1,6 @@
+using Microsoft.IO;
+using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using System;
using System.IO;
@@ -18,20 +21,27 @@ namespace Ryujinx.HLE.HOS.Ipc
HasPId = (word & 1) != 0;
- ToCopy = new int[(word >> 1) & 0xf];
- ToMove = new int[(word >> 5) & 0xf];
-
PId = HasPId ? reader.ReadUInt64() : 0;
- for (int index = 0; index < ToCopy.Length; index++)
+ int toCopySize = (word >> 1) & 0xf;
+ int[] toCopy = toCopySize == 0 ? Array.Empty<int>() : new int[toCopySize];
+
+ for (int index = 0; index < toCopy.Length; index++)
{
- ToCopy[index] = reader.ReadInt32();
+ toCopy[index] = reader.ReadInt32();
}
- for (int index = 0; index < ToMove.Length; index++)
+ ToCopy = toCopy;
+
+ int toMoveSize = (word >> 5) & 0xf;
+ int[] toMove = toMoveSize == 0 ? Array.Empty<int>() : new int[toMoveSize];
+
+ for (int index = 0; index < toMove.Length; index++)
{
- ToMove[index] = reader.ReadInt32();
+ toMove[index] = reader.ReadInt32();
}
+
+ ToMove = toMove;
}
public IpcHandleDesc(int[] copy, int[] move)
@@ -57,36 +67,27 @@ namespace Ryujinx.HLE.HOS.Ipc
return new IpcHandleDesc(Array.Empty<int>(), handles);
}
- public byte[] GetBytes()
+ public RecyclableMemoryStream GetStream()
{
- using (MemoryStream ms = new MemoryStream())
- {
- BinaryWriter writer = new BinaryWriter(ms);
-
- int word = HasPId ? 1 : 0;
+ RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
- word |= (ToCopy.Length & 0xf) << 1;
- word |= (ToMove.Length & 0xf) << 5;
+ int word = HasPId ? 1 : 0;
- writer.Write(word);
+ word |= (ToCopy.Length & 0xf) << 1;
+ word |= (ToMove.Length & 0xf) << 5;
- if (HasPId)
- {
- writer.Write(PId);
- }
+ ms.Write(word);
- foreach (int handle in ToCopy)
- {
- writer.Write(handle);
- }
+ if (HasPId)
+ {
+ ms.Write(PId);
+ }
- foreach (int handle in ToMove)
- {
- writer.Write(handle);
- }
+ ms.Write(ToCopy);
+ ms.Write(ToMove);
- return ms.ToArray();
- }
+ ms.Position = 0;
+ return ms;
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs b/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
index 55044da4..4e8f2fbf 100644
--- a/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
+++ b/Ryujinx.HLE/HOS/Ipc/IpcMessage.cs
@@ -1,4 +1,8 @@
+using Microsoft.IO;
+using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using System;
+using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -32,9 +36,9 @@ namespace Ryujinx.HLE.HOS.Ipc
ObjectIds = new List<int>();
}
- public IpcMessage(byte[] data, long cmdPtr) : this()
+ public IpcMessage(ReadOnlySpan<byte> data, long cmdPtr) : this()
{
- using (MemoryStream ms = new MemoryStream(data))
+ using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream(data))
{
BinaryReader reader = new BinaryReader(ms);
@@ -114,124 +118,119 @@ namespace Ryujinx.HLE.HOS.Ipc
for (int index = 0; index < recvListCount; index++)
{
- RecvListBuff.Add(new IpcRecvListBuffDesc(reader));
+ RecvListBuff.Add(new IpcRecvListBuffDesc(reader.ReadUInt64()));
}
}
- public byte[] GetBytes(long cmdPtr, ulong recvListAddr)
+ public RecyclableMemoryStream GetStream(long cmdPtr, ulong recvListAddr)
{
- using (MemoryStream ms = new MemoryStream())
- {
- BinaryWriter writer = new BinaryWriter(ms);
+ RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
- int word0;
- int word1;
+ int word0;
+ int word1;
- word0 = (int)Type;
- word0 |= (PtrBuff.Count & 0xf) << 16;
- word0 |= (SendBuff.Count & 0xf) << 20;
- word0 |= (ReceiveBuff.Count & 0xf) << 24;
- word0 |= (ExchangeBuff.Count & 0xf) << 28;
+ word0 = (int)Type;
+ word0 |= (PtrBuff.Count & 0xf) << 16;
+ word0 |= (SendBuff.Count & 0xf) << 20;
+ word0 |= (ReceiveBuff.Count & 0xf) << 24;
+ word0 |= (ExchangeBuff.Count & 0xf) << 28;
- byte[] handleData = Array.Empty<byte>();
+ using RecyclableMemoryStream handleDataStream = HandleDesc?.GetStream();
- if (HandleDesc != null)
- {
- handleData = HandleDesc.GetBytes();
- }
+ int dataLength = RawData?.Length ?? 0;
- int dataLength = RawData?.Length ?? 0;
+ dataLength = (dataLength + 3) & ~3;
- dataLength = (dataLength + 3) & ~3;
+ int rawLength = dataLength;
- int rawLength = dataLength;
+ int pad0 = (int)GetPadSize16(cmdPtr + 8 + (handleDataStream?.Length ?? 0) + PtrBuff.Count * 8);
- int pad0 = (int)GetPadSize16(cmdPtr + 8 + handleData.Length + PtrBuff.Count * 8);
+ // Apparently, padding after Raw Data is 16 bytes, however when there is
+ // padding before Raw Data too, we need to subtract the size of this padding.
+ // This is the weirdest padding I've seen so far...
+ int pad1 = 0x10 - pad0;
- // Apparently, padding after Raw Data is 16 bytes, however when there is
- // padding before Raw Data too, we need to subtract the size of this padding.
- // This is the weirdest padding I've seen so far...
- int pad1 = 0x10 - pad0;
+ dataLength = (dataLength + pad0 + pad1) / 4;
- dataLength = (dataLength + pad0 + pad1) / 4;
+ word1 = (dataLength & 0x3ff) | (2 << 10);
- word1 = (dataLength & 0x3ff) | (2 << 10);
+ if (HandleDesc != null)
+ {
+ word1 |= 1 << 31;
+ }
- if (HandleDesc != null)
- {
- word1 |= 1 << 31;
- }
+ ms.Write(word0);
+ ms.Write(word1);
- writer.Write(word0);
- writer.Write(word1);
- writer.Write(handleData);
+ if (handleDataStream != null)
+ {
+ ms.Write(handleDataStream);
+ }
- for (int index = 0; index < PtrBuff.Count; index++)
- {
- writer.Write(PtrBuff[index].GetWord0());
- writer.Write(PtrBuff[index].GetWord1());
- }
+ foreach (IpcPtrBuffDesc ptrBuffDesc in PtrBuff)
+ {
+ ms.Write(ptrBuffDesc.GetWord0());
+ ms.Write(ptrBuffDesc.GetWord1());
+ }
- ms.Seek(pad0, SeekOrigin.Current);
+ ms.WriteByte(0, pad0);
- if (RawData != null)
- {
- writer.Write(RawData);
- ms.Seek(rawLength - RawData.Length, SeekOrigin.Current);
- }
+ if (RawData != null)
+ {
+ ms.Write(RawData);
+ ms.WriteByte(0, rawLength - RawData.Length);
+ }
- writer.Write(new byte[pad1]);
- writer.Write(recvListAddr);
+ ms.WriteByte(0, pad1);
- return ms.ToArray();
- }
+ ms.Write(recvListAddr);
+
+ ms.Position = 0;
+
+ return ms;
}
- public byte[] GetBytesTipc()
+ public RecyclableMemoryStream GetStreamTipc()
{
Debug.Assert(PtrBuff.Count == 0);
- using (MemoryStream ms = new MemoryStream())
- {
- BinaryWriter writer = new BinaryWriter(ms);
+ RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
- int word0;
- int word1;
+ int word0;
+ int word1;
- word0 = (int)Type;
- word0 |= (SendBuff.Count & 0xf) << 20;
- word0 |= (ReceiveBuff.Count & 0xf) << 24;
- word0 |= (ExchangeBuff.Count & 0xf) << 28;
+ word0 = (int)Type;
+ word0 |= (SendBuff.Count & 0xf) << 20;
+ word0 |= (ReceiveBuff.Count & 0xf) << 24;
+ word0 |= (ExchangeBuff.Count & 0xf) << 28;
- byte[] handleData = Array.Empty<byte>();
+ using RecyclableMemoryStream handleDataStream = HandleDesc?.GetStream();
- if (HandleDesc != null)
- {
- handleData = HandleDesc.GetBytes();
- }
-
- int dataLength = RawData?.Length ?? 0;
+ int dataLength = RawData?.Length ?? 0;
- dataLength = ((dataLength + 3) & ~3) / 4;
+ dataLength = ((dataLength + 3) & ~3) / 4;
- word1 = (dataLength & 0x3ff);
+ word1 = (dataLength & 0x3ff);
- if (HandleDesc != null)
- {
- word1 |= 1 << 31;
- }
+ if (HandleDesc != null)
+ {
+ word1 |= 1 << 31;
+ }
- writer.Write(word0);
- writer.Write(word1);
- writer.Write(handleData);
+ ms.Write(word0);
+ ms.Write(word1);
- if (RawData != null)
- {
- writer.Write(RawData);
- }
+ if (handleDataStream != null)
+ {
+ ms.Write(handleDataStream);
+ }
- return ms.ToArray();
+ if (RawData != null)
+ {
+ ms.Write(RawData);
}
+
+ return ms;
}
private long GetPadSize16(long position)
diff --git a/Ryujinx.HLE/HOS/Ipc/IpcRecvListBuffDesc.cs b/Ryujinx.HLE/HOS/Ipc/IpcRecvListBuffDesc.cs
index 10406ac7..bcc9d8f8 100644
--- a/Ryujinx.HLE/HOS/Ipc/IpcRecvListBuffDesc.cs
+++ b/Ryujinx.HLE/HOS/Ipc/IpcRecvListBuffDesc.cs
@@ -13,13 +13,11 @@ namespace Ryujinx.HLE.HOS.Ipc
Size = size;
}
- public IpcRecvListBuffDesc(BinaryReader reader)
+ public IpcRecvListBuffDesc(ulong packedValue)
{
- ulong value = reader.ReadUInt64();
+ Position = packedValue & 0xffffffffffff;
- Position = value & 0xffffffffffff;
-
- Size = (ushort)(value >> 48);
+ Size = (ushort)(packedValue >> 48);
}
}
} \ No newline at end of file