| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- using Ryujinx.Common;
- using Ryujinx.Horizon.Sdk.Sf.Cmif;
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- namespace Ryujinx.Horizon.Sdk.Sf.Hipc
- {
- ref struct HipcMessage
- {
- public const int AutoReceiveStatic = byte.MaxValue;
- public HipcMetadata Meta;
- public HipcMessageData Data;
- public ulong Pid;
- public HipcMessage(Span<byte> data)
- {
- int initialLength = data.Length;
- Header header = MemoryMarshal.Cast<byte, Header>(data)[0];
- data = data[Unsafe.SizeOf<Header>()..];
- int receiveStaticsCount = 0;
- ulong pid = 0;
- if (header.ReceiveStaticMode != 0)
- {
- if (header.ReceiveStaticMode == 2)
- {
- receiveStaticsCount = AutoReceiveStatic;
- }
- else if (header.ReceiveStaticMode > 2)
- {
- receiveStaticsCount = header.ReceiveStaticMode - 2;
- }
- }
- SpecialHeader specialHeader = default;
- if (header.HasSpecialHeader)
- {
- specialHeader = MemoryMarshal.Cast<byte, SpecialHeader>(data)[0];
- data = data[Unsafe.SizeOf<SpecialHeader>()..];
- if (specialHeader.SendPid)
- {
- pid = MemoryMarshal.Cast<byte, ulong>(data)[0];
- data = data[sizeof(ulong)..];
- }
- }
- Meta = new HipcMetadata()
- {
- Type = (int)header.Type,
- SendStaticsCount = header.SendStaticsCount,
- SendBuffersCount = header.SendBuffersCount,
- ReceiveBuffersCount = header.ReceiveBuffersCount,
- ExchangeBuffersCount = header.ExchangeBuffersCount,
- DataWordsCount = header.DataWordsCount,
- ReceiveStaticsCount = receiveStaticsCount,
- SendPid = specialHeader.SendPid,
- CopyHandlesCount = specialHeader.CopyHandlesCount,
- MoveHandlesCount = specialHeader.MoveHandlesCount
- };
- Data = CreateMessageData(Meta, data, initialLength);
- Pid = pid;
- }
- public static HipcMessageData WriteResponse(
- Span<byte> destination,
- int sendStaticCount,
- int dataWordsCount,
- int copyHandlesCount,
- int moveHandlesCount)
- {
- return WriteMessage(destination, new HipcMetadata()
- {
- SendStaticsCount = sendStaticCount,
- DataWordsCount = dataWordsCount,
- CopyHandlesCount = copyHandlesCount,
- MoveHandlesCount = moveHandlesCount
- });
- }
- public static HipcMessageData WriteMessage(Span<byte> destination, HipcMetadata meta)
- {
- int initialLength = destination.Length;
- bool hasSpecialHeader = meta.SendPid || meta.CopyHandlesCount != 0 || meta.MoveHandlesCount != 0;
- MemoryMarshal.Cast<byte, Header>(destination)[0] = new Header()
- {
- Type = (CommandType)meta.Type,
- SendStaticsCount = meta.SendStaticsCount,
- SendBuffersCount = meta.SendBuffersCount,
- ReceiveBuffersCount = meta.ReceiveBuffersCount,
- ExchangeBuffersCount = meta.ExchangeBuffersCount,
- DataWordsCount = meta.DataWordsCount,
- ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0,
- HasSpecialHeader = hasSpecialHeader
- };
- destination = destination[Unsafe.SizeOf<Header>()..];
- if (hasSpecialHeader)
- {
- MemoryMarshal.Cast<byte, SpecialHeader>(destination)[0] = new SpecialHeader()
- {
- SendPid = meta.SendPid,
- CopyHandlesCount = meta.CopyHandlesCount,
- MoveHandlesCount = meta.MoveHandlesCount
- };
- destination = destination[Unsafe.SizeOf<SpecialHeader>()..];
- if (meta.SendPid)
- {
- destination = destination[sizeof(ulong)..];
- }
- }
- return CreateMessageData(meta, destination, initialLength);
- }
- private static HipcMessageData CreateMessageData(HipcMetadata meta, Span<byte> data, int initialLength)
- {
- Span<int> copyHandles = Span<int>.Empty;
- if (meta.CopyHandlesCount != 0)
- {
- copyHandles = MemoryMarshal.Cast<byte, int>(data)[..meta.CopyHandlesCount];
- data = data[(meta.CopyHandlesCount * sizeof(int))..];
- }
- Span<int> moveHandles = Span<int>.Empty;
- if (meta.MoveHandlesCount != 0)
- {
- moveHandles = MemoryMarshal.Cast<byte, int>(data)[..meta.MoveHandlesCount];
- data = data[(meta.MoveHandlesCount * sizeof(int))..];
- }
- Span<HipcStaticDescriptor> sendStatics = Span<HipcStaticDescriptor>.Empty;
- if (meta.SendStaticsCount != 0)
- {
- sendStatics = MemoryMarshal.Cast<byte, HipcStaticDescriptor>(data)[..meta.SendStaticsCount];
- data = data[(meta.SendStaticsCount * Unsafe.SizeOf<HipcStaticDescriptor>())..];
- }
- Span<HipcBufferDescriptor> sendBuffers = Span<HipcBufferDescriptor>.Empty;
- if (meta.SendBuffersCount != 0)
- {
- sendBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data)[..meta.SendBuffersCount];
- data = data[(meta.SendBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>())..];
- }
- Span<HipcBufferDescriptor> receiveBuffers = Span<HipcBufferDescriptor>.Empty;
- if (meta.ReceiveBuffersCount != 0)
- {
- receiveBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data)[..meta.ReceiveBuffersCount];
- data = data[(meta.ReceiveBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>())..];
- }
- Span<HipcBufferDescriptor> exchangeBuffers = Span<HipcBufferDescriptor>.Empty;
- if (meta.ExchangeBuffersCount != 0)
- {
- exchangeBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data)[..meta.ExchangeBuffersCount];
- data = data[(meta.ExchangeBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>())..];
- }
- Span<uint> dataWords = Span<uint>.Empty;
- if (meta.DataWordsCount != 0)
- {
- int dataOffset = initialLength - data.Length;
- int dataOffsetAligned = BitUtils.AlignUp(dataOffset, 0x10);
- int padding = (dataOffsetAligned - dataOffset) / sizeof(uint);
- dataWords = MemoryMarshal.Cast<byte, uint>(data)[padding..meta.DataWordsCount];
- data = data[(meta.DataWordsCount * sizeof(uint))..];
- }
- Span<HipcReceiveListEntry> receiveList = Span<HipcReceiveListEntry>.Empty;
- if (meta.ReceiveStaticsCount != 0)
- {
- int receiveListSize = meta.ReceiveStaticsCount == AutoReceiveStatic ? 1 : meta.ReceiveStaticsCount;
- receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data)[..receiveListSize];
- }
- return new HipcMessageData()
- {
- SendStatics = sendStatics,
- SendBuffers = sendBuffers,
- ReceiveBuffers = receiveBuffers,
- ExchangeBuffers = exchangeBuffers,
- DataWords = dataWords,
- ReceiveList = receiveList,
- CopyHandles = copyHandles,
- MoveHandles = moveHandles
- };
- }
- }
- }
|