mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 04:18:43 +00:00
Added CPU.GetMemoryMap
Fixed GetMBIAddress Plug Cleaned up code
This commit is contained in:
parent
25639bc279
commit
8996b1f8a3
6 changed files with 153 additions and 29 deletions
|
|
@ -22,6 +22,8 @@ namespace ProcessorTests
|
|||
{
|
||||
try
|
||||
{
|
||||
TestMultibootMemoryMap();
|
||||
TetsGetRam();
|
||||
TestVendorNameIsNotBlank();
|
||||
TestCycleCount();
|
||||
TestCycleRateIsNotZero();
|
||||
|
|
@ -37,6 +39,22 @@ namespace ProcessorTests
|
|||
}
|
||||
}
|
||||
|
||||
public void TetsGetRam()
|
||||
{
|
||||
Assert.IsTrue(CPU.GetAmountOfRAM() > 0, "CPU.GetAmountOfRAM() returns a positive value: " + CPU.GetAmountOfRAM());
|
||||
}
|
||||
|
||||
public void TestMultibootMemoryMap()
|
||||
{
|
||||
var memoryMap = CPU.GetMemoryMap();
|
||||
for (int i = 0; i < memoryMap.Length; i++)
|
||||
{
|
||||
mDebugger.Send($"Memory Map: {memoryMap[i].Address} " +
|
||||
$"Length: {memoryMap[i].Length} Type: {memoryMap[i].Type}");
|
||||
}
|
||||
Assert.IsTrue(memoryMap.Length != 0, "Memory Map is not empty! Length " + memoryMap.Length);
|
||||
}
|
||||
|
||||
public void TestMultiboot()
|
||||
{
|
||||
Assert.IsTrue(Multiboot.GetMBIAddress() != 0, $"Multiboot.GetMBIAddress works {Multiboot.GetMBIAddress()}");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
namespace Cosmos.Core
|
||||
using Cosmos.Debug.Kernel;
|
||||
using XSharp;
|
||||
|
||||
namespace Cosmos.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Bootstrap class. Used to invoke pre-boot methods.
|
||||
|
|
@ -22,7 +25,7 @@
|
|||
/// <summary>
|
||||
/// Multiboot header pointer.
|
||||
/// </summary>
|
||||
public static Multiboot.Header* header;
|
||||
public static Multiboot.Header* MultibootHeader;
|
||||
|
||||
/// <summary>
|
||||
/// VBE mode info pointer.
|
||||
|
|
@ -59,13 +62,10 @@
|
|||
*/
|
||||
CPU.InitFloat();
|
||||
|
||||
header = (Multiboot.Header*)Multiboot.GetMBIAddress();
|
||||
MultibootHeader = (Multiboot.Header*)Multiboot.GetMBIAddress();
|
||||
|
||||
modeinfo = (Core.VBE.ModeInfo*)header->vbeModeInfo;
|
||||
controllerinfo = (Core.VBE.ControllerInfo*)header->vbeControlInfo;
|
||||
|
||||
// Managed_Memory_System.ManagedMemory.Initialize();
|
||||
// Managed_Memory_System.ManagedMemory.SetUpMemoryArea();
|
||||
modeinfo = (Core.VBE.ModeInfo*)MultibootHeader->vbeModeInfo;
|
||||
controllerinfo = (Core.VBE.ControllerInfo*)MultibootHeader->vbeControlInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#define COSMOSDEBUG
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using IL2CPU.API.Attribs;
|
||||
|
||||
namespace Cosmos.Core
|
||||
|
|
@ -110,8 +112,6 @@ namespace Cosmos.Core
|
|||
return xResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get CPU vendor name.
|
||||
/// </summary>
|
||||
|
|
@ -300,7 +300,8 @@ namespace Cosmos.Core
|
|||
if (!(rs == ""))
|
||||
{
|
||||
return rs;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
|
@ -308,8 +309,6 @@ namespace Cosmos.Core
|
|||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if can read CPU ID. Plugged.
|
||||
/// </summary>
|
||||
|
|
@ -341,5 +340,107 @@ namespace Cosmos.Core
|
|||
/// <returns>ulong value.</returns>
|
||||
/// <exception cref="NotImplementedException">Thrown on fatal error, contact support.</exception>
|
||||
internal static ulong ReadFromModelSpecificRegister() => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if Multiboot returned a memory map
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static unsafe bool MemoryMapExists()
|
||||
{
|
||||
return (Bootstrap.MultibootHeader->Flags & 1 << 6) == 64;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Memory Map Information from Multiboot
|
||||
/// </summary>
|
||||
/// <returns>Returns an array of MemoryMaps containing the Multiboot Memory Map information. The array may have empty values at the end.</returns>
|
||||
public static unsafe MemoryMap[] GetMemoryMap()
|
||||
{
|
||||
if (!MemoryMapExists())
|
||||
{
|
||||
throw new Exception("No Memory Map was returned by Multiboot");
|
||||
}
|
||||
var rawMap = new RawMemoryMap[64];
|
||||
var currentMap = (RawMemoryMap*)Bootstrap.MultibootHeader->memMapAddress;
|
||||
int counter = 0;
|
||||
while ((uint)currentMap < (Bootstrap.MultibootHeader->memMapAddress + Bootstrap.MultibootHeader->memMapLength) && counter < 64)
|
||||
{
|
||||
rawMap[counter++] = *currentMap;
|
||||
currentMap = (RawMemoryMap*)((uint*)currentMap + ((currentMap->Size + 4 )>> 2)); //The size is in bits, not bytes
|
||||
if (currentMap->Size == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter >= 64)
|
||||
{
|
||||
throw new Exception("Memory Map returned too many segments");
|
||||
}
|
||||
|
||||
var entireMap = new MemoryMap[counter];
|
||||
for (int i = 0; i < counter; i++)
|
||||
{
|
||||
var rawMemoryMap = rawMap[i];
|
||||
entireMap[i] = new MemoryMap
|
||||
{
|
||||
Address = (ulong)rawMemoryMap.HighBaseAddr << 32 | rawMemoryMap.LowBaseAddr,
|
||||
Length = (ulong)rawMemoryMap.HighLength << 32 | rawMemoryMap.LowLength,
|
||||
Type = rawMemoryMap.Type
|
||||
};
|
||||
}
|
||||
return entireMap;
|
||||
}
|
||||
}
|
||||
|
||||
public class MemoryMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Base Address of the memory region
|
||||
/// </summary>
|
||||
public ulong Address;
|
||||
/// <summary>
|
||||
/// Length in bytes of the region
|
||||
/// </summary>
|
||||
public ulong Length;
|
||||
/// <summary>
|
||||
/// Type of RAM in region. 1 is available. 3 is for ACPI. All other is unavailable
|
||||
/// </summary>
|
||||
public uint Type;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 24)]
|
||||
public struct RawMemoryMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Size of this entry
|
||||
/// </summary>
|
||||
[FieldOffset(0)]
|
||||
public uint Size;
|
||||
/// <summary>
|
||||
/// Low 32 bits of the base address
|
||||
/// </summary>
|
||||
[FieldOffset(4)]
|
||||
public uint LowBaseAddr;
|
||||
/// <summary>
|
||||
/// High 32 bits of the base address
|
||||
/// </summary>
|
||||
[FieldOffset(8)]
|
||||
public uint HighBaseAddr;
|
||||
/// <summary>
|
||||
/// Low 32 bits of the length of memory block in bytes
|
||||
/// </summary>
|
||||
[FieldOffset(12)]
|
||||
public uint LowLength;
|
||||
/// <summary>
|
||||
/// High 32 bits of the length of memory block in bytes
|
||||
/// </summary>
|
||||
[FieldOffset(16)]
|
||||
public uint HighLength;
|
||||
/// <summary>
|
||||
/// Type of memory area, 1 if usable RAM, everything else unusable.
|
||||
/// </summary>
|
||||
[FieldOffset(20)]
|
||||
public uint Type;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace Cosmos.Core
|
|||
/// </summary>
|
||||
public unsafe class MemoryOperations
|
||||
{
|
||||
#region Fill
|
||||
/// <summary>
|
||||
/// Fill memory block. Plugged.
|
||||
/// </summary>
|
||||
|
|
@ -183,6 +184,23 @@ namespace Cosmos.Core
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill source to destination.
|
||||
/// </summary>
|
||||
/// <param name="dest">Destination.</param>
|
||||
/// <param name="src">Source.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static unsafe void Fill(sbyte[] dest, sbyte[] src)
|
||||
{
|
||||
fixed (sbyte* destPtr = dest)
|
||||
fixed (sbyte* srcPtr = src)
|
||||
{
|
||||
Copy(destPtr, srcPtr, dest.Length);
|
||||
}
|
||||
}
|
||||
#endregion Fill
|
||||
|
||||
#region Copy
|
||||
/// <summary>
|
||||
/// Copy source to destination.
|
||||
/// plugged.
|
||||
|
|
@ -329,19 +347,6 @@ namespace Cosmos.Core
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill source to destination.
|
||||
/// </summary>
|
||||
/// <param name="dest">Destination.</param>
|
||||
/// <param name="src">Source.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static unsafe void Fill(sbyte[] dest, sbyte[] src)
|
||||
{
|
||||
fixed (sbyte* destPtr = dest)
|
||||
fixed (sbyte* srcPtr = src)
|
||||
{
|
||||
Copy(destPtr, srcPtr, dest.Length);
|
||||
}
|
||||
}
|
||||
#endregion Copy
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ namespace Cosmos.Core
|
|||
/// <returns>True if is available, false if not</returns>
|
||||
public static bool IsAvailable()
|
||||
{
|
||||
if ((Bootstrap.header->Flags & VBEINFO_PRESENT) == 0)
|
||||
if ((Bootstrap.MultibootHeader->Flags & VBEINFO_PRESENT) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Cosmos.Core_Asm
|
|||
{
|
||||
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
|
||||
{
|
||||
XS.Push("MultibootSignature");
|
||||
XS.Push("MultiBootInfo_Structure", isIndirect: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue