From: Jani Nikula <jani.nikula@intel.com>
To: Mauro Carvalho Chehab <mauro.chehab@linux.intel.com>,
igt-dev@lists.freedesktop.org
Cc: kamil.konieczny@intel.com, katarzyna.piecielska@intel.com
Subject: Re: [PATCH i-g-t v4] tools/mk_detect_intel_gpu: add a tool to detect Intel GPUs from their PCI IDs
Date: Wed, 22 May 2024 15:54:10 +0300 [thread overview]
Message-ID: <87a5kiqa6l.fsf@intel.com> (raw)
In-Reply-To: <20240522120240.48463-1-mauro.chehab@linux.intel.com>
On Wed, 22 May 2024, Mauro Carvalho Chehab <mauro.chehab@linux.intel.com> wrote:
> From: Mauro Carvalho Chehab <mchehab@kernel.org>
>
> Such tool parses the Kernel drivers for both i915 and Xe and
> generates a script that helps detecting Intel GPU models.
I acknowledge the usefulness of such a tool, but to be brutally honest,
this implementation is horrible in so many levels.
IGT uses meson and avoids perl.
This has a makefile with perl to generate a header that's included in a
C program that is built and executed to generate a perl script that's
then the tool, and the generated perl script runs lspci(8).
I think there's really only one reasonable way to implement this in the
IGT context, and that's pure C, leveraging all the stuff in IGT, using
the PCI IDs listed in the IGT repo.
Or you can turn this into a separate pet project, because what you have
here does not fit IGT.
The i915_pciids.h parsing below is already stale, and you really can't
expect to get this merged and be kept up-to-date by folks updating
i915_pciids.h. IMO it's not maintainable.
BR,
Jani.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
> ---
> tools/mk_detect_intel_gpu/Makefile | 57 ++++++++
> tools/mk_detect_intel_gpu/get_gpu.c | 216 ++++++++++++++++++++++++++++
> 2 files changed, 273 insertions(+)
> create mode 100644 tools/mk_detect_intel_gpu/Makefile
> create mode 100644 tools/mk_detect_intel_gpu/get_gpu.c
>
> diff --git a/tools/mk_detect_intel_gpu/Makefile b/tools/mk_detect_intel_gpu/Makefile
> new file mode 100644
> index 000000000000..ea24307ce19c
> --- /dev/null
> +++ b/tools/mk_detect_intel_gpu/Makefile
> @@ -0,0 +1,57 @@
> +# SPDX-License-Identifier: MIT
> +#
> +# Copyright © 2022-2024 Intel Corporation
> +# Author: Mauro Carvalho Chehab <mchehab@kernel.org>
> +#
> +# Usage: specify either:
> +# make KERNEL_DIR=<directory to copy files for both i915 and Xe Intel drivers>
> +# or:
> +# make XE_DIR=<directory to copy files for Xe Intel driver> I915_DIR=<directory to copy files for i915 Intel driver>
> +
> +XE_DIR :=
> +I915_DIR :=
> +
> +all: intel_detect_gpu.pl
> +
> +clean:
> + rm i915_pciids.h i915_id.h xe_pciids.h xe_pci.c get_gpu intel_detect_gpu.pl
> +
> +ifneq ($(KERNEL_DIR),)
> + XE_DIR := $(KERNEL_DIR)
> + I915_DIR := $(KERNEL_DIR)
> +endif
> +
> +ifeq ($(XE_DIR),)
> + $(error Need a directory with the XE driver)
> +endif
> +
> +ifeq ($(I915_DIR),)
> + $(error Need a directory with the i915 driver)
> +endif
> +
> +intel_detect_gpu.pl: get_gpu
> + ./get_gpu >intel_detect_gpu.pl
> + chmod 755 intel_detect_gpu.pl
> +
> +i915_pciids.h:
> + cp ${I915_DIR}/include/drm/i915_pciids.h .
> + sed s,"(unsigned long) info }","info }", -i i915_pciids.h
> +
> +xe_pci_ids.h:
> + cp ${XE_DIR}/include/drm/xe_pciids.h .
> +
> +xe_pci.c:
> + cp ${XE_DIR}/drivers/gpu/drm/xe/xe_pci.c .
> +
> +i915_id.h: i915_pciids.h xe_pci.c
> + echo "static struct pci_device_id pci_ids[] = {" > i915_id.h
> + tac i915_pciids.h |grep define|perl -ne 'if (/define\s+INTEL_(\w+)_IDS/) { print "\tINTEL_$$1_IDS(\"$$1\"),\n" }' >> i915_id.h
> +
> + cat xe_pci.c|perl -ne 'if (m/(XE_)([\w_]+)(_IDS\(INTEL_VGA_DEVICE)/) { print "\t$$1$$2$$3, \"$$2\"),\n"}' >> i915_id.h
> +
> + echo "};" >> i915_id.h
> +
> +get_gpu: get_gpu.c i915_id.h i915_pciids.h xe_pci_ids.h
> + gcc -g -Wall get_gpu.c -o get_gpu
> +
> +.PHONY: i915_id.h i915_pciids.h
> diff --git a/tools/mk_detect_intel_gpu/get_gpu.c b/tools/mk_detect_intel_gpu/get_gpu.c
> new file mode 100644
> index 000000000000..44fee08d398b
> --- /dev/null
> +++ b/tools/mk_detect_intel_gpu/get_gpu.c
> @@ -0,0 +1,216 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2022-2024 Intel Corporation
> + * Author: Mauro Carvalho Chehab <mchehab@kernel.org>
> + */
> +
> +
> +#include "i915_pciids.h"
> +#include "xe_pciids.h"
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +
> +struct pci_device_id {
> + unsigned int vendor, device;
> + unsigned int subvendor, subdevice;
> + unsigned int class, class_mask;
> + char *name;
> +};
> +
> +#include "i915_id.h"
> +
> +#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(*arr)
> +
> +#define TGL "TGL_12"
> +
> +int cmpfunc (const void *_a, const void *_b) {
> + int ret;
> +
> + const struct pci_device_id *a = _a;
> + const struct pci_device_id *b = _b;
> +
> + ret = strcmp(a->name, b->name);
> + if (ret)
> + return ret;
> +
> + ret = a->vendor - b->vendor;
> + if (ret)
> + return ret;
> +
> + ret = a->device - b->device;
> + if (ret)
> + return ret;
> +
> + ret = a->subvendor - b->subvendor;
> + if (ret)
> + return ret;
> +
> + ret = a->subdevice - b->subdevice;
> + if (ret)
> + return ret;
> +
> + ret = a->class - b->class;
> + if (ret)
> + return ret;
> +
> + ret = a->class_mask - b->class_mask;
> +
> + return ret;
> +}
> +
> +
> +int main(void)
> +{
> + int i;
> + int shown[0x10000] = { [0 ... 0xffff] = -1 };
> + int ignore[ARRAY_SIZE(pci_ids)] = { 0 };
> + int other[ARRAY_SIZE(pci_ids)] = { [0 ... ARRAY_SIZE(pci_ids) - 1] = -1 };
> + char last[80] = "";
> +
> + printf("#!/usr/bin/perl\n\n");
> + printf("$ENV{'LC_ALL'} = 'C';\n\n");
> +
> + qsort(pci_ids, ARRAY_SIZE(pci_ids), sizeof(*pci_ids), cmpfunc);
> +
> + /*
> + * Step 1: Handle non-subvendor specific devices, discovering duplicates
> + */
> + for (i = 0; i < ARRAY_SIZE(pci_ids); i++) {
> + if (pci_ids[i].subvendor != (unsigned int)-1)
> + continue;
> +
> + if (!strncmp(pci_ids[i].name, TGL, strlen(TGL))) {
> + char *tmp = strdup(pci_ids[i].name);
> + pci_ids[i].name = tmp;
> + strcpy(pci_ids[i].name + 3, tmp + strlen(TGL));
> + }
> +
> + if (shown[pci_ids[i].device] >= 0) {
> + ignore[i] = i;
> +
> + // If it is duplicated, just ignore it
> + if (!cmpfunc(&pci_ids[i], &pci_ids[shown[pci_ids[i].device]]))
> + continue;
> +
> + fprintf(stderr, "PCI ID: %04x:%04x %s is a subtype of %s\n",
> + pci_ids[i].vendor, pci_ids[i].device,
> + pci_ids[i].name,
> + pci_ids[shown[pci_ids[i].device]].name);
> +
> + other[shown[pci_ids[i].device]] = i;
> + continue;
> + }
> + shown[pci_ids[i].device] = i;
> +
> + if (pci_ids[i].device == 0x56c0)
> + pci_ids[i].name = "ATS_M1";
> +
> + if (pci_ids[i].device == 0x56c1)
> + pci_ids[i].name = "ATS_M3";
> +
> + fprintf(stderr, "Adding: %s: vendor: %04x:%04x\n",
> + pci_ids[i].name,
> + pci_ids[i].vendor, pci_ids[i].device);
> + }
> +
> + /*
> + * Step 2: output array with all other devices
> + */
> + printf("my %%intel_pci_id = (");
> +
> + for (i = 0; i < ARRAY_SIZE(pci_ids); i++) {
> + if (ignore[i] > 0)
> + continue;
> +
> + if (strcmp(last, pci_ids[i].name)) {
> + strcpy(last, pci_ids[i].name);
> + printf("\n");
> + }
> +
> + printf("\t\"%04x:%04x\" => \"%s\",\n",
> + pci_ids[i].vendor, pci_ids[i].device,
> + pci_ids[i].name
> + );
> + }
> + printf(");\n\n");
> +
> + /*
> + * Step 3: output array with all other devices
> + */
> + printf("my %%intel_pci_id_alt_name = (");
> +
> + last[0] = '\0';
> + for (i = 0; i < ARRAY_SIZE(pci_ids); i++) {
> + if (ignore[i] > 0)
> + continue;
> +
> + if (other[i] < 0)
> + continue;
> +
> + if (strcmp(last, pci_ids[i].name)) {
> + strcpy(last, pci_ids[i].name);
> + printf("\n\t# %s alternative names\n", pci_ids[i].name);
> + }
> +
> + printf("\t\"%04x:%04x\" => \"%s\",\n",
> + pci_ids[i].vendor, pci_ids[i].device,
> + pci_ids[other[i]].name
> + );
> + }
> + printf(");\n\n");
> +
> + /*
> + * Step 4: output array for devices with subvendor/subdevice
> + */
> + printf("my %%intel_pci_subvendor_id = (\n");
> +
> + for (i = 0; i < ARRAY_SIZE(pci_ids); i++) {
> + if (pci_ids[i].subvendor == (unsigned int) -1)
> + continue;
> +
> + fprintf(stderr, "Adding: %s: vendor: %04x:%04x, subvendor: %04x:%04x\n",
> + pci_ids[i].name,
> + pci_ids[i].vendor, pci_ids[i].device,
> + pci_ids[i].subvendor, pci_ids[i].subdevice);
> +
> + printf("\t\"%04x:%04x %04x:%04x\" => \"%s\",\n",
> + pci_ids[i].vendor, pci_ids[i].device,
> + pci_ids[i].subvendor, pci_ids[i].subdevice,
> + pci_ids[i].name
> + );
> +
> + ignore[i] = 1;
> + }
> + printf(");\n\n");
> +
> + printf("sub fix_id($) {\n");
> + printf("\tmy $id = shift;\n");
> + printf("\t$id = $intel_pci_id{$id} if defined($intel_pci_id{$id});\n");
> + printf("\treturn $id;\n}\n\n");
> + printf("my @gpus;\n");
> + printf("my $id;\n\n");
> + printf("open IN, \"lspci -nm|\";\n");
> + printf("while (<IN>) {\n");
> + printf("\tif (m/\"(8086)\"\\s\"([\\da-f]+)\".*\"([^\\\"]*)\"\\s\"([^\\\"]*\")/) {\n");
> + printf("\t\tmy $pci_id_sub = \"$1:$2 $3:$4\";\n");
> + printf("\t\tmy $pci_id = \"$1:$2\";\n");
> + printf("\t\tif (defined($intel_pci_subvendor_id{$pci_id_sub})) {\n");
> + printf("\t\t\t$id = $intel_pci_subvendor_id{$pci_id};\n");
> + printf("\t\t} elsif (defined($intel_pci_id{$pci_id})) {\n");
> + printf("\t\t\t$id = $intel_pci_id{$pci_id};\n");
> + printf("\t\t}\n");
> + printf("\t\tif ($id) {\n");
> + printf("\t\t\tmy $subtype = \"\";\n");
> + printf("\t\t\t$subtype = \" (\" . $intel_pci_id_alt_name{$pci_id} .\")\" if defined($intel_pci_id_alt_name{$pci_id});\n");
> + printf("\t\t\tprint \"Detected GPU PCI device: $id$subtype, PCI ID: $pci_id\\n\";\n");
> + printf("\t\t\tundef($id);\n");
> + printf("\t\t\tpush @gpus, $id;\n\t\t}\n\t}\n}\n");
> + printf("close IN;\n\n");
> + printf("if (@gpus == 0) {\n");
> + printf("\tprint STDERR \"Warning: No Intel GPUs detected.\\n\";\n");
> + printf("} elsif (@gpus > 1) {\n");
> + printf("\tprint STDERR \"Warning: More than one Intel GPUs detected.\\n\";\n");
> + printf("}\n");
> +}
--
Jani Nikula, Intel
next prev parent reply other threads:[~2024-05-22 12:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-22 12:02 [PATCH i-g-t v4] tools/mk_detect_intel_gpu: add a tool to detect Intel GPUs from their PCI IDs Mauro Carvalho Chehab
2024-05-22 12:54 ` Jani Nikula [this message]
2024-05-22 13:26 ` Jani Nikula
2024-05-22 14:46 ` Kamil Konieczny
2024-05-23 5:03 ` Mauro Carvalho Chehab
2024-05-23 7:26 ` Jani Nikula
2024-05-23 7:30 ` Jani Nikula
2024-05-23 8:36 ` Mauro Carvalho Chehab
2024-05-23 9:10 ` Jani Nikula
2024-05-23 17:31 ` Kamil Konieczny
2024-05-24 8:49 ` Jani Nikula
2024-05-25 5:44 ` Mauro Carvalho Chehab
2024-06-03 7:35 ` Zbigniew Kempczyński
2024-06-04 8:05 ` Jani Nikula
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87a5kiqa6l.fsf@intel.com \
--to=jani.nikula@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=kamil.konieczny@intel.com \
--cc=katarzyna.piecielska@intel.com \
--cc=mauro.chehab@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox