返回提交历史
Modified
AGENTS.md
+4
-0
Modified
Source/XFESystem.NativeKernel/GpuHardwareBridge.cs
+3
-1
Modified
Source/XFESystem.NativeKernel/NativeGpuFirmware.cs
+46
-5
Modified
Source/XFESystem.NativeKernel/NvidiaBootProbe.cs
+29
-14
Modified
Source/XFESystem.NativeRuntime/Application/NativeGpuDiagnostics.cs
+1
-37
Added
Source/XFESystem.NativeRuntime/Application/NativeGpuReportFormatter.cs
+96
-0
Modified
Source/XFESystem.NativeRuntime/ConsoleApplication/ConsoleApplication.csproj
+1
-0
Added
Tests/XFESystem.Platform.Tests/NativeGpuReportTests.cs
+73
-0
Modified
Tools/IndependentKernel/GpuDiscoveryChecks/HardwareNotInvoked.cs
+1
-0
Modified
Tools/IndependentKernel/GpuDiscoveryChecks/ProbeGeometryChecks.cs
+7
-0
Modified
Tools/IndependentKernel/GpuFirmwareChecks/FirmwareFixture.cs
+3
-0
Modified
Tools/IndependentKernel/GpuFirmwareChecks/Program.cs
+24
-0
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
XFEstudio/XFESystem
Explain RTX 5090 resource rejection and distinguish unread FSP status
b430f86
代码差异
16 个文件
+505
-59
@@ -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 项宿主/原生验收证据未改变,本轮未重跑完整应用验收。
@@ -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
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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" />
@@ -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
}
@@ -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
{
@@ -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);
@@ -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.
@@ -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(); });