All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dale B Stimson <dale.b.stimson@intel.com>
To: igt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible)
Date: Mon, 10 Feb 2020 16:46:11 -0800	[thread overview]
Message-ID: <2f2d74a2aa0bb1ab0050bdeb5a272ae9d7f61c69.1581381780.git.dale.b.stimson@intel.com> (raw)
In-Reply-To: <cover.1581381780.git.dale.b.stimson@intel.com>

Signed-off-by: Dale B Stimson <dale.b.stimson@intel.com>
---
 lib/Makefile.sources     |   2 +
 lib/i915/gem_mmio_base.c | 346 +++++++++++++++++++++++++++++++++++++++
 lib/i915/gem_mmio_base.h |  19 +++
 lib/igt.h                |   1 +
 lib/meson.build          |   1 +
 5 files changed, 369 insertions(+)
 create mode 100644 lib/i915/gem_mmio_base.c
 create mode 100644 lib/i915/gem_mmio_base.h

diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index 3e573f267..4c5d50d5d 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -7,6 +7,8 @@ lib_source_list =	 	\
 	i915/gem_context.h	\
 	i915/gem_engine_topology.c	\
 	i915/gem_engine_topology.h	\
+	i915/gem_mmio_base.c	\
+	i915/gem_mmio_base.h	\
 	i915/gem_scheduler.c	\
 	i915/gem_scheduler.h	\
 	i915/gem_submission.c	\
