2024-06-17 12:37:11 +08:00
|
|
|
#include "gpu.h"
|
|
|
|
|
#include "common/properties.h"
|
|
|
|
|
#include "common/io/io.h"
|
2024-06-18 21:51:58 +08:00
|
|
|
#include "common/processing.h"
|
2024-06-17 12:37:11 +08:00
|
|
|
|
|
|
|
|
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
|
|
|
|
{
|
2024-06-18 21:51:58 +08:00
|
|
|
// SunOS requires root permission to query PCI device list, except `/usr/bin/scanpci`
|
|
|
|
|
// Same behavior can be observed with `cp $(which scanpci) /tmp/ && /tmp/scanpci`
|
2024-06-17 12:37:11 +08:00
|
|
|
|
2024-06-18 21:51:58 +08:00
|
|
|
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
|
|
|
|
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
|
|
|
|
|
"scanpci",
|
|
|
|
|
"-v",
|
|
|
|
|
NULL,
|
|
|
|
|
});
|
|
|
|
|
if (error)
|
|
|
|
|
return error;
|
|
|
|
|
|
2024-06-21 23:29:08 +08:00
|
|
|
if (!ffStrbufStartsWithS(&buffer, "\npci "))
|
2024-06-18 21:51:58 +08:00
|
|
|
return "Invalid scanpci result";
|
2024-06-17 12:37:11 +08:00
|
|
|
|
|
|
|
|
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
|
2024-06-18 21:51:58 +08:00
|
|
|
|
2024-06-21 23:29:08 +08:00
|
|
|
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
|
2024-06-18 21:51:58 +08:00
|
|
|
// Device unknown
|
|
|
|
|
// CardVendor 0x0000 card 0x0000 (Card unknown)
|
|
|
|
|
// STATUS 0x0010 COMMAND 0x0007
|
|
|
|
|
// CLASS 0x03 0x02 0x00 REVISION 0x00
|
|
|
|
|
// BIST 0x00 HEADER 0x00 LATENCY 0x00 CACHE 0x00
|
|
|
|
|
// MAX_LAT 0x00 MIN_GNT 0x00 INT_PIN 0x00 INT_LINE 0x00
|
|
|
|
|
|
|
|
|
|
for (
|
|
|
|
|
const char* pclass = strstr(buffer.chars, "\n CLASS 0x03 ");
|
|
|
|
|
pclass;
|
|
|
|
|
pclass = strstr(pclass, "\n CLASS 0x03 ")
|
|
|
|
|
)
|
2024-06-17 12:37:11 +08:00
|
|
|
{
|
2024-06-18 21:51:58 +08:00
|
|
|
// find the start of device entry
|
|
|
|
|
const char* pstart = memrchr(buffer.chars, '\n', (size_t) (pclass - buffer.chars));
|
|
|
|
|
while (pstart[1] != 'p')
|
|
|
|
|
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
|
|
|
|
|
++pstart;
|
|
|
|
|
|
2024-06-21 23:29:08 +08:00
|
|
|
uint32_t vendorId, deviceId;
|
|
|
|
|
if (sscanf(pstart, "pci %*[^:]: vendor %x device %x",
|
|
|
|
|
&vendorId, &deviceId) != 2)
|
2024-06-18 21:51:58 +08:00
|
|
|
return "PCI info not found, invalid scanpci result";
|
|
|
|
|
|
|
|
|
|
pclass += strlen("\n CLASS 0x03 ");
|
|
|
|
|
uint32_t subclass = (uint32_t) strtoul(pclass, NULL, 16);
|
|
|
|
|
pclass += strlen("0x02 0x00 REVISION ");
|
|
|
|
|
uint32_t revision = (uint32_t) strtoul(pclass, NULL, 16);
|
2024-06-17 12:37:11 +08:00
|
|
|
|
|
|
|
|
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
2024-06-18 21:51:58 +08:00
|
|
|
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
2024-06-17 12:37:11 +08:00
|
|
|
ffStrbufInit(&gpu->name);
|
|
|
|
|
ffStrbufInit(&gpu->driver);
|
|
|
|
|
ffStrbufInit(&gpu->platformApi);
|
|
|
|
|
gpu->temperature = FF_GPU_TEMP_UNSET;
|
|
|
|
|
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
|
|
|
|
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
|
|
|
|
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
2024-06-21 23:29:08 +08:00
|
|
|
gpu->deviceId = 0;
|
2024-06-17 12:37:11 +08:00
|
|
|
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
|
|
|
|
|
|
|
|
|
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
|
|
|
|
|
{
|
|
|
|
|
char query[32];
|
2024-06-18 21:51:58 +08:00
|
|
|
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
|
2024-06-17 12:37:11 +08:00
|
|
|
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gpu->name.length == 0)
|
|
|
|
|
{
|
|
|
|
|
if (pciids.length == 0)
|
2024-06-18 21:51:58 +08:00
|
|
|
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
|
|
|
|
|
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
2024-06-17 12:37:11 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|