Skip to content

Commit 2e73a90

Browse files
committed
GPU (OpenBSD): adds native GPU detection support
1 parent cc6273f commit 2e73a90

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ elseif(OpenBSD)
878878
src/detection/displayserver/linux/xlib.c
879879
src/detection/font/font_linux.c
880880
src/detection/gpu/gpu_pci.c
881-
src/detection/gpu/gpu_general.c
881+
src/detection/gpu/gpu_obsd.c
882882
src/detection/gtk_qt/gtk.c
883883
src/detection/host/host_obsd.c
884884
src/detection/lm/lm_nosupport.c

src/detection/gpu/gpu_obsd.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include "gpu.h"
2+
#include "common/io/io.h"
3+
4+
#include <sys/param.h>
5+
#include <sys/ioctl.h>
6+
#include <fcntl.h>
7+
#include <dev/pci/pcireg.h>
8+
#include <dev/pci/pcidevs.h>
9+
#include <sys/pciio.h>
10+
11+
static inline int pciReadConf(int fd, uint32_t bus, uint32_t device, uint32_t func, uint32_t reg, uint32_t* result)
12+
{
13+
struct pci_io bdfr = {
14+
.pi_sel = {
15+
.pc_bus = bus,
16+
.pc_dev = device,
17+
.pc_func = func,
18+
},
19+
.pi_reg = reg,
20+
.pi_width = 4,
21+
};
22+
23+
if (ioctl(fd, PCIOCREAD, &bdfr) == -1)
24+
return -1;
25+
26+
*result = bdfr.pi_data;
27+
return 0;
28+
}
29+
30+
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
31+
{
32+
char pciDevPath[] = "/dev/pci0";
33+
FF_AUTO_CLOSE_FD int pcifd = open(pciDevPath, O_RDONLY | O_CLOEXEC);
34+
if (pcifd < 0)
35+
return "open(\"/dev/pci0\", O_RDONLY | O_CLOEXEC) failed";
36+
37+
for (uint32_t bus = 0; bus <= 255; bus++)
38+
{
39+
for (uint32_t dev = 0; dev < 32; dev++)
40+
{
41+
uint32_t maxfuncs = 0;
42+
for (uint32_t func = 0; func <= maxfuncs; func++)
43+
{
44+
uint32_t pciid, pciclass;
45+
if (pciReadConf(pcifd, bus, dev, func, PCI_ID_REG, &pciid) != 0)
46+
continue;
47+
48+
if (PCI_VENDOR(pciid) == PCI_VENDOR_INVALID || PCI_VENDOR(pciid) == 0)
49+
continue;
50+
51+
if (pciReadConf(pcifd, bus, dev, func, PCI_CLASS_REG, &pciclass) != 0)
52+
continue;
53+
54+
if (func == 0)
55+
{
56+
// For some reason, pciReadConf returns success even for non-existing devices.
57+
// So we need to check for `PCI_VENDOR(pciid) == PCI_VENDOR_INVALID` above to filter them out.
58+
uint32_t bhlcr;
59+
if (pciReadConf(pcifd, bus, dev, 0, PCI_BHLC_REG, &bhlcr) != 0)
60+
continue;
61+
62+
if (PCI_HDRTYPE_MULTIFN(bhlcr)) maxfuncs = 7;
63+
}
64+
65+
if (PCI_CLASS(pciclass) != PCI_CLASS_DISPLAY)
66+
continue;
67+
68+
if (func > 0 && PCI_SUBCLASS(pciclass) == PCI_SUBCLASS_DISPLAY_MISC)
69+
continue; // Likely an auxiliary display controller (#2034)
70+
71+
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
72+
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(PCI_VENDOR(pciid)));
73+
ffStrbufInit(&gpu->name);
74+
ffStrbufInit(&gpu->driver);
75+
ffStrbufInitS(&gpu->platformApi, "/dev/pci0");
76+
ffStrbufInit(&gpu->memoryType);
77+
gpu->index = FF_GPU_INDEX_UNSET;
78+
gpu->temperature = FF_GPU_TEMP_UNSET;
79+
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
80+
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
81+
gpu->type = FF_GPU_TYPE_UNKNOWN;
82+
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
83+
gpu->deviceId = ffGPUPciAddr2Id(0, bus, dev, func);
84+
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
85+
86+
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
87+
ffGPUQueryAmdGpuName(PCI_PRODUCT(pciid), PCI_REVISION(pciid), gpu);
88+
if (gpu->name.length == 0)
89+
ffGPUFillVendorAndName(PCI_SUBCLASS(pciclass), PCI_VENDOR(pciid), PCI_PRODUCT(pciid), gpu);
90+
}
91+
}
92+
}
93+
94+
return NULL;
95+
}

0 commit comments

Comments
 (0)