Skip to content

Commit ca04999

Browse files
committed
GPU (SunOS): rework GPU detection
1 parent a9f021c commit ca04999

File tree

1 file changed

+49
-72
lines changed

1 file changed

+49
-72
lines changed

src/detection/gpu/gpu_sunos.c

Lines changed: 49 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,60 @@
11
#include "gpu.h"
2-
#include "common/io/io.h"
3-
#include "common/processing.h"
2+
#include "util/stringUtils.h"
43

5-
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
6-
{
7-
// SunOS requires root permission to query PCI device list, except `/usr/bin/scanpci`
8-
// Same behavior can be observed with `cp $(which scanpci) /tmp/ && /tmp/scanpci`
9-
10-
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
11-
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
12-
"/usr/bin/scanpci",
13-
"-v",
14-
NULL,
15-
});
16-
if (error)
17-
return error;
18-
19-
if (!ffStrbufStartsWithS(&buffer, "\npci "))
20-
return "Invalid scanpci result";
4+
#include <libdevinfo.h>
215

22-
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
23-
// Device unknown
24-
// CardVendor 0x0000 card 0x0000 (Card unknown)
25-
// STATUS 0x0010 COMMAND 0x0007
26-
// CLASS 0x03 0x02 0x00 REVISION 0x00
27-
// BIST 0x00 HEADER 0x00 LATENCY 0x00 CACHE 0x00
28-
// MAX_LAT 0x00 MIN_GNT 0x00 INT_PIN 0x00 INT_LINE 0x00
29-
30-
for (
31-
const char* pclass = strstr(buffer.chars, "\n CLASS 0x03 ");
32-
pclass;
33-
pclass = strstr(pclass, "\n CLASS 0x03 ")
34-
)
6+
static int walkDevTree(di_node_t node, FFlist* gpus)
7+
{
8+
if (ffStrEquals(di_node_name(node), "display"))
359
{
36-
// find the start of device entry
37-
const char* pstart = memrchr(buffer.chars, '\n', (size_t) (pclass - buffer.chars));
38-
if (pstart == NULL)
39-
return "PCI info not found, invalid scanpci result";
40-
while (pstart[1] != 'p')
10+
int* vendorId;
11+
int* deviceId;
12+
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "vendor-id", &vendorId) > 0
13+
&& di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-id", &deviceId) > 0)
4114
{
42-
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
43-
if (pstart == NULL)
44-
return "PCI info not found, invalid scanpci result";
15+
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
16+
ffStrbufInitS(&gpu->vendor, ffGPUGetVendorString((uint16_t) *vendorId));
17+
ffStrbufInit(&gpu->name);
18+
ffStrbufInitS(&gpu->driver, di_driver_name(node));
19+
ffStrbufInitStatic(&gpu->platformApi, "libdevinfo");
20+
ffStrbufInit(&gpu->memoryType);
21+
gpu->index = FF_GPU_INDEX_UNSET;
22+
gpu->temperature = FF_GPU_TEMP_UNSET;
23+
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
24+
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
25+
gpu->type = FF_GPU_TYPE_UNKNOWN;
26+
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
27+
gpu->deviceId = strtoul(di_bus_addr(node), NULL, 16);
28+
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
29+
30+
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
31+
{
32+
int* revId;
33+
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "revision-id", &revId) > 0)
34+
ffGPUQueryAmdGpuName((uint16_t) *deviceId, (uint8_t) *revId, gpu);
35+
}
36+
37+
if (gpu->name.length == 0)
38+
{
39+
uint8_t subclass = 0; // assume VGA
40+
int* classCode;
41+
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "class-code", &classCode) > 0)
42+
subclass = (uint8_t) (*classCode & 0xFFFF);
43+
ffGPUFillVendorAndName(subclass, (uint16_t) *vendorId, (uint16_t) *deviceId, gpu);
44+
}
4545
}
46-
++pstart;
47-
48-
uint32_t vendorId, deviceId;
49-
if (sscanf(pstart, "pci %*[^:]: vendor %x device %x",
50-
&vendorId, &deviceId) != 2)
51-
return "PCI info not found, invalid scanpci result";
52-
53-
pclass += strlen("\n CLASS 0x03 ");
54-
uint32_t subclass = (uint32_t) strtoul(pclass, NULL, 16);
55-
pclass += strlen("0x02 0x00 REVISION ");
56-
uint32_t revision = (uint32_t) strtoul(pclass, NULL, 16);
57-
58-
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
59-
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
60-
ffStrbufInit(&gpu->memoryType);
61-
ffStrbufInit(&gpu->name);
62-
ffStrbufInit(&gpu->driver);
63-
ffStrbufInitStatic(&gpu->platformApi, "/usr/bin/scanpci");
64-
gpu->index = FF_GPU_INDEX_UNSET;
65-
gpu->temperature = FF_GPU_TEMP_UNSET;
66-
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
67-
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
68-
gpu->type = FF_GPU_TYPE_UNKNOWN;
69-
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
70-
gpu->deviceId = 0;
71-
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
46+
}
7247

73-
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
74-
ffGPUQueryAmdGpuName((uint16_t) deviceId, (uint8_t) revision, gpu);
48+
return DI_WALK_CONTINUE;
49+
}
7550

76-
if (gpu->name.length == 0)
77-
{
78-
ffGPUFillVendorAndName((uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
79-
}
80-
}
51+
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
52+
{
53+
di_node_t rootNode = di_init("/", DINFOCPYALL);
54+
if (rootNode == DI_NODE_NIL)
55+
return "di_init() failed";
56+
di_walk_node(rootNode, DI_WALK_CLDFIRST, gpus, (void*) walkDevTree);
57+
di_fini(rootNode);
8158

8259
return NULL;
8360
}

0 commit comments

Comments
 (0)