[PATCH] intel_reg: add support to reading reg with debugfs ioctl

Dafna Hirschfeld dafna.hirschfeld at intel.com
Tue Feb 18 09:01:22 UTC 2025


use the new debugfs mmio ioctl in Xe driver to read/write
registers in the intel_reg tool

to use the debugfs ioctl, run:
sudo intel_reg write debugfs:0x71D05000 1
sudo intel_reg read debugfs:0x71D05000
      debugfs:0x71d05000 (debugfs:0x71d05000): 0x00000001

Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld at intel.com>
---
The Xe driver patch is:
https://patchwork.freedesktop.org/patch/594198/?series=133505
(mailinglist archv) https://lore.kernel.org/intel-xe/20240515165244.156194-1-kelbaz@habana.ai/

 lib/xe/xe_debugfs_mmio.h | 39 +++++++++++++++++++++++
 tools/intel_reg.c        | 69 ++++++++++++++++++++++++++++++++++++++++
 tools/intel_reg_spec.c   |  5 +++
 tools/intel_reg_spec.h   |  2 ++
 4 files changed, 115 insertions(+)
 create mode 100644 lib/xe/xe_debugfs_mmio.h

diff --git a/lib/xe/xe_debugfs_mmio.h b/lib/xe/xe_debugfs_mmio.h
new file mode 100644
index 000000000..a715487c7
--- /dev/null
+++ b/lib/xe/xe_debugfs_mmio.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _XE_DEBUGFS_MMIO_H_
+#define _XE_DEBUGFS_MMIO_H_
+
+#include <drm/drm.h>
+
+#define XE_DEBUGFS_MMIO_32BIT		0x1
+#define XE_DEBUGFS_MMIO_64BIT		0x2
+#define XE_DEBUGFS_MMIO_BITS_MASK	(XE_DEBUGFS_MMIO_32BIT | XE_DEBUGFS_MMIO_64BIT)
+#define XE_DEBUGFS_MMIO_READ		0x4
+#define XE_DEBUGFS_MMIO_WRITE		0x8
+#define XE_DEBUGFS_MMIO_OPS_MASK	(XE_DEBUGFS_MMIO_READ | XE_DEBUGFS_MMIO_WRITE)
+
+#define XE_DEBUGFS_MMIO_VALID_FLAGS (XE_DEBUGFS_MMIO_BITS_MASK | XE_DEBUGFS_MMIO_OPS_MASK)
+
+struct xe_debugfs_mmio_ioctl_data {
+	/** @extensions: Pointer to the first extension struct, if any */
+	__u64 extensions;
+
+	__u32 addr;
+
+	__u32 flags;
+
+	__u64 value;
+
+	/** @reserved: Reserved */
+	__u64 reserved[2];
+};
+
+#define XE_DEBUGFS_MMIO_IOCTL_NR	0x00
+
+#define XE_DEBUGFS_MMIO_IOCTL \
+	_IOWR(0x20, XE_DEBUGFS_MMIO_IOCTL_NR, struct xe_debugfs_mmio_ioctl_data)
+
+#endif /* _XE_DEBUGFS_MMIO_H_ */
diff --git a/tools/intel_reg.c b/tools/intel_reg.c
index bb1ab2889..36f549385 100644
--- a/tools/intel_reg.c
+++ b/tools/intel_reg.c
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <sys/ioctl.h>
 
 #include "i915/gem_create.h"
 #include "igt.h"
@@ -39,6 +40,7 @@
 #include "intel_chipset.h"
 
 #include "intel_reg_spec.h"
+#include "xe/xe_debugfs_mmio.h"
 
 
 #ifdef HAVE_SYS_IO_H
@@ -497,6 +499,67 @@ static void vga_cr_write(uint8_t index, uint8_t value, bool mmio)
 	vga_idx_write(vga_crx(mmio), vga_crd(mmio), index, value, mmio);
 }
 
+static uint64_t debugfs_ioctl_write(uint64_t addr, uint32_t val)
+{
+	int ret, fd, fd_dbg;
+	struct xe_debugfs_mmio_ioctl_data args;
+
+	fd = __drm_open_driver(DRIVER_ANY);
+	if (fd == -1)
+		exit(EXIT_FAILURE);
+
+	fd_dbg = igt_debugfs_open(fd, "mmio", O_RDWR);
+	if (fd_dbg == -1)
+		exit(EXIT_FAILURE);
+
+	memset(&args, 0, sizeof(args));
+	args.addr =  addr;
+	args.flags = XE_DEBUGFS_MMIO_WRITE | XE_DEBUGFS_MMIO_32BIT;
+	args.value = val;
+
+	ret = ioctl(fd_dbg, XE_DEBUGFS_MMIO_IOCTL, &args);
+	if (ret) {
+		fprintf(stderr, "error writing register with debugfs ioctl: %s",
+				strerror(errno));
+		close(fd_dbg);
+		close(fd);
+		exit(EXIT_FAILURE);
+	}
+	close(fd_dbg);
+	close(fd);
+	return 0;
+}
+
+static uint64_t debugfs_ioctl_read(uint64_t addr)
+{
+	int ret, fd, fd_dbg;
+	struct xe_debugfs_mmio_ioctl_data args;
+
+	fd = __drm_open_driver(DRIVER_ANY);
+	if (fd == -1)
+		exit(EXIT_FAILURE);
+
+	fd_dbg = igt_debugfs_open(fd, "mmio", O_RDWR);
+	if (fd_dbg == -1)
+		exit(EXIT_FAILURE);
+
+	memset(&args, 0, sizeof(args));
+	args.addr =  addr;
+	args.flags = XE_DEBUGFS_MMIO_READ | XE_DEBUGFS_MMIO_32BIT;
+
+	ret = ioctl(fd_dbg, XE_DEBUGFS_MMIO_IOCTL, &args);
+	if (ret) {
+		fprintf(stderr, "error reading register with debugfs ioctl: %s",
+				strerror(errno));
+		close(fd_dbg);
+		close(fd);
+		exit(EXIT_FAILURE);
+	}
+	close(fd_dbg);
+	close(fd);
+	return args.value;
+}
+
 static int read_register(struct config *config, struct reg *reg, uint32_t *valp)
 {
 	uint32_t val = 0;
@@ -546,6 +609,9 @@ static int read_register(struct config *config, struct reg *reg, uint32_t *valp)
 	case PORT_PORTIO_VGA_CR:
 		val = vga_cr_read(reg->addr, false);
 		break;
+	case PORT_DEBUGFS_IOCTL:
+		val = debugfs_ioctl_read(reg->mmio_offset + reg->addr);
+		break;
 	case PORT_BUNIT:
 	case PORT_PUNIT:
 	case PORT_NC:
@@ -650,6 +716,9 @@ static int write_register(struct config *config, struct reg *reg, uint32_t val)
 		}
 		vga_cr_write(reg->addr, val, true);
 		break;
+	case PORT_DEBUGFS_IOCTL:
+		val = debugfs_ioctl_write(reg->mmio_offset + reg->addr, val);
+		break;
 	case PORT_PORTIO:
 		if (val > 0xff) {
 			fprintf(stderr, "value 0x%08x out of range for port %s\n",
diff --git a/tools/intel_reg_spec.c b/tools/intel_reg_spec.c
index 632db6b9f..5c3ded213 100644
--- a/tools/intel_reg_spec.c
+++ b/tools/intel_reg_spec.c
@@ -108,6 +108,11 @@ static const struct port_desc port_descs[] = {
 		.port = PORT_PORTIO_VGA_CR,
 		.stride = 1,
 	},
+	{
+		.name = "debugfs",
+		.port = PORT_DEBUGFS_IOCTL,
+		.stride = 4, /* we only support 4 bytes read for debufs */
+	},
 	{
 		.name = "bunit",
 		.port = PORT_BUNIT,
diff --git a/tools/intel_reg_spec.h b/tools/intel_reg_spec.h
index af396a294..39337e0e9 100644
--- a/tools/intel_reg_spec.h
+++ b/tools/intel_reg_spec.h
@@ -46,6 +46,8 @@ enum port_addr {
 	PORT_PORTIO_VGA_GR,
 	PORT_PORTIO_VGA_CR,
 
+	PORT_DEBUGFS_IOCTL,
+
 	PORT_NONE = 0,
 
 	/* vlv */
-- 
2.34.1



More information about the igt-dev mailing list