aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Common/SystemInfo/SystemInfo.cs
blob: e9ce3c58a1adf2fe0437756bdf0d97b3382e57b4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using Ryujinx.Common.Logging;
using System;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
using System.Text;

namespace Ryujinx.Common.SystemInfo
{
    public class SystemInfo
    {
        public string OsDescription { get; protected set; }
        public string CpuName { get; protected set; }
        public ulong RamTotal { get; protected set; }
        public ulong RamAvailable { get; protected set; }
        protected static int LogicalCoreCount => Environment.ProcessorCount;

        protected SystemInfo()
        {
            OsDescription = $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})";
            CpuName = "Unknown";
        }

        private static string ToMiBString(ulong bytesValue) => (bytesValue == 0) ? "Unknown" : $"{bytesValue / 1024 / 1024} MiB";

        public void Print()
        {
            Logger.Notice.Print(LogClass.Application, $"Operating System: {OsDescription}");
            Logger.Notice.Print(LogClass.Application, $"CPU: {CpuName}");
            Logger.Notice.Print(LogClass.Application, $"RAM: Total {ToMiBString(RamTotal)} ; Available {ToMiBString(RamAvailable)}");
        }

        public static SystemInfo Gather()
        {
            if (OperatingSystem.IsWindows())
            {
                return new WindowsSystemInfo();
            }
            else if (OperatingSystem.IsLinux())
            {
                return new LinuxSystemInfo();
            }
            else if (OperatingSystem.IsMacOS())
            {
                return new MacOSSystemInfo();
            }
            else
            {
                Logger.Error?.Print(LogClass.Application, "SystemInfo unsupported on this platform");

                return new SystemInfo();
            }
        }

        // x86 exposes a 48 byte ASCII "CPU brand" string via CPUID leaves 0x80000002-0x80000004.
        internal static string GetCpuidCpuName()
        {
            if (!X86Base.IsSupported)
            {
                return null;
            }

            // Check if CPU supports the query
            if ((uint)X86Base.CpuId(unchecked((int)0x80000000), 0).Eax < 0x80000004)
            {
                return null;
            }

            int[] regs = new int[12];

            for (uint i = 0; i < 3; ++i)
            {
                (regs[4 * i], regs[4 * i + 1], regs[4 * i + 2], regs[4 * i + 3]) = X86Base.CpuId((int)(0x80000002 + i), 0);
            }

            string name = Encoding.ASCII.GetString(MemoryMarshal.Cast<int, byte>(regs)).Replace('\0', ' ').Trim();

            return string.IsNullOrEmpty(name) ? null : name;
        }
    }
}