diff --git a/lib/i915/gem_mmio_base.c b/lib/i915/gem_mmio_base.c
new file mode 100644
index 000000000..8718c092f
--- /dev/null
+++ b/lib/i915/gem_mmio_base.c
@@ -0,0 +1,346 @@
+//  Copyright (C) 2020 Intel Corporation
+//
+//  SPDX-License-Identifier: MIT
+
+#include <ctype.h>
+
+#include <fcntl.h>
+
+#include "igt.h"
+
+struct eng_mmio_base_s {
+	char       name[8];
+	uint32_t   mmio_base;
+};
+
+struct eng_mmio_base_table_s {
+	unsigned int           mb_cnt;
+	struct eng_mmio_base_s mb_tab[GEM_MAX_ENGINES];
+};
+
+
+static struct eng_mmio_base_table_s *_gem_engine_mmio_info_dup(
+	const struct eng_mmio_base_table_s *mbpi)
+{
+	struct eng_mmio_base_table_s *mbpo;
+	size_t nbytes;
+
+	nbytes = offsetof(typeof(struct eng_mmio_base_table_s), mb_tab[mbpi->mb_cnt]);
+	mbpo = malloc(nbytes);
+	igt_assert(mbpo);
+	memcpy(mbpo, mbpi, nbytes);
+
+	return mbpo;
+}
+
+void gem_engine_mmio_base_info_free(struct eng_mmio_base_table_s *mbp)
+{
+	free(mbp);
+}
+
+static void _gem_engine_mmio_info_legacy_add(struct eng_mmio_base_table_s *mbp,
+	const char *eng_name, uint32_t mmio_base)
+{
+	if (mmio_base) {
+		strncpy(mbp->mb_tab[mbp->mb_cnt].name, eng_name,
+			sizeof(mbp->mb_tab[0].name));
+		mbp->mb_tab[mbp->mb_cnt].mmio_base = mmio_base;
+		mbp->mb_cnt++;
+	}
+}
+
+/**
+ * _gem_engine_mmio_base_info_get_legacy:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Provides per-engine mmio_base information from legacy built-in values
+ * for the case when the information is not otherwise available.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ */
+static struct eng_mmio_base_table_s *_gem_engine_mmio_base_info_get_legacy(int fd_dev)
+{
+	int gen;
+	uint32_t mmio_base;
+	struct eng_mmio_base_table_s mbt;
+	struct eng_mmio_base_table_s *mbp;
+
+	memset(&mbt, 0, sizeof(mbt));
+
+	gen = intel_gen(intel_get_drm_devid(fd_dev));
+
+	/* The mmio_base values for engine instances 1 and higher cannot
+	 * be reliability determinated a priori. */
+
+	_gem_engine_mmio_info_legacy_add(&mbt, "rcs0", 0x2000);
+	_gem_engine_mmio_info_legacy_add(&mbt, "bcs0", 0x22000);
+
+	if (gen < 6)
+		mmio_base = 0x4000;
+	else if (gen < 11)
+		mmio_base = 0x12000;
+	else
+		mmio_base = 0x1c0000;
+	_gem_engine_mmio_info_legacy_add(&mbt, "vcs0", mmio_base);
+
+	if (gen < 11)
+		mmio_base = 0x1a000;
+	else
+		mmio_base = 0x1c8000;
+	_gem_engine_mmio_info_legacy_add(&mbt, "vecs0", mmio_base);
+
+	if (mbt.mb_cnt <= 0)
+		return NULL;
+
+	mbp = _gem_engine_mmio_info_dup(&mbt);
+
+	return mbp;
+}
+
+
+/**
+ * _gem_engine_mmio_base_info_get_debugfs:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Obtains per-engine mmio_base information from debugfs.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ *
+ * Looking in debugfs for per-engine instances of:
+ *	<engine_name>
+ *              ...
+ *		MMIO base: <u32_hex_number>
+ *
+ * Example of relevant lines from debugfs:
+ *	vcs0
+ *		MMIO base:  0x001c0000
+ *	vcs1
+ *		MMIO base:  0x001d0000
+ *
+ * In order to qualify as the introduction of a new per-engine section, an
+ * input line must consist solely of an engine name.  An engine name must
+ * be 7 or fewer characters in length and must consist of an engine class
+ * name of 3 or more lower case characters followed by an instance number.
+ */
+static struct eng_mmio_base_table_s *_gem_engine_mmio_base_info_get_debugfs(int fd_dev)
+{
+	static const char pth_ei[] = "i915_engine_info";
+	static const char str_mmio_base[] = "MMIO base:";
+	const size_t len_mmio_base = sizeof(str_mmio_base) - 1;
+	FILE *fpi;
+	char line_buf[128];
+	char *plne;
+	char *p_name;
+	char *pbeg;
+	size_t line_len;
+	struct eng_mmio_base_table_s mbt;
+	struct eng_mmio_base_table_s *mbp;
+	const size_t name_max = sizeof(mbt.mb_tab[0].name);
+	int ec;
+	int eng_found;
+	int nc;
+	int fd_ei;
+	int eof_seen;
+
+	fd_ei = igt_debugfs_open(fd_dev, pth_ei, O_RDONLY);
+	if (fd_ei < 0)
+		return NULL;
+
+	fpi = fdopen(fd_ei, "r");
+	if (!fpi) {
+		if (errno != ENOENT) {
+			igt_warn("open failed: %s: %s\n", pth_ei,
+				strerror(errno));
+		}
+		return NULL;
+	}
+
+	memset(&mbt, 0, sizeof(mbt));
+
+	ec = 0;
+	eng_found = 0;
+	eof_seen = 0;
+	while (!eof_seen) {
+		plne = fgets(line_buf, sizeof(line_buf), fpi);
+		if (!plne) {
+			eof_seen = 1;
+			plne = line_buf;
+			plne[0] = '\0';
+		}
+
+		if (plne[0]) {
+			/* Ignore lines that exceed allowed length. */
+			line_len = strlen(plne);
+			if (plne[line_len-1] != '\n') {
+				for (;;) {
+					plne = fgets(line_buf,
+						sizeof(line_buf), fpi);
+					if (!plne)
+						break;
+					line_len = strlen(plne);
+					if (plne[line_len-1] == '\n')
+						break;
+				}
+				continue;
+			}
+			plne[line_len-1] = '\0';
+
+			p_name = NULL;
+			nc = 0;
+			do {
+				for (; nc < name_max; nc++) {
+					if (!islower(plne[nc]))
+						break;
+				}
+				if (nc < 3)
+					break;
+				if (!isdigit(plne[nc]))
+					break;
+				for (; nc < name_max; nc++) {
+					if (!isdigit(plne[nc]))
+						break;
+				}
+				if ((nc >= name_max) || plne[nc])
+					break;
+				p_name = plne;
+			} while (0);
+		}
+
+		if (eof_seen || p_name) {
+			if (eng_found) {
+				eng_found = 0;
+				if ((ec + 1) >= GEM_MAX_ENGINES)
+					continue;
+				ec++;
+			}
+		}
+
+		if (p_name) {
+			strncpy(mbt.mb_tab[ec].name, p_name, nc);
+			eng_found = 1;
+			continue;
+		}
+
+		if (eng_found) {
+			pbeg = plne;
+			while (isspace(pbeg[0]))
+				pbeg++;
+			if (strncmp(pbeg, str_mmio_base, len_mmio_base) == 0) {
+				unsigned long int ulv;
+				uint32_t uiv;
+				char *ep;
+
+				pbeg += len_mmio_base;
+				ulv = strtoul(pbeg, &ep, 16);
+
+				uiv = (uint32_t) ulv;
+				igt_assert_f(((pbeg != ep) && (ulv == uiv)),
+					"invalid number: %s\n", plne);
+
+				while (isspace(*ep))
+					ep++;
+				igt_assert_f((!*ep),
+					"junk follows number: \"%s\"\n", plne);
+
+				mbt.mb_tab[ec].mmio_base = uiv;
+			}
+		}
+	}
+
+	if (fpi)
+		fclose(fpi);
+
+	mbt.mb_cnt = ec;
+
+	if (mbt.mb_cnt <= 0)
+		return NULL;
+
+	mbp = _gem_engine_mmio_info_dup(&mbt);
+
+	return mbp;
+}
+
+/**
+ * gem_engine_mmio_base_info_get:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Obtains per-engine mmio_base information.  Multiple sub-functions will
+ * be tried in order of preference.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ */
+struct eng_mmio_base_table_s *gem_engine_mmio_base_info_get(int fd_dev)
+{
+	struct eng_mmio_base_table_s *mbp = NULL;
+
+	/* If and when better ways are provided to find the mmio_base
+	 * information, they may be added them here in order of preference.
+	 */
+
+#if 0
+	if (!mbp)
+		mbp = _mmio_base_info_get_via_sysfs(fd_dev);
+#endif
+
+	if (!mbp)
+		mbp = _gem_engine_mmio_base_info_get_debugfs(fd_dev);
+
+	if (!mbp)
+		mbp = _gem_engine_mmio_base_info_get_legacy(fd_dev);
+
+	if (!mbp)
+		igt_warn("Per-engine mmio_base data is not present\n");
+
+	return mbp;
+}
+
+/**
+ * gem_engine_mmio_base_info_dump:
+ *
+ * Dumps engine mmio_base data.
+ *
+ * Returns: void
+ */
+void gem_engine_mmio_base_info_dump(const struct eng_mmio_base_table_s *mbp)
+{
+	int ix;
+	const struct eng_mmio_base_s *e_mb;
+
+	fprintf(stdout, "engine names and mmio_base addresses:\n");
+
+	for (ix = 0; ix < mbp->mb_cnt; ix++) {
+		e_mb = mbp->mb_tab + ix;
+		if (e_mb->mmio_base) {
+			fprintf(stdout, "%-8s 0x%8.8x\n",
+				e_mb->name, e_mb->mmio_base);
+		}
+	}
+}
+
+uint32_t gem_engine_mmio_base(const struct eng_mmio_base_table_s *mbp,
+	const char *eng_name)
+{
+	int ix;
+	const struct eng_mmio_base_s *e_mb;
+
+	for (ix = 0; ix < mbp->mb_cnt; ix++) {
+		e_mb = mbp->mb_tab + ix;
+		if (e_mb->mmio_base && !strcmp(eng_name, e_mb->name)) {
+			return e_mb->mmio_base;
+		}
+	}
+
+	return 0;
+}
diff --git a/lib/i915/gem_mmio_base.h b/lib/i915/gem_mmio_base.h
new file mode 100644
index 000000000..1e138690f
--- /dev/null
+++ b/lib/i915/gem_mmio_base.h
@@ -0,0 +1,19 @@
+//  Copyright (C) 2020 Intel Corporation
+//
+//  SPDX-License-Identifier: MIT
+
+#ifndef GEM_MMIO_BASE_H
+#define GEM_MMIO_BASE_H
+
+struct eng_mmio_base_table_s;
+
+struct eng_mmio_base_table_s *gem_engine_mmio_base_info_get(int fd_dev);
+
+void gem_engine_mmio_base_info_free(struct eng_mmio_base_table_s *mbp);
+
+void gem_engine_mmio_base_info_dump(const struct eng_mmio_base_table_s *mbp);
+
+uint32_t gem_engine_mmio_base(const struct eng_mmio_base_table_s *mbp,
+	const char *eng_name);
+
+#endif /* GEM_MMIO_BASE_H */
diff --git a/lib/igt.h b/lib/igt.h
index a6c4e44d2..8e70dcb02 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -55,5 +55,6 @@
 #include "rendercopy.h"
 #include "i915/gem_mman.h"
 #include "i915/gem_engine_topology.h"
