From: Matt Roper <matthew.d.roper@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: matthew.d.roper@intel.com
Subject: [PATCH v2 3/4] drm/xe: Add facility to lookup the value of a register in a default LRC
Date: Wed, 11 Feb 2026 15:34:15 -0800 [thread overview]
Message-ID: <20260211233411.614951-9-matthew.d.roper@intel.com> (raw)
In-Reply-To: <20260211233411.614951-6-matthew.d.roper@intel.com>
An LRC is stored in memory as a special batchbuffer that hardware will
execute to re-load state when switching to the context; it's a
collection of register values (encoded as MI_LOAD_REGISTER_IMM commands)
and other state instructions (e.g., 3DSTATE_*). The value that will be
loaded for a given register can be determined by parsing the batchbuffer
to find MI_LRI commands and extracting the value from the offset/value
pairs it contains. Add functions to do this, which will be used in a
future patch to help verify that our expected reg_sr programming is in
place.
The implementation here returns the value as soon as it finds a match in
the LRC. Technically a register could appear multiple times (either due
to memory corruption or a hardware defect) and the last value
encountered would be the one in effect when the context resumes
execution. We can adjust the logic to keep looking and return the last
match instead of first in the future if we encounter real-world cases
where this would assist with debugging.
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
drivers/gpu/drm/xe/xe_lrc.c | 96 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_lrc.h | 4 ++
2 files changed, 100 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index 38f648b98868..57ef4f527ed0 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -2155,6 +2155,102 @@ void xe_lrc_dump_default(struct drm_printer *p,
}
}
+/*
+ * Lookup the value of a register within the offset/value pairs of an
+ * MI_LOAD_REGISTER_IMM instruction.
+ *
+ * Return -ENOENT if the register is not present in the MI_LRI instruction.
+ */
+static int lookup_reg_in_mi_lri(u32 offset, u32 *value,
+ const u32 *dword_pair, int num_regs)
+{
+ for (int i = 0; i < num_regs; i++) {
+ if (dword_pair[2 * i] == offset) {
+ *value = dword_pair[2 * i + 1];
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+/*
+ * Lookup the value of a register in a specific engine type's default LRC.
+ *
+ * Return -EINVAL if the default LRC doesn't exist, or ENOENT if the register
+ * cannot be found in the default LRC.
+ */
+int xe_lrc_lookup_default_reg_value(struct xe_gt *gt,
+ enum xe_engine_class hwe_class,
+ u32 offset,
+ u32 *value)
+{
+ u32 *dw;
+ int remaining_dw, ret;
+
+ if (!gt->default_lrc[hwe_class])
+ return -EINVAL;
+
+ /*
+ * Skip the beginning of the LRC since it contains the per-process
+ * hardware status page.
+ */
+ dw = gt->default_lrc[hwe_class] + LRC_PPHWSP_SIZE;
+ remaining_dw = (xe_gt_lrc_size(gt, hwe_class) - LRC_PPHWSP_SIZE) / 4;
+
+ while (remaining_dw > 0) {
+ u32 num_dw = instr_dw(*dw);
+
+ if (num_dw > remaining_dw)
+ num_dw = remaining_dw;
+
+ switch (*dw & XE_INSTR_CMD_TYPE) {
+ case XE_INSTR_MI:
+ switch (*dw & MI_OPCODE) {
+ case MI_BATCH_BUFFER_END:
+ /* End of LRC; register not found */
+ return -ENOENT;
+
+ case MI_NOOP:
+ case MI_TOPOLOGY_FILTER:
+ /*
+ * MI_NOOP and MI_TOPOLOGY_FILTER don't have
+ * a length field and are always 1-dword
+ * instructions.
+ */
+ remaining_dw--;
+ dw++;
+ break;
+
+ case MI_LOAD_REGISTER_IMM:
+ ret = lookup_reg_in_mi_lri(offset, value,
+ dw + 1, (num_dw - 1) / 2);
+ if (ret == 0)
+ return 0;
+
+ fallthrough;
+
+ default:
+ /*
+ * Jump to next instruction based on length
+ * field.
+ */
+ remaining_dw -= num_dw;
+ dw += num_dw;
+ break;
+ }
+ break;
+
+ default:
+ /* Jump to next instruction based on length field. */
+ remaining_dw -= num_dw;
+ dw += num_dw;
+ }
+ }
+
+ return -ENOENT;
+}
+
struct instr_state {
u32 instr;
u16 num_dw;
diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h
index c307a3fd9ea2..3e500004f1ae 100644
--- a/drivers/gpu/drm/xe/xe_lrc.h
+++ b/drivers/gpu/drm/xe/xe_lrc.h
@@ -133,6 +133,10 @@ size_t xe_lrc_skip_size(struct xe_device *xe);
void xe_lrc_dump_default(struct drm_printer *p,
struct xe_gt *gt,
enum xe_engine_class);
+int xe_lrc_lookup_default_reg_value(struct xe_gt *gt,
+ enum xe_engine_class hwe_class,
+ u32 offset,
+ u32 *value);
u32 *xe_lrc_emit_hwe_state_instructions(struct xe_exec_queue *q, u32 *cs);
--
2.53.0
next prev parent reply other threads:[~2026-02-11 23:34 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-11 23:34 [PATCH v2 0/4] Add debugfs facility to catch RTP mistakes Matt Roper
2026-02-11 23:34 ` [PATCH v2 1/4] drm/xe/reg_sr: Don't process gt/hwe lists in VF Matt Roper
2026-02-11 23:34 ` [PATCH v2 2/4] drm/xe/reg_sr: Add debugfs to verify status of reg_sr programming Matt Roper
2026-02-11 23:34 ` Matt Roper [this message]
2026-02-11 23:34 ` [PATCH v2 4/4] drm/xe/reg_sr: Allow register_save_restore_check debugfs to verify LRC values Matt Roper
2026-02-12 0:23 ` ✓ CI.KUnit: success for Add debugfs facility to catch RTP mistakes Patchwork
2026-02-12 1:05 ` ✗ Xe.CI.BAT: failure " 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=20260211233411.614951-9-matthew.d.roper@intel.com \
--to=matthew.d.roper@intel.com \
--cc=intel-xe@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox