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.Boot;
using Xunit;

namespace XFESystem.Boot.Tests;

public unsafe class FirmwareGpuTests
{
    static void Write64(byte* target, ulong value)
    {
        for (int i = 0; i < 8; i++) target[i] = (byte)(value >> (i * 8));
    }

    static void Descriptor(byte* data, ulong address, ulong length, byte type = 0)
    {
        for (int i = 0; i < 48; i++) data[i] = 0;
        data[0] = 0x8a; data[1] = 43; data[3] = type;
        Write64(data + 6, type == 1 ? 0UL : address > uint.MaxValue ? 64UL : 32UL);
        Write64(data + 14, address); Write64(data + 22, length - 1);
        Write64(data + 38, length); data[46] = 0x79;
    }

    [Fact]
    public void ExactPointerFreeAbiFitsFirmwareAllocation()
    {
        Assert.Equal(24, sizeof(FirmwareGpuBar));
        Assert.Equal(176, sizeof(FirmwareGpuDevice));
        Assert.Equal(1440, sizeof(FirmwareGpuHandoff));
        Assert.Equal(24, (int)Marshal.OffsetOf<FirmwareGpuHandoff>(nameof(FirmwareGpuHandoff.Checksum)));
        Assert.Equal(32, (int)Marshal.OffsetOf<FirmwareGpuHandoff>(nameof(FirmwareGpuHandoff.Devices)));
    }

    [Fact]
    public void Exact64BitFirmwareResourceMatchesLiveBar()
    {
        byte* data = stackalloc byte[48]; FirmwareGpuBar bar;
        Descriptor(data, 0x4000000000, 0x800000000);
        Assert.True(FirmwareGpuResources.DecodeBarDescriptor(data, 48, 1, 0xc, 0x40, &bar));
        Assert.Equal(0x4000000000UL, bar.Address); Assert.Equal(0x800000000UL, bar.Bytes);
        Assert.Equal(1u, bar.Index); Assert.Equal(27u, bar.Flags);
    }

    [Fact]
    public void OrdinaryBar0NeedsNoDestructiveProbe()
    {
        byte* data = stackalloc byte[48]; FirmwareGpuBar bar;
        Descriptor(data, 0xfc000000, 0x1000000);
        Assert.True(FirmwareGpuResources.DecodeBarDescriptor(data, 48, 0, 0xfc000000, 0, &bar));
        Assert.Equal(0x1000000UL, bar.Bytes); Assert.Equal(3u, bar.Flags);
    }

    [Fact]
    public void IoApertureCannotBecomeMmio()
    {
        byte* data = stackalloc byte[48]; FirmwareGpuBar bar;
        Descriptor(data, 0x2000, 0x80, 1);
        Assert.True(FirmwareGpuResources.DecodeBarDescriptor(data, 48, 5, 0x2001, 0, &bar));
        Assert.Equal(FirmwareGpuResources.Valid | FirmwareGpuResources.Io, bar.Flags);
        data[3] = 0;
        Assert.False(FirmwareGpuResources.DecodeBarDescriptor(data, 48, 5, 0x2001, 0, &bar));
        Assert.Equal(0UL, bar.Bytes);
    }

    [Theory]
    [InlineData(0)] [InlineData(1)] [InlineData(2)] [InlineData(3)]
    [InlineData(4)] [InlineData(5)] [InlineData(6)] [InlineData(7)]
    [InlineData(8)] [InlineData(9)] [InlineData(10)] [InlineData(11)]
    [InlineData(12)] [InlineData(13)] [InlineData(14)]
    public void RejectsUntrustedDescriptorGeometry(int mutation)
    {
        byte* data = stackalloc byte[48]; FirmwareGpuBar bar;
        Descriptor(data, 0xfc000000, 0x1000000);
        uint bytes = 48, index = 0, low = 0xfc000000, high = 0;
        switch (mutation)
        {
            case 0: bytes = 47; break;
            case 1: index = 6; break;
            case 2: data[0] = 0x87; break;
            case 3: data[1] = 42; break;
            case 4: data[2] = 1; break;
            case 5: data[3] = 1; break;
            case 6: data[46] = 0; break;
            case 7: Write64(data + 30, 0x1000); break;
            case 8: Write64(data + 14, 0xfb000000); break;
            case 9: Write64(data + 22, 0xfd000000); break;
            case 10: Write64(data + 38, 0); break;
            case 11: Write64(data + 38, 0x1000001); break;
            case 12: index = 5; low |= 4; break;
            case 13: low |= 2; break;
            case 14: Descriptor(data, 0xffffff0000000000, 0x20000000000); low = 4; high = 0xffffff00; break;
        }
        Assert.False(FirmwareGpuResources.DecodeBarDescriptor(data, bytes, index, low, high, &bar));
        Assert.Equal(0u, bar.Flags); Assert.Equal(0UL, bar.Address);
    }

    [Fact]
    public void HandoffChecksumProtectsFullDeviceTableAndHeader()
    {
        FirmwareGpuHandoff report = default;
        report.Magic = FirmwareGpuHandoff.Signature; report.Version = 1;
        report.Bytes = FirmwareGpuHandoff.TotalBytes;
        report.Checksum = FirmwareGpuResources.Checksum((byte*)&report, report.Bytes);
        Assert.True(FirmwareGpuResources.Validate(&report, report.Bytes));
        for (uint i = 0; i < report.Bytes; i++)
        {
            byte* data = (byte*)&report;
            data[i] ^= 1;
            Assert.False(FirmwareGpuResources.Validate(&report, FirmwareGpuHandoff.TotalBytes));
            data[i] ^= 1;
        }
        Assert.False(FirmwareGpuResources.Validate(&report, report.Bytes - 1));
    }

    [Fact]
    public void RecomputedChecksumDoesNotAuthorizeBadSchema()
    {
        FirmwareGpuHandoff report = default;
        report.Magic = FirmwareGpuHandoff.Signature; report.Version = 1;
        report.Bytes = FirmwareGpuHandoff.TotalBytes; report.Count = 9;
        report.Checksum = FirmwareGpuResources.Checksum((byte*)&report, report.Bytes);
        Assert.False(FirmwareGpuResources.Validate(&report, report.Bytes));
        report.Count = 1; report.Reserved = 1;
        report.Checksum = FirmwareGpuResources.Checksum((byte*)&report, report.Bytes);
        Assert.False(FirmwareGpuResources.Validate(&report, report.Bytes));
    }
}