+#include "i915/gem_mmio_base.h"
 
 #endif /* IGT_H */
diff --git a/lib/meson.build b/lib/meson.build
index e87e58036..def72c2bd 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -2,6 +2,7 @@ lib_sources = [
 	'drmtest.c',
 	'i915/gem_context.c',
 	'i915/gem_engine_topology.c',
+	'i915/gem_mmio_base.c',
 	'i915/gem_scheduler.c',
 	'i915/gem_submission.c',
 	'i915/gem_ring.c',
-- 
2.25.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Dale B Stimson <dale.b.stimson@intel.com>
To: igt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible)
Date: Wed, 12 Feb 2020 10:01:42 -0800	[thread overview]
Message-ID: <2f2d74a2aa0bb1ab0050bdeb5a272ae9d7f61c69.1581381780.git.dale.b.stimson@intel.com> (raw)
Message-ID: <20200212180142.KLCOs7O9NvAHtty6_MgM_W6eLyHdcmyfN6iL83WEm8E@z> (raw)
In-Reply-To: <cover.1581381780.git.dale.b.stimson@intel.com>

Signed-off-by: Dale B Stimson <dale.b.stimson@intel.com>
---
 lib/Makefile.sources     |   2 +
 lib/i915/gem_mmio_base.c | 346 +++++++++++++++++++++++++++++++++++++++
 lib/i915/gem_mmio_base.h |  19 +++
 lib/igt.h                |   1 +
 lib/meson.build          |   1 +
 5 files changed, 369 insertions(+)
 create mode 100644 lib/i915/gem_mmio_base.c
 create mode 100644 lib/i915/gem_mmio_base.h

diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index 3e573f267..4c5d50d5d 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -7,6 +7,8 @@ lib_source_list =	 	\
 	i915/gem_context.h	\
 	i915/gem_engine_topology.c	\
 	i915/gem_engine_topology.h	\
+	i915/gem_mmio_base.c	\
+	i915/gem_mmio_base.h	\
 	i915/gem_scheduler.c	\
 	i915/gem_scheduler.h	\
 	i915/gem_submission.c	\
diff --git a/lib/i915/gem_mmio_base.c b/lib/i915/gem_mmio_base.c
new file mode 100644
index 000000000..8718c092f
--- /dev/null
+++ b/lib/i915/gem_mmio_base.c
@@ -0,0 +1,346 @@
+//  Copyright (C) 2020 Intel Corporation
+//
+//  SPDX-License-Identifier: MIT
+
+#include <ctype.h>
+
+#include <fcntl.h>
+
+#include "igt.h"
+
+struct eng_mmio_base_s {
+	char       name[8];
+	uint32_t   mmio_base;
+};
+
+struct eng_mmio_base_table_s {
+	unsigned int           mb_cnt;
+	struct eng_mmio_base_s mb_tab[GEM_MAX_ENGINES];
+};
+
+
+static struct eng_mmio_base_table_s *_gem_engine_mmio_info_dup(
+	const struct eng_mmio_base_table_s *mbpi)
+{
+	struct eng_mmio_base_table_s *mbpo;
+	size_t nbytes;
+
+	nbytes = offsetof(typeof(struct eng_mmio_base_table_s), mb_tab[mbpi->mb_cnt]);
+	mbpo = malloc(nbytes);
+	igt_assert(mbpo);
+	memcpy(mbpo, mbpi, nbytes);
+
+	return mbpo;
+}
+
+void gem_engine_mmio_base_info_free(struct eng_mmio_base_table_s *mbp)
+{
+	free(mbp);
+}
+
+static void _gem_engine_mmio_info_legacy_add(struct eng_mmio_base_table_s *mbp,
+	const char *eng_name, uint32_t mmio_base)
+{
+	if (mmio_base) {
+		strncpy(mbp->mb_tab[mbp->mb_cnt].name, eng_name,
+			sizeof(mbp->mb_tab[0].name));
+		mbp->mb_tab[mbp->mb_cnt].mmio_base = mmio_base;
+		mbp->mb_cnt++;
+	}
+}
+
+/**
+ * _gem_engine_mmio_base_info_get_legacy:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Provides per-engine mmio_base information from legacy built-in values
+ * for the case when the information is not otherwise available.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ */
+static struct eng_mmio_base_table_s *_gem_engine_mmio_base_info_get_legacy(int fd_dev)
+{
+	int gen;
+	uint32_t mmio_base;
+	struct eng_mmio_base_table_s mbt;
+	struct eng_mmio_base_table_s *mbp;
+
+	memset(&mbt, 0, sizeof(mbt));
+
+	gen = intel_gen(intel_get_drm_devid(fd_dev));
+
+	/* The mmio_base values for engine instances 1 and higher cannot
+	 * be reliability determinated a priori. */
+
+	_gem_engine_mmio_info_legacy_add(&mbt, "rcs0", 0x2000);
+	_gem_engine_mmio_info_legacy_add(&mbt, "bcs0", 0x22000);
+
+	if (gen < 6)
+		mmio_base = 0x4000;
+	else if (gen < 11)
+		mmio_base = 0x12000;
+	else
+		mmio_base = 0x1c0000;
+	_gem_engine_mmio_info_legacy_add(&mbt, "vcs0", mmio_base);
+
+	if (gen < 11)
+		mmio_base = 0x1a000;
+	else
+		mmio_base = 0x1c8000;
+	_gem_engine_mmio_info_legacy_add(&mbt, "vecs0", mmio_base);
+
+	if (mbt.mb_cnt <= 0)
+		return NULL;
+
+	mbp = _gem_engine_mmio_info_dup(&mbt);
+
+	return mbp;
+}
+
+
+/**
+ * _gem_engine_mmio_base_info_get_debugfs:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Obtains per-engine mmio_base information from debugfs.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ *
+ * Looking in debugfs for per-engine instances of:
+ *	<engine_name>
+ *              ...
+ *		MMIO base: <u32_hex_number>
+ *
+ * Example of relevant lines from debugfs:
+ *	vcs0
+ *		MMIO base:  0x001c0000
+ *	vcs1
+ *		MMIO base:  0x001d0000
+ *
+ * In order to qualify as the introduction of a new per-engine section, an
+ * input line must consist solely of an engine name.  An engine name must
+ * be 7 or fewer characters in length and must consist of an engine class
+ * name of 3 or more lower case characters followed by an instance number.
+ */
+static struct eng_mmio_base_table_s *_gem_engine_mmio_base_info_get_debugfs(int fd_dev)
+{
+	static const char pth_ei[] = "i915_engine_info";
+	static const char str_mmio_base[] = "MMIO base:";
+	const size_t len_mmio_base = sizeof(str_mmio_base) - 1;
+	FILE *fpi;
+	char line_buf[128];
+	char *plne;
+	char *p_name;
+	char *pbeg;
+	size_t line_len;
+	struct eng_mmio_base_table_s mbt;
+	struct eng_mmio_base_table_s *mbp;
+	const size_t name_max = sizeof(mbt.mb_tab[0].name);
+	int ec;
+	int eng_found;
+	int nc;
+	int fd_ei;
+	int eof_seen;
+
+	fd_ei = igt_debugfs_open(fd_dev, pth_ei, O_RDONLY);
+	if (fd_ei < 0)
+		return NULL;
+
+	fpi = fdopen(fd_ei, "r");
+	if (!fpi) {
+		if (errno != ENOENT) {
+			igt_warn("open failed: %s: %s\n", pth_ei,
+				strerror(errno));
+		}
+		return NULL;
+	}
+
+	memset(&mbt, 0, sizeof(mbt));
+
+	ec = 0;
+	eng_found = 0;
+	eof_seen = 0;
+	while (!eof_seen) {
+		plne = fgets(line_buf, sizeof(line_buf), fpi);
+		if (!plne) {
+			eof_seen = 1;
+			plne = line_buf;
+			plne[0] = '\0';
+		}
+
+		if (plne[0]) {
+			/* Ignore lines that exceed allowed length. */
+			line_len = strlen(plne);
+			if (plne[line_len-1] != '\n') {
+				for (;;) {
+					plne = fgets(line_buf,
+						sizeof(line_buf), fpi);
+					if (!plne)
+						break;
+					line_len = strlen(plne);
+					if (plne[line_len-1] == '\n')
+						break;
+				}
+				continue;
+			}
+			plne[line_len-1] = '\0';
+
+			p_name = NULL;
+			nc = 0;
+			do {
+				for (; nc < name_max; nc++) {
+					if (!islower(plne[nc]))
+						break;
+				}
+				if (nc < 3)
+					break;
+				if (!isdigit(plne[nc]))
+					break;
+				for (; nc < name_max; nc++) {
+					if (!isdigit(plne[nc]))
+						break;
+				}
+				if ((nc >= name_max) || plne[nc])
+					break;
+				p_name = plne;
+			} while (0);
+		}
+
+		if (eof_seen || p_name) {
+			if (eng_found) {
+				eng_found = 0;
+				if ((ec + 1) >= GEM_MAX_ENGINES)
+					continue;
+				ec++;
+			}
+		}
+
+		if (p_name) {
+			strncpy(mbt.mb_tab[ec].name, p_name, nc);
+			eng_found = 1;
+			continue;
+		}
+
+		if (eng_found) {
+			pbeg = plne;
+			while (isspace(pbeg[0]))
+				pbeg++;
+			if (strncmp(pbeg, str_mmio_base, len_mmio_base) == 0) {
+				unsigned long int ulv;
+				uint32_t uiv;
+				char *ep;
+
+				pbeg += len_mmio_base;
+				ulv = strtoul(pbeg, &ep, 16);
+
+				uiv = (uint32_t) ulv;
+				igt_assert_f(((pbeg != ep) && (ulv == uiv)),
+					"invalid number: %s\n", plne);
+
+				while (isspace(*ep))
+					ep++;
+				igt_assert_f((!*ep),
+					"junk follows number: \"%s\"\n", plne);
+
+				mbt.mb_tab[ec].mmio_base = uiv;
+			}
+		}
+	}
+
+	if (fpi)
+		fclose(fpi);
+
+	mbt.mb_cnt = ec;
+
+	if (mbt.mb_cnt <= 0)
+		return NULL;
+
+	mbp = _gem_engine_mmio_info_dup(&mbt);
+
+	return mbp;
+}
+
+/**
+ * gem_engine_mmio_base_info_get:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Obtains per-engine mmio_base information.  Multiple sub-functions will
+ * be tried in order of preference.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ */
+struct eng_mmio_base_table_s *gem_engine_mmio_base_info_get(int fd_dev)
+{
+	struct eng_mmio_base_table_s *mbp = NULL;
+
+	/* If and when better ways are provided to find the mmio_base
+	 * information, they may be added them here in order of preference.
+	 */
+
+#if 0
+	if (!mbp)
+		mbp = _mmio_base_info_get_via_sysfs(fd_dev);
+#endif
+
+	if (!mbp)
+		mbp = _gem_engine_mmio_base_info_get_debugfs(fd_dev);
+
+	if (!mbp)
+		mbp = _gem_engine_mmio_base_info_get_legacy(fd_dev);
+
+	if (!mbp)
+		igt_warn("Per-engine mmio_base data is not present\n");
+
+	return mbp;
+}
+
+/**
+ * gem_engine_mmio_base_info_dump:
+ *
+ * Dumps engine mmio_base data.
+ *
+ * Returns: void
+ */
+void gem_engine_mmio_base_info_dump(const struct eng_mmio_base_table_s *mbp)
+{
+	int ix;
+	const struct eng_mmio_base_s *e_mb;
+
+	fprintf(stdout, "engine names and mmio_base addresses:\n");
+
+	for (ix = 0; ix < mbp->mb_cnt; ix++) {
+		e_mb = mbp->mb_tab + ix;
+		if (e_mb->mmio_base) {
+			fprintf(stdout, "%-8s 0x%8.8x\n",
+				e_mb->name, e_mb->mmio_base);
+		}
+	}
+}
+
+uint32_t gem_engine_mmio_base(const struct eng_mmio_base_table_s *mbp,
+	const char *eng_name)
+{
+	int ix;
+	const struct eng_mmio_base_s *e_mb;
+
+	for (ix = 0; ix < mbp->mb_cnt; ix++) {
+		e_mb = mbp->mb_tab + ix;
+		if (e_mb->mmio_base && !strcmp(eng_name, e_mb->name)) {
+			return e_mb->mmio_base;
+		}
+	}
+
+	return 0;
+}
diff --git a/lib/i915/gem_mmio_base.h b/lib/i915/gem_mmio_base.h
new file mode 100644
index 000000000..1e138690f
--- /dev/null
+++ b/lib/i915/gem_mmio_base.h
@@ -0,0 +1,19 @@
+//  Copyright (C) 2020 Intel Corporation
+//
+//  SPDX-License-Identifier: MIT
+
+#ifndef GEM_MMIO_BASE_H
+#define GEM_MMIO_BASE_H
+
+struct eng_mmio_base_table_s;
+
+struct eng_mmio_base_table_s *gem_engine_mmio_base_info_get(int fd_dev);
+
+void gem_engine_mmio_base_info_free(struct eng_mmio_base_table_s *mbp);
+
+void gem_engine_mmio_base_info_dump(const struct eng_mmio_base_table_s *mbp);
+
+uint32_t gem_engine_mmio_base(const struct eng_mmio_base_table_s *mbp,
+	const char *eng_name);
+
+#endif /* GEM_MMIO_BASE_H */
diff --git a/lib/igt.h b/lib/igt.h
index a6c4e44d2..8e70dcb02 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -55,5 +55,6 @@
 #include "rendercopy.h"
 #include "i915/gem_mman.h"
 #include "i915/gem_engine_topology.h"
