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;

/// <summary>Value/pointer-only PCI, DMA and device mapping ABI for the independent network driver.</summary>
public static unsafe class NetworkHardwareBridge
{
    [DllImport("xfe_native", EntryPoint = "xfe_network_port_read32")] static extern uint ReadPort(ushort port);
    [DllImport("xfe_native", EntryPoint = "xfe_network_port_write32")] static extern void WritePort(ushort port, uint value);
    static bool Valid(uint bus, uint device, uint function, uint offset) => bus < 256 && device < 32 && function < 8 && offset < 256 && (offset & 3) == 0;
    [UnmanagedCallersOnly(EntryPoint = "xfe_network_pci_read")]
    public static uint ReadPci(uint bus, uint device, uint function, uint offset)
    {
        if (!Valid(bus, device, function, offset)) return 0xffffffff;
        ulong flags = Native.IrqSave();
        WritePort(0xcf8, 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | offset);
        uint result = ReadPort(0xcfc); Native.IrqRestore(flags); return result;
    }
    [UnmanagedCallersOnly(EntryPoint = "xfe_network_pci_write")]
    public static int WritePci(uint bus, uint device, uint function, uint offset, uint value)
    {
        if (!Valid(bus, device, function, offset)) return 0;
        ulong flags = Native.IrqSave();
        WritePort(0xcf8, 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | offset);
        WritePort(0xcfc, value); Native.IrqRestore(flags); return 1;
    }
    [UnmanagedCallersOnly(EntryPoint = "xfe_network_map_mmio")]
    public static ulong MapMmio(ulong physical, uint bytes)
    {
        if (physical == 0 || (physical & 4095) != 0 || bytes == 0 || bytes > 1048576) return 0;
        ulong flags = Native.IrqSave(); ulong result = VirtualMemory.MapDevice(physical, bytes); Native.IrqRestore(flags); return result;
    }
    [UnmanagedCallersOnly(EntryPoint = "xfe_network_dma_allocate")]
    public static void* Allocate(uint pages, ulong* physical)
    {
        if (physical == null || pages == 0 || pages > 64) return null;
        *physical = 0; ulong flags = Native.IrqSave(); ulong address = PhysicalMemory.Allocate(pages);
        if (address != 0) *physical = address;
        void* result = address == 0 ? null : (void*)PhysicalMemory.ToVirtual(address);
        Native.IrqRestore(flags); return result;
    }
    [UnmanagedCallersOnly(EntryPoint = "xfe_network_dma_free")]
    public static int Release(void* address, uint pages)
    {
        if (address == null || pages == 0 || pages > 64 || (ulong)address < PhysicalMemory.Hhdm) return 0;
        ulong flags = Native.IrqSave(); bool result = PhysicalMemory.Release((ulong)address - PhysicalMemory.Hhdm, pages);
        Native.IrqRestore(flags); return result ? 1 : 0;
    }
}