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

XFESystem

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

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESystem

Explain RTX 5090 resource rejection and distinguish unread FSP status

b430f86
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

16 个文件 +505 -59
Modified AGENTS.md +4 -0
@@ -1,5 +1,9 @@
1 1 # XFESystem 用户约定
2 2
3 2026-10-17 用户提供 RTX 5090 实体 GPU.txt 照片:01:00.0 / 10de:2b85 已发现,BAR0 0xD8000000 长度/来源为 0,BAR1 32 GiB 来源为 ReBAR。GB202 probe state 2 在 MMIO 前拒绝,旧 FSP scratch 0 未发生实际读取,不能算显卡返回零。已在隔离分支 `codex/rtx5090-resource-diagnostics` 完成 **0.3.0-dev.4-gpu-report.1** 补充诊断:EFI 表映射/CRC/设备匹配/BAR0 应用阶段、第一拒绝原因、实际采样标记及旧 ABI 文本兼容;接受资源的安全规则未放宽,CUDA/GPU 渲染仍未实现。17 组、1676 项宿主检查、63 组/200 项固件断言、108 项资源检查及同一 Desktop 单系统 USB 工作区镜像的完整原生回归通过;928 个合并输入与暂存/构建字节一致。源码不混入主目录并行的多屏 WIP,原 EFI 换行差异保留。
4
5 本轮镜像及 ZIP、重定位 PS5.1 启动计划已完成,源 SHA256 `071d5f4c7427cf9b5f956229adb04cad9c95a029431875c4af8415b0e3d27d9b`,ZIP SHA256 `f3e3745c0de0d9d8f987ca89dbaefca1ba9db0f01b3c4a2bcbdc023619151797`。后续导出和写盘备份位于 `E:\XFESystemArtifacts\GpuReport20261017-1792200770239`。构建副本迁移清理被自动审批拒绝、未执行,没有删除或移动旧文件。当前 Windows 管理员提升仍待处理,辅助写盘进程未启动、实体磁盘未打开,**本轮尚未更新 USB**,原有 2026-10-17 成功版本继续保留。新写盘必须继续 `IndependentCSharpUsb256`、固定上一版成功回执、完整备份恢复工作区和全盘范围校验。详情 `docs/Rtx5090PhysicalReport20261017.md` 及对应 JSON;`ImageDeliveryComplete=true`、`DeliveryComplete=false`、`UsbWritten=false`、`FullReleaseQualified=false`。
6
3 7 2026-10-17 用户明确恢复写入授权,已将 **0.3.0-dev.4-bing-css-monaco.1 / Desktop USB 工作区单系统** 写入专用 USB `230222336207` / `5000000000002AEF`。源镜像保持 `e463fa94b7fa162662c330b0c0fa7d1f1e9ac21a05b57086a66a3d52900c18de`;完整 `268435456` 字节容量调整及工作区恢复后的预期/实际 SHA256 均为 `5248ef1bf450c1cff99a44830bd115100c924173f802c64110f0edf330fbc473`,真实盘尾 GPT `ActualLastLba=500118191` 通过。**已有 64 MiB 工作区已实际备份并逐字节恢复**,SHA256 `b2c02a637875fdea037978e837bdba80e1c9fe0fa151712faaa3bafa841fbeab`,位置随新版 FAT 分配迁移,不清空用户文件和设置。
4 8
5 9 初次更新因两版自带 `UsbHello.dll` 哈希不同而在首个磁盘字节写入前拒绝,已打开的句柄随后关闭,原失败留存。写盘器增加仅适用 `IndependentCSharpUsb256` 的 `-PreviousWriteResult` / `-PreviousWriteResultSha256`:显式固定同一专用设备的历史成功回执,核验并锁定旧镜像、清单、启动回执、源码快照;只有与已验证旧版示例完全相符的文件允许备份升级,任意用户替换和额外文件继续拒绝覆盖。本次旧示例确实匹配上一版原文件,5632 字节已单独备份。17 项新增检查、原工作区升级保护、原物理写盘保护及 5 项交付分派检查通过;软件镜像与其原有 17 组、1666 项宿主/原生验收证据未改变,本轮未重跑完整应用验收。
Modified Source/XFESystem.NativeKernel/GpuHardwareBridge.cs +3 -1
@@ -144,7 +144,8 @@ public static unsafe class GpuHardwareBridge
144 144 // A fixed integer ABI: 0 version, 1 record bytes, 2 saved count, 3 matched
145 145 // count, 4 state (0 not run/1 running/2 complete/3 unavailable), 5 MCFG
146 146 // status, 6 configuration reads, 7 GPU acceleration=0, 8 CUDA=0,
147 // 9 capacity, 10 omitted, 11 ECAM page maps, 12 unmap failures, 13 BAR bytes.
147 // 9 capacity, 10 omitted, 11 ECAM page maps, 12 unmap failures, 13 BAR bytes,
148 // 14..19 additive firmware diagnostic version/stage/count/address/match/BAR0.
148 149 [UnmanagedCallersOnly(EntryPoint = "xfe_gpu_discovery_info")]
149 150 public static ulong Info(uint field)
150 151 {
@@ -160,6 +161,7 @@ public static unsafe class GpuHardwareBridge
160 161 if (field == 11) return _ecamMaps;
161 162 if (field == 12) return _unmapFailures;
162 163 if (field == 13) return (ulong)sizeof(NativeGpuBarDiscovery);
164 if (field >= 14 && field <= 19) return NativeGpuFirmware.Diagnostic(field - 14);
163 165 return 0;
164 166 }
165 167
Modified Source/XFESystem.NativeKernel/NativeGpuFirmware.cs +46 -5
@@ -8,6 +8,23 @@ public static unsafe class NativeGpuFirmware
8 8 {
9 9 static FirmwareGpuHandoff* _report;
10 10 static bool _initialized;
11 static uint _locateState, _matchState, _bar0State;
12 static ulong _tablePhysical;
13
14 // Additive, value-only diagnostics. No firmware pointers cross the ABI.
15 // Locate: 1 boot context, 2 table mapping, 3 signature, 4 header/CRC,
16 // 5 array shape, 6 array mapping, 7 missing GUID, 8 duplicate GUID,
17 // 9 report mapping, 10 report schema/CRC, 11 accepted.
18 public static ulong Diagnostic(uint field)
19 {
20 if (field == 0) return 1;
21 if (field == 1) return _locateState;
22 if (field == 2) return _report == null ? 0UL : _report->Count;
23 if (field == 3) return _tablePhysical;
24 if (field == 4) return _matchState;
25 if (field == 5) return _bar0State;
26 return 0;
27 }
11 28
12 29 static byte* PhysicalPointer(NativeBootInfo* boot, ulong physical, ulong bytes)
13 30 {
@@ -53,55 +70,79 @@ public static unsafe class NativeGpuFirmware
53 70
54 71 static FirmwareGpuHandoff* Locate(NativeBootInfo* boot)
55 72 {
73 _locateState = 1;
56 74 if (boot == null || boot->MemoryEntries == null || boot->MemoryEntryCount == 0 ||
57 75 boot->MemoryEntryCount > 4096 || boot->EfiSystemTable < boot->Hhdm) return null;
58 76 ulong physical = boot->EfiSystemTable - boot->Hhdm;
77 _tablePhysical = physical;
78 _locateState = 2;
59 79 byte* table = PhysicalPointer(boot, physical, 120);
60 if (table == null || *(ulong*)table != 0x5453595320494249UL || *(uint*)(table + 20) != 0) return null;
80 if (table == null) return null;
81 _locateState = 3;
82 if (*(ulong*)table != 0x5453595320494249UL || *(uint*)(table + 20) != 0) return null;
61 83 uint headerBytes = *(uint*)(table + 12);
84 _locateState = 4;
62 85 if (headerBytes < 120 || headerBytes > 4096 || PhysicalPointer(boot, physical, headerBytes) == null ||
63 86 *(uint*)(table + 16) != HeaderCrc(table, headerBytes)) return null;
64 87 ulong count = *(ulong*)(table + 104), arrayPhysical = *(ulong*)(table + 112);
88 _locateState = 5;
65 89 if (count == 0 || count > 4096) return null;
90 _locateState = 6;
66 91 byte* entries = PhysicalPointer(boot, arrayPhysical, count * 24);
67 92 if (entries == null) return null;
93 _locateState = 7;
68 94 FirmwareGpuHandoff* selected = null;
69 95 for (ulong i = 0; i < count; i++)
70 96 {
71 97 byte* entry = entries + i * 24;
72 98 if (*(ulong*)entry != FirmwareGpuHandoff.GuidLow || *(ulong*)(entry + 8) != FirmwareGpuHandoff.GuidHigh) continue;
99 _locateState = 8;
100 if (selected != null) return null;
101 _locateState = 9;
73 102 FirmwareGpuHandoff* report = (FirmwareGpuHandoff*)PhysicalPointer(boot, *(ulong*)(entry + 16), FirmwareGpuHandoff.TotalBytes);
74 if (selected != null || !FirmwareGpuResources.Validate(report, FirmwareGpuHandoff.TotalBytes) || report->Flags != 0) return null;
103 if (report == null) return null;
104 _locateState = 10;
105 if (!FirmwareGpuResources.Validate(report, FirmwareGpuHandoff.TotalBytes) || report->Flags != 0) return null;
75 106 selected = report;
76 107 }
108 _locateState = selected == null ? 7u : 11u;
77 109 return selected;
78 110 }
79 111
80 112 public static void Apply(NativeBootInfo* boot, NativeGpuDeviceDiscovery* record)
81 113 {
82 114 Initialize(boot);
115 bool diagnose = record != null && record->VendorId == 0x10de && record->DeviceId == 0x2b85;
116 if (diagnose) { _matchState = 1; _bar0State = 0; }
83 117 if (_report == null || record == null) return;
118 if (diagnose) _matchState = 2;
84 119 FirmwareGpuDevice* selected = null;
85 120 for (uint i = 0; i < _report->Count; i++)
86 121 {
87 122 FirmwareGpuDevice* item = (FirmwareGpuDevice*)(_report->Devices + i * FirmwareGpuHandoff.DeviceBytes);
88 123 if (item->Segment != record->Segment || item->Bus != record->Bus || item->Device != record->Device ||
89 124 item->Function != record->Function) continue;
90 if (selected != null || item->VendorId != record->VendorId || item->DeviceId != record->DeviceId ||
91 item->ClassCode != record->ClassCode || (item->Command & 3) != (record->Command & 3)) return;
125 if (selected != null) { if (diagnose) _matchState = 4; return; }
126 if (item->VendorId != record->VendorId || item->DeviceId != record->DeviceId ||
127 item->ClassCode != record->ClassCode || (item->Command & 3) != (record->Command & 3))
128 { if (diagnose) _matchState = 3; return; }
92 129 selected = item;
93 130 }
94 131 if (selected == null) return;
132 if (diagnose) _matchState = 5;
95 133 for (uint i = 0; i < 6; i++)
96 134 {
97 135 FirmwareGpuBar* source = (FirmwareGpuBar*)(selected->Bars + i * 24);
136 if (diagnose && i == 0) _bar0State = source->Flags == 0 ? 1u : 2u;
98 137 if (source->Index != i || (source->Flags & 7) != 3 || (source->Flags & ~31u) != 0) continue;
99 138 NativeGpuBarDiscovery* target = &record->Bar0 + i;
100 139 // Firmware descriptors cannot reinterpret an I/O BAR or the high
101 140 // DWORD of a 64-bit BAR. ApplyResourceSize checks the live address.
141 if (diagnose && i == 0) _bar0State = 3;
102 142 if ((target->Flags & 1) == 0 || ((target->Flags & 4) != 0) != ((source->Flags & 8) != 0) ||
103 143 ((target->Flags & 8) != 0) != ((source->Flags & 16) != 0)) continue;
104 GpuHardwareBridge.ApplyResourceSize(target, source->Address, source->Bytes, 2);
144 bool applied = GpuHardwareBridge.ApplyResourceSize(target, source->Address, source->Bytes, 2);
145 if (diagnose && i == 0) _bar0State = applied ? 5u : 4u;
105 146 }
106 147 }
107 148 }
Modified Source/XFESystem.NativeKernel/NvidiaBootProbe.cs +29 -14
@@ -8,7 +8,7 @@ namespace XFESystem.NativeKernel;
8 8 public static unsafe class NvidiaBootProbe
9 9 {
10 10 public const uint FspBootComplete = 0x00ad00bc;
11 static uint _state, _sample;
11 static uint _state, _sample, _rejection, _sampled;
12 12 static ulong _physical, _elapsed;
13 13 [DllImport("xfe_native", EntryPoint = "xfe_gpu_discovery_info")] static extern ulong DiscoveryInfo(uint field);
14 14 [DllImport("xfe_native", EntryPoint = "xfe_gpu_discovery_record")]
@@ -30,13 +30,15 @@ public static unsafe class NvidiaBootProbe
30 30 record.VendorId != 0x10de || record.DeviceId != 0x2b85) continue;
31 31 _state = 2;
32 32 ulong page;
33 if (!TryRegisterPage(boot, &record, &page)) break;
33 _rejection = RegisterPageRejection(boot, &record, &page);
34 if (_rejection != 0) break;
34 35 _physical = page + (FspBootComplete & 4095);
35 36 ulong flags = Native.IrqSave();
36 37 ulong mapping = VirtualMemory.MapDeviceReadOnly(page, 4096);
37 38 Native.IrqRestore(flags);
38 39 if (mapping == 0) { _state = 3; break; }
39 40 _sample = Native.MmioRead32(mapping + (FspBootComplete & 4095));
41 _sampled = 1;
40 42 _state = _sample == 0xff ? 5u : _sample == 0xffffffff ? 6u : 4u;
41 43 flags = Native.IrqSave();
42 44 bool unmapped = VirtualMemory.UnmapDevice(mapping, 4096);
@@ -49,42 +51,52 @@ public static unsafe class NvidiaBootProbe
49 51 Serial.Write("XFE_NVIDIA_BOOT_PROBE|State|"); Serial.Number(_state);
50 52 Serial.Write("|FspScratch|"); Serial.Hex(_sample); Serial.Write("|Physical|"); Serial.Hex(_physical);
51 53 Serial.Write("|ElapsedNs|"); Serial.Number(_elapsed);
54 Serial.Write("|Rejection|"); Serial.Number(_rejection);
55 Serial.Write("|Sampled|"); Serial.Number(_sampled);
52 56 Serial.Line("|ReadOnly|1|GspStarted|0|ChannelCreated|0|Cuda|0|GpuRasterization|0");
53 57 }
54 58
55 59 // Validate the entire page against a matching firmware-assigned aperture,
56 60 // not just its first byte. ReBAR alone cannot establish ordinary BAR0 size.
57 61 public static bool TryRegisterPage(NativeBootInfo* boot, NativeGpuDeviceDiscovery* record, ulong* physical)
62 => RegisterPageRejection(boot, record, physical) == 0;
63
64 // Same acceptance rules as TryRegisterPage, with the first failed
65 // precondition exposed for physical reports. Zero alone permits mapping.
66 public static uint RegisterPageRejection(NativeBootInfo* boot, NativeGpuDeviceDiscovery* record, ulong* physical)
58 67 {
59 if (physical == null) return false;
68 if (physical == null) return 1;
60 69 *physical = 0;
61 70 if (boot == null || record == null || boot->MemoryEntries == null || boot->MemoryEntryCount == 0 ||
62 boot->MemoryEntryCount > 4096 || record->AbiVersion != 1 || record->RecordBytes != sizeof(NativeGpuDeviceDiscovery) ||
63 record->VendorId != 0x10de || record->DeviceId != 0x2b85 || record->CapabilityStatus != 1 ||
71 boot->MemoryEntryCount > 4096) return 2;
72 if (record->AbiVersion != 1 || record->RecordBytes != sizeof(NativeGpuDeviceDiscovery)) return 3;
73 if (record->VendorId != 0x10de || record->DeviceId != 0x2b85 ||
64 74 record->Segment != 0 || record->Bus > 255 || record->Device > 31 || record->Function > 7 ||
65 (record->ClassCode >> 16) != 3 || (record->HeaderType & 127) != 0 ||
66 record->Bar0.Index != 0 || record->Bar0.Reserved != 0 ||
67 (record->Command & 2) == 0 || record->Bar0.SizeSource != GpuHardwareBridge.SourceFirmware ||
68 (record->Bar0.Flags & (GpuHardwareBridge.Memory | GpuHardwareBridge.Io | GpuHardwareBridge.SizeKnown |
75 (record->ClassCode >> 16) != 3 || (record->HeaderType & 127) != 0) return 4;
76 if (record->CapabilityStatus != 1) return 5;
77 if ((record->Command & 2) == 0) return 6;
78 if (record->Bar0.Index != 0 || record->Bar0.Reserved != 0) return 7;
79 if (record->Bar0.SizeSource != GpuHardwareBridge.SourceFirmware) return 8;
80 if ((record->Bar0.Flags & (GpuHardwareBridge.Memory | GpuHardwareBridge.Io | GpuHardwareBridge.SizeKnown |
69 81 GpuHardwareBridge.Invalid | GpuHardwareBridge.Unassigned | GpuHardwareBridge.UpperHalf)) !=
70 (GpuHardwareBridge.Memory | GpuHardwareBridge.SizeKnown)) return false;
82 (GpuHardwareBridge.Memory | GpuHardwareBridge.SizeKnown)) return 9;
71 83 ulong pageOffset = FspBootComplete & ~4095UL;
72 84 ulong address = record->Bar0.Address, size = record->Bar0.Size;
73 85 if (address == 0 || (address & 4095) != 0 || size < pageOffset + 4096 || (size & (size - 1)) != 0 ||
74 86 (address & (size - 1)) != 0 || address >= (1UL << 52) || size > (1UL << 52) - address ||
75 ((record->Bar0.Flags & GpuHardwareBridge.Width64) == 0 && (address >= 0x100000000UL || size > 0x100000000UL - address))) return false;
87 ((record->Bar0.Flags & GpuHardwareBridge.Width64) == 0 && (address >= 0x100000000UL || size > 0x100000000UL - address))) return 10;
76 88 ulong page = address + pageOffset;
77 89 for (ulong i = 0; i < boot->MemoryEntryCount; i++)
78 90 {
79 91 MemoryMapEntry* entry = boot->MemoryEntries[i];
80 if (entry == null || entry->Length > ~0UL - entry->Base) return false;
92 if (entry == null || entry->Length > ~0UL - entry->Base) return 11;
81 93 // A BAR may be absent from the boot memory map or explicitly
82 94 // reserved. It must never alias RAM, ACPI, kernel or GOP memory.
83 95 if (entry->Length != 0 && address < entry->Base + entry->Length && entry->Base < address + size && entry->Kind != 1)
84 return false;
96 return 12;
85 97 }
86 98 *physical = page;
87 return true;
99 return 0;
88 100 }
89 101
90 102 [UnmanagedCallersOnly(EntryPoint = "xfe_gpu_boot_probe_info")]
@@ -95,6 +107,9 @@ public static unsafe class NvidiaBootProbe
95 107 if (field == 2) return _sample;
96 108 if (field == 3) return _physical;
97 109 if (field == 4) return _elapsed;
110 if (field == 5) return _rejection;
111 if (field == 6) return _sampled;
112 if (field == 7) return 1; // Additive diagnostic fields version.
98 113 // No field can be read as an acceleration/firmware-started claim.
99 114 return 0;
100 115 }
Modified Source/XFESystem.NativeRuntime/Application/NativeGpuDiagnostics.cs +1 -37
@@ -1,6 +1,4 @@
1 using System.Buffers.Binary;
2 1 using System.Runtime.InteropServices;
3 using System.Text;
4 2
5 3 namespace XFESystem.NativeRuntime.Application;
6 4
@@ -16,39 +14,5 @@ internal static unsafe class NativeGpuDiagnostics
16 14 private static extern ulong BootInfo(uint field);
17 15
18 16 internal static string ReadReport(out bool hasRtx5090)
19 {
20 hasRtx5090 = false;
21 const int RecordBytes = 272;
22 var text = new StringBuilder("XFESystem NVIDIA native port diagnostics\nScope: XFESystemGuest\nCUDA: unavailable\nGPU rasterization: unavailable\n");
23 if (Info(0) != 1 || Info(1) != RecordBytes || Info(13) != 32 || Info(2) > 8 || BootInfo(0) != 1)
24 return text.Append("Kernel diagnostic ABI: rejected\n").ToString();
25 text.Append("Discovery state: ").Append(Info(4)).Append("; devices: ").Append(Info(2)).Append('\n');
26 Span<byte> data = stackalloc byte[RecordBytes];
27 for (uint i = 0; i < Info(2); i++)
28 {
29 data.Clear();
30 fixed (byte* target = data)
31 if (CopyRecord(i, target, RecordBytes) != 1) throw new InvalidDataException("GPU record copy failed.");
32 if (BinaryPrimitives.ReadUInt32LittleEndian(data) != 1 || BinaryPrimitives.ReadUInt32LittleEndian(data[4..]) != RecordBytes)
33 throw new InvalidDataException("GPU record ABI mismatch.");
34 hasRtx5090 |= U32(data, 24) == 0x10de && U32(data, 28) == 0x2b85;
35 // Read through helpers over the span below instead of sharing
36 // either runtime's managed structs across the kernel boundary.
37 text.Append("PCI ").Append(U32(data, 12)).Append(':').Append(U32(data, 16)).Append('.').Append(U32(data, 20))
38 .Append("; Vendor 0x").Append(U32(data, 24).ToString("X4")).Append("; Device 0x").Append(U32(data, 28).ToString("X4")).Append('\n');
39 for (int bar = 0; bar < 6; bar++)
40 {
41 int offset = 80 + bar * 32;
42 ulong address = BinaryPrimitives.ReadUInt64LittleEndian(data[offset..]);
43 ulong bytes = BinaryPrimitives.ReadUInt64LittleEndian(data[(offset + 8)..]);
44 text.Append("BAR").Append(bar).Append(" 0x").Append(address.ToString("X"))
45 .Append("; bytes ").Append(bytes).Append("; size source ").Append(U32(data, offset + 24)).Append('\n');
46 }
47 }
48 text.Append("GB202 boot probe state: ").Append(BootInfo(1)).Append("; FSP scratch 0x").Append(BootInfo(2).ToString("X8")).Append('\n');
49 text.Append("FSP state 5 means secure boot observed; it does not mean GSP/RM/channel/CUDA initialized.\n");
50 text.Append("This version only queries assigned resources and reads the validated GB202 FSP status register.\n");
51 return text.ToString();
52 }
53 private static uint U32(ReadOnlySpan<byte> data, int offset) => BinaryPrimitives.ReadUInt32LittleEndian(data[offset..]);
17 => NativeGpuReportFormatter.Format(Info, CopyRecord, BootInfo, out hasRtx5090);
54 18 }
Added Source/XFESystem.NativeRuntime/Application/NativeGpuReportFormatter.cs +96 -0
@@ -0,0 +1,96 @@
1 using System.Buffers.Binary;
2 using System.Text;
3
4 namespace XFESystem.NativeRuntime.Application;
5
6 // Pure rendering of the kernel's integer ABI; injectable readers let host
7 // checks verify physical-failure reports without touching a GPU or host driver.
8 public static unsafe class NativeGpuReportFormatter
9 {
10 public delegate int RecordReader(uint index, byte* record, uint bytes);
11
12 public static string Format(Func<uint, ulong> info, RecordReader copyRecord, Func<uint, ulong> bootInfo,
13 out bool hasRtx5090)
14 {
15 hasRtx5090 = false;
16 const int recordBytes = 272;
17 ulong count = info(2);
18 var text = new StringBuilder("XFESystem NVIDIA native port diagnostics\nScope: XFESystemGuest\nCUDA: unavailable\nGPU rasterization: unavailable\n");
19 if (info(0) != 1 || info(1) != recordBytes || info(13) != 32 || count > 8 || bootInfo(0) != 1)
20 return text.Append("Kernel diagnostic ABI: rejected\n").ToString();
21 text.Append("Discovery state: ").Append(info(4)).Append("; devices: ").Append(count).Append('\n');
22 if (info(14) == 1)
23 {
24 text.Append("UEFI resource handoff: ").Append(HandoffState(info(15))).Append(" (").Append(info(15)).Append("); devices: ").Append(info(16)).Append('\n');
25 text.Append("RTX 5090 firmware match: ").Append(MatchState(info(18))).Append(" (").Append(info(18)).Append(")\n");
26 text.Append("BAR0 firmware resource: ").Append(BarState(info(19))).Append(" (").Append(info(19)).Append(")\n");
27 }
28 else text.Append("UEFI handoff detail: unavailable in this kernel\n");
29 Span<byte> data = stackalloc byte[recordBytes];
30 for (uint i = 0; i < count; i++)
31 {
32 data.Clear();
33 fixed (byte* target = data)
34 if (copyRecord(i, target, recordBytes) != 1) throw new InvalidDataException("GPU record copy failed.");
35 if (U32(data, 0) != 1 || U32(data, 4) != recordBytes)
36 throw new InvalidDataException("GPU record ABI mismatch.");
37 hasRtx5090 |= U32(data, 24) == 0x10de && U32(data, 28) == 0x2b85;
38 text.Append("PCI ").Append(U32(data, 12)).Append(':').Append(U32(data, 16)).Append('.').Append(U32(data, 20))
39 .Append("; Vendor 0x").Append(U32(data, 24).ToString("X4")).Append("; Device 0x").Append(U32(data, 28).ToString("X4")).Append('\n');
40 text.Append("PCI command 0x").Append(U32(data, 44).ToString("X4")).Append("; PCIe status ").Append(U32(data, 56)).Append('\n');
41 for (int bar = 0; bar < 6; bar++)
42 {
43 int offset = 80 + bar * 32;
44 text.Append("BAR").Append(bar).Append(" 0x").Append(BinaryPrimitives.ReadUInt64LittleEndian(data[offset..]).ToString("X"))
45 .Append("; bytes ").Append(BinaryPrimitives.ReadUInt64LittleEndian(data[(offset + 8)..]))
46 .Append("; size source ").Append(U32(data, offset + 24))
47 .Append("; flags 0x").Append(U32(data, offset + 20).ToString("X2")).Append('\n');
48 }
49 }
50 ulong state = bootInfo(1);
51 text.Append("GB202 boot probe state: ").Append(state).Append('\n');
52 bool detailed = bootInfo(7) == 1;
53 // Earlier kernels have no sampled flag. States 4..7 are only reached
54 // after MmioRead32 returns; a zero value at state 2 was never a sample.
55 bool sampled = detailed ? bootInfo(6) == 1 : state >= 4 && state <= 7;
56 if (sampled) text.Append("FSP scratch 0x").Append(bootInfo(2).ToString("X8")).Append(" (register read completed)\n");
57 else text.Append("FSP scratch: not read\n");
58 if (state == 2)
59 text.Append("Probe stopped before MMIO: ").Append(detailed ? Rejection(bootInfo(5)) : "required BAR0 resource validation failed; detailed reason unavailable").Append('\n');
60 if (state == 3) text.Append("Probe stopped before MMIO: register page mapping failed\n");
61 text.Append("FSP state 5 means secure boot observed; it does not mean GSP/RM/channel/CUDA initialized.\n");
62 text.Append("This version only queries assigned resources and reads the validated GB202 FSP status register.\n");
63 return text.ToString();
64 }
65
66 private static string HandoffState(ulong state) => state switch
67 {
68 0 => "not attempted", 1 => "invalid boot context", 2 => "EFI system table not in mapped firmware memory",
69 3 => "EFI system table signature rejected", 4 => "EFI system table header/CRC rejected",
70 5 => "configuration table count rejected", 6 => "configuration table array not mapped",
71 7 => "GPU resource table missing", 8 => "duplicate GPU resource table",
72 9 => "GPU resource table not mapped", 10 => "GPU resource table schema/CRC rejected",
73 11 => "accepted", _ => "unknown status"
74 };
75 private static string MatchState(ulong state) => state switch
76 {
77 0 => "not attempted", 1 => "no accepted handoff", 2 => "PCI address not in handoff",
78 3 => "PCI identity/command mismatch", 4 => "duplicate PCI address", 5 => "matched", _ => "unknown status"
79 };
80 private static string BarState(ulong state) => state switch
81 {
82 0 => "not attempted", 1 => "no accepted firmware descriptor",
83 2 => "descriptor index/type/flags rejected", 3 => "live BAR type/width/prefetch mismatch",
84 4 => "address/size invalid or conflicts with ReBAR", 5 => "applied", _ => "unknown status"
85 };
86 private static string Rejection(ulong reason) => reason switch
87 {
88 1 => "missing output storage", 2 => "invalid boot memory map/device record", 3 => "device ABI mismatch",
89 4 => "PCI identity/address/type rejected", 5 => "PCIe capability not validated", 6 => "PCI memory decode disabled",
90 7 => "BAR0 index/reserved field rejected", 8 => "BAR0 length has no validated firmware source",
91 9 => "BAR0 memory/size flags rejected", 10 => "BAR0 address/length cannot contain the full register page",
92 11 => "boot memory map entry invalid", 12 => "BAR0 overlaps protected memory",
93 _ => "unknown rejection reason"
94 };
95 private static uint U32(ReadOnlySpan<byte> data, int offset) => BinaryPrimitives.ReadUInt32LittleEndian(data[offset..]);
96 }
Modified Source/XFESystem.NativeRuntime/ConsoleApplication/ConsoleApplication.csproj +1 -0
@@ -20,6 +20,7 @@
20 20 <Compile Include="../Application/NativeDiagnosticWriter.cs" Link="Platform/NativeDiagnosticWriter.cs" />
21 21 <Compile Include="../Application/RuntimeSelfCheck.cs" Link="Platform/RuntimeSelfCheck.cs" />
22 22 <Compile Include="../Application/NativeGpuDiagnostics.cs" Link="Platform/NativeGpuDiagnostics.cs" />
23 <Compile Include="../Application/NativeGpuReportFormatter.cs" Link="Platform/NativeGpuReportFormatter.cs" />
23 24 <Compile Include="../Application/NativeUsbDiagnostics.cs" Link="Platform/NativeUsbDiagnostics.cs" />
24 25 <ProjectReference Include="../../XFESystem.Core/XFESystem.Core.csproj" />
25 26 <ProjectReference Include="../../XFESystem.Storage/XFESystem.Storage.csproj" />
Added Tests/XFESystem.Platform.Tests/NativeGpuReportTests.cs +73 -0
@@ -0,0 +1,73 @@
1 using System.Buffers.Binary;
2 using XFESystem.NativeRuntime.Application;
3
4 namespace XFESystem.Platform.Tests;
5
6 public unsafe class NativeGpuReportTests
7 {
8 private static ulong Info(uint field) => field switch { 0 => 1, 1 => 272, 2 => 1, 4 => 2, 13 => 32, _ => 0 };
9 private static int PhotoRecord(uint index, byte* record, uint bytes)
10 {
11 Assert.Equal(0u, index); Assert.Equal(272u, bytes);
12 Span<byte> data = new(record, 272); data.Clear();
13 U32(data, 0, 1); U32(data, 4, 272); U32(data, 12, 1); U32(data, 24, 0x10de); U32(data, 28, 0x2b85);
14 BinaryPrimitives.WriteUInt64LittleEndian(data[80..], 0xd8000000);
15 BinaryPrimitives.WriteUInt64LittleEndian(data[112..], 0xf000000000);
16 BinaryPrimitives.WriteUInt64LittleEndian(data[120..], 34359738368);
17 U32(data, 136, 1);
18 return 1;
19 }
20
21 [Fact]
22 public void LegacyPhysicalReportDoesNotPresentDefaultZeroAsARegisterRead()
23 {
24 string text = NativeGpuReportFormatter.Format(Info, PhotoRecord, field => field switch { 0 => 1, 1 => 2, _ => 0 }, out bool rtx);
25 Assert.True(rtx);
26 Assert.Contains("PCI 1:0.0; Vendor 0x10DE; Device 0x2B85", text);
27 Assert.Contains("BAR0 0xD8000000; bytes 0; size source 0", text);
28 Assert.Contains("BAR1 0xF000000000; bytes 34359738368; size source 1", text);
29 Assert.Contains("FSP scratch: not read", text);
30 Assert.DoesNotContain("FSP scratch 0x00000000", text);
31 Assert.Contains("CUDA: unavailable", text);
32 Assert.Contains("GPU rasterization: unavailable", text);
33 }
34
35 [Theory]
36 [InlineData(2u, "EFI system table not in mapped firmware memory")]
37 [InlineData(7u, "GPU resource table missing")]
38 [InlineData(10u, "GPU resource table schema/CRC rejected")]
39 [InlineData(11u, "accepted")]
40 public void ShowsFirmwareHandoffStageAndFirstProbeRejection(uint stage, string expected)
41 {
42 ulong DetailedInfo(uint field) => field switch { 14 => 1, 15 => stage, 16 => stage == 11 ? 1UL : 0, _ => Info(field) };
43 string text = NativeGpuReportFormatter.Format(DetailedInfo, PhotoRecord,
44 field => field switch { 0 => 1, 1 => 2, 5 => 8, 7 => 1, _ => 0 }, out _);
45 Assert.Contains("UEFI resource handoff: " + expected, text);
46 Assert.Contains("Probe stopped before MMIO: BAR0 length has no validated firmware source", text);
47 Assert.Contains("FSP scratch: not read", text);
48 }
49
50 [Theory]
51 [InlineData(4u, 0u)]
52 [InlineData(5u, 255u)]
53 [InlineData(6u, uint.MaxValue)]
54 [InlineData(7u, 255u)]
55 public void ActualSamplesIncludingZeroRemainVisibleWithoutAnAccelerationClaim(uint state, uint sample)
56 {
57 string text = NativeGpuReportFormatter.Format(Info, PhotoRecord,
58 field => field switch { 0 => 1, 1 => state, 2 => sample, 6 => 1, 7 => 1, _ => 0 }, out _);
59 Assert.Contains("FSP scratch 0x" + sample.ToString("X8") + " (register read completed)", text);
60 Assert.Contains("CUDA: unavailable", text);
61 Assert.Contains("GPU rasterization: unavailable", text);
62 }
63
64 [Fact]
65 public void ExcessiveCountRejectsBeforeCopyingAnyRecord()
66 {
67 string text = NativeGpuReportFormatter.Format(field => field == 2 ? 9 : Info(field),
68 (_, _, _) => throw new InvalidOperationException("Must not copy"), field => 1, out bool rtx);
69 Assert.False(rtx); Assert.Contains("Kernel diagnostic ABI: rejected", text);
70 }
71
72 private static void U32(Span<byte> data, int offset, uint value) => BinaryPrimitives.WriteUInt32LittleEndian(data[offset..], value);
73 }
Modified Tools/IndependentKernel/GpuDiscoveryChecks/HardwareNotInvoked.cs +1 -0
@@ -17,6 +17,7 @@ public static unsafe class NativeGpuFirmware
17 17 {
18 18 public static void Initialize(NativeBootInfo* _) => throw new InvalidOperationException("No guest firmware in host parser tests");
19 19 public static void Apply(NativeBootInfo* _, NativeGpuDeviceDiscovery* __) => throw new InvalidOperationException("No guest firmware in host parser tests");
20 public static ulong Diagnostic(uint _) => throw new InvalidOperationException("No guest firmware diagnostics in host parser tests");
20 21 }
21 22 public static class Serial
22 23 {
Modified Tools/IndependentKernel/GpuDiscoveryChecks/ProbeGeometryChecks.cs +7 -0
@@ -38,6 +38,13 @@ public static unsafe class ProbeGeometryChecks
38 38 r = Valid(); Deny("Probe null boot", null, &r); Deny("Probe null device", &boot, null);
39 39 Program.Check("Probe null output rejected", !NvidiaBootProbe.TryRegisterPage(&boot, &r, null));
40 40 r.Bar0.SizeSource = 0; Deny("Probe unknown BAR size denied", &boot, &r);
41 r.Bar0.Address = 0xd8000000; r.Bar0.Size = 0; r.Bar0.Flags = GpuHardwareBridge.Memory;
42 r.Bar1 = new() { Index = 1, Address = 0xf000000000, Size = 34359738368,
43 Flags = GpuHardwareBridge.Memory | GpuHardwareBridge.Width64 | GpuHardwareBridge.Prefetch | GpuHardwareBridge.SizeKnown,
44 SizeSource = GpuHardwareBridge.SourceRebar };
45 ulong diagnosticPage = 123;
46 Program.Check("Physical report BAR1 cannot authorize BAR0; first reason is missing firmware source",
47 NvidiaBootProbe.RegisterPageRejection(&boot, &r, &diagnosticPage) == 8 && diagnosticPage == 0);
41 48 r = Valid(); r.Bar0.SizeSource = 1; Deny("ReBAR alone not BAR0 firmware resource", &boot, &r);
42 49 r = Valid(); r.Bar0.Size = 0; Deny("Probe zero aperture denied", &boot, &r);
43 50 r = Valid(); r.Bar0.Size = 0x100000; Deny("Probe small aperture denied", &boot, &r);
Modified Tools/IndependentKernel/GpuFirmwareChecks/FirmwareFixture.cs +3 -0
@@ -61,6 +61,9 @@ internal sealed unsafe class FirmwareFixture : IDisposable
61 61 FieldInfo initialized = typeof(NativeGpuFirmware).GetField("_initialized", binding) ?? throw new MissingFieldException();
62 62 FieldInfo report = typeof(NativeGpuFirmware).GetField("_report", binding) ?? throw new MissingFieldException();
63 63 initialized.SetValue(null, false); report.SetValue(null, Pointer.Box(null, report.FieldType));
64 foreach (string name in new[] { "_locateState", "_matchState", "_bar0State" })
65 (typeof(NativeGpuFirmware).GetField(name, binding) ?? throw new MissingFieldException(name)).SetValue(null, 0u);
66 (typeof(NativeGpuFirmware).GetField("_tablePhysical", binding) ?? throw new MissingFieldException()).SetValue(null, 0UL);
64 67 }
65 68 // Independent table-driven IEEE CRC32 fixture generator. Production parsers
66 69 // remain linked verbatim and never generate their own expected checksum.
Modified Tools/IndependentKernel/GpuFirmwareChecks/Program.cs +24 -0
@@ -37,6 +37,30 @@ internal static unsafe class Program
37 37 Check(live.Bar0.SizeSource == GpuHardwareBridge.SourceFirmware && (live.Bar0.Flags & GpuHardwareBridge.SizeKnown) != 0, "source and known-size flags reflect actual producer");
38 38 Check(Serial.Text.ToString().Contains("|Valid|1|Count|1|ResourceOnly|1|Cuda|0|GpuRasterization|0", StringComparison.Ordinal), "production diagnostic remains resource-only");
39 39 Check(live.Bar1.Size == 0 && live.Bar2.Size == 0, "no unsupported aperture size invented");
40 Check(NativeGpuFirmware.Diagnostic(0) == 1 && NativeGpuFirmware.Diagnostic(1) == 11, "accepted handoff has a versioned diagnostic");
41 Check(NativeGpuFirmware.Diagnostic(2) == 1 && NativeGpuFirmware.Diagnostic(3) == FirmwareFixture.PhysicalBase, "handoff count and physical address are value-only");
42 Check(NativeGpuFirmware.Diagnostic(4) == 5 && NativeGpuFirmware.Diagnostic(5) == 5, "exact identity and BAR0 application reported");
43 });
44 foreach ((string name, uint stage, Action<FirmwareFixture> mutate) in new (string, uint, Action<FirmwareFixture>)[]
45 {
46 ("SystemMapping", 2, fixture => fixture.Maps[0].Kind = 0),
47 ("SystemCrc", 4, fixture => *(uint*)(fixture.SystemTable + 16) ^= 1),
48 ("ArrayMapping", 6, fixture => fixture.Maps[0].Length = 4096),
49 ("MissingGuid", 7, fixture => FirmwareFixture.U64(fixture.ConfigArray, 0, 0)),
50 ("ReportMapping", 9, fixture => fixture.Maps[0].Length = 8192),
51 ("ReportCrc", 10, fixture => fixture.Report->Checksum ^= 1)
52 }) Run("DiagnosticSeparates-" + name, fixture =>
53 {
54 mutate(fixture); ExpectNoSize(fixture, true);
55 Check(NativeGpuFirmware.Diagnostic(1) == stage, "first failing handoff stage preserved");
56 Check(NativeGpuFirmware.Diagnostic(4) == 1, "no accepted handoff cannot be a device match");
57 Check(NativeGpuFirmware.Diagnostic(5) == 0, "no accepted handoff cannot apply BAR0");
58 });
59 Run("DiagnosticDistinguishesEmptyDescriptorFromMissingTable", fixture =>
60 {
61 *fixture.Bar0 = default; fixture.FixReportCrc(); ExpectNoSize(fixture, false);
62 Check(NativeGpuFirmware.Diagnostic(1) == 11 && NativeGpuFirmware.Diagnostic(4) == 5, "firmware table and exact device accepted");
63 Check(NativeGpuFirmware.Diagnostic(5) == 1, "BAR0 descriptor is absent/rejected in producer, not a fabricated zero-size aperture");
40 64 });
41 65 Reject("SystemTableWrongCrc", fixture => *(uint*)(fixture.SystemTable + 16) ^= 1);
42 66 Reject("SystemTableWrongSignature", fixture => { *(ulong*)fixture.SystemTable ^= 1; fixture.FixSystemCrc(); });
Modified Tools/IndependentKernel/Open.ps1 +1 -1
Modified Tools/IndependentKernel/TestBoot.py +1 -1
Added docs/Rtx5090PhysicalReport20261017.md +63 -0
Added docs/validation-results/Rtx5090PhysicalReport20261017.json +152 -0