IpcLog.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.IO;
  3. namespace Ryujinx.Core.OsHle.Ipc
  4. {
  5. public static class IpcLog
  6. {
  7. public static string Message(byte[] Data, long CmdPtr, bool Domain)
  8. {
  9. string IpcMessage = "";
  10. using (MemoryStream MS = new MemoryStream(Data))
  11. {
  12. BinaryReader Reader = new BinaryReader(MS);
  13. int Word0 = Reader.ReadInt32();
  14. int Word1 = Reader.ReadInt32();
  15. int Type = (Word0 & 0xffff);
  16. int PtrBuffCount = (Word0 >> 16) & 0xf;
  17. int SendBuffCount = (Word0 >> 20) & 0xf;
  18. int RecvBuffCount = (Word0 >> 24) & 0xf;
  19. int XchgBuffCount = (Word0 >> 28) & 0xf;
  20. int RawDataSize = (Word1 >> 0) & 0x3ff;
  21. int RecvListFlags = (Word1 >> 10) & 0xf;
  22. bool HndDescEnable = ((Word1 >> 31) & 0x1) != 0;
  23. IpcMessage += Environment.NewLine + $" {Logging.GetExecutionTime()} | IpcMessage >" + Environment.NewLine +
  24. $" Type: {Enum.GetName(typeof(IpcMessageType), Type)}" + Environment.NewLine +
  25. $" PtrBuffCount: {PtrBuffCount.ToString()}" + Environment.NewLine +
  26. $" SendBuffCount: {SendBuffCount.ToString()}" + Environment.NewLine +
  27. $" RecvBuffCount: {RecvBuffCount.ToString()}" + Environment.NewLine +
  28. $" XchgBuffCount: {XchgBuffCount.ToString()}" + Environment.NewLine +
  29. $" RawDataSize: {RawDataSize.ToString()}" + Environment.NewLine +
  30. $" RecvListFlags: {RecvListFlags.ToString()}" + Environment.NewLine +
  31. $" HndDescEnable: {HndDescEnable.ToString()}" + Environment.NewLine;
  32. if (HndDescEnable)
  33. {
  34. int Word = Reader.ReadInt32();
  35. bool HasPId = (Word & 1) != 0;
  36. int[] ToCopy = new int[(Word >> 1) & 0xf];
  37. int[] ToMove = new int[(Word >> 5) & 0xf];
  38. long PId = HasPId ? Reader.ReadInt64() : 0;
  39. for (int Index = 0; Index < ToCopy.Length; Index++)
  40. {
  41. ToCopy[Index] = Reader.ReadInt32();
  42. }
  43. for (int Index = 0; Index < ToMove.Length; Index++)
  44. {
  45. ToMove[Index] = Reader.ReadInt32();
  46. }
  47. IpcMessage += Environment.NewLine + " HndDesc:" + Environment.NewLine +
  48. $" PId: {PId.ToString()}" + Environment.NewLine +
  49. $" ToCopy.Length: {ToCopy.Length.ToString()}" + Environment.NewLine +
  50. $" ToMove.Length: {ToMove.Length.ToString()}" + Environment.NewLine;
  51. }
  52. for (int Index = 0; Index < PtrBuffCount; Index++)
  53. {
  54. long IpcPtrBuffDescWord0 = Reader.ReadUInt32();
  55. long IpcPtrBuffDescWord1 = Reader.ReadUInt32();
  56. long Position = IpcPtrBuffDescWord1;
  57. Position |= (IpcPtrBuffDescWord0 << 20) & 0x0f00000000;
  58. Position |= (IpcPtrBuffDescWord0 << 30) & 0x7000000000;
  59. int IpcPtrBuffDescIndex = ((int)IpcPtrBuffDescWord0 >> 0) & 0x03f;
  60. IpcPtrBuffDescIndex |= ((int)IpcPtrBuffDescWord0 >> 3) & 0x1c0;
  61. short Size = (short)(IpcPtrBuffDescWord0 >> 16);
  62. IpcMessage += Environment.NewLine + $" PtrBuff[{Index}]:" + Environment.NewLine +
  63. $" Position: {Position.ToString()}" + Environment.NewLine +
  64. $" IpcPtrBuffDescIndex: {IpcPtrBuffDescIndex.ToString()}" + Environment.NewLine +
  65. $" Size: {Size.ToString()}" + Environment.NewLine;
  66. }
  67. ReadIpcBuffValues(Reader, SendBuffCount, IpcMessage, "SendBuff");
  68. ReadIpcBuffValues(Reader, RecvBuffCount, IpcMessage, "RecvBuff");
  69. ReadIpcBuffValues(Reader, XchgBuffCount, IpcMessage, "XchgBuff");
  70. RawDataSize *= 4;
  71. long RecvListPos = Reader.BaseStream.Position + RawDataSize;
  72. long Pad0 = 0;
  73. if ((Reader.BaseStream.Position + CmdPtr & 0xf) != 0)
  74. {
  75. Pad0 = 0x10 - (Reader.BaseStream.Position + CmdPtr & 0xf);
  76. }
  77. Reader.BaseStream.Seek(Pad0, SeekOrigin.Current);
  78. int RecvListCount = RecvListFlags - 2;
  79. if (RecvListCount == 0)
  80. {
  81. RecvListCount = 1;
  82. }
  83. else if (RecvListCount < 0)
  84. {
  85. RecvListCount = 0;
  86. }
  87. if (Domain && (IpcMessageType)Type == IpcMessageType.Request)
  88. {
  89. int DomWord0 = Reader.ReadInt32();
  90. int DomCmd = (DomWord0 & 0xff);
  91. RawDataSize = (DomWord0 >> 16) & 0xffff;
  92. int DomObjId = Reader.ReadInt32();
  93. Reader.ReadInt64(); //Padding
  94. IpcMessage += Environment.NewLine + $" Domain:" + Environment.NewLine + Environment.NewLine +
  95. $" DomObjId: {DomObjId.ToString()}" + Environment.NewLine;
  96. }
  97. byte[] RawData = Reader.ReadBytes(RawDataSize);
  98. IpcMessage += Environment.NewLine + $" RawData:" + Environment.NewLine + Logging.HexDump(RawData);
  99. Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin);
  100. for (int Index = 0; Index < RecvListCount; Index++)
  101. {
  102. long RecvListBuffValue = Reader.ReadInt64();
  103. long RecvListBuffPosition = RecvListBuffValue & 0xffffffffffff;
  104. long RecvListBuffSize = (short)(RecvListBuffValue >> 48);
  105. IpcMessage += Environment.NewLine + $" RecvList[{Index}]:" + Environment.NewLine +
  106. $" Value: {RecvListBuffValue.ToString()}" + Environment.NewLine +
  107. $" Position: {RecvListBuffPosition.ToString()}" + Environment.NewLine +
  108. $" Size: {RecvListBuffSize.ToString()}" + Environment.NewLine;
  109. }
  110. }
  111. return IpcMessage;
  112. }
  113. private static void ReadIpcBuffValues(BinaryReader Reader, int Count, string IpcMessage, string BufferName)
  114. {
  115. for (int Index = 0; Index < Count; Index++)
  116. {
  117. long Word0 = Reader.ReadUInt32();
  118. long Word1 = Reader.ReadUInt32();
  119. long Word2 = Reader.ReadUInt32();
  120. long Position = Word1;
  121. Position |= (Word2 << 4) & 0x0f00000000;
  122. Position |= (Word2 << 34) & 0x7000000000;
  123. long Size = Word0;
  124. Size |= (Word2 << 8) & 0xf00000000;
  125. int Flags = (int)Word2 & 3;
  126. IpcMessage += Environment.NewLine + $" {BufferName}[{Index}]:" + Environment.NewLine +
  127. $" Position: {Position.ToString()}" + Environment.NewLine +
  128. $" Flags: {Flags.ToString()}" + Environment.NewLine +
  129. $" Size: {Size.ToString()}" + Environment.NewLine;
  130. }
  131. }
  132. }
  133. }