XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.InteropServices;

namespace XFESystem.NativeKernel;

// Test-only CPU and page ownership provider. VirtualMemory.cs is linked intact;
// no page walk, mapping, rollback, protect or unmap algorithm is reimplemented.
internal static unsafe class Native
{
    public static nint Root, Regions;
    public const ulong RootPhysical = 0x1000;
    public static bool PatSupported = true, NxSupported = true, FiveLevel;
    public static uint PhysicalBits = 52, MaximumExtendedLeaf = 0x80000008;
    public static ulong Pat = 0x0007040600070406, Efer;
    public static List<ulong> Invalidations { get; } = [];
    public static List<uint> MsrReads { get; } = [];
    public static ulong ReadCr4() => FiveLevel ? 1UL << 12 : 0;
    public static ulong ReadCr3() => RootPhysical;
    public static void* Storage(uint kind) => kind == 6 ? (void*)Regions : null;
    public static void CpuId(uint leaf, uint subleaf, uint* output)
    {
        for (int index = 0; index < 4; index++) output[index] = 0;
        if (leaf == 0x80000000) output[0] = MaximumExtendedLeaf;
        if (leaf == 0x80000008 && MaximumExtendedLeaf >= leaf) output[0] = PhysicalBits;
        if (leaf == 0x80000001 && NxSupported) output[3] = 1u << 20;
        if (leaf == 1 && PatSupported) output[3] = 1u << 16;
    }
    public static ulong ReadMsr(uint index) { MsrReads.Add(index); return index == 0x277 ? Pat : Efer; }
    public static void WriteMsr(uint index, ulong value)
    {
        if (index != 0xc0000080) throw new InvalidOperationException("Unexpected simulated MSR write.");
        Efer = value;
    }
    public static void MemoryBarrier() => Thread.MemoryBarrier();
    public static void InvalidatePage(ulong address) => Invalidations.Add(address);
    public static ulong KernelImageStart() => 0;
    public static ulong KernelImageEnd() => 0;

    public static void Reset()
    {
        PatSupported = NxSupported = true; FiveLevel = false; PhysicalBits = 52; MaximumExtendedLeaf = 0x80000008;
        Pat = 0x0007040600070406; Efer = 0; Invalidations.Clear(); MsrReads.Clear();
    }
}

internal static unsafe class PhysicalMemory
{
    private sealed class Page(nint pointer, bool owned) { public readonly nint Pointer = pointer; public bool Owned = owned; }
    private static readonly Dictionary<ulong, Page> Pages = [];
    private static ulong nextPhysical;
    public static bool Ready;
    public static ulong AvailablePages, AllocatedPages;
    public static int AllocationAllowance = int.MaxValue;
    public static int SuccessfulAllocations;
    public static List<(ulong Physical, bool Released)> Releases { get; } = [];

    public static void Setup()
    {
        VirtualMemory.Ready = false; Dispose(); Native.Reset();
        Native.Root = AllocateHost(4096); Native.Regions = AllocateHost(8192);
        nextPhysical = 0x100000; AvailablePages = 2048; AllocatedPages = 0; SuccessfulAllocations = 0;
        AllocationAllowance = int.MaxValue; Releases.Clear(); Ready = true;
    }
    private static nint AllocateHost(nuint bytes)
    {
        void* pointer = System.Runtime.InteropServices.NativeMemory.AlignedAlloc(bytes, 4096);
        if (pointer is null) throw new OutOfMemoryException();
        System.Runtime.InteropServices.NativeMemory.Clear(pointer, bytes); return (nint)pointer;
    }
    public static ulong Allocate(uint count = 1)
    {
        if (!Ready || count != 1 || AvailablePages == 0 || AllocationAllowance == 0) return 0;
        if (AllocationAllowance != int.MaxValue) AllocationAllowance--;
        ulong physical = nextPhysical; nextPhysical += 4096;
        Pages.Add(physical, new(AllocateHost(4096), true)); AvailablePages--; AllocatedPages++; SuccessfulAllocations++;
        return physical;
    }
    public static bool Release(ulong physical, uint count = 1)
    {
        bool valid = Ready && count == 1 && Pages.TryGetValue(physical, out var page) && page.Owned;
        Releases.Add((physical, valid));
        if (!valid) return false;
        Pages[physical].Owned = false; AvailablePages++; AllocatedPages--; return true;
    }
    public static ulong ToVirtual(ulong physical)
    {
        if (!Ready) return 0;
        if (physical == Native.RootPhysical) return (ulong)Native.Root;
        return Pages.TryGetValue(physical, out var page) ? (ulong)page.Pointer : 0;
    }
    public static ulong ForeignTable()
    {
        ulong physical = nextPhysical; nextPhysical += 4096;
        Pages.Add(physical, new(AllocateHost(4096), false)); return physical;
    }
    public static bool Owns(ulong physical) => Pages.TryGetValue(physical, out var page) && page.Owned;
    public static void Dispose()
    {
        Ready = false;
        foreach (var page in Pages.Values) System.Runtime.InteropServices.NativeMemory.AlignedFree((void*)page.Pointer);
        Pages.Clear();
        if (Native.Root != 0) System.Runtime.InteropServices.NativeMemory.AlignedFree((void*)Native.Root);
        if (Native.Regions != 0) System.Runtime.InteropServices.NativeMemory.AlignedFree((void*)Native.Regions);
        Native.Root = Native.Regions = 0;
    }
}

internal static class Kernel { public static void Fail(string code) => throw new InvalidOperationException("Production Kernel.Fail: " + code); }
internal static class Cpu { public static bool ProtectionProbe(ulong address, uint mode) => throw new InvalidOperationException("The host harness must not call the bare-metal fault self-test."); }