diff --git a/Test.sln b/Test.sln
index 11b29781f..f5490f973 100644
--- a/Test.sln
+++ b/Test.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29102.190
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{DAEF99B5-22F0-4885-B45B-9B600B857E1C}"
EndProject
@@ -162,10 +162,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cosmos.System.Tests", "Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cosmos.Kernel.Tests.DiskManager", "Tests\Kernels\Cosmos.Kernel.Tests.DiskManager\Cosmos.Kernel.Tests.DiskManager.csproj", "{BB6A5306-4C7A-4973-A48E-9FE3E683EAEC}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuiCsKernel", "Tests\Kernels\GuiCsKernel\GuiCsKernel.csproj", "{E2F0CB6D-C054-4CCC-923B-E41690945A68}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProcessorTests", "Tests\Kernels\ProcessorTests\ProcessorTests.csproj", "{61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -174,6 +170,14 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Debug|x86.Build.0 = Debug|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Release|x86.ActiveCfg = Release|Any CPU
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B}.Release|x86.Build.0 = Release|Any CPU
{F74A4B2B-02DA-455A-89FB-803A442B5B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F74A4B2B-02DA-455A-89FB-803A442B5B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F74A4B2B-02DA-455A-89FB-803A442B5B2C}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -535,6 +539,14 @@ Global
{FF46829E-B612-4D36-80BE-ED04521AD91A}.Release|Any CPU.Build.0 = Release|Any CPU
{FF46829E-B612-4D36-80BE-ED04521AD91A}.Release|x86.ActiveCfg = Release|Any CPU
{FF46829E-B612-4D36-80BE-ED04521AD91A}.Release|x86.Build.0 = Release|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Debug|x86.Build.0 = Debug|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Release|x86.ActiveCfg = Release|Any CPU
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67}.Release|x86.Build.0 = Release|Any CPU
{D21A7C6C-A696-4EC3-84EB-70700C1E3B34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D21A7C6C-A696-4EC3-84EB-70700C1E3B34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D21A7C6C-A696-4EC3-84EB-70700C1E3B34}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -623,27 +635,12 @@ Global
{BB6A5306-4C7A-4973-A48E-9FE3E683EAEC}.Release|Any CPU.Build.0 = Release|Any CPU
{BB6A5306-4C7A-4973-A48E-9FE3E683EAEC}.Release|x86.ActiveCfg = Release|Any CPU
{BB6A5306-4C7A-4973-A48E-9FE3E683EAEC}.Release|x86.Build.0 = Release|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Debug|x86.ActiveCfg = Debug|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Debug|x86.Build.0 = Debug|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Release|Any CPU.Build.0 = Release|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Release|x86.ActiveCfg = Release|Any CPU
- {E2F0CB6D-C054-4CCC-923B-E41690945A68}.Release|x86.Build.0 = Release|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Debug|x86.ActiveCfg = Debug|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Debug|x86.Build.0 = Debug|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Release|Any CPU.Build.0 = Release|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Release|x86.ActiveCfg = Release|Any CPU
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {0CDB3F6E-7971-426B-81F8-38B966A54C2B} = {E9CD521E-C386-466D-B5F7-A5EB19A61625}
{F74A4B2B-02DA-455A-89FB-803A442B5B2C} = {DAEF99B5-22F0-4885-B45B-9B600B857E1C}
{4F903492-CCA6-4FD9-A1B6-5E4CC0CE7767} = {C286932C-3F6D-47F0-BEEF-26843D1BB11B}
{34AEEB7C-FD5D-4B15-A830-B429681844BD} = {C286932C-3F6D-47F0-BEEF-26843D1BB11B}
@@ -705,6 +702,7 @@ Global
{3DD192AF-2D72-449F-936C-ED8734225B18} = {C286932C-3F6D-47F0-BEEF-26843D1BB11B}
{929EE8ED-6AD3-4442-A0C1-EC70665F2DCF} = {99192440-2DD7-4E71-B730-D44A73F46533}
{FF46829E-B612-4D36-80BE-ED04521AD91A} = {E9CD521E-C386-466D-B5F7-A5EB19A61625}
+ {D0EABA08-88C9-4F7C-BCA9-361B58B20D67} = {E9CD521E-C386-466D-B5F7-A5EB19A61625}
{D21A7C6C-A696-4EC3-84EB-70700C1E3B34} = {ECEA7778-E786-4317-90B9-A2D4427CB91C}
{0DF97CAC-220B-4DAD-B397-42E394255763} = {ECEA7778-E786-4317-90B9-A2D4427CB91C}
{2992AA07-E126-4EE0-B31C-D0B2ADE3393A} = {0E67EFE8-5944-4F6C-8B47-C5E06D4C79F5}
@@ -716,8 +714,6 @@ Global
{99E24E61-0743-47FF-AB0A-55A36C5E184C} = {52D81759-C7CC-427F-8C96-89CA10C914B5}
{970C5E07-5D09-4882-949C-A8E876B22732} = {52D81759-C7CC-427F-8C96-89CA10C914B5}
{BB6A5306-4C7A-4973-A48E-9FE3E683EAEC} = {29EEC029-6A2B-478A-B6E5-D63A91388ABA}
- {E2F0CB6D-C054-4CCC-923B-E41690945A68} = {29EEC029-6A2B-478A-B6E5-D63A91388ABA}
- {61BC9C74-10E9-407A-8A2D-6A5E282FBDE4} = {29EEC029-6A2B-478A-B6E5-D63A91388ABA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4418C803-277E-448F-A0A0-52788FA215AD}
diff --git a/Tests/Cosmos.TestRunner.Full/Cosmos.TestRunner.Full.csproj b/Tests/Cosmos.TestRunner.Full/Cosmos.TestRunner.Full.csproj
index f13330ca8..420536e31 100644
--- a/Tests/Cosmos.TestRunner.Full/Cosmos.TestRunner.Full.csproj
+++ b/Tests/Cosmos.TestRunner.Full/Cosmos.TestRunner.Full.csproj
@@ -29,9 +29,7 @@
-
-
diff --git a/Tests/Cosmos.TestRunner.Full/TestKernelSets.cs b/Tests/Cosmos.TestRunner.Full/TestKernelSets.cs
index 7a44580ba..83ab5528e 100644
--- a/Tests/Cosmos.TestRunner.Full/TestKernelSets.cs
+++ b/Tests/Cosmos.TestRunner.Full/TestKernelSets.cs
@@ -15,27 +15,25 @@ namespace Cosmos.TestRunner.Full
// Stable kernel types: the ones that are stable and will run in AppVeyor
public static IEnumerable GetStableKernelTypes()
{
- //yield return typeof(BoxingTests.Kernel);
- //yield return typeof(Cosmos.Compiler.Tests.TypeSystem.Kernel);
- //yield return typeof(Cosmos.Compiler.Tests.Bcl.Kernel);
- ////yield return typeof(Cosmos.Compiler.Tests.Encryption.Kernel);
- //yield return typeof(Cosmos.Compiler.Tests.Exceptions.Kernel);
- //yield return typeof(Cosmos.Compiler.Tests.MethodTests.Kernel);
- //yield return typeof(Cosmos.Compiler.Tests.SingleEchoTest.Kernel);
- //yield return typeof(Cosmos.Kernel.Tests.Fat.Kernel);
- //yield return typeof(Cosmos.Kernel.Tests.IO.Kernel);
- //yield return typeof(SimpleStructsAndArraysTest.Kernel);
- //yield return typeof(Cosmos.Kernel.Tests.DiskManager.Kernel);
+ yield return typeof(BoxingTests.Kernel);
+ yield return typeof(Cosmos.Compiler.Tests.TypeSystem.Kernel);
+ yield return typeof(Cosmos.Compiler.Tests.Bcl.Kernel);
+ //yield return typeof(Cosmos.Compiler.Tests.Encryption.Kernel);
+ yield return typeof(Cosmos.Compiler.Tests.Exceptions.Kernel);
+ yield return typeof(Cosmos.Compiler.Tests.MethodTests.Kernel);
+ yield return typeof(Cosmos.Compiler.Tests.SingleEchoTest.Kernel);
+ yield return typeof(Cosmos.Kernel.Tests.Fat.Kernel);
+ yield return typeof(Cosmos.Kernel.Tests.IO.Kernel);
+ yield return typeof(SimpleStructsAndArraysTest.Kernel);
+ yield return typeof(Cosmos.Kernel.Tests.DiskManager.Kernel);
- ////yield return typeof(KernelGen3.Boot);
+ //yield return typeof(KernelGen3.Boot);
- //yield return typeof(GraphicTest.Kernel);
- ///* Please see the notes on the kernel itself before enabling it */
- ////yield return typeof(ConsoleTest.Kernel);
- ///* This is a bit slow and works only because ring check is disabled to decide if leave it enabled */
- //yield return typeof(MemoryOperationsTest.Kernel);
-
- yield return typeof(ProcessorTests.Kernel);
+ yield return typeof(GraphicTest.Kernel);
+ /* Please see the notes on the kernel itself before enabling it */
+ //yield return typeof(ConsoleTest.Kernel);
+ /* This is a bit slow and works only because ring check is disabled to decide if leave it enabled */
+ yield return typeof(MemoryOperationsTest.Kernel);
}
}
}
diff --git a/Tests/Kernels/ProcessorTests/Kernel.cs b/Tests/Kernels/ProcessorTests/Kernel.cs
deleted file mode 100644
index 93233e7b1..000000000
--- a/Tests/Kernels/ProcessorTests/Kernel.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using Sys = Cosmos.System;
-using Cosmos.TestRunner;
-using Cosmos.System.Graphics;
-using System.Text;
-using Cosmos.System.ExtendedASCII;
-using Cosmos.System.ScanMaps;
-using Cosmos.Core;
-using System.Runtime.InteropServices;
-using Cosmos.HAL;
-
-namespace ProcessorTests
-{
- public class Kernel : Sys.Kernel
- {
- protected override void BeforeRun()
- {
- Console.WriteLine("Cosmos booted successfully. Starting Tests");
- }
-
- protected override void Run()
- {
- try
- {
- TestVendorNameIsNotBlank();
- TestCycleCountIsNotZero();
- TestCycleRateIsNotZero();
-
- TestController.Completed();
- }
- catch (Exception e)
- {
- mDebugger.Send("Exception occurred: " + e.Message);
- mDebugger.Send(e.Message);
- TestController.Failed();
- }
- }
-
- public void TestVendorNameIsNotBlank()
- {
- //string vendorName = CPU.GetCPUVendorName();
- //bool isVendorNameBlank = string.IsNullOrWhiteSpace(vendorName);
- //Assert.IsFalse(isVendorNameBlank, "Processor vendor name is blank.");
- }
-
- public void TestCycleCountIsNotZero()
- {
- long cycleCount = CPU.GetCPUUptime();
- bool isCycleCountZero = cycleCount == 0;
- Assert.IsFalse(isCycleCountZero, "Processor cycle count is zero.");
- }
-
- public void TestCycleRateIsNotZero()
- {
- //long cycleRate = CPU.GetCPUCycleSpeed();
- //bool isCycleRateZero = cycleRate == 0;
- //Assert.IsFalse(isCycleRateZero, "Processor cycle rate is zero.");
- }
- }
-}
diff --git a/Tests/Kernels/ProcessorTests/ProcessorTests.csproj b/Tests/Kernels/ProcessorTests/ProcessorTests.csproj
deleted file mode 100644
index d6e0d7a18..000000000
--- a/Tests/Kernels/ProcessorTests/ProcessorTests.csproj
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- netcoreapp2.0
- True
-
-
-
-
-
-
-
-
-
diff --git a/source/Cosmos.Core/CPU.cs b/source/Cosmos.Core/CPU.cs
index 344885d17..13a1c1a88 100644
--- a/source/Cosmos.Core/CPU.cs
+++ b/source/Cosmos.Core/CPU.cs
@@ -1,4 +1,3 @@
-using System;
using IL2CPU.API.Attribs;
namespace Cosmos.Core
@@ -69,35 +68,5 @@ namespace Cosmos.Core
mInterruptsEnabled = false;
return xResult;
}
-
- public static string GetCPUVendorName()
- {
- // TODO Call cpuid and parse response
- int[] value = ReadCPUID(0); // 0 is vendor name
- return "";
- }
-
- public static long GetCPUUptime()
- {
- // TODO Call read timestamp counter and parse response
- int[] value = ReadTimestampCounter();
- // ((long)val[0] << 32) | (uint)val[1];
- return 0;
- }
-
- public static long GetCPUCycleSpeed()
- {
- // TODO read cpuid response and do a bitwise and 0x0000ffff
- int[] value = ReadCPUID(16); // 16 is max cycle rate
- return 0;
- }
-
- internal static int CarReadCPUID() => throw new NotImplementedException();
-
- internal static int[] ReadCPUID(int type) => throw new NotImplementedException();
-
- internal static int[] ReadTimestampCounter() => throw new NotImplementedException();
-
- internal static int[] ReadFromModelSpecificRegister() => throw new NotImplementedException();
}
}
diff --git a/source/Cosmos.Core/ProcessorInformation.cs b/source/Cosmos.Core/ProcessorInformation.cs
new file mode 100644
index 000000000..28716c37d
--- /dev/null
+++ b/source/Cosmos.Core/ProcessorInformation.cs
@@ -0,0 +1,53 @@
+namespace Cosmos.Core
+{
+ public unsafe class ProcessorInformation
+ {
+ ///
+ /// Returns the Processor's vendor name
+ ///
+ /// CPU Vendor name
+ public static string GetVendorName()
+ {
+ if (CanReadCPUID() > 0)
+ {
+ int[] raw = new int[3];
+
+ fixed (int* ptr = raw)
+ FetchCPUVendor(ptr);
+
+ return new string(new char[] {
+ (char)(raw[0] >> 24),
+ (char)((raw[0] >> 16) & 0xff),
+ (char)((raw[0] >> 8) & 0xff),
+ (char)(raw[0] & 0xff),
+ (char)(raw[1] >> 24),
+ (char)((raw[1] >> 16) & 0xff),
+ (char)((raw[1] >> 8) & 0xff),
+ (char)(raw[1] & 0xff),
+ (char)(raw[2] >> 24),
+ (char)((raw[2] >> 16) & 0xff),
+ (char)((raw[2] >> 8) & 0xff),
+ (char)(raw[2] & 0xff),
+ });
+ }
+ else
+ return "\0";
+ }
+
+ internal static int CanReadCPUID() => 0; //plugged
+
+ internal static void FetchCPUVendor(int* target) { } //plugged
+
+ ///
+ /// Returns the number of CPU cycles since startup of the current CPU core
+ ///
+ /// Number of CPU cycles since startup
+ public static long GetCycleCount() => 0; //plugged
+
+ ///
+ /// Returns the number of CPU cycles per seconds
+ ///
+ /// Number of CPU cycles per seconds
+ public static long GetCycleRate() => 0; //plugged
+ }
+}
diff --git a/source/Cosmos.Core_Asm/CPU/CPUCanReadCPUIDAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUCanReadCPUIDAsm.cs
deleted file mode 100644
index 7939f03d4..000000000
--- a/source/Cosmos.Core_Asm/CPU/CPUCanReadCPUIDAsm.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using XSharp.Assembler;
-
-namespace Cosmos.Core_Asm
-{
- public class CPUCanReadCPUIDAsm : AssemblerMethod
- {
- public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
- {
- // TODO Need to move the result from EAX to the return value
- /*
- * pushfd
- * pushfd
- * xor dword [esp], 00200000h
- * popfd
- * pushfd
- * pop eax
- * xor eax, [esp]
- * and eax, 00200000h
- * ret
- */
- //XS.Pushfd();
- //XS.Pushfd();
- //XS.Xor(XSRegisters.ESP, 0x00200000, destinationIsIndirect: true);
- //XS.Popfd();
- //XS.Pushfd();
- //XS.Pop(XSRegisters.EAX);
- //XS.Xor(XSRegisters.EAX, XSRegisters.ESP, destinationIsIndirect: true);
- //XS.Popfd();
- //XS.And(XSRegisters.EAX, 0x00200000);
- //XS.Return();
- }
- }
-}
diff --git a/source/Cosmos.Core_Asm/CPU/CPUReadCPUIDAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUReadCPUIDAsm.cs
deleted file mode 100644
index 1042d2a14..000000000
--- a/source/Cosmos.Core_Asm/CPU/CPUReadCPUIDAsm.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using XSharp.Assembler;
-
-namespace Cosmos.Core_Asm
-{
- public class CPUReadCPUIDAsm : AssemblerMethod
- {
- public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
- {
- // TODO Get the type parameter from EBP+8 and move it to EAX
- /*
- * mov eax, 16h
- * cpuid
- */
- // TODO The result of cpuid will be in EDX:EAX so it will need to be moved to the return value
- // Set ESI to EBP+8?
- }
- }
-}
diff --git a/source/Cosmos.Core_Asm/CPU/CPUReadModelSpecificRegisterAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUReadModelSpecificRegisterAsm.cs
deleted file mode 100644
index 3331d95c8..000000000
--- a/source/Cosmos.Core_Asm/CPU/CPUReadModelSpecificRegisterAsm.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using XSharp.Assembler;
-
-namespace Cosmos.Core_Asm
-{
- public class CPUReadModelSpecificRegisterAsm : AssemblerMethod
- {
- public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
- {
- /*
- * ; esi register layout: (mperf_hi, mperf_lo, aperf_hi, aperf_lo)
- * ;
- * ; int* ptr = new int[4];
- * ;
- * lea esi, ptr ;equivalent with `mov esi, &ptr`
- * mov ecx, e7h
- * rdmsr
- * mov [esi + 4], eax
- * mov [esi], edx
- * mov ecx, e8h
- * rdmsr
- * mov [esi + 12], eax
- * mov [esi + 8], edx
- * xor eax, eax
- * ret
- */
-
- //XS.Lea(XSRegisters.ESI, intname);
- //XS.Set(XSRegisters.ECX, 0xe7);
- //XS.Rdmsr();
- //XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 4);
- //XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 0);
- //XS.Set(XSRegisters.ECX, 0xe8);
- //XS.Rdmsr();
- //XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 12);
- //XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 8);
- //XS.Xor(XSRegisters.EAX, XSRegisters.EAX);
- //XS.Return();
- }
- }
-}
\ No newline at end of file
diff --git a/source/Cosmos.Core_Asm/CPU/CPUReadTimestampCounterAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUReadTimestampCounterAsm.cs
deleted file mode 100644
index 9905048f7..000000000
--- a/source/Cosmos.Core_Asm/CPU/CPUReadTimestampCounterAsm.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using XSharp.Assembler;
-
-namespace Cosmos.Core_Asm
-{
- public class CPUReadTimestampCounterAsm : AssemblerMethod
- {
- public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
- {
- // TODO need to move result from EDX:EAX to return value. Set ESI to EBP+8?
- /*
- * push eax
- * push ecx
- * push edx
- * rdtsc
- * mov [esi+4], eax
- * mov [esi], edx
- * pop edx
- * pop ecx
- * pop eax
- * ret
- */
-
- //XS.Push(XSRegisters.EAX);
- //XS.Push(XSRegisters.ECX);
- //XS.Push(XSRegisters.EDX);
- //XS.Rdtsc();
- //XS.Set(XSRegisters.ESI, XSRegisters.EAX, destinationIsIndirect: true, destinationDisplacement: 4);
- //XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true);
- //XS.Pop(XSRegisters.EDX);
- //XS.Pop(XSRegisters.ECX);
- //XS.Pop(XSRegisters.EAX);
- //XS.Return();
- }
- }
-}
diff --git a/source/Cosmos.Core_Asm/CPUImpl.cs b/source/Cosmos.Core_Asm/CPUImpl.cs
index a6f1cd993..f796e0233 100644
--- a/source/Cosmos.Core_Asm/CPUImpl.cs
+++ b/source/Cosmos.Core_Asm/CPUImpl.cs
@@ -1,4 +1,3 @@
-using System;
using Cosmos.Core;
using IL2CPU.API.Attribs;
@@ -35,17 +34,5 @@ namespace Cosmos.Core_Asm
[PlugMethod(Assembler = typeof(CPUEnableINTsAsm))]
public static void DoEnableInterrupts() => throw null;
-
- [PlugMethod(Assembler = typeof(CPUCanReadCPUIDAsm))]
- public static int CanReadCPUID() => throw new NotImplementedException();
-
- [PlugMethod(Assembler = typeof(CPUReadCPUIDAsm))]
- public static int[] ReadCPUID(int type) => throw new NotImplementedException();
-
- [PlugMethod(Assembler = typeof(CPUReadTimestampCounterAsm))]
- public static int[] ReadTimestampCounter() => throw new NotImplementedException();
-
- [PlugMethod(Assembler = typeof(CPUReadModelSpecificRegisterAsm))]
- public static int[] ReadFromModelSpecificRegister() => throw new NotImplementedException();
}
}
diff --git a/source/Cosmos.Core_Asm/ProcessorInformationImpl.cs b/source/Cosmos.Core_Asm/ProcessorInformationImpl.cs
new file mode 100644
index 000000000..2bd7d4c4a
--- /dev/null
+++ b/source/Cosmos.Core_Asm/ProcessorInformationImpl.cs
@@ -0,0 +1,212 @@
+using Cosmos.Core;
+
+using IL2CPU.API;
+using IL2CPU.API.Attribs;
+
+using XSharp;
+
+namespace Cosmos.Core_Asm
+{
+ [Plug(Target = typeof(ProcessorInformation))]
+ public unsafe class ProcessorInformationImpl
+ {
+ /* The following three int*-pointers are needed for the lea instruction due to the following reason:
+ * When comiling, the IL-code will be translated into x86-ASM, which has specific and unique names for local variables.
+ * To access these local variables, I have to pass their excat name to the instruction in question. This is rather
+ * difficult with reflection, if these variables reside in the local function scope. For this reason, I move the
+ * pointer to class scope to access them quicker and more easily
+ */
+ private static int* __cyclesrdtscptr, __raterdmsrptr, __vendortargetptr;
+ private static long __ticktate = -1;
+
+ ///
+ /// Returns the number of CPU cycles since startup
+ ///
+ /// Number of CPU cycles
+ public static long GetCycleCount()
+ {
+ int[] val = new int[2];
+
+ fixed (int* ptr = val)
+ {
+ __cyclesrdtsc(ptr);
+ }
+
+ return ((long)val[0] << 32) | (uint)val[1];
+ }
+
+ ///
+ /// Returns the CPU cycle rate (in cycles/µs)
+ ///
+ /// CPU cycle rate
+ public static long GetCycleRate()
+ {
+ if (__ticktate == -1)
+ {
+ int[] raw = new int[4];
+
+ fixed (int* ptr = raw)
+ {
+ __raterdmsr(ptr);
+ }
+
+ ulong l1 = (ulong)__maxrate();
+ ulong l2 = ((ulong)raw[0] << 32) | (uint)raw[1];
+ ulong l3 = ((ulong)raw[2] << 32) | (uint)raw[3];
+
+ __ticktate = (long)l2; // (long)((double)l1 * l3 / l2);
+ }
+
+ return __ticktate;
+ }
+
+ ///
+ /// Copies the maximum cpu rate set by the bios at startup to the given int pointer
+ ///
+ [Inline]
+ private static int __maxrate()
+ {
+ /*
+ * mov eax, 16h
+ * cpuid
+ * and eax, ffffh
+ * ret
+ */
+
+ XS.Set(XSRegisters.EAX, 0x00000016);
+ XS.Cpuid();
+ XS.And(XSRegisters.EAX, 0x0000ffff);
+ XS.Return();
+
+ return 0;
+ }
+
+ ///
+ /// Copies the cycle count to the given int pointer
+ ///
+ [Inline]
+ private static void __cyclesrdtsc(int* target)
+ {
+ /*
+ * push eax
+ * push ecx
+ * push edx
+ * lea esi, target
+ * rdtsc
+ * mov [esi+4], eax
+ * mov [esi], edx
+ * pop edx
+ * pop ecx
+ * pop eax
+ * ret
+ */
+ __cyclesrdtscptr = target;
+
+ string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__cyclesrdtscptr)));
+
+ XS.Push(XSRegisters.EAX);
+ XS.Push(XSRegisters.ECX);
+ XS.Push(XSRegisters.EDX);
+ XS.Lea(XSRegisters.ESI, intname);
+ XS.Rdtsc();
+ XS.Set(XSRegisters.ESI, XSRegisters.EAX, destinationIsIndirect: true, destinationDisplacement: 4);
+ XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true);
+ XS.Push(XSRegisters.EDX);
+ XS.Push(XSRegisters.ECX);
+ XS.Push(XSRegisters.EAX);
+ XS.Return();
+ }
+
+ ///
+ /// Copies the cycle rate to the given int pointer
+ ///
+ [Inline]
+ private static void __raterdmsr(int* target)
+ {
+ /*
+ * ; esi register layout: (mperf_hi, mperf_lo, aperf_hi, aperf_lo)
+ * ;
+ * ; int* ptr = new int[4];
+ * ;
+ * lea esi, ptr ;equivalent with `mov esi, &ptr`
+ * mov ecx, e7h
+ * rdmsr
+ * mov [esi + 4], eax
+ * mov [esi], edx
+ * mov ecx, e8h
+ * rdmsr
+ * mov [esi + 12], eax
+ * mov [esi + 8], edx
+ * xor eax, eax
+ * ret
+ */
+ __raterdmsrptr = target;
+
+ string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__raterdmsrptr)));
+
+ XS.Lea(XSRegisters.ESI, intname);
+ XS.Set(XSRegisters.ECX, 0xe7);
+ XS.Rdmsr();
+ XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 4);
+ XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 0);
+ XS.Set(XSRegisters.ECX, 0xe8);
+ XS.Rdmsr();
+ XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 12);
+ XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 8);
+ XS.Xor(XSRegisters.EAX, XSRegisters.EAX); // XS.Set(XSRegisters.EAX, 0);
+ XS.Return();
+ }
+
+ [Inline]
+ internal static void FetchCPUVendor(int* target)
+ {
+ /*
+ * lea esi, target
+ * xor eax, eax
+ * cpuid
+ * mov [esi], ebx
+ * mov [esi + 4], edx
+ * mov [esi + 8], ecx
+ * ret
+ */
+ __vendortargetptr = target;
+
+ string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__vendortargetptr)));
+
+ XS.Lea(XSRegisters.ESI, intname); // new Lea { DestinationReg = RegistersEnum.ESI, SourceRef = ElementReference.New(intname) };
+ XS.Cpuid();
+ XS.Set(XSRegisters.ESI, XSRegisters.EBX, destinationIsIndirect: true);
+ XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true, destinationDisplacement: 4);
+ XS.Set(XSRegisters.ESI, XSRegisters.ECX, destinationIsIndirect: true, destinationDisplacement: 8);
+ XS.Return();
+ }
+
+ [Inline]
+ internal static int CanReadCPUID()
+ {
+ /*
+ * pushfd
+ * pushfd
+ * xor dword [esp], 00200000h
+ * popfd
+ * pushfd
+ * pop eax
+ * xor eax, [esp]
+ * and eax, 00200000h
+ * ret
+ */
+ XS.Pushfd();
+ XS.Pushfd();
+ XS.Xor(XSRegisters.ESP, 0x00200000, destinationIsIndirect: true);
+ XS.Popfd();
+ XS.Pushfd();
+ XS.Pop(XSRegisters.EAX);
+ XS.Xor(XSRegisters.EAX, XSRegisters.ESP, destinationIsIndirect: true);
+ XS.Popfd();
+ XS.And(XSRegisters.EAX, 0x00200000);
+ XS.Return();
+
+ return 0; // should be ignored by the compiler
+ }
+ }
+}