namespace XFESystem.Boot;
public static unsafe partial class EfiEntry
{
// EFI PCI I/O protocol layout and signatures follow UEFI/EDK II PciIo.h
// (edk2-stable202608, BSD-2-Clause-Patent). Only read/query calls are used.
static void PublishGpuResources(BootServices* boot)
{
FirmwareGpuHandoff* report = (FirmwareGpuHandoff*)Allocate(boot, FirmwareGpuHandoff.TotalBytes, 6);
if (report == null) return;
Zero((byte*)report, FirmwareGpuHandoff.TotalBytes);
report->Magic = FirmwareGpuHandoff.Signature; report->Version = 1; report->Bytes = FirmwareGpuHandoff.TotalBytes;
nuint count; void** handles = Handles(boot, PciGuid(), &count);
if (handles != null)
{
uint* config = stackalloc uint[16];
for (nuint i = 0; i < count && report->Count < FirmwareGpuHandoff.MaximumDevices; i++)
{
ulong* pci = (ulong*)Protocol(boot, handles[i], PciGuid());
if (pci == null || pci[6] == 0 || pci[14] == 0 || pci[16] == 0) continue;
for (uint d = 0; d < 16; d++) config[d] = 0;
if (((delegate* unmanaged<void*, uint, uint, nuint, void*, nuint>)pci[6])(pci, 2, 0, 16, config) != 0 ||
(config[0] & 65535) != 0x10de || (config[2] >> 24) != 3 || ((config[3] >> 16) & 127) != 0) continue;
nuint segment = 0, bus = 0, device = 0, function = 0;
if (((delegate* unmanaged<void*, nuint*, nuint*, nuint*, nuint*, nuint>)pci[14])
(pci, &segment, &bus, &device, &function) != 0 || segment > 65535 || bus > 255 || device > 31 || function > 7) continue;
FirmwareGpuDevice* item = (FirmwareGpuDevice*)(report->Devices + report->Count * FirmwareGpuHandoff.DeviceBytes);
item->Segment = (uint)segment; item->Bus = (uint)bus; item->Device = (uint)device; item->Function = (uint)function;
item->VendorId = config[0] & 65535; item->DeviceId = config[0] >> 16;
item->ClassCode = config[2] >> 8; item->Command = config[1] & 65535;
for (uint bar = 0; bar < 6; bar++)
{
uint low = config[4 + bar], high = bar < 5 ? config[5 + bar] : 0;
void* resources = null; ulong supports = 0;
nuint status = ((delegate* unmanaged<void*, byte, ulong*, void**, nuint>)pci[16])(pci, (byte)bar, &supports, &resources);
if (status == 0 && resources != null)
{
FirmwareGpuResources.DecodeBarDescriptor((byte*)resources, 48, bar, low, high,
(FirmwareGpuBar*)(item->Bars + bar * 24));
Free(boot, resources);
}
// An error does not transfer buffer ownership. EDK II can
// free an allocated descriptor before returning failure.
if ((low & 7) == 4) bar++; // The upper DWORD is not another BAR.
}
report->Count++;
}
Free(boot, handles);
}
report->Checksum = FirmwareGpuResources.Checksum((byte*)report, FirmwareGpuHandoff.TotalBytes);
Guid id = new Guid(FirmwareGpuHandoff.GuidLow, FirmwareGpuHandoff.GuidHigh);
if (((delegate* unmanaged<Guid*, void*, nuint>)boot->Functions[21])(&id, report) != 0) Free(boot, report);
}
}
namespace XFESystem.Boot;
public static unsafe partial class EfiEntry
{
// EFI PCI I/O protocol layout and signatures follow UEFI/EDK II PciIo.h
// (edk2-stable202608, BSD-2-Clause-Patent). Only read/query calls are used.
static void PublishGpuResources(BootServices* boot)
{
FirmwareGpuHandoff* report = (FirmwareGpuHandoff*)Allocate(boot, FirmwareGpuHandoff.TotalBytes, 6);
if (report == null) return;
Zero((byte*)report, FirmwareGpuHandoff.TotalBytes);
report->Magic = FirmwareGpuHandoff.Signature; report->Version = 1; report->Bytes = FirmwareGpuHandoff.TotalBytes;
nuint count; void** handles = Handles(boot, PciGuid(), &count);
if (handles != null)
{
uint* config = stackalloc uint[16];
for (nuint i = 0; i < count && report->Count < FirmwareGpuHandoff.MaximumDevices; i++)
{
ulong* pci = (ulong*)Protocol(boot, handles[i], PciGuid());
if (pci == null || pci[6] == 0 || pci[14] == 0 || pci[16] == 0) continue;
for (uint d = 0; d < 16; d++) config[d] = 0;
if (((delegate* unmanaged<void*, uint, uint, nuint, void*, nuint>)pci[6])(pci, 2, 0, 16, config) != 0 ||
(config[0] & 65535) != 0x10de || (config[2] >> 24) != 3 || ((config[3] >> 16) & 127) != 0) continue;
nuint segment = 0, bus = 0, device = 0, function = 0;
if (((delegate* unmanaged<void*, nuint*, nuint*, nuint*, nuint*, nuint>)pci[14])
(pci, &segment, &bus, &device, &function) != 0 || segment > 65535 || bus > 255 || device > 31 || function > 7) continue;
FirmwareGpuDevice* item = (FirmwareGpuDevice*)(report->Devices + report->Count * FirmwareGpuHandoff.DeviceBytes);
item->Segment = (uint)segment; item->Bus = (uint)bus; item->Device = (uint)device; item->Function = (uint)function;
item->VendorId = config[0] & 65535; item->DeviceId = config[0] >> 16;
item->ClassCode = config[2] >> 8; item->Command = config[1] & 65535;
for (uint bar = 0; bar < 6; bar++)
{
uint low = config[4 + bar], high = bar < 5 ? config[5 + bar] : 0;
void* resources = null; ulong supports = 0;
nuint status = ((delegate* unmanaged<void*, byte, ulong*, void**, nuint>)pci[16])(pci, (byte)bar, &supports, &resources);
if (status == 0 && resources != null)
{
FirmwareGpuResources.DecodeBarDescriptor((byte*)resources, 48, bar, low, high,
(FirmwareGpuBar*)(item->Bars + bar * 24));
Free(boot, resources);
}
// An error does not transfer buffer ownership. EDK II can
// free an allocated descriptor before returning failure.
if ((low & 7) == 4) bar++; // The upper DWORD is not another BAR.
}
report->Count++;
}
Free(boot, handles);
}
report->Checksum = FirmwareGpuResources.Checksum((byte*)report, FirmwareGpuHandoff.TotalBytes);
Guid id = new Guid(FirmwareGpuHandoff.GuidLow, FirmwareGpuHandoff.GuidHigh);
if (((delegate* unmanaged<Guid*, void*, nuint>)boot->Functions[21])(&id, report) != 0) Free(boot, report);
}
}