+#include "i915/gem_mmio_base.h"
 
 #endif /* IGT_H */
diff --git a/lib/meson.build b/lib/meson.build
index e87e58036..def72c2bd 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -2,6 +2,7 @@ lib_sources = [
 	'drmtest.c',
 	'i915/gem_context.c',
 	'i915/gem_engine_topology.c',
+	'i915/gem_mmio_base.c',
 	'i915/gem_scheduler.c',
 	'i915/gem_submission.c',
 	'i915/gem_ring.c',
-- 
2.25.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Dale B Stimson <dale.b.stimson@intel.com>
To: igt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible)
Date: Mon, 10 Feb 2020 16:46:11 -0800	[thread overview]
Message-ID: <2f2d74a2aa0bb1ab0050bdeb5a272ae9d7f61c69.1581381780.git.dale.b.stimson@intel.com> (raw)
In-Reply-To: <cover.1581381780.git.dale.b.stimson@intel.com>

Signed-off-by: Dale B Stimson <dale.b.stimson@intel.com>
---
 lib/Makefile.sources     |   2 +
 lib/i915/gem_mmio_base.c | 346 +++++++++++++++++++++++++++++++++++++++
 lib/i915/gem_mmio_base.h |  19 +++
 lib/igt.h                |   1 +
 lib/meson.build          |   1 +
 5 files changed, 369 insertions(+)
 create mode 100644 lib/i915/gem_mmio_base.c
 create mode 100644 lib/i915/gem_mmio_base.h

diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index 3e573f267..4c5d50d5d 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -7,6 +7,8 @@ lib_source_list =	 	\
 	i915/gem_context.h	\
 	i915/gem_engine_topology.c	\
 	i915/gem_engine_topology.h	\
+	i915/gem_mmio_base.c	\
+	i915/gem_mmio_base.h	\
 	i915/gem_scheduler.c	\
 	i915/gem_scheduler.h	\
 	i915/gem_submission.c	\
diff --git a/lib/i915/gem_mmio_base.c b/lib/i915/gem_mmio_base.c
new file mode 100644
index 000000000..8718c092f
--- /dev/null
+++ b/lib/i915/gem_mmio_base.c
@@ -0,0 +1,346 @@
+//  Copyright (C) 2020 Intel Corporation
+//
+//  SPDX-License-Identifier: MIT
+
+#include <ctype.h>
+
+#include <fcntl.h>
+
+#include "igt.h"
+
+struct eng_mmio_base_s {
+	char       name[8];
+	uint32_t   mmio_base;
+};
+
+struct eng_mmio_base_table_s {
+	unsigned int           mb_cnt;
+	struct eng_mmio_base_s mb_tab[GEM_MAX_ENGINES];
+};
+
+
+static struct eng_mmio_base_table_s *_gem_engine_mmio_info_dup(
+	const struct eng_mmio_base_table_s *mbpi)
+{
+	struct eng_mmio_base_table_s *mbpo;
+	size_t nbytes;
+
+	nbytes = offsetof(typeof(struct eng_mmio_base_table_s), mb_tab[mbpi->mb_cnt]);
+	mbpo = malloc(nbytes);
+	igt_assert(mbpo);
+	memcpy(mbpo, mbpi, nbytes);
+
+	return mbpo;
+}
+
+void gem_engine_mmio_base_info_free(struct eng_mmio_base_table_s *mbp)
+{
+	free(mbp);
+}
+
+static void _gem_engine_mmio_info_legacy_add(struct eng_mmio_base_table_s *mbp,
+	const char *eng_name, uint32_t mmio_base)
+{
+	if (mmio_base) {
+		strncpy(mbp->mb_tab[mbp->mb_cnt].name, eng_name,
+			sizeof(mbp->mb_tab[0].name));
+		mbp->mb_tab[mbp->mb_cnt].mmio_base = mmio_base;
+		mbp->mb_cnt++;
+	}
+}
+
+/**
+ * _gem_engine_mmio_base_info_get_legacy:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Provides per-engine mmio_base information from legacy built-in values
+ * for the case when the information is not otherwise available.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ */
+static struct eng_mmio_base_table_s *_gem_engine_mmio_base_info_get_legacy(int fd_dev)
+{
+	int gen;
+	uint32_t mmio_base;
+	struct eng_mmio_base_table_s mbt;
+	struct eng_mmio_base_table_s *mbp;
+
+	memset(&mbt, 0, sizeof(mbt));
+
+	gen = intel_gen(intel_get_drm_devid(fd_dev));
+
+	/* The mmio_base values for engine instances 1 and higher cannot
+	 * be reliability determinated a priori. */
+
+	_gem_engine_mmio_info_legacy_add(&mbt, "rcs0", 0x2000);
+	_gem_engine_mmio_info_legacy_add(&mbt, "bcs0", 0x22000);
+
+	if (gen < 6)
+		mmio_base = 0x4000;
+	else if (gen < 11)
+		mmio_base = 0x12000;
+	else
+		mmio_base = 0x1c0000;
+	_gem_engine_mmio_info_legacy_add(&mbt, "vcs0", mmio_base);
+
+	if (gen < 11)
+		mmio_base = 0x1a000;
+	else
+		mmio_base = 0x1c8000;
+	_gem_engine_mmio_info_legacy_add(&mbt, "vecs0", mmio_base);
+
+	if (mbt.mb_cnt <= 0)
+		return NULL;
+
+	mbp = _gem_engine_mmio_info_dup(&mbt);
+
+	return mbp;
+}
+
+
+/**
+ * _gem_engine_mmio_base_info_get_debugfs:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Obtains per-engine mmio_base information from debugfs.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ *
+ * Looking in debugfs for per-engine instances of:
+ *	<engine_name>
+ *              ...
+ *		MMIO base: <u32_hex_number>
+ *
+ * Example of relevant lines from debugfs:
+ *	vcs0
+ *		MMIO base:  0x001c0000
+ *	vcs1
+ *		MMIO base:  0x001d0000
+ *
+ * In order to qualify as the introduction of a new per-engine section, an
+ * input line must consist solely of an engine name.  An engine name must
+ * be 7 or fewer characters in length and must consist of an engine class
+ * name of 3 or more lower case characters followed by an instance number.
+ */
+static struct eng_mmio_base_table_s *_gem_engine_mmio_base_info_get_debugfs(int fd_dev)
+{
+	static const char pth_ei[] = "i915_engine_info";
+	static const char str_mmio_base[] = "MMIO base:";
+	const size_t len_mmio_base = sizeof(str_mmio_base) - 1;
+	FILE *fpi;
+	char line_buf[128];
+	char *plne;
+	char *p_name;
+	char *pbeg;
+	size_t line_len;
+	struct eng_mmio_base_table_s mbt;
+	struct eng_mmio_base_table_s *mbp;
+	const size_t name_max = sizeof(mbt.mb_tab[0].name);
+	int ec;
+	int eng_found;
+	int nc;
+	int fd_ei;
+	int eof_seen;
+
+	fd_ei = igt_debugfs_open(fd_dev, pth_ei, O_RDONLY);
+	if (fd_ei < 0)
+		return NULL;
+
+	fpi = fdopen(fd_ei, "r");
+	if (!fpi) {
+		if (errno != ENOENT) {
+			igt_warn("open failed: %s: %s\n", pth_ei,
+				strerror(errno));
+		}
+		return NULL;
+	}
+
+	memset(&mbt, 0, sizeof(mbt));
+
+	ec = 0;
+	eng_found = 0;
+	eof_seen = 0;
+	while (!eof_seen) {
+		plne = fgets(line_buf, sizeof(line_buf), fpi);
+		if (!plne) {
+			eof_seen = 1;
+			plne = line_buf;
+			plne[0] = '\0';
+		}
+
+		if (plne[0]) {
+			/* Ignore lines that exceed allowed length. */
+			line_len = strlen(plne);
+			if (plne[line_len-1] != '\n') {
+				for (;;) {
+					plne = fgets(line_buf,
+						sizeof(line_buf), fpi);
+					if (!plne)
+						break;
+					line_len = strlen(plne);
+					if (plne[line_len-1] == '\n')
+						break;
+				}
+				continue;
+			}
+			plne[line_len-1] = '\0';
+
+			p_name = NULL;
+			nc = 0;
+			do {
+				for (; nc < name_max; nc++) {
+					if (!islower(plne[nc]))
+						break;
+				}
+				if (nc < 3)
+					break;
+				if (!isdigit(plne[nc]))
+					break;
+				for (; nc < name_max; nc++) {
+					if (!isdigit(plne[nc]))
+						break;
+				}
+				if ((nc >= name_max) || plne[nc])
+					break;
+				p_name = plne;
+			} while (0);
+		}
+
+		if (eof_seen || p_name) {
+			if (eng_found) {
+				eng_found = 0;
+				if ((ec + 1) >= GEM_MAX_ENGINES)
+					continue;
+				ec++;
+			}
+		}
+
+		if (p_name) {
+			strncpy(mbt.mb_tab[ec].name, p_name, nc);
+			eng_found = 1;
+			continue;
+		}
+
+		if (eng_found) {
+			pbeg = plne;
+			while (isspace(pbeg[0]))
+				pbeg++;
+			if (strncmp(pbeg, str_mmio_base, len_mmio_base) == 0) {
+				unsigned long int ulv;
+				uint32_t uiv;
+				char *ep;
+
+				pbeg += len_mmio_base;
+				ulv = strtoul(pbeg, &ep, 16);
+
+				uiv = (uint32_t) ulv;
+				igt_assert_f(((pbeg != ep) && (ulv == uiv)),
+					"invalid number: %s\n", plne);
+
+				while (isspace(*ep))
+					ep++;
+				igt_assert_f((!*ep),
+					"junk follows number: \"%s\"\n", plne);
+
+				mbt.mb_tab[ec].mmio_base = uiv;
+			}
+		}
+	}
+
+	if (fpi)
+		fclose(fpi);
+
+	mbt.mb_cnt = ec;
+
+	if (mbt.mb_cnt <= 0)
+		return NULL;
+
+	mbp = _gem_engine_mmio_info_dup(&mbt);
+
+	return mbp;
+}
+
+/**
+ * gem_engine_mmio_base_info_get:
+ * @fd_dev: file descriptor upon which device is open or -1 to use defaults.
+ *
+ * Obtains per-engine mmio_base information.  Multiple sub-functions will
+ * be tried in order of preference.
+ *
+ * Returns:
+ * Pointer to dynamically allocated struct eng_mmio_base_table_s describing
+ * engine config or NULL.
+ * The allocated size does not include unused engine entries.
+ * If non-NULL, it is caller's responsibility to free.
+ */
+struct eng_mmio_base_table_s *gem_engine_mmio_base_info_get(int fd_dev)
+{
+	struct eng_mmio_base_table_s *mbp = NULL;
+
+	/* If and when better ways are provided to find the mmio_base
+	 * information, they may be added them here in order of preference.
+	 */
+
+#if 0
+	if (!mbp)
+		mbp = _mmio_base_info_get_via_sysfs(fd_dev);
+#endif
+
+	if (!mbp)
+		mbp = _gem_engine_mmio_base_info_get_debugfs(fd_dev);
+
+	if (!mbp)
+		mbp = _gem_engine_mmio_base_info_get_legacy(fd_dev);
+
+	if (!mbp)
+		igt_warn("Per-engine mmio_base data is not present\n");
+
+	return mbp;
+}
+
+/**
+ * gem_engine_mmio_base_info_dump:
+ *
+ * Dumps engine mmio_base data.
+ *
+ * Returns: void
+ */
+void gem_engine_mmio_base_info_dump(const struct eng_mmio_base_table_s *mbp)
+{
+	int ix;
+	const struct eng_mmio_base_s *e_mb;
+
+	fprintf(stdout, "engine names and mmio_base addresses:\n");
+
+	for (ix = 0; ix < mbp->mb_cnt; ix++) {
+		e_mb = mbp->mb_tab + ix;
+		if (e_mb->mmio_base) {
+			fprintf(stdout, "%-8s 0x%8.8x\n",
+				e_mb->name, e_mb->mmio_base);
+		}
+	}
+}
+
+uint32_t gem_engine_mmio_base(const struct eng_mmio_base_table_s *mbp,
+	const char *eng_name)
+{
+	int ix;
+	const struct eng_mmio_base_s *e_mb;
+
+	for (ix = 0; ix < mbp->mb_cnt; ix++) {
+		e_mb = mbp->mb_tab + ix;
+		if (e_mb->mmio_base && !strcmp(eng_name, e_mb->name)) {
+			return e_mb->mmio_base;
+		}
+	}
+
+	return 0;
+}
diff --git a/lib/i915/gem_mmio_base.h b/lib/i915/gem_mmio_base.h
new file mode 100644
index 000000000..1e138690f
--- /dev/null
+++ b/lib/i915/gem_mmio_base.h
@@ -0,0 +1,19 @@
+//  Copyright (C) 2020 Intel Corporation
+//
+//  SPDX-License-Identifier: MIT
+
+#ifndef GEM_MMIO_BASE_H
+#define GEM_MMIO_BASE_H
+
+struct eng_mmio_base_table_s;
+
+struct eng_mmio_base_table_s *gem_engine_mmio_base_info_get(int fd_dev);
+
+void gem_engine_mmio_base_info_free(struct eng_mmio_base_table_s *mbp);
+
+void gem_engine_mmio_base_info_dump(const struct eng_mmio_base_table_s *mbp);
+
+uint32_t gem_engine_mmio_base(const struct eng_mmio_base_table_s *mbp,
+	const char *eng_name);
+
+#endif /* GEM_MMIO_BASE_H */
diff --git a/lib/igt.h b/lib/igt.h
index a6c4e44d2..8e70dcb02 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -55,5 +55,6 @@
 #include "rendercopy.h"
 #include "i915/gem_mman.h"
 #include "i915/gem_engine_topology.h"
