diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Ipc')
-rw-r--r-- | Ryujinx.HLE/HOS/Ipc/IpcHandleDesc.cs | 61 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Ipc/IpcMessage.cs | 163 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Ipc/IpcRecvListBuffDesc.cs | 8 |
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 |