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

XFESystem

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

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

namespace XFESystem.NativeRuntime.Application.Network;

/// <summary>Lazy network initialization belongs to the caller's network worker, never the desktop UI.</summary>
public static class NativeNetwork
{
    static readonly object gate = new();
    static Func<uint>? random;
    static Ipv4Network? network;
    static E1000Device? device;
    public static void ConfigureEntropy(Func<uint> random32)
    { ArgumentNullException.ThrowIfNull(random32); lock (gate) random = random32; }
    public static Stream OpenTcp(string host, int port, int timeoutMilliseconds = 15000)
    {
        Func<uint>? entropy = Volatile.Read(ref random);
        if (entropy == null) throw new InvalidOperationException("Native TCP requires an explicitly configured strong random source.");
        if (timeoutMilliseconds is < 1 or > 120000) throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds));
        long deadline = checked(NativePlatform.Milliseconds() + timeoutMilliseconds);
        long remaining = deadline - NativePlatform.Milliseconds();
        if (remaining <= 0 || !Monitor.TryEnter(gate, checked((int)remaining))) throw new IOException("Native network ownership timed out.");
        try
        {
            if (NativePlatform.Milliseconds() >= deadline) throw new IOException("Native network ownership timed out.");
            if (network == null)
            {
                var platform = new Platform(entropy);
                device = new E1000Device(new Hardware(), platform, deadline);
                network = new Ipv4Network(device, platform, Ipv4Configuration.QemuUserNat);
                NativePlatform.Write("XFE_NETWORK_CONFIGURATION|Mode|ExplicitStaticQemuUserNat|Address|10.0.2.15|Mask|255.255.255.0|Gateway|10.0.2.2|Dns|10.0.2.3|Dhcp|0\n");
            }
            return network.OpenTcpUntil(host, port, deadline, timeoutMilliseconds);
        }
        finally { Monitor.Exit(gate); }
    }
    sealed class Platform(Func<uint> random32) : INetworkPlatform
    {
        public long Milliseconds => NativePlatform.Milliseconds();
        public void Wait(int milliseconds) => Thread.Sleep(milliseconds);
        public uint Random32() => random32();
        public void Trace(string text) => NativePlatform.Write(text);
    }
    sealed unsafe class Hardware : IE1000Hardware
    {
        const string Library = "xfe_pal";
        [DllImport(Library, EntryPoint = "xfe_network_pci_read", CallingConvention = CallingConvention.Cdecl)] static extern uint PciRead(uint bus, uint device, uint function, uint offset);
        [DllImport(Library, EntryPoint = "xfe_network_pci_write", CallingConvention = CallingConvention.Cdecl)] static extern int PciWrite(uint bus, uint device, uint function, uint offset, uint value);
        [DllImport(Library, EntryPoint = "xfe_network_map_mmio", CallingConvention = CallingConvention.Cdecl)] static extern ulong Map(ulong physical, uint bytes);
        [DllImport(Library, EntryPoint = "xfe_mmio_read32", CallingConvention = CallingConvention.Cdecl)] static extern uint MmioRead(ulong address);
        [DllImport(Library, EntryPoint = "xfe_mmio_write32", CallingConvention = CallingConvention.Cdecl)] static extern void MmioWrite(ulong address, uint value);
        [DllImport(Library, EntryPoint = "xfe_network_dma_allocate", CallingConvention = CallingConvention.Cdecl)] static extern void* Allocate(uint pages, ulong* physical);
        [DllImport(Library, EntryPoint = "xfe_network_dma_free", CallingConvention = CallingConvention.Cdecl)] static extern int Free(void* address, uint pages);
        public uint ReadPci(uint bus, uint device, uint function, uint offset) => PciRead(bus, device, function, offset);
        public void WritePci(uint bus, uint device, uint function, uint offset, uint value)
        { if (PciWrite(bus, device, function, offset, value) != 1) throw new IOException("Invalid PCI configuration write."); }
        public nuint MapMmio(ulong physical, uint bytes) => checked((nuint)Map(physical, bytes));
        public uint ReadMmio(nuint address) => MmioRead(address);
        public void WriteMmio(nuint address, uint value) => MmioWrite(address, value);
        public DmaMemory AllocateDma(uint pages)
        { ulong physical = 0; void* address = Allocate(pages, &physical); return new((nuint)address, physical, pages); }
        public void FreeDma(DmaMemory memory)
        { if (Free((void*)memory.Address, memory.Pages) != 1) throw new IOException("Native DMA ownership release failed."); }
    }
}