KernelAccessControl.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using System.Collections.Generic;
  2. using System.IO;
  3. namespace Ryujinx.HLE.Loaders.Npdm
  4. {
  5. public class KernelAccessControlIRQ
  6. {
  7. public uint IRQ0;
  8. public uint IRQ1;
  9. }
  10. public class KernelAccessControlMMIO
  11. {
  12. public ulong Address;
  13. public ulong Size;
  14. public bool IsRO;
  15. public bool IsNormal;
  16. }
  17. public class KernelAccessControlItems
  18. {
  19. public bool HasKernelFlags;
  20. public uint LowestThreadPriority;
  21. public uint HighestThreadPriority;
  22. public uint LowestCpuId;
  23. public uint HighestCpuId;
  24. public bool HasSVCFlags;
  25. public int[] SVCsAllowed;
  26. public List<KernelAccessControlMMIO> NormalMMIO;
  27. public List<KernelAccessControlMMIO> PageMMIO;
  28. public List<KernelAccessControlIRQ> IRQ;
  29. public bool HasApplicationType;
  30. public int ApplicationType;
  31. public bool HasKernelVersion;
  32. public int KernelVersionRelease;
  33. public bool HasHandleTableSize;
  34. public int HandleTableSize;
  35. public bool HasDebugFlags;
  36. public bool AllowDebug;
  37. public bool ForceDebug;
  38. }
  39. public class KernelAccessControl
  40. {
  41. public KernelAccessControlItems[] Items;
  42. public KernelAccessControl(Stream FSAccessControlsStream, int Offset, int Size)
  43. {
  44. FSAccessControlsStream.Seek(Offset, SeekOrigin.Begin);
  45. BinaryReader Reader = new BinaryReader(FSAccessControlsStream);
  46. Items = new KernelAccessControlItems[Size / 4];
  47. for (int i = 0; i < Size / 4; i++)
  48. {
  49. uint Descriptor = Reader.ReadUInt32();
  50. if (Descriptor == 0xFFFFFFFF) //Ignore the descriptor
  51. {
  52. continue;
  53. }
  54. Items[i] = new KernelAccessControlItems();
  55. int LowBits = 0;
  56. while ((Descriptor & 1) != 0)
  57. {
  58. Descriptor >>= 1;
  59. LowBits++;
  60. }
  61. Descriptor >>= 1;
  62. switch (LowBits)
  63. {
  64. case 3: // Kernel flags
  65. {
  66. Items[i].HasKernelFlags = true;
  67. Items[i].HighestThreadPriority = Descriptor & 0x3F;
  68. Items[i].LowestThreadPriority = (Descriptor >> 6) & 0x3F;
  69. Items[i].LowestCpuId = (Descriptor >> 12) & 0xFF;
  70. Items[i].HighestCpuId = (Descriptor >> 20) & 0xFF;
  71. break;
  72. }
  73. case 4: // Syscall mask
  74. {
  75. Items[i].HasSVCFlags = true;
  76. Items[i].SVCsAllowed = new int[0x80];
  77. int SysCallBase = (int)(Descriptor >> 24) * 0x18;
  78. for (int SysCall = 0; SysCall < 0x18 && SysCallBase + SysCall < 0x80; SysCall++)
  79. {
  80. Items[i].SVCsAllowed[SysCallBase + SysCall] = (int)Descriptor & 1;
  81. Descriptor >>= 1;
  82. }
  83. break;
  84. }
  85. case 6: // Map IO/Normal - Never tested.
  86. {
  87. KernelAccessControlMMIO TempNormalMMIO = new KernelAccessControlMMIO
  88. {
  89. Address = (Descriptor & 0xFFFFFF) << 12,
  90. IsRO = (Descriptor >> 24) != 0
  91. };
  92. if (i == Size / 4 - 1)
  93. {
  94. throw new InvalidNpdmException("Invalid Kernel Access Control Descriptors!");
  95. }
  96. Descriptor = Reader.ReadUInt32();
  97. if ((Descriptor & 0x7F) != 0x3F)
  98. {
  99. throw new InvalidNpdmException("Invalid Kernel Access Control Descriptors!");
  100. }
  101. Descriptor >>= 7;
  102. TempNormalMMIO.Size = (Descriptor & 0xFFFFFF) << 12;
  103. TempNormalMMIO.IsNormal = (Descriptor >> 24) != 0;
  104. Items[i].NormalMMIO.Add(TempNormalMMIO);
  105. i++;
  106. break;
  107. }
  108. case 7: // Map Normal Page - Never tested.
  109. {
  110. KernelAccessControlMMIO TempPageMMIO = new KernelAccessControlMMIO
  111. {
  112. Address = Descriptor << 12,
  113. Size = 0x1000,
  114. IsRO = false,
  115. IsNormal = false
  116. };
  117. Items[i].PageMMIO.Add(TempPageMMIO);
  118. break;
  119. }
  120. case 11: // IRQ Pair - Never tested.
  121. {
  122. KernelAccessControlIRQ TempIRQ = new KernelAccessControlIRQ
  123. {
  124. IRQ0 = Descriptor & 0x3FF,
  125. IRQ1 = (Descriptor >> 10) & 0x3FF
  126. };
  127. break;
  128. }
  129. case 13: // App Type
  130. {
  131. Items[i].HasApplicationType = true;
  132. Items[i].ApplicationType = (int)Descriptor & 7;
  133. break;
  134. }
  135. case 14: // Kernel Release Version
  136. {
  137. Items[i].HasKernelVersion = true;
  138. Items[i].KernelVersionRelease = (int)Descriptor;
  139. break;
  140. }
  141. case 15: // Handle Table Size
  142. {
  143. Items[i].HasHandleTableSize = true;
  144. Items[i].HandleTableSize = (int)Descriptor;
  145. break;
  146. }
  147. case 16: // Debug Flags
  148. {
  149. Items[i].HasDebugFlags = true;
  150. Items[i].AllowDebug = (Descriptor & 1) != 0;
  151. Items[i].ForceDebug = ((Descriptor >> 1) & 1) != 0;
  152. break;
  153. }
  154. }
  155. }
  156. }
  157. }
  158. }