Merge branch 'master' into add_issue_templates

This commit is contained in:
Quajak 2020-10-15 11:57:29 +02:00 committed by GitHub
commit cba51fb9be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 300 deletions

View file

@ -12,7 +12,6 @@ namespace Cosmos.Kernel.Tests.Fat.System.IO
/// </summary>
public static void Execute(Debugger mDebugger)
{
mDebugger.Send("START TEST: Delete a directory:");
Directory.CreateDirectory(@"0:\TestDir1");
Assert.IsTrue(Directory.Exists(@"0:\TestDir1"), "TestDir1 wasn't created!");
@ -97,22 +96,20 @@ namespace Cosmos.Kernel.Tests.Fat.System.IO
mDebugger.Send("");
#if false
mDebugger.Send("START TEST: Delete a file with Directory.Delete:");
File.Create(@"0:\file1.txt");
mDebugger.Send("START TEST: Creating a subdirecty with Directory.CreateDirectory:");
try
{
Directory.Delete(@"0:\file1.txt");
}
catch (Exception e)
{
Assert.IsTrue(File.Exists(@"0:\file1.txt"), "The file was deleted by Directory.Delete.");
}
Directory.CreateDirectory(@"0:\TestDir1");
Assert.IsTrue(Directory.Exists(@"0:\TestDir1"), "TestDir1 was created!");
Directory.CreateDirectory(@"0:\TestDir1\test");
Assert.IsTrue(Directory.Exists(@"0:\TestDir1\test"), "test subdirectory was created!");
Directory.Delete(@"0:\TestDir1\test");
Assert.IsFalse(Directory.Exists(@"0:\TestDir1\test"), "test subdirectory was deleted!");
Directory.Delete(@"0:\TestDir1");
Assert.IsFalse(Directory.Exists(@"0:\TestDir1"), "TestDir1 was deleted!");
mDebugger.Send("END TEST");
mDebugger.Send("");
#endif
mDebugger.Send("START TEST: Create a directory with a Long Filename:");
Directory.CreateDirectory(@"0:\TestDir1");

View file

@ -315,7 +315,7 @@ namespace Cosmos.Core
/// </summary>
/// <returns>non-zero if can read.</returns>
/// <exception cref="NotImplementedException">Thrown on fatal error, contact support.</exception>
internal static int CanReadCPUID() => throw new NotImplementedException();
public static int CanReadCPUID() => throw new NotImplementedException();
/// <summary>
/// Read CPU ID. Plugged.
@ -326,7 +326,7 @@ namespace Cosmos.Core
/// <param name="ecx">ecx.</param>
/// <param name="edx">edx.</param>
/// <exception cref="NotImplementedException">Thrown on fatal error, contact support.</exception>
internal static void ReadCPUID(uint type, ref int eax, ref int ebx, ref int ecx, ref int edx) => throw new NotImplementedException();
public static void ReadCPUID(uint type, ref int eax, ref int ebx, ref int ecx, ref int edx) => throw new NotImplementedException();
/// <summary>
/// Read timestamp counter. Plugged.

View file

@ -1,64 +0,0 @@
namespace Cosmos.Core
{
/// <summary>
/// ProcessorInformation class. Used to get vendor information from the CPU.
/// </summary>
public unsafe class ProcessorInformation
{
/// <summary>
/// Returns the Processor's vendor name
/// </summary>
/// <returns>CPU Vendor name</returns>
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";
}
/// <summary>
/// Check if can read CPU ID.
/// </summary>
/// <returns>int value.</returns>
internal static int CanReadCPUID() => 0; //plugged
/// <summary>
/// Fetch CPU vendor.
/// </summary>
/// <param name="target">pointer to target.</param>
internal static void FetchCPUVendor(int* target) { } //plugged
/// <summary>
/// Returns the number of CPU cycles since startup of the current CPU core
/// </summary>
/// <returns>Number of CPU cycles since startup</returns>
public static long GetCycleCount() => 0; //plugged
/// <summary>
/// Returns the number of CPU cycles per seconds
/// </summary>
/// <returns>Number of CPU cycles per seconds</returns>
public static long GetCycleRate() => 0; //plugged
}
}

View file

