/ src / Ryujinx.UI.Common / SystemInfo / SystemInfo.cs
SystemInfo.cs
 1  using Ryujinx.Common.Logging;
 2  using Ryujinx.UI.Common.Helper;
 3  using System;
 4  using System.Runtime.InteropServices;
 5  using System.Runtime.Intrinsics.X86;
 6  using System.Text;
 7  
 8  namespace Ryujinx.UI.Common.SystemInfo
 9  {
10      public class SystemInfo
11      {
12          public string OsDescription { get; protected set; }
13          public string CpuName { get; protected set; }
14          public ulong RamTotal { get; protected set; }
15          public ulong RamAvailable { get; protected set; }
16          protected static int LogicalCoreCount => Environment.ProcessorCount;
17  
18          protected SystemInfo()
19          {
20              OsDescription = $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})";
21              CpuName = "Unknown";
22          }
23  
24          private static string ToGBString(ulong bytesValue) => (bytesValue == 0) ? "Unknown" : ValueFormatUtils.FormatFileSize((long)bytesValue, ValueFormatUtils.FileSizeUnits.Gibibytes);
25  
26          public void Print()
27          {
28              Logger.Notice.Print(LogClass.Application, $"Operating System: {OsDescription}");
29              Logger.Notice.Print(LogClass.Application, $"CPU: {CpuName}");
30              Logger.Notice.Print(LogClass.Application, $"RAM: Total {ToGBString(RamTotal)} ; Available {ToGBString(RamAvailable)}");
31          }
32  
33          public static SystemInfo Gather()
34          {
35              if (OperatingSystem.IsWindows())
36              {
37                  return new WindowsSystemInfo();
38              }
39              else if (OperatingSystem.IsLinux())
40              {
41                  return new LinuxSystemInfo();
42              }
43              else if (OperatingSystem.IsMacOS())
44              {
45                  return new MacOSSystemInfo();
46              }
47  
48              Logger.Error?.Print(LogClass.Application, "SystemInfo unsupported on this platform");
49  
50              return new SystemInfo();
51          }
52  
53          // x86 exposes a 48 byte ASCII "CPU brand" string via CPUID leaves 0x80000002-0x80000004.
54          internal static string GetCpuidCpuName()
55          {
56              if (!X86Base.IsSupported)
57              {
58                  return null;
59              }
60  
61              // Check if CPU supports the query
62              if ((uint)X86Base.CpuId(unchecked((int)0x80000000), 0).Eax < 0x80000004)
63              {
64                  return null;
65              }
66  
67              int[] regs = new int[12];
68  
69              for (uint i = 0; i < 3; ++i)
70              {
71                  (regs[4 * i], regs[4 * i + 1], regs[4 * i + 2], regs[4 * i + 3]) = X86Base.CpuId((int)(0x80000002 + i), 0);
72              }
73  
74              string name = Encoding.ASCII.GetString(MemoryMarshal.Cast<int, byte>(regs)).Replace('\0', ' ').Trim();
75  
76              return string.IsNullOrEmpty(name) ? null : name;
77          }
78      }
79  }