From: Xin Wang <x.wang@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: alex.zuo@intel.com, Xin Wang <x.wang@intel.com>,
Shuicheng Lin <shuicheng.lin@intel.com>,
Kamil Konieczny <kamil.konieczny@intel.com>,
Matthew Auld <matthew.auld@intel.com>
Subject: [PATCH v3 1/2] lib/intel_pat: read Xe PAT config from debugfs
Date: Wed, 10 Dec 2025 05:23:25 +0000 [thread overview]
Message-ID: <20251210052327.149365-1-x.wang@intel.com> (raw)
In-Reply-To: <20251206011241.67825-1-x.wang@intel.com>
Parse the PAT software configuration from gt0/pat_sw_config instead
of relying on hard-coded indices.
Expose xe_get_pat_entries() so tests can grab the PAT table.
V2: (Kamil)
- Show a detailed skip info when opening the debugfs file fails.
CC: Shuicheng Lin <shuicheng.lin@intel.com>
CC: Kamil Konieczny <kamil.konieczny@intel.com>
CC: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Xin Wang <x.wang@intel.com>
---
lib/intel_pat.c | 127 ++++++++++++++++++++++++++++++++++++++++++------
lib/intel_pat.h | 9 ++++
2 files changed, 120 insertions(+), 16 deletions(-)
diff --git a/lib/intel_pat.c b/lib/intel_pat.c
index e3588110a..4aee16f39 100644
--- a/lib/intel_pat.c
+++ b/lib/intel_pat.c
@@ -3,9 +3,9 @@
* Copyright © 2023 Intel Corporation
*/
+#include "igt.h"
#include "intel_pat.h"
-#include "igt.h"
struct intel_pat_cache {
uint8_t uc; /* UC + COH_NONE */
@@ -13,27 +13,112 @@ struct intel_pat_cache {
uint8_t wb; /* WB + COH_AT_LEAST_1WAY */
uint8_t uc_comp; /* UC + COH_NONE + COMPRESSION, XE2 and later*/
uint8_t max_index;
+ struct xe_pat_entry entries[XE_PAT_MAX_ENTRIES];
+ uint32_t pat_mode;
+ uint32_t pat_ats;
};
+/**
+ * xe_get_pat_sw_config - Helper to read PAT (Page Attribute Table) software configuration
+ * from debugfs
+ *
+ * @drm_fd: DRM device fd to use with igt_debugfs_open
+ * @xe_pat_cache: Pointer to a struct that will receive the parsed PAT configuration
+ *
+ * Returns: The number of PAT entries successfully read on success, or a negative error
+ * code on failure (-ENOENT if debugfs is missing, -errno otherwise)
+ */
+static int32_t xe_get_pat_sw_config(int drm_fd, struct intel_pat_cache *xe_pat_cache)
+{
+ char *line = NULL;
+ size_t line_len = 0;
+ ssize_t nread;
+ int32_t parsed = 0;
+ int dbgfs_fd;
+ FILE *dbgfs_file = NULL;
+
+ dbgfs_fd = igt_debugfs_open(drm_fd, "gt0/pat_sw_config", O_RDONLY);
+ if (dbgfs_fd < 0)
+ return -ENOENT;
+ dbgfs_file = fdopen(dbgfs_fd, "r");
+ if (!dbgfs_file) {
+ close(dbgfs_fd);
+ return -errno;
+ }
+
+ memset(xe_pat_cache, 0, sizeof(*xe_pat_cache));
+ while ((nread = getline(&line, &line_len, dbgfs_file)) != -1) {
+ uint32_t value = 0;
+ char *p = NULL;
+
+ /* Expect patterns like: PAT[ 0] = [ 0, 0, 0, 0, 0 ] ( 0x0) */
+ if (strncmp(line, "PAT[", 4) == 0) {
+ bool is_reserved;
+ p = strstr(line, "(");
+ if (p && sscanf(p, "(%x", &value) == 1) {
+ if (parsed < XE_PAT_MAX_ENTRIES) {
+ is_reserved = strchr(line, '*') != NULL;
+ xe_pat_cache->entries[parsed].pat = value;
+ xe_pat_cache->entries[parsed].rsvd = is_reserved;
+ xe_pat_cache->max_index = parsed;
+ parsed++;
+
+ igt_debug("Parsed PAT entry %d: 0x%08x%s\n",
+ parsed - 1, value,
+ is_reserved ? " (reserved)" : "");
+ } else {
+ igt_warn("Too many PAT entries, line ignored: %s\n", line);
+ }
+ } else {
+ igt_warn("Failed to parse PAT entry line: %s\n", line);
+ }
+ } else if (strncmp(line, "PAT_MODE", 8) == 0) {
+ p = strstr(line, "(");
+ if (p && sscanf(p, "(%x", &value) == 1)
+ xe_pat_cache->pat_mode = value;
+ } else if (strncmp(line, "PAT_ATS", 7) == 0) {
+ p = strstr(line, "(");
+ if (p && sscanf(p, "(%x", &value) == 1)
+ xe_pat_cache->pat_ats = value;
+ } else if (strncmp(line, "IDX[XE_CACHE_NONE]", 18) == 0) {
+ p = strstr(line, "=");
+ if (p && sscanf(p, "= %d", &value) == 1)
+ xe_pat_cache->uc = value;
+ } else if (strncmp(line, "IDX[XE_CACHE_WT]", 16) == 0) {
+ p = strstr(line, "=");
+ if (p && sscanf(p, "= %d", &value) == 1)
+ xe_pat_cache->wt = value;
+ } else if (strncmp(line, "IDX[XE_CACHE_WB]", 16) == 0) {
+ p = strstr(line, "=");
+ if (p && sscanf(p, "= %d", &value) == 1)
+ xe_pat_cache->wb = value;
+ } else if (strncmp(line, "IDX[XE_CACHE_NONE_COMPRESSION]", 28) == 0) {
+ p = strstr(line, "=");
+ if (p && sscanf(p, "= %d", &value) == 1)
+ xe_pat_cache->uc_comp = value;
+ }
+ }
+
+ free(line);
+ fclose(dbgfs_file);
+
+ return parsed;
+}
+
static void intel_get_pat_idx(int fd, struct intel_pat_cache *pat)
{
uint16_t dev_id = intel_get_drm_devid(fd);
- if (intel_graphics_ver(dev_id) == IP_VER(35, 11)) {
- pat->uc = 3;
- pat->wb = 2;
- pat->max_index = 31;
- } else if (intel_get_device_info(dev_id)->graphics_ver == 30 ||
- intel_get_device_info(dev_id)->graphics_ver == 20) {
- pat->uc = 3;
- pat->wt = 15; /* Compressed + WB-transient */
- pat->wb = 2;
- pat->uc_comp = 12; /* Compressed + UC, XE2 and later */
- pat->max_index = 31;
-
- /* Wa_16023588340: CLOS3 entries at end of table are unusable */
- if (intel_graphics_ver(dev_id) == IP_VER(20, 1))
- pat->max_index -= 4;
+ if (intel_graphics_ver(dev_id) >= IP_VER(20, 0)) {
+ /* Cache parsed PAT config per device to avoid re-reading debugfs on every call */
+ static __thread struct intel_pat_cache intel_pat_cache;
+ static __thread uint16_t cached_devid;
+ if (cached_devid != dev_id) {
+ int ret = xe_get_pat_sw_config(fd, &intel_pat_cache);
+ igt_require_f(ret > 0, "Unable to open the pat_sw_config file in debugfs.\n");
+ cached_devid = dev_id;
+ }
+ *pat = intel_pat_cache;
} else if (IS_METEORLAKE(dev_id)) {
pat->uc = 2;
pat->wt = 1;
@@ -96,3 +181,13 @@ uint8_t intel_get_pat_idx_wb(int fd)
intel_get_pat_idx(fd, &pat);
return pat.wb;
}
+
+uint8_t xe_get_pat_entries(int fd, struct xe_pat_entry *xe_pat_table)
+{
+ struct intel_pat_cache pat = {};
+ intel_get_pat_idx(fd, &pat);
+
+ memcpy(xe_pat_table, pat.entries, (pat.max_index + 1) * sizeof(struct xe_pat_entry));
+
+ return pat.max_index + 1;
+}
diff --git a/lib/intel_pat.h b/lib/intel_pat.h
index eb48cbc65..1d6c4f1ad 100644
--- a/lib/intel_pat.h
+++ b/lib/intel_pat.h
@@ -6,9 +6,16 @@
#ifndef INTEL_PAT_H
#define INTEL_PAT_H
+#include <stdbool.h>
#include <stdint.h>
#define DEFAULT_PAT_INDEX ((uint8_t)-1) /* igt-core can pick 1way or better */
+#define XE_PAT_MAX_ENTRIES 32
+
+struct xe_pat_entry {
+ uint32_t pat;
+ bool rsvd;
+};
uint8_t intel_get_max_pat_index(int fd);
@@ -18,4 +25,6 @@ uint8_t intel_get_pat_idx_wb(int fd);
uint8_t intel_get_pat_idx_uc_comp(int fd);
+uint8_t xe_get_pat_entries(int fd, struct xe_pat_entry *xe_pat_table);
+
#endif /* INTEL_PAT_H */
--
2.43.0
next prev parent reply other threads:[~2025-12-10 5:23 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-13 7:05 [PATCH] tests/intel/xe_pat: add helper funtion to read PAT table Xin Wang
2025-11-13 7:57 ` ✗ Xe.CI.BAT: failure for " Patchwork
2025-11-13 14:33 ` ✓ Xe.CI.Full: success " Patchwork
2025-11-13 20:55 ` ✓ i915.CI.BAT: " Patchwork
2025-11-13 21:40 ` [PATCH] " Wang, X
2025-11-13 22:12 ` ✓ i915.CI.Full: success for " Patchwork
2025-12-06 1:12 ` [PATCH v2 1/2] lib/intel_pat: read Xe PAT config from debugfs Xin Wang
2025-12-06 1:12 ` [PATCH v2 2/2] tests/intel/xe_pat: sync with Xe PAT debugfs parser Xin Wang
2025-12-08 16:48 ` Matthew Auld
2025-12-10 5:24 ` [PATCH v3 " Xin Wang
2025-12-06 18:48 ` [PATCH v2 1/2] lib/intel_pat: read Xe PAT config from debugfs Lin, Shuicheng
2025-12-08 18:37 ` Wang, X
2025-12-08 23:27 ` Lin, Shuicheng
2025-12-09 9:36 ` Kamil Konieczny
2025-12-09 16:41 ` Wang, X
2025-12-08 19:25 ` Wang, X
2025-12-10 5:23 ` Xin Wang [this message]
2025-12-11 7:27 ` [PATCH v4 0/2] tests/intel/xe_pat: add helper funtion to read PAT table Xin Wang
2025-12-11 7:27 ` [PATCH v4 1/2] lib/intel_pat: read Xe PAT config from debugfs Xin Wang
2025-12-11 7:27 ` [PATCH v4 2/2] tests/intel/xe_pat: sync with Xe PAT debugfs parser Xin Wang
2025-12-06 1:57 ` ✓ Xe.CI.BAT: success for tests/intel/xe_pat: add helper funtion to read PAT table (rev2) Patchwork
2025-12-06 2:05 ` ✓ i915.CI.BAT: " Patchwork
2025-12-06 13:36 ` ✗ Xe.CI.Full: failure " Patchwork
2025-12-07 4:24 ` ✗ i915.CI.Full: " Patchwork
2025-12-10 9:21 ` ✓ Xe.CI.BAT: success for tests/intel/xe_pat: add helper funtion to read PAT table (rev4) Patchwork
2025-12-10 11:05 ` ✓ i915.CI.BAT: " Patchwork
2025-12-10 12:32 ` ✗ Xe.CI.Full: failure " Patchwork
2025-12-10 12:55 ` ✓ i915.CI.Full: success " Patchwork
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=20251210052327.149365-1-x.wang@intel.com \
--to=x.wang@intel.com \
--cc=alex.zuo@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=kamil.konieczny@intel.com \
--cc=matthew.auld@intel.com \
--cc=shuicheng.lin@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;
as well as URLs for NNTP newsgroup(s).