@ -1,212 +0,0 @@
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;
/// <summary>
/// Returns the number of CPU cycles since startup
/// </summary>
/// <returns>Number of CPU cycles</returns>
public static long GetCycleCount()
{
int[] val = new int[2];
fixed (int* ptr = val)
{
__cyclesrdtsc(ptr);
}
return ((long)val[0] << 32) | (uint)val[1];
}
/// <summary>
/// Returns the CPU cycle rate (in cycles/µs)
/// </summary>
/// <returns>CPU cycle rate</returns>
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;
}
/// <summary>
/// Copies the maximum cpu rate set by the bios at startup to the given int pointer
/// </summary>
[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;
}
/// <summary>
/// Copies the cycle count to the given int pointer
/// </summary>
[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();
}
/// <summary>
/// Copies the cycle rate to the given int pointer
/// </summary>
[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
}
}
}

View file

@ -13,7 +13,7 @@ namespace Cosmos.Core_Plugs.System.Diagnostics
{
if (Stopwatch.IsHighResolution)
// see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx for more details
return (long)(ProcessorInformation.GetCycleCount() / (double)ProcessorInformation.GetCycleRate() * 1000000d);
return (long)(CPU.GetCPUUptime() / (double)CPU.GetCPUUptime() * 1000000d);
else
return DateTime.UtcNow.Ticks;
}

View file

@ -23,10 +23,10 @@ namespace Cosmos.Core_Plugs.System.Threading
// if ((ms > 0) && (ms != Timeout.Infinite))
// {
// double fac = ProcessorInformation.GetCycleRate() / 1000d;
// double ticks = ms / 1000d * Stopwatch.Frequency + ProcessorInformation.GetCycleCount() * fac;
// double fac = CPU.GetCycleRate() / 1000d;
// double ticks = ms / 1000d * Stopwatch.Frequency + CPU.GetCycleCount() * fac;
// while (ticks < ProcessorInformation.GetCycleCount() * fac)
// while (ticks < CPU.GetCycleCount() * fac)
// new Action(() => { }).Invoke(); // execute an empty operation
// }
// else if (ms < 0)

View file

@ -512,6 +512,8 @@ namespace Cosmos.System.FileSystem.FAT.Listing
/// <exception cref="NotSupportedException">Thrown when FAT type is unknown.</exception>
public void DeleteDirectoryEntry()
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.DeleteDirectoryEntry --");
if (mEntryType == DirectoryEntryTypeEnum.Unknown)
{
throw new NotImplementedException();
@ -524,12 +526,17 @@ namespace Cosmos.System.FileSystem.FAT.Listing
var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData();
var xEntryOffset = mEntryHeaderDataOffset - 32;
while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName)
if(mEntryHeaderDataOffset > 32)
{
xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry;
xEntryOffset -= 32;
var xEntryOffset = mEntryHeaderDataOffset - 32;
Global.mFileSystemDebugger.SendInternal("xEntryOffset: " + xEntryOffset);
while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName)
{
xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry;
xEntryOffset -= 32;
}
}
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
@ -988,6 +995,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, byte aValue)
{
Global.mFileSystemDebugger.SendInternal(" -- FatDirectoryEntry.SetDirectoryEntryMetadataValue(uint) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue = " + aValue);
if (IsRootDirectory())
@ -1043,6 +1051,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, ushort aValue)
{
Global.mFileSystemDebugger.SendInternal(" -- FatDirectoryEntry.SetDirectoryEntryMetadataValue(uint) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue = " + aValue);
if (IsRootDirectory())
@ -1054,6 +1063,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
if (xData.Length > 0)
{
Global.mFileSystemDebugger.SendInternal("mEntryHeaderDataOffset = " + mEntryHeaderDataOffset);
var xValue = new byte[aEntryMetadata.DataLength];
xValue.SetUInt16(0, aValue);
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
@ -1100,6 +1110,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, uint aValue)
{
Global.mFileSystemDebugger.SendInternal(" -- FatDirectoryEntry.SetDirectoryEntryMetadataValue(uint) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue = " + aValue);
if (IsRootDirectory())
@ -1157,6 +1168,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, long aValue)
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.SetDirectoryEntryMetadataValue(long) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue =");
Global.mFileSystemDebugger.SendInternal(aValue);
@ -1218,6 +1230,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, string aValue)
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.SetDirectoryEntryMetadataValue(string) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal($"aValue = {aValue}");
if (IsRootDirectory())