+#include "i915/gem_mmio_base.h"
 
 #endif /* IGT_H */
diff --git a/lib/meson.build b/lib/meson.build
index e87e58036..def72c2bd 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -2,6 +2,7 @@ lib_sources = [
 	'drmtest.c',
 	'i915/gem_context.c',
 	'i915/gem_engine_topology.c',
+	'i915/gem_mmio_base.c',
 	'i915/gem_scheduler.c',
 	'i915/gem_submission.c',
 	'i915/gem_ring.c',
-- 
2.25.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2020-02-11  0:47 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-11  0:46 [Intel-gfx] [PATCH i-g-t 0/3] mmio_base via debugfs infrastructure + gem_ctx_isolation Dale B Stimson
2020-02-12 18:01 ` Dale B Stimson
2020-02-11  0:46 ` [igt-dev] " Dale B Stimson
2020-02-11  0:46 ` Dale B Stimson [this message]
2020-02-12 18:01   ` [Intel-gfx] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible) Dale B Stimson
2020-02-11  0:46   ` [igt-dev] " Dale B Stimson
2020-02-11  0:46   ` [Intel-gfx] [PATCH i-g-t 2/3] i915/gem_ctx_isolation: Check engine relative registers Dale B Stimson
2020-02-12 18:01     ` Dale B Stimson
2020-02-11  0:46     ` [igt-dev] " Dale B Stimson
2020-02-11  0:46     ` [Intel-gfx] [PATCH i-g-t 3/3] i915/gem_ctx_isolation: Check engine relative registers - Part 2 Dale B Stimson
2020-02-12 18:01       ` Dale B Stimson
2020-02-11  0:46       ` [igt-dev] " Dale B Stimson
2020-02-11  9:22   ` [Intel-gfx] [igt-dev] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible) Petri Latvala
2020-02-11  9:22     ` Petri Latvala
2020-02-11  9:30     ` [Intel-gfx] " Jani Nikula
2020-02-11  9:30       ` [igt-dev] [Intel-gfx] " Jani Nikula
2020-02-11  9:37       ` [Intel-gfx] [igt-dev] " Petri Latvala
2020-02-11  9:37         ` [igt-dev] [Intel-gfx] " Petri Latvala
2020-02-11  9:53         ` [Intel-gfx] [igt-dev] " Petri Latvala
2020-02-11  9:53           ` [igt-dev] [Intel-gfx] " Petri Latvala
2020-02-12 18:09 [Intel-gfx] [PATCH i-g-t 0/3] mmio_base via debugfs infrastructure + gem_ctx_isolation Dale B Stimson
2020-02-12 18:09 ` [Intel-gfx] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible) Dale B Stimson
2020-02-12 22:34 [Intel-gfx] [PATCH i-g-t 0/3] mmio_base via debugfs infrastructure + gem_ctx_isolation Dale B Stimson
2020-02-12 22:34 ` [Intel-gfx] [PATCH i-g-t 1/3] i915/gem_mmio_base.c - get mmio_base from debugfs (if possible) Dale B Stimson

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=2f2d74a2aa0bb1ab0050bdeb5a272ae9d7f61c69.1581381780.git.dale.b.stimson@intel.com \
    --to=dale.b.stimson@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.