diff --git a/Tests/Kernels/ProcessorTests/Kernel.cs b/Tests/Kernels/ProcessorTests/Kernel.cs index 9f221bb3f..eb66d296d 100644 --- a/Tests/Kernels/ProcessorTests/Kernel.cs +++ b/Tests/Kernels/ProcessorTests/Kernel.cs @@ -24,8 +24,8 @@ namespace ProcessorTests { //TestVendorNameIsNotBlank(); TestCycleCount(); - //TestCycleRateIsNotZero(); - + TestCycleRateIsNotZero(); + TestController.Completed(); } catch (Exception e) @@ -39,7 +39,7 @@ namespace ProcessorTests public void TestVendorNameIsNotBlank() { string vendorName = CPU.GetCPUVendorName(); - mDebugger.Send(vendorName); + mDebugger.Send("Vendor name: " + vendorName); bool isVendorNameBlank = string.IsNullOrWhiteSpace(vendorName); mDebugger.Send("Vendor name: "); mDebugger.Send(vendorName); @@ -49,13 +49,9 @@ namespace ProcessorTests public void TestCycleCount() { ulong cycleCount = CPU.GetCPUUptime(); - mDebugger.Send("Cycle count: " + cycleCount); - mDebugger.SendNumber(cycleCount); bool isCycleCountZero = cycleCount == 0; - Assert.IsFalse(isCycleCountZero, "Processor cycle count is zero."); + Assert.IsFalse(isCycleCountZero, "Processor cycle count is not zero."); ulong secondCount = CPU.GetCPUUptime(); - mDebugger.Send("Cycle count: " + secondCount); - mDebugger.SendNumber(secondCount); Assert.IsTrue(secondCount > cycleCount, "Processor cycle count is increasing"); } @@ -63,7 +59,8 @@ namespace ProcessorTests { long cycleRate = CPU.GetCPUCycleSpeed(); bool isCycleRateZero = cycleRate == 0; - Assert.IsFalse(isCycleRateZero, "Processor cycle rate is zero."); + Assert.IsFalse(isCycleRateZero, "Processor cycle rate is not zero."); + Assert.IsTrue(CPU.GetCPUCycleSpeed() == cycleRate, "Processor cycle speed is not constant"); } } } diff --git a/source/Cosmos.Core/CPU.cs b/source/Cosmos.Core/CPU.cs index ff2760dae..9f597f0f9 100644 --- a/source/Cosmos.Core/CPU.cs +++ b/source/Cosmos.Core/CPU.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using IL2CPU.API.Attribs; namespace Cosmos.Core @@ -110,18 +111,81 @@ namespace Cosmos.Core { if (CanReadCPUID() != 0) { - // TODO read cpuid response and do a bitwise and 0x0000ffff + // See https://c9x.me/x86/html/file_module_x86_id_45.html + int eax = 0; int ebx = 0; int ecx = 0; int edx = 0; - ReadCPUID(16, ref eax, ref ebx, ref ecx, ref edx); // 16 is max cycle rate - Global.mDebugger.Send("GetCPUCycleSpeed Registers"); - Global.mDebugger.SendNumber(eax); - Global.mDebugger.SendNumber(ebx); - Global.mDebugger.SendNumber(ecx); - Global.mDebugger.SendNumber(edx); - return 0; + string s = ""; + + for (uint i = 0; i < 3; i++) + { + ReadCPUID(0x80000002 + i, ref eax, ref ebx, ref ecx, ref edx); + s += (char)(ebx % 256); + s += (char)((ebx >> 8) % 256); + s += (char)((ebx>> 16) % 256); + s += (char)((ebx >> 24) % 256); + s += (char)(edx % 256); + s += (char)((edx >> 8) % 256); + s += (char)((edx >> 16) % 256); + s += (char)((edx >> 24) % 256); + s += (char)(ecx % 256); + s += (char)((ecx >> 8) % 256); + s += (char)((ecx >> 16) % 256); + s += (char)((ecx >> 24) % 256); + } + var _words = new List(); + string curr = ""; + for (int i = 0; i < s.Length; i++) + { + if (s[i] == ' ' || (byte)s[i] == 0) + { + if (curr != "") + { + _words.Add(curr); + } + curr = ""; + } + else + { + curr += s[i]; + } + } + _words.Add(curr); + string[] words = _words.ToArray(); + string[] w = new string[words.Length]; + for (int i = 0; i < words.Length; i++) + { + w[i] = words[words.Length - i - 1]; + } + words = w; + double multiplier = 0; + double value = 0; + for (int i = 0; i < words.Length; i++) + { + if (words[i] == "MHz") + { + multiplier = 10e6; + break; + } + else if (words[i] == "GHz") + { + multiplier = 10e9; + break; + } + else if (words[i] == "THz") + { + multiplier = 10e12; + break; + } + else if (value == 0) + { + Double.TryParse(words[i], out value); + } + } + value *= multiplier; + return (long)value; } throw new NotSupportedException(); @@ -129,10 +193,10 @@ namespace Cosmos.Core internal static int CanReadCPUID() => throw new NotImplementedException(); - internal static void ReadCPUID(int type, ref int eax, ref int ebx, ref int ecx, ref int edx) => throw new NotImplementedException(); + internal static void ReadCPUID(uint type, ref int eax, ref int ebx, ref int ecx, ref int edx) => throw new NotImplementedException(); internal static ulong ReadTimestampCounter() => throw new NotImplementedException(); - internal static int[] ReadFromModelSpecificRegister() => throw new NotImplementedException(); + internal static ulong ReadFromModelSpecificRegister() => throw new NotImplementedException(); } }