* [PATCH v5 1/7] drm/xe/devcoredump: Capture GT fuse registers in devcoredump
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 2/7] drm/xe/devcoredump: Add GuC register snapshot to devcoredump Nareshkumar Gollakoti
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Capture fuse-related GT register state in the Xe devcoredump to preserve
additional hardware configuration information for postmortem debugging.
Add generic register snapshot storage and helpers for capturing,
printing, and freeing MMIO register dumps. Use them to record both
primary GT and media GT fuse register state during devcoredump snapshot
collection and print the captured values in the coredump output.
Also add the required GT register definitions for RPM and mirror
copy-enable state used by the new dump paths.
v2:(Sashiko)
- Fix GT/media fuse snapshot capture to use the correct GT context.
- Add non-fault GT force wake for cross-GT register capture.
- Skip reading registers when SR-IOV VF.
- Skip media GT capture when media GT is absent.
- Add RPM snapshot print/free handling explicitly.
- Add POWERGATE_ENABLE register to get render awake status
v3:(Sashiko)
- Check RENDER_POWERGATE_ENABLE of POWERGATE_ENABLE register
- Replace "render is not awake" message with "render powergating
appears not enabled"
v4:
- Reduce multiple apis and optimize the suggest way of struct arrays(Tejas)
- Add document for struct xe_gt_regset gt member(Hook failure)
- Change struct reg_desc to header file
- Remove Graphics version check for these registers set
v5:
- Fix possible Null dereference using valid gt instead of q->gt(sashiko)
- refactor struct member commenting(Tejas)
- Avoid using xe3p naming as the regs are for all platforms
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 2 +
drivers/gpu/drm/xe/xe_devcoredump.c | 228 +++++++++++++++++++++-
drivers/gpu/drm/xe/xe_devcoredump_types.h | 52 +++++
3 files changed, 281 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index f5cd3a94e47f..e93895e0c731 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -22,6 +22,8 @@
#define MTL_CC_MASK REG_GENMASK(12, 9)
#define MTL_CRST 0xf
+#define RPM_GCD XE_REG(0xc98)
+
/* RPM unit config (Gen8+) */
#define RPM_CONFIG0 XE_REG(0xd00)
#define RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK REG_GENMASK(5, 3)
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c
index ab681b148869..e363818160af 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -25,6 +25,8 @@
#include "xe_pm.h"
#include "xe_sched_job.h"
#include "xe_vm.h"
+#include "xe_mmio.h"
+#include "regs/xe_gt_regs.h"
/**
* DOC: Xe device coredump
@@ -69,6 +71,179 @@
/* 1 hour timeout */
#define XE_COREDUMP_TIMEOUT_JIFFIES (60 * 60 * HZ)
+#define XE_REG_DESC(_reg, _name) { .reg = (_reg), .name = (_name) }
+
+static const struct xe_reg_desc xe_dbg_gt_fuse_reglist[] = {
+ XE_REG_DESC(XELP_GT_GEOMETRY_DSS_ENABLE, "GT_GEOMETRY_DSS_ENABLE"),
+ XE_REG_DESC(XEHP_GT_COMPUTE_DSS_ENABLE, "GT_COMPUTE_DSS_ENABLE"),
+ XE_REG_DESC(XELP_EU_ENABLE, "EU_ENABLE"),
+ XE_REG_DESC(MIRROR_FUSE1, "MIRROR_FUSE1"),
+ XE_REG_DESC(GT_VEBOX_VDBOX_DISABLE, "GT_VEBOX_VDBOX_DISABLE"),
+ XE_REG_DESC(SERVICE_COPY_ENABLE, "SERVICE_COPY_ENABLE"),
+ XE_REG_DESC(RESOURCE_COPY_ENABLE, "COPY_ENABLE_GTFS_GCD"),
+ XE_REG_DESC(XE2_GT_GEOMETRY_DSS_1, "GT_GEOMETRY_DSS_1"),
+ XE_REG_DESC(XE2_GT_GEOMETRY_DSS_2, "GT_GEOMETRY_DSS_2"),
+ XE_REG_DESC(XE2_GT_COMPUTE_DSS_2, "GT_COMPUTE_DSS_2"),
+ XE_REG_DESC(XEHPC_GT_COMPUTE_DSS_ENABLE_EXT, "GT_COMPUTE_DSS_ENABLE_EXT"),
+ XE_REG_DESC(XE3P_XPC_GT_GEOMETRY_DSS_3, "GT_GEOMETRY_DSS_3"),
+ XE_REG_DESC(XE3P_XPC_GT_COMPUTE_DSS_3, "GT_COMPUTE_DSS_3"),
+};
+
+static const struct xe_reg_desc xe_dbg_media_gt_fuse_reglist[] = {
+ XE_REG_DESC(SERVICE_COPY_ENABLE, "SERVICE_COPY_ENABLE"),
+ XE_REG_DESC(RESOURCE_COPY_ENABLE, "COPY_ENABLE_GTFS_GCD"),
+};
+
+static const struct xe_reg_desc xe_dbg_gt_rpm_reglist[] = {
+ XE_REG_DESC(RPM_GCD, "RPM_GCD"),
+ XE_REG_DESC(POWERGATE_ENABLE, "POWERGATE_ENABLE"),
+};
+
+static const struct xe_reg_desc xe_dbg_media_gt_rpm_reglist[] = {
+ XE_REG_DESC(RPM_GCD, "RPM_GCD"),
+};
+
+/**
+ * struct xe_gt_regset - Struct for register descriptor list for GT
+ *
+ * This struct is used to reference the corresponding reglist of
+ * Main GT and media GT
+ */
+struct xe_gt_regset {
+ /**
+ * @gt: GT array indexed by enum xe_gt_type starting at 1
+ * (UNINITIALIZED=0, MAIN=1, MEDIA=2)
+ */
+ struct xe_reg_desc_list gt[XE_MAX_GT_PER_TILE + 1];
+};
+
+/**
+ * enum xe_dbg_regset_type - debug register set types
+ * @XE_DBG_REGSET_FUSE: Fuse register set
+ * @XE_DBG_REGSET_RPM: RPM register set
+ * @XE_DBG_REGSET_MAX: Number of debug register set types
+ */
+enum xe_dbg_regset_type {
+ XE_DBG_REGSET_FUSE,
+ XE_DBG_REGSET_RPM,
+ XE_DBG_REGSET_MAX,
+};
+
+static const struct xe_gt_regset xe_dbg_regsets[XE_DBG_REGSET_MAX] = {
+ [XE_DBG_REGSET_FUSE] = {
+ .gt[XE_GT_TYPE_MAIN] = { xe_dbg_gt_fuse_reglist,
+ ARRAY_SIZE(xe_dbg_gt_fuse_reglist) },
+ .gt[XE_GT_TYPE_MEDIA] = { xe_dbg_media_gt_fuse_reglist,
+ ARRAY_SIZE(xe_dbg_media_gt_fuse_reglist) },
+ },
+ [XE_DBG_REGSET_RPM] = {
+ .gt[XE_GT_TYPE_MAIN] = { xe_dbg_gt_rpm_reglist,
+ ARRAY_SIZE(xe_dbg_gt_rpm_reglist) },
+ .gt[XE_GT_TYPE_MEDIA] = { xe_dbg_media_gt_rpm_reglist,
+ ARRAY_SIZE(xe_dbg_media_gt_rpm_reglist) },
+ },
+};
+
+static void xe_dbg_reg_snapshot_print(struct drm_printer *p,
+ const char *title,
+ const struct xe_dbg_reg_snapshot *snap)
+{
+ u32 i;
+
+ if (!snap)
+ return;
+
+ if (title)
+ drm_printf(p, "\n**** %s ****\n", title);
+
+ for (i = 0; i < snap->num_regs; i++)
+ drm_printf(p, " %s [0x%x] = 0x%08x\n",
+ snap->desc->regs[i].name,
+ snap->desc->regs[i].reg.addr,
+ snap->values[i]);
+}
+
+static void xe_dbg_reg_snapshot_free(struct xe_dbg_reg_snapshot *snap)
+{
+ kfree(snap);
+}
+
+static const u32 *xe_dbg_find_value(const struct xe_dbg_reg_snapshot *snap,
+ struct xe_reg reg)
+{
+ int i;
+
+ if (!snap)
+ return NULL;
+
+ for (i = 0; i < snap->num_regs; i++)
+ if (snap->desc->regs[i].reg.addr == reg.addr)
+ return &snap->values[i];
+
+ return NULL;
+}
+
+static void xe_gt_rpm_snapshot_print(struct drm_printer *p,
+ const char *title,
+ const struct xe_dbg_reg_snapshot *snap)
+{
+ const u32 *val;
+
+ xe_dbg_reg_snapshot_print(p, title, snap);
+
+ if (!snap)
+ return;
+
+ val = xe_dbg_find_value(snap, POWERGATE_ENABLE);
+ if (val && !(*val & RENDER_POWERGATE_ENABLE))
+ drm_puts(p, "render powergating appears not enabled\n");
+}
+
+static struct xe_dbg_reg_snapshot *
+xe_dbg_reg_snapshot_capture_target(struct xe_gt *gt,
+ const struct xe_reg_desc_list *reglist)
+{
+ struct xe_dbg_reg_snapshot *snap;
+ int i;
+
+ if (IS_SRIOV_VF(gt_to_xe(gt)))
+ return NULL;
+
+ snap = kmalloc(struct_size(snap, values, reglist->num_regs), GFP_ATOMIC);
+ if (!snap)
+ return NULL;
+
+ snap->desc = reglist;
+ snap->num_regs = reglist->num_regs;
+ for (i = 0; i < reglist->num_regs; i++)
+ snap->values[i] = xe_mmio_read32(>->mmio, reglist->regs[i].reg);
+
+ return snap;
+}
+
+static struct xe_dbg_reg_snapshot *
+xe_dbg_gt_snapshot_capture(struct xe_gt *fault_gt, struct xe_gt *other_gt,
+ enum xe_dbg_regset_type type,
+ enum xe_gt_type gt_type)
+{
+ struct xe_gt *target_gt;
+
+ if (!fault_gt || !fault_gt->tile)
+ return NULL;
+
+ target_gt = gt_type == XE_GT_TYPE_MEDIA ? fault_gt->tile->media_gt
+ : fault_gt->tile->primary_gt;
+ if (!target_gt)
+ return NULL;
+
+ /* non-fault GT needs the caller's confirmed forcewake */
+ if (target_gt != fault_gt && target_gt != other_gt)
+ return NULL;
+
+ return xe_dbg_reg_snapshot_capture_target(target_gt,
+ &xe_dbg_regsets[type].gt[gt_type]);
+}
+
static struct xe_device *coredump_to_xe(const struct xe_devcoredump *coredump)
{
return container_of(coredump, struct xe_device, devcoredump);
@@ -109,6 +284,11 @@ static ssize_t __xe_devcoredump_read(char *buffer, ssize_t count,
drm_printf(&p, "\n**** GT #%d ****\n", ss->gt->info.id);
drm_printf(&p, "\tTile: %d\n", ss->gt->tile->id);
+ xe_dbg_reg_snapshot_print(&p, "GT Fuse Register Dump", ss->gt_fuse);
+ xe_dbg_reg_snapshot_print(&p, "Media GT Fuse Register Dump", ss->media_fuse);
+ xe_gt_rpm_snapshot_print(&p, "GT RPM Register Dump", ss->gt_rpm);
+ xe_dbg_reg_snapshot_print(&p, "Media GT RPM Register Dump", ss->media_gt_rpm);
+
drm_puts(&p, "\n**** GuC Log ****\n");
xe_guc_log_snapshot_print(ss->guc.log, &p);
drm_puts(&p, "\n**** GuC CT ****\n");
@@ -146,6 +326,18 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
xe_guc_ct_snapshot_free(ss->guc.ct);
ss->guc.ct = NULL;
+ xe_dbg_reg_snapshot_free(ss->gt_fuse);
+ ss->gt_fuse = NULL;
+
+ xe_dbg_reg_snapshot_free(ss->media_fuse);
+ ss->media_fuse = NULL;
+
+ xe_dbg_reg_snapshot_free(ss->gt_rpm);
+ ss->gt_rpm = NULL;
+
+ xe_dbg_reg_snapshot_free(ss->media_gt_rpm);
+ ss->media_gt_rpm = NULL;
+
if (!IS_ERR_OR_NULL(ss->gt))
xe_guc_capture_put_matched_nodes(&ss->gt->uc.guc);
ss->matched_node = NULL;
@@ -319,6 +511,27 @@ static void xe_devcoredump_deferred_snap_work(struct work_struct *work)
}
}
+static void xe_devcoredump_capture_gt_regs(struct xe_devcoredump_snapshot *ss,
+ struct xe_gt *gt, struct xe_gt *other_gt)
+{
+ ss->gt_fuse = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_FUSE,
+ XE_GT_TYPE_MAIN);
+ ss->media_fuse = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_FUSE,
+ XE_GT_TYPE_MEDIA);
+ ss->gt_rpm = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_RPM,
+ XE_GT_TYPE_MAIN);
+ ss->media_gt_rpm = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_RPM,
+ XE_GT_TYPE_MEDIA);
+}
+
static void devcoredump_snapshot(struct xe_devcoredump *coredump,
struct xe_gt *gt,
struct xe_exec_queue *q,
@@ -328,6 +541,7 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump,
struct xe_guc *guc = >->uc.guc;
const char *process_name = "no process";
bool cookie;
+ struct xe_gt *other_gt;
ss->snapshot_time = ktime_get_real();
ss->boot_time = ktime_get_boottime();
@@ -342,11 +556,23 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump,
ss->gt = gt;
INIT_WORK(&ss->work, xe_devcoredump_deferred_snap_work);
- /* keep going if fw fails as we still want to save the memory and SW data */
+ /* fw_ref_other must stay in scope through the register captures below */
CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FORCEWAKE_ALL);
cookie = dma_fence_begin_signalling();
+ other_gt = gt->tile->media_gt == gt ? gt->tile->primary_gt
+ : gt->tile->media_gt;
+ if (other_gt) {
+ CLASS(xe_force_wake, fw_ref_other)(gt_to_fw(other_gt),
+ XE_FORCEWAKE_ALL);
+ if (!xe_force_wake_ref_has_domain(fw_ref_other.domains, XE_FORCEWAKE_ALL))
+ other_gt = NULL;
+ xe_devcoredump_capture_gt_regs(ss, gt, other_gt);
+ } else {
+ xe_devcoredump_capture_gt_regs(ss, gt, NULL);
+ }
+
ss->guc.log = xe_guc_log_snapshot_capture(&guc->log, true);
ss->guc.ct = xe_guc_ct_snapshot_capture(&guc->ct);
diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h
index a174385a6d83..e2fac33dce09 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump_types.h
+++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h
@@ -14,6 +14,48 @@
struct xe_device;
struct xe_gt;
+/**
+ * struct xe_reg_desc - Register descriptor struct to make reg list
+ *
+ * This struct is used as descriptor containing reg address and name
+ * of the register to dump its value during coredump for debug purpose.
+ */
+struct xe_reg_desc {
+ /** @reg: The register */
+ struct xe_reg reg;
+ /** @name: Name of the register */
+ const char *name;
+};
+
+/**
+ * struct xe_reg_desc_list - Struct for register descriptor list
+ *
+ * This struct is used to reference the corresponding reglist of
+ * various component
+ */
+struct xe_reg_desc_list {
+ /** @regs: Pointer to an array of register descriptors. */
+ const struct xe_reg_desc *regs;
+ /** @num_regs: number of registers in the descriptor list*/
+ u32 num_regs;
+};
+
+/**
+ * struct xe_dbg_reg_snapshot - Register snapshot
+ *
+ * This struct contains the register values captured at the time of the crash.
+ * It is used to store the register values in a human-readable format for
+ * debugging purposes.
+ */
+struct xe_dbg_reg_snapshot {
+ /** @desc: register descriptor list. */
+ const struct xe_reg_desc_list *desc;
+ /** @num_regs: Number of registers needed for capture. */
+ u32 num_regs;
+ /** @values: register values*/
+ u32 values[];
+};
+
/**
* struct xe_devcoredump_snapshot - Crash snapshot
*
@@ -35,6 +77,16 @@ struct xe_devcoredump_snapshot {
/** @gt: Affected GT, used by forcewake for delayed capture */
struct xe_gt *gt;
+
+ /** @gt_fuse: Fuse snapshot */
+ struct xe_dbg_reg_snapshot *gt_fuse;
+ /** @media_fuse: Media Fuse snapshot */
+ struct xe_dbg_reg_snapshot *media_fuse;
+ /** @gt_rpm: GT RPM snapshot */
+ struct xe_dbg_reg_snapshot *gt_rpm;
+ /** @media_gt_rpm: Media GT RPM snapshot */
+ struct xe_dbg_reg_snapshot *media_gt_rpm;
+
/** @work: Workqueue for deferred capture outside of signaling context */
struct work_struct work;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v5 2/7] drm/xe/devcoredump: Add GuC register snapshot to devcoredump
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 1/7] drm/xe/devcoredump: Capture GT fuse registers " Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 3/7] drm/xe/guc: Print register addresses in capture snapshot output Nareshkumar Gollakoti
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Add support for capturing GuC register state as part of the xe
devcoredump snapshot.
Define a dedicated GuC register snapshot structure, record selected
GT and media GuC status/error registers during devcoredump capture,
and free the snapshot during teardown.
Keeping these register values in the devcoredump helps with
post-mortem analysis of GuC-related failures.
v2:(Sashiko)
- Reuse the generic target GT snapshot helper for GuC register capture
- Capture primary and media GuC registers using correct GT MMIO context
- Avoid reading the same on SR-IOV VF
- skip reading media GT GuC registers when media is not present
- drop hardcoded media register address macros
v5:
- Rebase as per patch1 changes
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_guc_regs.h | 5 ++++
drivers/gpu/drm/xe/xe_devcoredump.c | 35 +++++++++++++++++++++++
drivers/gpu/drm/xe/xe_devcoredump_types.h | 5 ++++
3 files changed, 45 insertions(+)
diff --git a/drivers/gpu/drm/xe/regs/xe_guc_regs.h b/drivers/gpu/drm/xe/regs/xe_guc_regs.h
index 5faac8316b66..c13ee6e21e37 100644
--- a/drivers/gpu/drm/xe/regs/xe_guc_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_guc_regs.h
@@ -150,6 +150,11 @@
#define GUC_INTR_SW_INT_1 REG_BIT(1)
#define GUC_INTR_SW_INT_0 REG_BIT(0)
+#define GUC_DEVICEID XE_REG(0xc008)
+#define GUC_SHIM_ERR_TRAP XE_REG(0xc070)
+#define GUC_HW_FATL_ERR XE_REG(0xc598)
+#define GUC_HW_NOTIFY_ERR XE_REG(0xc59c)
+
#define GUC_NUM_DOORBELLS 256
/* format of the HW-monitored doorbell cacheline */
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c
index e363818160af..ee92a0d203b8 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -27,6 +27,7 @@
#include "xe_vm.h"
#include "xe_mmio.h"
#include "regs/xe_gt_regs.h"
+#include "regs/xe_guc_regs.h"
/**
* DOC: Xe device coredump
@@ -73,6 +74,16 @@
#define XE_REG_DESC(_reg, _name) { .reg = (_reg), .name = (_name) }
+static const struct xe_reg_desc xe_dbg_gt_guc_reglist[] = {
+ XE_REG_DESC(GUC_STATUS, "GUC_STATUS"),
+ XE_REG_DESC(GUC_WOPCM_SIZE, "GUC_WOPCM_SIZE"),
+ XE_REG_DESC(GUC_DEVICEID, "GUC_DEVICEID"),
+ XE_REG_DESC(DMA_CTRL, "DMA_CTRL"),
+ XE_REG_DESC(GUC_HW_FATL_ERR, "GUC_HW_FATL_ERR"),
+ XE_REG_DESC(GUC_HW_NOTIFY_ERR, "GUC_HW_NOTIFY_ERR"),
+ XE_REG_DESC(GUC_SHIM_ERR_TRAP, "GUC_SHIM_ERR_TRAP"),
+};
+
static const struct xe_reg_desc xe_dbg_gt_fuse_reglist[] = {
XE_REG_DESC(XELP_GT_GEOMETRY_DSS_ENABLE, "GT_GEOMETRY_DSS_ENABLE"),
XE_REG_DESC(XEHP_GT_COMPUTE_DSS_ENABLE, "GT_COMPUTE_DSS_ENABLE"),
@@ -121,11 +132,13 @@ struct xe_gt_regset {
* enum xe_dbg_regset_type - debug register set types
* @XE_DBG_REGSET_FUSE: Fuse register set
* @XE_DBG_REGSET_RPM: RPM register set
+ * @XE_DBG_REGSET_GUC: GUC register set
* @XE_DBG_REGSET_MAX: Number of debug register set types
*/
enum xe_dbg_regset_type {
XE_DBG_REGSET_FUSE,
XE_DBG_REGSET_RPM,
+ XE_DBG_REGSET_GUC,
XE_DBG_REGSET_MAX,
};
@@ -142,6 +155,12 @@ static const struct xe_gt_regset xe_dbg_regsets[XE_DBG_REGSET_MAX] = {
.gt[XE_GT_TYPE_MEDIA] = { xe_dbg_media_gt_rpm_reglist,
ARRAY_SIZE(xe_dbg_media_gt_rpm_reglist) },
},
+ [XE_DBG_REGSET_GUC] = {
+ .gt[XE_GT_TYPE_MAIN] = { xe_dbg_gt_guc_reglist,
+ ARRAY_SIZE(xe_dbg_gt_guc_reglist) },
+ .gt[XE_GT_TYPE_MEDIA] = { xe_dbg_gt_guc_reglist,
+ ARRAY_SIZE(xe_dbg_gt_guc_reglist) },
+ },
};
static void xe_dbg_reg_snapshot_print(struct drm_printer *p,
@@ -288,6 +307,8 @@ static ssize_t __xe_devcoredump_read(char *buffer, ssize_t count,
xe_dbg_reg_snapshot_print(&p, "Media GT Fuse Register Dump", ss->media_fuse);
xe_gt_rpm_snapshot_print(&p, "GT RPM Register Dump", ss->gt_rpm);
xe_dbg_reg_snapshot_print(&p, "Media GT RPM Register Dump", ss->media_gt_rpm);
+ xe_dbg_reg_snapshot_print(&p, "GT GuC Register Dump", ss->gt_guc_reg);
+ xe_dbg_reg_snapshot_print(&p, "Media GT GuC Register Dump", ss->media_gt_guc_reg);
drm_puts(&p, "\n**** GuC Log ****\n");
xe_guc_log_snapshot_print(ss->guc.log, &p);
@@ -338,6 +359,12 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
xe_dbg_reg_snapshot_free(ss->media_gt_rpm);
ss->media_gt_rpm = NULL;
+ xe_dbg_reg_snapshot_free(ss->gt_guc_reg);
+ ss->gt_guc_reg = NULL;
+
+ xe_dbg_reg_snapshot_free(ss->media_gt_guc_reg);
+ ss->media_gt_guc_reg = NULL;
+
if (!IS_ERR_OR_NULL(ss->gt))
xe_guc_capture_put_matched_nodes(&ss->gt->uc.guc);
ss->matched_node = NULL;
@@ -530,6 +557,14 @@ static void xe_devcoredump_capture_gt_regs(struct xe_devcoredump_snapshot *ss,
other_gt,
XE_DBG_REGSET_RPM,
XE_GT_TYPE_MEDIA);
+ ss->gt_guc_reg = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_GUC,
+ XE_GT_TYPE_MAIN);
+ ss->media_gt_guc_reg = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_GUC,
+ XE_GT_TYPE_MEDIA);
}
static void devcoredump_snapshot(struct xe_devcoredump *coredump,
diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h
index e2fac33dce09..52db64640f89 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump_types.h
+++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h
@@ -87,6 +87,11 @@ struct xe_devcoredump_snapshot {
/** @media_gt_rpm: Media GT RPM snapshot */
struct xe_dbg_reg_snapshot *media_gt_rpm;
+ /** @gt_guc_reg: gt guc reg snapshot */
+ struct xe_dbg_reg_snapshot *gt_guc_reg;
+ /** @media_gt_guc_reg: media gt guc reg snapshot */
+ struct xe_dbg_reg_snapshot *media_gt_guc_reg;
+
/** @work: Workqueue for deferred capture outside of signaling context */
struct work_struct work;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v5 3/7] drm/xe/guc: Print register addresses in capture snapshot output
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 1/7] drm/xe/devcoredump: Capture GT fuse registers " Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 2/7] drm/xe/devcoredump: Add GuC register snapshot to devcoredump Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 4/7] drm/xe: dump GAM page fault report registers in devcoredump Nareshkumar Gollakoti
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Include register offsets in GuC capture snapshot print output for both
32-bit and 64-bit registers.
When dumping captured engine register state, print each register name
alongside its MMIO offset to make the snapshot output easier to
cross-reference with register definitions and hardware debug
documentation.
This improves postmortem analysis without changing capture contents.
v2:(Sashiko)
- Ensure lower DWORD prints
v3:(Sashiko)
- Use the LOW_DW MMIO offset(capture in last_address) when combined 64bit
register values in the dump instead of HI_SW offset
- preserve existing coredump register-name format and append register
address as trailing metadata as a debug info and avoids disrupting
existing format
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/xe_guc_capture.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
index 5a4d085660a2..3e99aef53b46 100644
--- a/drivers/gpu/drm/xe/xe_guc_capture.c
+++ b/drivers/gpu/drm/xe/xe_guc_capture.c
@@ -1716,6 +1716,7 @@ snapshot_print_by_list_order(struct xe_hw_engine_snapshot *snapshot, struct drm_
struct xe_devcoredump_snapshot *devcore_snapshot = &devcoredump->snapshot;
struct gcap_reg_list_info *reginfo = NULL;
u32 i, last_value = 0;
+ u32 last_address = 0;
bool low32_ready = false;
if (!list || !list->list || list->num_regs == 0)
@@ -1743,6 +1744,7 @@ snapshot_print_by_list_order(struct xe_hw_engine_snapshot *snapshot, struct drm_
switch (reg_desc->data_type) {
case REG_64BIT_LOW_DW:
last_value = value;
+ last_address = reg_desc->reg.addr;
/*
* A 64 bit register define requires 2 consecutive
@@ -1774,7 +1776,11 @@ snapshot_print_by_list_order(struct xe_hw_engine_snapshot *snapshot, struct drm_
XE_WARN_ON(!low32_ready);
low32_ready = false;
- drm_printf(p, "\t%s: 0x%016llx\n", reg_desc->regname, value_qw);
+ drm_printf(p, "\t%s: 0x%016llx [addr=0x%x]\n",
+ reg_desc->regname,
+ value_qw,
+ last_address);
+
break;
}
@@ -1788,10 +1794,14 @@ snapshot_print_by_list_order(struct xe_hw_engine_snapshot *snapshot, struct drm_
XE_WARN_ON(low32_ready);
if (FIELD_GET(GUC_REGSET_STEERING_NEEDED, reg_desc->flags))
- drm_printf(p, "\t%s[%u]: 0x%08x\n", reg_desc->regname,
- reg_desc->dss_id, value);
+ drm_printf(p, "\t%s[%u]: 0x%08x [addr=0x%x]\n",
+ reg_desc->regname,
+ reg_desc->dss_id, value, reg_desc->reg.addr);
+
else
- drm_printf(p, "\t%s: 0x%08x\n", reg_desc->regname, value);
+ drm_printf(p, "\t%s: 0x%08x [addr=0x%x]\n",
+ reg_desc->regname, value, reg_desc->reg.addr);
+
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v5 4/7] drm/xe: dump GAM page fault report registers in devcoredump
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
` (2 preceding siblings ...)
2026-10-22 13:29 ` [PATCH v5 3/7] drm/xe/guc: Print register addresses in capture snapshot output Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 5/7] drm/xe/guc: add TDL, SLICE gfx registers to capture list Nareshkumar Gollakoti
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Add PAGE_FLTRPTQ_HEAD_GAMCTRL and PAGE_FLTRPTQ_TAIL_GAMCTRL to the Xe
register definitions and capture them as part of the devcoredump
snapshot.
Include the register dump in the devcoredump output and release the
snapshot during cleanup so page fault report state is available for
post-mortem debugging.
v2:
- As design change made for previous patches. refactored this patch
as well to accommodate those changes.
- Add PF occurred print when the two register values are not equal
v4:
Refactored as per the patch1 change(Tejas)
v5:
Refactored as per patch1 changes
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 ++
drivers/gpu/drm/xe/xe_devcoredump.c | 37 +++++++++++++++++++++++
drivers/gpu/drm/xe/xe_devcoredump_types.h | 3 ++
3 files changed, 43 insertions(+)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index e93895e0c731..e9eb0bd04af1 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -530,6 +530,9 @@
#define LMEM_EN REG_BIT(31)
#define LMTT_DIR_PTR REG_GENMASK(30, 0) /* in multiples of 64KB */
+#define PAGE_FLTRPTQ_HEAD_GAMCTRL XE_REG(0xcf90)
+#define PAGE_FLTRPTQ_TAIL_GAMCTRL XE_REG(0xcf94)
+
#define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
#define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c
index ee92a0d203b8..9f2f46e40012 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -114,6 +114,11 @@ static const struct xe_reg_desc xe_dbg_media_gt_rpm_reglist[] = {
XE_REG_DESC(RPM_GCD, "RPM_GCD"),
};
+static const struct xe_reg_desc xe_dbg_gam_pf_reglist[] = {
+ XE_REG_DESC(PAGE_FLTRPTQ_HEAD_GAMCTRL, "PAGE_FLTRPTQ_HEAD_GAMCTRL"),
+ XE_REG_DESC(PAGE_FLTRPTQ_TAIL_GAMCTRL, "PAGE_FLTRPTQ_TAIL_GAMCTRL"),
+};
+
/**
* struct xe_gt_regset - Struct for register descriptor list for GT
*
@@ -133,12 +138,14 @@ struct xe_gt_regset {
* @XE_DBG_REGSET_FUSE: Fuse register set
* @XE_DBG_REGSET_RPM: RPM register set
* @XE_DBG_REGSET_GUC: GUC register set
+ * @XE_DBG_REGSET_GAM_PF: GAM Pagefault registers set
* @XE_DBG_REGSET_MAX: Number of debug register set types
*/
enum xe_dbg_regset_type {
XE_DBG_REGSET_FUSE,
XE_DBG_REGSET_RPM,
XE_DBG_REGSET_GUC,
+ XE_DBG_REGSET_GAM_PF,
XE_DBG_REGSET_MAX,
};
@@ -161,6 +168,10 @@ static const struct xe_gt_regset xe_dbg_regsets[XE_DBG_REGSET_MAX] = {
.gt[XE_GT_TYPE_MEDIA] = { xe_dbg_gt_guc_reglist,
ARRAY_SIZE(xe_dbg_gt_guc_reglist) },
},
+ [XE_DBG_REGSET_GAM_PF] = {
+ .gt[XE_GT_TYPE_MAIN] = { xe_dbg_gam_pf_reglist,
+ ARRAY_SIZE(xe_dbg_gam_pf_reglist) },
+ },
};
static void xe_dbg_reg_snapshot_print(struct drm_printer *p,
@@ -202,6 +213,23 @@ static const u32 *xe_dbg_find_value(const struct xe_dbg_reg_snapshot *snap,
return NULL;
}
+static void xe_gam_pf_snapshot_print(struct drm_printer *p,
+ const char *title,
+ const struct xe_dbg_reg_snapshot *snap)
+{
+ const u32 *val1, *val2;
+
+ xe_dbg_reg_snapshot_print(p, title, snap);
+
+ if (!snap)
+ return;
+
+ val1 = xe_dbg_find_value(snap, PAGE_FLTRPTQ_HEAD_GAMCTRL);
+ val2 = xe_dbg_find_value(snap, PAGE_FLTRPTQ_TAIL_GAMCTRL);
+ if ((val1 && val2) && (*val1 != *val2))
+ drm_printf(p, "PF occurred, refer to dmesg log for PF info\n");
+}
+
static void xe_gt_rpm_snapshot_print(struct drm_printer *p,
const char *title,
const struct xe_dbg_reg_snapshot *snap)
@@ -315,6 +343,8 @@ static ssize_t __xe_devcoredump_read(char *buffer, ssize_t count,
drm_puts(&p, "\n**** GuC CT ****\n");
xe_guc_ct_snapshot_print(ss->guc.ct, &p);
+ xe_gam_pf_snapshot_print(&p, "GAM PF Report", ss->gam_pf_report);
+
drm_puts(&p, "\n**** Contexts ****\n");
xe_guc_exec_queue_snapshot_print(ss->ge, &p);
@@ -369,6 +399,9 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
xe_guc_capture_put_matched_nodes(&ss->gt->uc.guc);
ss->matched_node = NULL;
+ xe_dbg_reg_snapshot_free(ss->gam_pf_report);
+ ss->gam_pf_report = NULL;
+
xe_guc_exec_queue_snapshot_free(ss->ge);
ss->ge = NULL;
@@ -565,6 +598,10 @@ static void xe_devcoredump_capture_gt_regs(struct xe_devcoredump_snapshot *ss,
other_gt,
XE_DBG_REGSET_GUC,
XE_GT_TYPE_MEDIA);
+ ss->gam_pf_report = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_GAM_PF,
+ XE_GT_TYPE_MAIN);
}
static void devcoredump_snapshot(struct xe_devcoredump *coredump,
diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h
index 52db64640f89..34f224a6751f 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump_types.h
+++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h
@@ -103,6 +103,9 @@ struct xe_devcoredump_snapshot {
struct xe_guc_log_snapshot *log;
} guc;
+ /** @gam_pf_report: GAM PF report snapshot */
+ struct xe_dbg_reg_snapshot *gam_pf_report;
+
/** @ge: GuC Submission Engine snapshot */
struct xe_guc_submit_exec_queue_snapshot *ge;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v5 5/7] drm/xe/guc: add TDL, SLICE gfx registers to capture list
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
` (3 preceding siblings ...)
2026-10-22 13:29 ` [PATCH v5 4/7] drm/xe: dump GAM page fault report registers in devcoredump Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 6/7] drm/xe: capture L3 node status registers in devcoredump Nareshkumar Gollakoti
2026-10-22 13:29 ` [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers Nareshkumar Gollakoti
6 siblings, 0 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Add ROW_INSTDONE_TDL_GFX, SS_LSC_HDC_IDLE_TDL_GFX and SLICE_ARB_STATUS
register definitions and include them in the XeHPG extended GuC capture
register list.
v2:(Sashiko)
- Refactored ROW_INSTDONE_TDL_GFX to ROW_INSTDONE_TDL_GFX
- Add SLICE_ARB_STATUS register to xeHP register list
- Refactor commit message
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 +++++
drivers/gpu/drm/xe/xe_guc_capture.c | 5 ++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index e9eb0bd04af1..2e4cb4957479 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -533,6 +533,8 @@
#define PAGE_FLTRPTQ_HEAD_GAMCTRL XE_REG(0xcf90)
#define PAGE_FLTRPTQ_TAIL_GAMCTRL XE_REG(0xcf94)
+#define SLICE_ARB_STATUS XE_REG_MCR(0xd814)
+
#define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
#define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
@@ -597,6 +599,9 @@
#define EU_SYSTOLIC_LIC_THROTTLE_CTL_WITH_LOCK XE_REG_MCR(0xe534)
#define EU_SYSTOLIC_LIC_THROTTLE_CTL_LOCK_BIT REG_BIT(31)
+#define ROW_INSTDONE_TDL_GFX XE_REG_MCR(0xe580)
+#define SS_LSC_HDC_IDLE_TDL_GFX XE_REG_MCR(0xe584)
+
#define XEHP_HDC_CHICKEN0 XE_REG_MCR(0xe5f0, XE_REG_OPTION_MASKED)
#define LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK REG_GENMASK(13, 11)
#define DIS_ATOMIC_CHAINING_TYPED_WRITES REG_BIT(3)
diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
index 3e99aef53b46..6a20eab0f820 100644
--- a/drivers/gpu/drm/xe/xe_guc_capture.c
+++ b/drivers/gpu/drm/xe/xe_guc_capture.c
@@ -376,7 +376,10 @@ static const struct __ext_steer_reg xehpg_extregs[] = {
{"SC_INSTDONE", XEHPG_SC_INSTDONE},
{"SC_INSTDONE_EXTRA", XEHPG_SC_INSTDONE_EXTRA},
{"SC_INSTDONE_EXTRA2", XEHPG_SC_INSTDONE_EXTRA2},
- {"INSTDONE_GEOM_SVGUNIT", XEHPG_INSTDONE_GEOM_SVGUNIT}
+ {"INSTDONE_GEOM_SVGUNIT", XEHPG_INSTDONE_GEOM_SVGUNIT},
+ {"ROW_INSTDONE_TDL_GFX", ROW_INSTDONE_TDL_GFX},
+ {"SS_LSC_HDC_IDLE_TDL_GFX", SS_LSC_HDC_IDLE_TDL_GFX},
+ {"SLICE_ARB_STATUS", SLICE_ARB_STATUS}
};
static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext,
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v5 6/7] drm/xe: capture L3 node status registers in devcoredump
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
` (4 preceding siblings ...)
2026-10-22 13:29 ` [PATCH v5 5/7] drm/xe/guc: add TDL, SLICE gfx registers to capture list Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
2026-10-26 7:06 ` Upadhyay, Tejas
2026-10-22 13:29 ` [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers Nareshkumar Gollakoti
6 siblings, 1 reply; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Add L3_NODE_IDLE and L3STAT_LBCF_GFX register definitions and include
them in the devcoredump snapshot as a node status section.
Extend the register descriptor to mark MCR registers so the snapshot
code can read them through xe_gt_mcr_unicast_read_any(), then print and
free the captured node status registers alongside the existing dump
sections.
v2:(Sashiko)
- change L3 node registers as XE_REG_MCR type
- identify mcr register type from reg.mcr
- As generic capture function ensure VF check this will not execute
on VF Mode.
v4:(Tejas)
- Add L3_NODE type into the enum as changed/added in initial patch
v5:
- Rebase
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 +++
drivers/gpu/drm/xe/xe_devcoredump.c | 32 ++++++++++++++++++++---
drivers/gpu/drm/xe/xe_devcoredump_types.h | 10 +++++--
3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 2e4cb4957479..55f0eee4e20e 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -454,6 +454,9 @@
#define L3_ESC_MASK REG_BIT(0)
#define L3_ESC(value) REG_FIELD_PREP(L3_ESC_MASK, value)
+#define L3_NODE_IDLE XE_REG_MCR(0xb0b0)
+#define L3STAT_LBCF_GFX XE_REG_MCR(0xb128)
+
#define XEHP_L3NODEARBCFG XE_REG_MCR(0xb0b4)
#define XEHP_LNESPARE REG_BIT(19)
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c
index 9f2f46e40012..1c80cc6c3b6a 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -28,6 +28,7 @@
#include "xe_mmio.h"
#include "regs/xe_gt_regs.h"
#include "regs/xe_guc_regs.h"
+#include "xe_gt_mcr.h"
/**
* DOC: Xe device coredump
@@ -73,6 +74,7 @@
#define XE_COREDUMP_TIMEOUT_JIFFIES (60 * 60 * HZ)
#define XE_REG_DESC(_reg, _name) { .reg = (_reg), .name = (_name) }
+#define XE_REG_DESC_MCR(_reg, _name) { .mcr_reg = (_reg), .name = (_name) }
static const struct xe_reg_desc xe_dbg_gt_guc_reglist[] = {
XE_REG_DESC(GUC_STATUS, "GUC_STATUS"),
@@ -119,6 +121,11 @@ static const struct xe_reg_desc xe_dbg_gam_pf_reglist[] = {
XE_REG_DESC(PAGE_FLTRPTQ_TAIL_GAMCTRL, "PAGE_FLTRPTQ_TAIL_GAMCTRL"),
};
+static const struct xe_reg_desc xe_dbg_l3_node_reglist[] = {
+ XE_REG_DESC_MCR(L3_NODE_IDLE, "L3_NODE_IDLE"),
+ XE_REG_DESC_MCR(L3STAT_LBCF_GFX, "L3STAT_LBCF_GFX"),
+};
+
/**
* struct xe_gt_regset - Struct for register descriptor list for GT
*
@@ -139,6 +146,7 @@ struct xe_gt_regset {
* @XE_DBG_REGSET_RPM: RPM register set
* @XE_DBG_REGSET_GUC: GUC register set
* @XE_DBG_REGSET_GAM_PF: GAM Pagefault registers set
+ * @XE_DBG_REGSET_L3_NODE: L3 Node register Set
* @XE_DBG_REGSET_MAX: Number of debug register set types
*/
enum xe_dbg_regset_type {
@@ -146,6 +154,7 @@ enum xe_dbg_regset_type {
XE_DBG_REGSET_RPM,
XE_DBG_REGSET_GUC,
XE_DBG_REGSET_GAM_PF,
+ XE_DBG_REGSET_L3_NODE,
XE_DBG_REGSET_MAX,
};
@@ -172,6 +181,10 @@ static const struct xe_gt_regset xe_dbg_regsets[XE_DBG_REGSET_MAX] = {
.gt[XE_GT_TYPE_MAIN] = { xe_dbg_gam_pf_reglist,
ARRAY_SIZE(xe_dbg_gam_pf_reglist) },
},
+ [XE_DBG_REGSET_L3_NODE] = {
+ .gt[XE_GT_TYPE_MAIN] = { xe_dbg_l3_node_reglist,
+ ARRAY_SIZE(xe_dbg_l3_node_reglist) },
+ },
};
static void xe_dbg_reg_snapshot_print(struct drm_printer *p,
@@ -262,8 +275,13 @@ xe_dbg_reg_snapshot_capture_target(struct xe_gt *gt,
snap->desc = reglist;
snap->num_regs = reglist->num_regs;
- for (i = 0; i < reglist->num_regs; i++)
- snap->values[i] = xe_mmio_read32(>->mmio, reglist->regs[i].reg);
+ for (i = 0; i < reglist->num_regs; i++) {
+ if (reglist->regs[i].reg.mcr)
+ snap->values[i] = xe_gt_mcr_unicast_read_any(gt,
+ reglist->regs[i].mcr_reg);
+ else
+ snap->values[i] = xe_mmio_read32(>->mmio, reglist->regs[i].reg);
+ }
return snap;
}
@@ -345,6 +363,8 @@ static ssize_t __xe_devcoredump_read(char *buffer, ssize_t count,
xe_gam_pf_snapshot_print(&p, "GAM PF Report", ss->gam_pf_report);
+ xe_dbg_reg_snapshot_print(&p, "Node Status", ss->ns);
+
drm_puts(&p, "\n**** Contexts ****\n");
xe_guc_exec_queue_snapshot_print(ss->ge, &p);
@@ -402,6 +422,9 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
xe_dbg_reg_snapshot_free(ss->gam_pf_report);
ss->gam_pf_report = NULL;
+ xe_dbg_reg_snapshot_free(ss->ns);
+ ss->ns = NULL;
+
xe_guc_exec_queue_snapshot_free(ss->ge);
ss->ge = NULL;
@@ -602,6 +625,10 @@ static void xe_devcoredump_capture_gt_regs(struct xe_devcoredump_snapshot *ss,
other_gt,
XE_DBG_REGSET_GAM_PF,
XE_GT_TYPE_MAIN);
+ ss->ns = xe_dbg_gt_snapshot_capture(gt,
+ other_gt,
+ XE_DBG_REGSET_L3_NODE,
+ XE_GT_TYPE_MAIN);
}
static void devcoredump_snapshot(struct xe_devcoredump *coredump,
@@ -653,7 +680,6 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump,
if (job)
ss->job = xe_sched_job_snapshot_capture(job);
ss->vm = xe_vm_snapshot_capture(q->vm);
-
xe_engine_snapshot_capture_for_queue(q);
}
diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h
index 34f224a6751f..6cbecad43c42 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump_types.h
+++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h
@@ -21,8 +21,12 @@ struct xe_gt;
* of the register to dump its value during coredump for debug purpose.
*/
struct xe_reg_desc {
- /** @reg: The register */
- struct xe_reg reg;
+ union {
+ /** @reg: The register */
+ struct xe_reg reg;
+ /** @mcr_reg: The mcr register */
+ struct xe_reg_mcr mcr_reg;
+ };
/** @name: Name of the register */
const char *name;
};
@@ -105,6 +109,8 @@ struct xe_devcoredump_snapshot {
/** @gam_pf_report: GAM PF report snapshot */
struct xe_dbg_reg_snapshot *gam_pf_report;
+ /** @ns: Node status snapshot */
+ struct xe_dbg_reg_snapshot *ns;
/** @ge: GuC Submission Engine snapshot */
struct xe_guc_submit_exec_queue_snapshot *ge;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* RE: [PATCH v5 6/7] drm/xe: capture L3 node status registers in devcoredump
2026-10-22 13:29 ` [PATCH v5 6/7] drm/xe: capture L3 node status registers in devcoredump Nareshkumar Gollakoti
@ 2026-10-26 7:06 ` Upadhyay, Tejas
2026-10-28 13:43 ` Upadhyay, Tejas
0 siblings, 1 reply; 13+ messages in thread
From: Upadhyay, Tejas @ 2026-10-26 7:06 UTC (permalink / raw)
To: Kumar G, Naresh, intel-xe@lists.freedesktop.org
> -----Original Message-----
> From: Kumar G, Naresh <naresh.kumar.g@intel.com>
> Sent: 22 October 2026 19:00
> To: intel-xe@lists.freedesktop.org
> Cc: Upadhyay, Tejas <tejas.upadhyay@intel.com>; Kumar G, Naresh
> <naresh.kumar.g@intel.com>
> Subject: [PATCH v5 6/7] drm/xe: capture L3 node status registers in
> devcoredump
>
> Add L3_NODE_IDLE and L3STAT_LBCF_GFX register definitions and include
> them in the devcoredump snapshot as a node status section.
>
> Extend the register descriptor to mark MCR registers so the snapshot code can
> read them through xe_gt_mcr_unicast_read_any(), then print and free the
> captured node status registers alongside the existing dump sections.
>
> v2:(Sashiko)
> - change L3 node registers as XE_REG_MCR type
> - identify mcr register type from reg.mcr
> - As generic capture function ensure VF check this will not execute
> on VF Mode.
>
> v4:(Tejas)
> - Add L3_NODE type into the enum as changed/added in initial patch
>
> v5:
> - Rebase
>
> Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
> ---
> drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 +++
> drivers/gpu/drm/xe/xe_devcoredump.c | 32 ++++++++++++++++++++---
> drivers/gpu/drm/xe/xe_devcoredump_types.h | 10 +++++--
> 3 files changed, 40 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> index 2e4cb4957479..55f0eee4e20e 100644
> --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> @@ -454,6 +454,9 @@
> #define L3_ESC_MASK REG_BIT(0)
> #define L3_ESC(value)
> REG_FIELD_PREP(L3_ESC_MASK, value)
>
> +#define L3_NODE_IDLE
> XE_REG_MCR(0xb0b0)
> +#define L3STAT_LBCF_GFX
> XE_REG_MCR(0xb128)
> +
> #define XEHP_L3NODEARBCFG XE_REG_MCR(0xb0b4)
> #define XEHP_LNESPARE REG_BIT(19)
>
> diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c
> b/drivers/gpu/drm/xe/xe_devcoredump.c
> index 9f2f46e40012..1c80cc6c3b6a 100644
> --- a/drivers/gpu/drm/xe/xe_devcoredump.c
> +++ b/drivers/gpu/drm/xe/xe_devcoredump.c
> @@ -28,6 +28,7 @@
> #include "xe_mmio.h"
> #include "regs/xe_gt_regs.h"
> #include "regs/xe_guc_regs.h"
> +#include "xe_gt_mcr.h"
Place correctly
>
> /**
> * DOC: Xe device coredump
> @@ -73,6 +74,7 @@
> #define XE_COREDUMP_TIMEOUT_JIFFIES (60 * 60 * HZ)
>
> #define XE_REG_DESC(_reg, _name) { .reg = (_reg), .name = (_name) }
> +#define XE_REG_DESC_MCR(_reg, _name) { .mcr_reg = (_reg), .name =
> (_name) }
>
> static const struct xe_reg_desc xe_dbg_gt_guc_reglist[] = {
> XE_REG_DESC(GUC_STATUS, "GUC_STATUS"),
> @@ -119,6 +121,11 @@ static const struct xe_reg_desc
> xe_dbg_gam_pf_reglist[] = {
> XE_REG_DESC(PAGE_FLTRPTQ_TAIL_GAMCTRL,
> "PAGE_FLTRPTQ_TAIL_GAMCTRL"), };
>
> +static const struct xe_reg_desc xe_dbg_l3_node_reglist[] = {
> + XE_REG_DESC_MCR(L3_NODE_IDLE, "L3_NODE_IDLE"),
> + XE_REG_DESC_MCR(L3STAT_LBCF_GFX, "L3STAT_LBCF_GFX"), };
> +
> /**
> * struct xe_gt_regset - Struct for register descriptor list for GT
> *
> @@ -139,6 +146,7 @@ struct xe_gt_regset {
> * @XE_DBG_REGSET_RPM: RPM register set
> * @XE_DBG_REGSET_GUC: GUC register set
> * @XE_DBG_REGSET_GAM_PF: GAM Pagefault registers set
> + * @XE_DBG_REGSET_L3_NODE: L3 Node register Set
> * @XE_DBG_REGSET_MAX: Number of debug register set types
> */
> enum xe_dbg_regset_type {
> @@ -146,6 +154,7 @@ enum xe_dbg_regset_type {
> XE_DBG_REGSET_RPM,
> XE_DBG_REGSET_GUC,
> XE_DBG_REGSET_GAM_PF,
> + XE_DBG_REGSET_L3_NODE,
> XE_DBG_REGSET_MAX,
> };
>
> @@ -172,6 +181,10 @@ static const struct xe_gt_regset
> xe_dbg_regsets[XE_DBG_REGSET_MAX] = {
> .gt[XE_GT_TYPE_MAIN] = { xe_dbg_gam_pf_reglist,
> ARRAY_SIZE(xe_dbg_gam_pf_reglist)
> },
> },
> + [XE_DBG_REGSET_L3_NODE] = {
> + .gt[XE_GT_TYPE_MAIN] = { xe_dbg_l3_node_reglist,
> + ARRAY_SIZE(xe_dbg_l3_node_reglist)
> },
> + },
> };
>
> static void xe_dbg_reg_snapshot_print(struct drm_printer *p, @@ -262,8
> +275,13 @@ xe_dbg_reg_snapshot_capture_target(struct xe_gt *gt,
>
> snap->desc = reglist;
> snap->num_regs = reglist->num_regs;
> - for (i = 0; i < reglist->num_regs; i++)
> - snap->values[i] = xe_mmio_read32(>->mmio, reglist-
> >regs[i].reg);
> + for (i = 0; i < reglist->num_regs; i++) {
> + if (reglist->regs[i].reg.mcr)
> + snap->values[i] = xe_gt_mcr_unicast_read_any(gt,
> + reglist-
> >regs[i].mcr_reg);
The requirement calls for reading L3_NODE_IDLE once per groupid (0-7), and L3STAT_LBCF_GFX once per every groupid×instanceid combination (8×4 = 32 reads), each explicitly steered via the MCR selector and labeled Node[groupid]/Bank[groupid][instanceid]. Isn't it?
Tejas
> + else
> + snap->values[i] = xe_mmio_read32(>->mmio,
> reglist->regs[i].reg);
> + }
>
> return snap;
> }
> @@ -345,6 +363,8 @@ static ssize_t __xe_devcoredump_read(char *buffer,
> ssize_t count,
>
> xe_gam_pf_snapshot_print(&p, "GAM PF Report", ss-
> >gam_pf_report);
>
> + xe_dbg_reg_snapshot_print(&p, "Node Status", ss->ns);
> +
> drm_puts(&p, "\n**** Contexts ****\n");
> xe_guc_exec_queue_snapshot_print(ss->ge, &p);
>
> @@ -402,6 +422,9 @@ static void xe_devcoredump_snapshot_free(struct
> xe_devcoredump_snapshot *ss)
> xe_dbg_reg_snapshot_free(ss->gam_pf_report);
> ss->gam_pf_report = NULL;
>
> + xe_dbg_reg_snapshot_free(ss->ns);
> + ss->ns = NULL;
> +
> xe_guc_exec_queue_snapshot_free(ss->ge);
> ss->ge = NULL;
>
> @@ -602,6 +625,10 @@ static void xe_devcoredump_capture_gt_regs(struct
> xe_devcoredump_snapshot *ss,
> other_gt,
>
> XE_DBG_REGSET_GAM_PF,
> XE_GT_TYPE_MAIN);
> + ss->ns = xe_dbg_gt_snapshot_capture(gt,
> + other_gt,
> + XE_DBG_REGSET_L3_NODE,
> + XE_GT_TYPE_MAIN);
> }
>
> static void devcoredump_snapshot(struct xe_devcoredump *coredump, @@
> -653,7 +680,6 @@ static void devcoredump_snapshot(struct
> xe_devcoredump *coredump,
> if (job)
> ss->job = xe_sched_job_snapshot_capture(job);
> ss->vm = xe_vm_snapshot_capture(q->vm);
> -
> xe_engine_snapshot_capture_for_queue(q);
> }
>
> diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h
> b/drivers/gpu/drm/xe/xe_devcoredump_types.h
> index 34f224a6751f..6cbecad43c42 100644
> --- a/drivers/gpu/drm/xe/xe_devcoredump_types.h
> +++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h
> @@ -21,8 +21,12 @@ struct xe_gt;
> * of the register to dump its value during coredump for debug purpose.
> */
> struct xe_reg_desc {
> - /** @reg: The register */
> - struct xe_reg reg;
> + union {
> + /** @reg: The register */
> + struct xe_reg reg;
> + /** @mcr_reg: The mcr register */
> + struct xe_reg_mcr mcr_reg;
> + };
> /** @name: Name of the register */
> const char *name;
> };
> @@ -105,6 +109,8 @@ struct xe_devcoredump_snapshot {
>
> /** @gam_pf_report: GAM PF report snapshot */
> struct xe_dbg_reg_snapshot *gam_pf_report;
> + /** @ns: Node status snapshot */
> + struct xe_dbg_reg_snapshot *ns;
>
> /** @ge: GuC Submission Engine snapshot */
> struct xe_guc_submit_exec_queue_snapshot *ge;
> --
> 2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread* RE: [PATCH v5 6/7] drm/xe: capture L3 node status registers in devcoredump
2026-10-26 7:06 ` Upadhyay, Tejas
@ 2026-10-28 13:43 ` Upadhyay, Tejas
0 siblings, 0 replies; 13+ messages in thread
From: Upadhyay, Tejas @ 2026-10-28 13:43 UTC (permalink / raw)
To: Upadhyay, Tejas, Kumar G, Naresh, intel-xe@lists.freedesktop.org
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of
> Upadhyay, Tejas
> Sent: 26 October 2026 12:37
> To: Kumar G, Naresh <naresh.kumar.g@intel.com>; intel-
> xe@lists.freedesktop.org
> Subject: RE: [PATCH v5 6/7] drm/xe: capture L3 node status registers in
> devcoredump
>
>
>
> > -----Original Message-----
> > From: Kumar G, Naresh <naresh.kumar.g@intel.com>
> > Sent: 22 October 2026 19:00
> > To: intel-xe@lists.freedesktop.org
> > Cc: Upadhyay, Tejas <tejas.upadhyay@intel.com>; Kumar G, Naresh
> > <naresh.kumar.g@intel.com>
> > Subject: [PATCH v5 6/7] drm/xe: capture L3 node status registers in
> > devcoredump
> >
> > Add L3_NODE_IDLE and L3STAT_LBCF_GFX register definitions and include
> > them in the devcoredump snapshot as a node status section.
> >
> > Extend the register descriptor to mark MCR registers so the snapshot
> > code can read them through xe_gt_mcr_unicast_read_any(), then print
> > and free the captured node status registers alongside the existing dump
> sections.
> >
> > v2:(Sashiko)
> > - change L3 node registers as XE_REG_MCR type
> > - identify mcr register type from reg.mcr
> > - As generic capture function ensure VF check this will not execute
> > on VF Mode.
> >
> > v4:(Tejas)
> > - Add L3_NODE type into the enum as changed/added in initial patch
> >
> > v5:
> > - Rebase
> >
> > Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
> > ---
> > drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 +++
> > drivers/gpu/drm/xe/xe_devcoredump.c | 32 ++++++++++++++++++++-
> --
> > drivers/gpu/drm/xe/xe_devcoredump_types.h | 10 +++++--
> > 3 files changed, 40 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > index 2e4cb4957479..55f0eee4e20e 100644
> > --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > @@ -454,6 +454,9 @@
> > #define L3_ESC_MASK REG_BIT(0)
> > #define L3_ESC(value)
> > REG_FIELD_PREP(L3_ESC_MASK, value)
> >
> > +#define L3_NODE_IDLE
> > XE_REG_MCR(0xb0b0)
> > +#define L3STAT_LBCF_GFX
> > XE_REG_MCR(0xb128)
> > +
> > #define XEHP_L3NODEARBCFG
> XE_REG_MCR(0xb0b4)
> > #define XEHP_LNESPARE REG_BIT(19)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c
> > b/drivers/gpu/drm/xe/xe_devcoredump.c
> > index 9f2f46e40012..1c80cc6c3b6a 100644
> > --- a/drivers/gpu/drm/xe/xe_devcoredump.c
> > +++ b/drivers/gpu/drm/xe/xe_devcoredump.c
> > @@ -28,6 +28,7 @@
> > #include "xe_mmio.h"
> > #include "regs/xe_gt_regs.h"
> > #include "regs/xe_guc_regs.h"
> > +#include "xe_gt_mcr.h"
>
> Place correctly
>
> >
> > /**
> > * DOC: Xe device coredump
> > @@ -73,6 +74,7 @@
> > #define XE_COREDUMP_TIMEOUT_JIFFIES (60 * 60 * HZ)
> >
> > #define XE_REG_DESC(_reg, _name) { .reg = (_reg), .name = (_name) }
> > +#define XE_REG_DESC_MCR(_reg, _name) { .mcr_reg = (_reg), .name =
> > (_name) }
> >
> > static const struct xe_reg_desc xe_dbg_gt_guc_reglist[] = {
> > XE_REG_DESC(GUC_STATUS, "GUC_STATUS"),
> > @@ -119,6 +121,11 @@ static const struct xe_reg_desc
> > xe_dbg_gam_pf_reglist[] = {
> > XE_REG_DESC(PAGE_FLTRPTQ_TAIL_GAMCTRL,
> > "PAGE_FLTRPTQ_TAIL_GAMCTRL"), };
> >
> > +static const struct xe_reg_desc xe_dbg_l3_node_reglist[] = {
> > + XE_REG_DESC_MCR(L3_NODE_IDLE, "L3_NODE_IDLE"),
> > + XE_REG_DESC_MCR(L3STAT_LBCF_GFX, "L3STAT_LBCF_GFX"), };
> > +
> > /**
> > * struct xe_gt_regset - Struct for register descriptor list for GT
> > *
> > @@ -139,6 +146,7 @@ struct xe_gt_regset {
> > * @XE_DBG_REGSET_RPM: RPM register set
> > * @XE_DBG_REGSET_GUC: GUC register set
> > * @XE_DBG_REGSET_GAM_PF: GAM Pagefault registers set
> > + * @XE_DBG_REGSET_L3_NODE: L3 Node register Set
> > * @XE_DBG_REGSET_MAX: Number of debug register set types
> > */
> > enum xe_dbg_regset_type {
> > @@ -146,6 +154,7 @@ enum xe_dbg_regset_type {
> > XE_DBG_REGSET_RPM,
> > XE_DBG_REGSET_GUC,
> > XE_DBG_REGSET_GAM_PF,
> > + XE_DBG_REGSET_L3_NODE,
> > XE_DBG_REGSET_MAX,
> > };
> >
> > @@ -172,6 +181,10 @@ static const struct xe_gt_regset
> > xe_dbg_regsets[XE_DBG_REGSET_MAX] = {
> > .gt[XE_GT_TYPE_MAIN] = { xe_dbg_gam_pf_reglist,
> > ARRAY_SIZE(xe_dbg_gam_pf_reglist)
> },
> > },
> > + [XE_DBG_REGSET_L3_NODE] = {
> > + .gt[XE_GT_TYPE_MAIN] = { xe_dbg_l3_node_reglist,
> > + ARRAY_SIZE(xe_dbg_l3_node_reglist)
> > },
> > + },
> > };
> >
> > static void xe_dbg_reg_snapshot_print(struct drm_printer *p, @@
> > -262,8
> > +275,13 @@ xe_dbg_reg_snapshot_capture_target(struct xe_gt *gt,
> >
> > snap->desc = reglist;
> > snap->num_regs = reglist->num_regs;
> > - for (i = 0; i < reglist->num_regs; i++)
> > - snap->values[i] = xe_mmio_read32(>->mmio, reglist-
> > >regs[i].reg);
> > + for (i = 0; i < reglist->num_regs; i++) {
> > + if (reglist->regs[i].reg.mcr)
> > + snap->values[i] = xe_gt_mcr_unicast_read_any(gt,
> > + reglist-
> > >regs[i].mcr_reg);
>
> The requirement calls for reading L3_NODE_IDLE once per groupid (0-7), and
> L3STAT_LBCF_GFX once per every groupid×instanceid combination (8×4 = 32
> reads), each explicitly steered via the MCR selector and labeled
> Node[groupid]/Bank[groupid][instanceid]. Isn't it?
Was this addressed?
Tejas
>
> Tejas
>
> > + else
> > + snap->values[i] = xe_mmio_read32(>->mmio,
> > reglist->regs[i].reg);
> > + }
> >
> > return snap;
> > }
> > @@ -345,6 +363,8 @@ static ssize_t __xe_devcoredump_read(char *buffer,
> > ssize_t count,
> >
> > xe_gam_pf_snapshot_print(&p, "GAM PF Report", ss-
> > >gam_pf_report);
> >
> > + xe_dbg_reg_snapshot_print(&p, "Node Status", ss->ns);
> > +
> > drm_puts(&p, "\n**** Contexts ****\n");
> > xe_guc_exec_queue_snapshot_print(ss->ge, &p);
> >
> > @@ -402,6 +422,9 @@ static void xe_devcoredump_snapshot_free(struct
> > xe_devcoredump_snapshot *ss)
> > xe_dbg_reg_snapshot_free(ss->gam_pf_report);
> > ss->gam_pf_report = NULL;
> >
> > + xe_dbg_reg_snapshot_free(ss->ns);
> > + ss->ns = NULL;
> > +
> > xe_guc_exec_queue_snapshot_free(ss->ge);
> > ss->ge = NULL;
> >
> > @@ -602,6 +625,10 @@ static void
> xe_devcoredump_capture_gt_regs(struct
> > xe_devcoredump_snapshot *ss,
> > other_gt,
> >
> > XE_DBG_REGSET_GAM_PF,
> > XE_GT_TYPE_MAIN);
> > + ss->ns = xe_dbg_gt_snapshot_capture(gt,
> > + other_gt,
> > + XE_DBG_REGSET_L3_NODE,
> > + XE_GT_TYPE_MAIN);
> > }
> >
> > static void devcoredump_snapshot(struct xe_devcoredump *coredump,
> @@
> > -653,7 +680,6 @@ static void devcoredump_snapshot(struct
> > xe_devcoredump *coredump,
> > if (job)
> > ss->job = xe_sched_job_snapshot_capture(job);
> > ss->vm = xe_vm_snapshot_capture(q->vm);
> > -
> > xe_engine_snapshot_capture_for_queue(q);
> > }
> >
> > diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h
> > b/drivers/gpu/drm/xe/xe_devcoredump_types.h
> > index 34f224a6751f..6cbecad43c42 100644
> > --- a/drivers/gpu/drm/xe/xe_devcoredump_types.h
> > +++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h
> > @@ -21,8 +21,12 @@ struct xe_gt;
> > * of the register to dump its value during coredump for debug purpose.
> > */
> > struct xe_reg_desc {
> > - /** @reg: The register */
> > - struct xe_reg reg;
> > + union {
> > + /** @reg: The register */
> > + struct xe_reg reg;
> > + /** @mcr_reg: The mcr register */
> > + struct xe_reg_mcr mcr_reg;
> > + };
> > /** @name: Name of the register */
> > const char *name;
> > };
> > @@ -105,6 +109,8 @@ struct xe_devcoredump_snapshot {
> >
> > /** @gam_pf_report: GAM PF report snapshot */
> > struct xe_dbg_reg_snapshot *gam_pf_report;
> > + /** @ns: Node status snapshot */
> > + struct xe_dbg_reg_snapshot *ns;
> >
> > /** @ge: GuC Submission Engine snapshot */
> > struct xe_guc_submit_exec_queue_snapshot *ge;
> > --
> > 2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers
2026-10-22 13:29 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
` (5 preceding siblings ...)
2026-10-22 13:29 ` [PATCH v5 6/7] drm/xe: capture L3 node status registers in devcoredump Nareshkumar Gollakoti
@ 2026-10-22 13:29 ` Nareshkumar Gollakoti
6 siblings, 0 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-22 13:29 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Add a wider set of engine state registers to GuC error capture to improve
post-mortem debugging of engine hangs and reset-related failures.
Define the missing register offsets in xe_engine_regs.h and include them in
the GuC capture list. The additional registers cover reset state, front-end
and back-end FSM state, power state, batch buffer state, instruction state,
preemption status, and related chicken/debug controls.
This provides more complete engine context in capture dumps, which should
help root-cause analysis when investigating GuC-reported engine failures.
v3:(Sashiko)
- Move FF_SLICE_CS_CHICKEN1/2 out of COMMON_BASE_ENGINE_INSTANCE
- Add XE3P_RC_SLICE_INSTANCE and include it only in xe3p_rc_inst_regs[]
- Add XE_BCS_RCS_ENGINE_INSTANCE for registers shared only by
BCS/RCS paths
- Include XE_BCS_RCS_ENGINE_INSTANCE only in
xe_blt_inst_regs[] and xe3p_rc_inst_regs[]
- Keep COMMON_BASE_ENGINE_INSTANCE limited to registers
valid across all engine classes
v5:(Sashiko)
- Keep RING_EXECLIST_* in COMMON_BASE_ENGINE_INSTANCE
- Drop XE_BCS_RCS_ENGINE_INSTANCE
- BCS_SWCTRL only on xe3p_blt_inst_regs
- CS_DEBUG_MODE1/CS_CHICKEN1/CS_PREEMPTION_STATUS only on xe3p_rc_inst_regs
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_engine_regs.h | 22 +++++++++
drivers/gpu/drm/xe/xe_guc_capture.c | 57 ++++++++++++++++++++++--
2 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
index 94033982e694..9f328b1b18f5 100644
--- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
@@ -60,6 +60,8 @@
#define RING_START_UDW(base) XE_REG((base) + 0x48)
+#define RING_CSFE_GLB_CHICKEN3(base) XE_REG((base) + 0x4c)
+
#define RING_PSMI_CTL(base) XE_REG((base) + 0x50, XE_REG_OPTION_MASKED)
#define RC_SEMA_IDLE_MSG_DISABLE REG_BIT(12)
#define WAIT_FOR_EVENT_POWER_DOWN_DISABLE REG_BIT(7)
@@ -72,6 +74,7 @@
#define RING_DMA_FADD_UDW(base) XE_REG((base) + 0x60)
#define RING_IPEHR(base) XE_REG((base) + 0x68)
#define RING_INSTDONE(base) XE_REG((base) + 0x6c)
+#define RING_INSTPS(base) XE_REG((base) + 0x70)
#define RING_ACTHD(base) XE_REG((base) + 0x74)
#define RING_DMA_FADD(base) XE_REG((base) + 0x78)
#define RING_HWS_PGA(base) XE_REG((base) + 0x80)
@@ -102,6 +105,8 @@
#define SELECTIVE_READ_GROUP REG_GENMASK(29, 23)
#define SELECTIVE_READ_INSTANCE REG_GENMASK(22, 16)
+#define RESET_CTRL(base) XE_REG((base) + 0xd0)
+
/*
* CMD_CCTL read/write fields take a MOCS value and _not_ a table index.
* The lsb of each can be considered a separate enabling bit for encryption.
@@ -123,15 +128,21 @@
#define FF_SLICE_CS_CHICKEN1(base) XE_REG((base) + 0xe0, XE_REG_OPTION_MASKED)
#define FFSC_PERCTX_PREEMPT_CTRL REG_BIT(14)
+#define FF_SLICE_CS_CHICKEN2(base) XE_REG((base) + 0xe4, XE_REG_OPTION_MASKED)
+
#define CS_DEBUG_MODE1(base) XE_REG((base) + 0xec, XE_REG_OPTION_MASKED)
#define FF_DOP_CLOCK_GATE_DISABLE REG_BIT(1)
#define REPLAY_MODE_GRANULARITY REG_BIT(0)
#define INDIRECT_RING_STATE(base) XE_REG((base) + 0x108)
+#define RING_BB_STATE(base) XE_REG((base) + 0x110)
+
#define RING_BBADDR(base) XE_REG((base) + 0x140)
#define RING_BBADDR_UDW(base) XE_REG((base) + 0x168)
+#define RING_BB_ADDR_DIFF(base) XE_REG((base) + 0x154)
+
#define PR_CTR_CTRL(base) XE_REG((base) + 0x178)
#define CTR_COUNT_SELECT_FF REG_BIT(31)
#define CTR_LOGIC_OP_MASK REG_GENMASK(30, 0)
@@ -148,6 +159,8 @@
#define BLIT_CCTL_DST_MOCS_MASK REG_GENMASK(14, 9)
#define BLIT_CCTL_SRC_MOCS_MASK REG_GENMASK(6, 1)
+#define RING_CSBEFSM3(base) XE_REG((base) + 0x224)
+
#define RING_EXECLIST_STATUS_LO(base) XE_REG((base) + 0x234)
#define RING_EXECLIST_STATUS_HI(base) XE_REG((base) + 0x234 + 4)
@@ -169,9 +182,16 @@
#define GFX_MSIX_INTERRUPT_ENABLE REG_BIT(13)
#define GFX_DISABLE_LEGACY_MODE REG_BIT(3)
+#define RING_CSFESM(base) XE_REG((base) + 0x2a0)
+#define RING_CSFESM2(base) XE_REG((base) + 0x2a4)
+#define RING_CSFESM3(base) XE_REG((base) + 0x2a8)
+#define RING_CSPWRFSM(base) XE_REG((base) + 0x2ac)
+
#define RING_CSMQDEBUG(base) XE_REG((base) + 0x2b0)
#define CURRENT_ACTIVE_QUEUE_ID_MASK REG_GENMASK(7, 0)
+#define RING_CSBEFSM(base) XE_REG((base) + 0x2bc)
+
#define RING_QUEUE_TIMESTAMP(base) XE_REG((base) + 0x4c0)
#define RING_QUEUE_TIMESTAMP_UDW(base) XE_REG((base) + 0x4c0 + 4)
@@ -217,6 +237,8 @@
#define PREEMPT_GPGPU_LEVEL_MASK PREEMPT_GPGPU_LEVEL(1, 1)
#define PREEMPT_3D_OBJECT_LEVEL REG_BIT(0)
+#define CS_PREEMPTION_STATUS(base) XE_REG((base) + 0x5ac)
+
#define CS_GPR_DATA(base, n) XE_REG((base) + 0x600 + (n) * 4)
#define CS_GPR_REG(base, n) CS_GPR_DATA((base), (n) * 2)
#define CS_GPR_REG_UDW(base, n) CS_GPR_DATA((base), (n) * 2 + 1)
diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
index 6a20eab0f820..2e13df97e106 100644
--- a/drivers/gpu/drm/xe/xe_guc_capture.c
+++ b/drivers/gpu/drm/xe/xe_guc_capture.c
@@ -150,6 +150,33 @@ struct __guc_capture_parsed_output {
#define XE3P_BASE_ENGINE_INSTANCE \
{ RING_CSMQDEBUG(0), REG_32BIT, 0, 0, 0, "CSMQDEBUG"}
+#define XE3P_CS_DEBUG_INSTANCE \
+ { RESET_CTRL(0), REG_32BIT, 0, 0, 0, "RESET_CTRL"}, \
+ { RING_CSBEFSM3(0), REG_32BIT, 0, 0, 0, "RING_CSBEFSM3"}, \
+ { RING_CSFESM(0), REG_32BIT, 0, 0, 0, "RING_CSFESM"}, \
+ { RING_CSFESM2(0), REG_32BIT, 0, 0, 0, "RING_CSFESM2"}, \
+ { RING_CSFESM3(0), REG_32BIT, 0, 0, 0, "RING_CSFESM3"}, \
+ { RING_CSPWRFSM(0), REG_32BIT, 0, 0, 0, "RING_CSPWRFSM"}, \
+ { RING_CSBEFSM(0), REG_32BIT, 0, 0, 0, "RING_CSBEFSM"}, \
+ { RING_CSFE_GLB_CHICKEN3(0), REG_32BIT, 0, 0, 0, "RING_CSFE_GLB_CHICKEN3"}, \
+ { RING_PSMI_CTL(0), REG_32BIT, 0, 0, 0, "RING_PSMI_CTL"}, \
+ { RING_INSTPS(0), REG_32BIT, 0, 0, 0, "RING_INSTPS"}, \
+ { RING_BB_ADDR_DIFF(0), REG_32BIT, 0, 0, 0, "RING_BB_ADDR_DIFF"}, \
+ { RING_BB_STATE(0), REG_32BIT, 0, 0, 0, "RING_BB_STATE"}
+
+/*
+ * CS_CHICKEN1 has GPGPU/3D preempt bits; keep with RCS/CCS only.
+ * RCS+CCS share GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE, so these cannot
+ * be RCS-only.
+ */
+#define XE3P_RC_CS_PREEMPT_INSTANCE \
+ { CS_DEBUG_MODE1(0), REG_32BIT, 0, 0, 0, "CS_DEBUG_MODE1"}, \
+ { CS_CHICKEN1(0), REG_32BIT, 0, 0, 0, "CS_CHICKEN1"}, \
+ { CS_PREEMPTION_STATUS(0), REG_32BIT, 0, 0, 0, "CS_PREEMPTION_STATUS"}
+
+#define XE3P_BCS_ONLY_INSTANCE \
+ { BCS_SWCTRL(0), REG_32BIT, 0, 0, 0, "BCS_SWCTRL"}
+
/* XE_LP Global */
static const struct __guc_mmio_reg_descr xe_lp_global_regs[] = {
COMMON_XELP_BASE_GLOBAL,
@@ -186,9 +213,12 @@ static const struct __guc_mmio_reg_descr xe_vec_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
+#define XE_BLT_INST_REGS \
+ COMMON_BASE_ENGINE_INSTANCE
+
/* Blitter Per-Engine-Instance */
static const struct __guc_mmio_reg_descr xe_blt_inst_regs[] = {
- COMMON_BASE_ENGINE_INSTANCE,
+ XE_BLT_INST_REGS,
};
/* XE_LP - GSC Per-Engine-Instance */
@@ -200,6 +230,15 @@ static const struct __guc_mmio_reg_descr xe_lp_gsc_inst_regs[] = {
static const struct __guc_mmio_reg_descr xe3p_rc_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
XE3P_BASE_ENGINE_INSTANCE,
+ XE3P_CS_DEBUG_INSTANCE,
+ XE3P_RC_CS_PREEMPT_INSTANCE,
+};
+
+/* Xe3p Blitter Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr xe3p_blt_inst_regs[] = {
+ XE_BLT_INST_REGS,
+ XE3P_CS_DEBUG_INSTANCE,
+ XE3P_BCS_ONLY_INSTANCE,
};
/*
@@ -264,7 +303,7 @@ static const struct __guc_mmio_reg_descr_group xe3p_lists[] = {
MAKE_REGLIST(xe_vec_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
MAKE_REGLIST(xe_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER),
- MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
+ MAKE_REGLIST(xe3p_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_PAGING),
@@ -377,9 +416,12 @@ static const struct __ext_steer_reg xehpg_extregs[] = {
{"SC_INSTDONE_EXTRA", XEHPG_SC_INSTDONE_EXTRA},
{"SC_INSTDONE_EXTRA2", XEHPG_SC_INSTDONE_EXTRA2},
{"INSTDONE_GEOM_SVGUNIT", XEHPG_INSTDONE_GEOM_SVGUNIT},
+};
+
+static const struct __ext_steer_reg xe2_extregs[] = {
{"ROW_INSTDONE_TDL_GFX", ROW_INSTDONE_TDL_GFX},
{"SS_LSC_HDC_IDLE_TDL_GFX", SS_LSC_HDC_IDLE_TDL_GFX},
- {"SLICE_ARB_STATUS", SLICE_ARB_STATUS}
+ {"SLICE_ARB_STATUS", SLICE_ARB_STATUS},
};
static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext,
@@ -422,6 +464,8 @@ static int guc_capture_get_steer_reg_num(struct xe_device *xe)
if (GRAPHICS_VERx100(xe) >= 1255)
num += ARRAY_SIZE(xehpg_extregs);
+ if (GRAPHICS_VER(xe) >= 20)
+ num += ARRAY_SIZE(xe2_extregs);
return num;
}
@@ -434,6 +478,7 @@ static void guc_capture_alloc_steered_lists(struct xe_guc *guc)
const struct __guc_mmio_reg_descr_group *lists = guc->capture->reglists;
const struct __guc_mmio_reg_descr_group *list;
struct __guc_mmio_reg_descr_group *extlists;
+ bool has_xe2_extregs = GRAPHICS_VER(gt_to_xe(gt)) >= 20;
struct __guc_mmio_reg_descr *extarray;
bool has_xehpg_extregs = GRAPHICS_VERx100(gt_to_xe(gt)) >= 1255;
struct drm_device *drm = >_to_xe(gt)->drm;
@@ -504,6 +549,12 @@ static void guc_capture_alloc_steered_lists(struct xe_guc *guc)
__fill_ext_reg(extarray, &xehpg_extregs[i], dss, slice, subslice);
++extarray;
}
+
+ if (has_xe2_extregs)
+ for (i = 0; i < ARRAY_SIZE(xe2_extregs); ++i) {
+ __fill_ext_reg(extarray, &xe2_extregs[i], dss, slice, subslice);
+ ++extarray;
+ }
}
extlists[0].num_regs = total;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers
2026-10-23 6:05 [PATCH v5 0/7] drm/xe: Capture additional HW register state in devcoredump Nareshkumar Gollakoti
@ 2026-10-23 6:05 ` Nareshkumar Gollakoti
2026-10-23 6:26 ` sashiko-bot
2026-10-26 9:15 ` Upadhyay, Tejas
0 siblings, 2 replies; 13+ messages in thread
From: Nareshkumar Gollakoti @ 2026-10-23 6:05 UTC (permalink / raw)
To: intel-xe; +Cc: tejas.upadhyay, Nareshkumar Gollakoti
Add a wider set of engine state registers to GuC error capture to improve
post-mortem debugging of engine hangs and reset-related failures.
Define the missing register offsets in xe_engine_regs.h and include them in
the GuC capture list. The additional registers cover reset state, front-end
and back-end FSM state, power state, batch buffer state, instruction state,
preemption status, and related chicken/debug controls.
This provides more complete engine context in capture dumps, which should
help root-cause analysis when investigating GuC-reported engine failures.
v3:(Sashiko)
- Move FF_SLICE_CS_CHICKEN1/2 out of COMMON_BASE_ENGINE_INSTANCE
- Add XE3P_RC_SLICE_INSTANCE and include it only in xe3p_rc_inst_regs[]
- Add XE_BCS_RCS_ENGINE_INSTANCE for registers shared only by
BCS/RCS paths
- Include XE_BCS_RCS_ENGINE_INSTANCE only in
xe_blt_inst_regs[] and xe3p_rc_inst_regs[]
- Keep COMMON_BASE_ENGINE_INSTANCE limited to registers
valid across all engine classes
v5:(Sashiko)
- Keep RING_EXECLIST_* in COMMON_BASE_ENGINE_INSTANCE
- Drop XE_BCS_RCS_ENGINE_INSTANCE
- BCS_SWCTRL only on xe3p_blt_inst_regs
- CS_DEBUG_MODE1/CS_CHICKEN1/CS_PREEMPTION_STATUS only on xe3p_rc_inst_regs
Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
---
drivers/gpu/drm/xe/regs/xe_engine_regs.h | 22 +++++++++
drivers/gpu/drm/xe/xe_guc_capture.c | 57 ++++++++++++++++++++++--
2 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
index 94033982e694..9f328b1b18f5 100644
--- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
@@ -60,6 +60,8 @@
#define RING_START_UDW(base) XE_REG((base) + 0x48)
+#define RING_CSFE_GLB_CHICKEN3(base) XE_REG((base) + 0x4c)
+
#define RING_PSMI_CTL(base) XE_REG((base) + 0x50, XE_REG_OPTION_MASKED)
#define RC_SEMA_IDLE_MSG_DISABLE REG_BIT(12)
#define WAIT_FOR_EVENT_POWER_DOWN_DISABLE REG_BIT(7)
@@ -72,6 +74,7 @@
#define RING_DMA_FADD_UDW(base) XE_REG((base) + 0x60)
#define RING_IPEHR(base) XE_REG((base) + 0x68)
#define RING_INSTDONE(base) XE_REG((base) + 0x6c)
+#define RING_INSTPS(base) XE_REG((base) + 0x70)
#define RING_ACTHD(base) XE_REG((base) + 0x74)
#define RING_DMA_FADD(base) XE_REG((base) + 0x78)
#define RING_HWS_PGA(base) XE_REG((base) + 0x80)
@@ -102,6 +105,8 @@
#define SELECTIVE_READ_GROUP REG_GENMASK(29, 23)
#define SELECTIVE_READ_INSTANCE REG_GENMASK(22, 16)
+#define RESET_CTRL(base) XE_REG((base) + 0xd0)
+
/*
* CMD_CCTL read/write fields take a MOCS value and _not_ a table index.
* The lsb of each can be considered a separate enabling bit for encryption.
@@ -123,15 +128,21 @@
#define FF_SLICE_CS_CHICKEN1(base) XE_REG((base) + 0xe0, XE_REG_OPTION_MASKED)
#define FFSC_PERCTX_PREEMPT_CTRL REG_BIT(14)
+#define FF_SLICE_CS_CHICKEN2(base) XE_REG((base) + 0xe4, XE_REG_OPTION_MASKED)
+
#define CS_DEBUG_MODE1(base) XE_REG((base) + 0xec, XE_REG_OPTION_MASKED)
#define FF_DOP_CLOCK_GATE_DISABLE REG_BIT(1)
#define REPLAY_MODE_GRANULARITY REG_BIT(0)
#define INDIRECT_RING_STATE(base) XE_REG((base) + 0x108)
+#define RING_BB_STATE(base) XE_REG((base) + 0x110)
+
#define RING_BBADDR(base) XE_REG((base) + 0x140)
#define RING_BBADDR_UDW(base) XE_REG((base) + 0x168)
+#define RING_BB_ADDR_DIFF(base) XE_REG((base) + 0x154)
+
#define PR_CTR_CTRL(base) XE_REG((base) + 0x178)
#define CTR_COUNT_SELECT_FF REG_BIT(31)
#define CTR_LOGIC_OP_MASK REG_GENMASK(30, 0)
@@ -148,6 +159,8 @@
#define BLIT_CCTL_DST_MOCS_MASK REG_GENMASK(14, 9)
#define BLIT_CCTL_SRC_MOCS_MASK REG_GENMASK(6, 1)
+#define RING_CSBEFSM3(base) XE_REG((base) + 0x224)
+
#define RING_EXECLIST_STATUS_LO(base) XE_REG((base) + 0x234)
#define RING_EXECLIST_STATUS_HI(base) XE_REG((base) + 0x234 + 4)
@@ -169,9 +182,16 @@
#define GFX_MSIX_INTERRUPT_ENABLE REG_BIT(13)
#define GFX_DISABLE_LEGACY_MODE REG_BIT(3)
+#define RING_CSFESM(base) XE_REG((base) + 0x2a0)
+#define RING_CSFESM2(base) XE_REG((base) + 0x2a4)
+#define RING_CSFESM3(base) XE_REG((base) + 0x2a8)
+#define RING_CSPWRFSM(base) XE_REG((base) + 0x2ac)
+
#define RING_CSMQDEBUG(base) XE_REG((base) + 0x2b0)
#define CURRENT_ACTIVE_QUEUE_ID_MASK REG_GENMASK(7, 0)
+#define RING_CSBEFSM(base) XE_REG((base) + 0x2bc)
+
#define RING_QUEUE_TIMESTAMP(base) XE_REG((base) + 0x4c0)
#define RING_QUEUE_TIMESTAMP_UDW(base) XE_REG((base) + 0x4c0 + 4)
@@ -217,6 +237,8 @@
#define PREEMPT_GPGPU_LEVEL_MASK PREEMPT_GPGPU_LEVEL(1, 1)
#define PREEMPT_3D_OBJECT_LEVEL REG_BIT(0)
+#define CS_PREEMPTION_STATUS(base) XE_REG((base) + 0x5ac)
+
#define CS_GPR_DATA(base, n) XE_REG((base) + 0x600 + (n) * 4)
#define CS_GPR_REG(base, n) CS_GPR_DATA((base), (n) * 2)
#define CS_GPR_REG_UDW(base, n) CS_GPR_DATA((base), (n) * 2 + 1)
diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
index 6a20eab0f820..2e13df97e106 100644
--- a/drivers/gpu/drm/xe/xe_guc_capture.c
+++ b/drivers/gpu/drm/xe/xe_guc_capture.c
@@ -150,6 +150,33 @@ struct __guc_capture_parsed_output {
#define XE3P_BASE_ENGINE_INSTANCE \
{ RING_CSMQDEBUG(0), REG_32BIT, 0, 0, 0, "CSMQDEBUG"}
+#define XE3P_CS_DEBUG_INSTANCE \
+ { RESET_CTRL(0), REG_32BIT, 0, 0, 0, "RESET_CTRL"}, \
+ { RING_CSBEFSM3(0), REG_32BIT, 0, 0, 0, "RING_CSBEFSM3"}, \
+ { RING_CSFESM(0), REG_32BIT, 0, 0, 0, "RING_CSFESM"}, \
+ { RING_CSFESM2(0), REG_32BIT, 0, 0, 0, "RING_CSFESM2"}, \
+ { RING_CSFESM3(0), REG_32BIT, 0, 0, 0, "RING_CSFESM3"}, \
+ { RING_CSPWRFSM(0), REG_32BIT, 0, 0, 0, "RING_CSPWRFSM"}, \
+ { RING_CSBEFSM(0), REG_32BIT, 0, 0, 0, "RING_CSBEFSM"}, \
+ { RING_CSFE_GLB_CHICKEN3(0), REG_32BIT, 0, 0, 0, "RING_CSFE_GLB_CHICKEN3"}, \
+ { RING_PSMI_CTL(0), REG_32BIT, 0, 0, 0, "RING_PSMI_CTL"}, \
+ { RING_INSTPS(0), REG_32BIT, 0, 0, 0, "RING_INSTPS"}, \
+ { RING_BB_ADDR_DIFF(0), REG_32BIT, 0, 0, 0, "RING_BB_ADDR_DIFF"}, \
+ { RING_BB_STATE(0), REG_32BIT, 0, 0, 0, "RING_BB_STATE"}
+
+/*
+ * CS_CHICKEN1 has GPGPU/3D preempt bits; keep with RCS/CCS only.
+ * RCS+CCS share GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE, so these cannot
+ * be RCS-only.
+ */
+#define XE3P_RC_CS_PREEMPT_INSTANCE \
+ { CS_DEBUG_MODE1(0), REG_32BIT, 0, 0, 0, "CS_DEBUG_MODE1"}, \
+ { CS_CHICKEN1(0), REG_32BIT, 0, 0, 0, "CS_CHICKEN1"}, \
+ { CS_PREEMPTION_STATUS(0), REG_32BIT, 0, 0, 0, "CS_PREEMPTION_STATUS"}
+
+#define XE3P_BCS_ONLY_INSTANCE \
+ { BCS_SWCTRL(0), REG_32BIT, 0, 0, 0, "BCS_SWCTRL"}
+
/* XE_LP Global */
static const struct __guc_mmio_reg_descr xe_lp_global_regs[] = {
COMMON_XELP_BASE_GLOBAL,
@@ -186,9 +213,12 @@ static const struct __guc_mmio_reg_descr xe_vec_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
};
+#define XE_BLT_INST_REGS \
+ COMMON_BASE_ENGINE_INSTANCE
+
/* Blitter Per-Engine-Instance */
static const struct __guc_mmio_reg_descr xe_blt_inst_regs[] = {
- COMMON_BASE_ENGINE_INSTANCE,
+ XE_BLT_INST_REGS,
};
/* XE_LP - GSC Per-Engine-Instance */
@@ -200,6 +230,15 @@ static const struct __guc_mmio_reg_descr xe_lp_gsc_inst_regs[] = {
static const struct __guc_mmio_reg_descr xe3p_rc_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
XE3P_BASE_ENGINE_INSTANCE,
+ XE3P_CS_DEBUG_INSTANCE,
+ XE3P_RC_CS_PREEMPT_INSTANCE,
+};
+
+/* Xe3p Blitter Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr xe3p_blt_inst_regs[] = {
+ XE_BLT_INST_REGS,
+ XE3P_CS_DEBUG_INSTANCE,
+ XE3P_BCS_ONLY_INSTANCE,
};
/*
@@ -264,7 +303,7 @@ static const struct __guc_mmio_reg_descr_group xe3p_lists[] = {
MAKE_REGLIST(xe_vec_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
MAKE_REGLIST(xe_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER),
- MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
+ MAKE_REGLIST(xe3p_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_PAGING),
@@ -377,9 +416,12 @@ static const struct __ext_steer_reg xehpg_extregs[] = {
{"SC_INSTDONE_EXTRA", XEHPG_SC_INSTDONE_EXTRA},
{"SC_INSTDONE_EXTRA2", XEHPG_SC_INSTDONE_EXTRA2},
{"INSTDONE_GEOM_SVGUNIT", XEHPG_INSTDONE_GEOM_SVGUNIT},
+};
+
+static const struct __ext_steer_reg xe2_extregs[] = {
{"ROW_INSTDONE_TDL_GFX", ROW_INSTDONE_TDL_GFX},
{"SS_LSC_HDC_IDLE_TDL_GFX", SS_LSC_HDC_IDLE_TDL_GFX},
- {"SLICE_ARB_STATUS", SLICE_ARB_STATUS}
+ {"SLICE_ARB_STATUS", SLICE_ARB_STATUS},
};
static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext,
@@ -422,6 +464,8 @@ static int guc_capture_get_steer_reg_num(struct xe_device *xe)
if (GRAPHICS_VERx100(xe) >= 1255)
num += ARRAY_SIZE(xehpg_extregs);
+ if (GRAPHICS_VER(xe) >= 20)
+ num += ARRAY_SIZE(xe2_extregs);
return num;
}
@@ -434,6 +478,7 @@ static void guc_capture_alloc_steered_lists(struct xe_guc *guc)
const struct __guc_mmio_reg_descr_group *lists = guc->capture->reglists;
const struct __guc_mmio_reg_descr_group *list;
struct __guc_mmio_reg_descr_group *extlists;
+ bool has_xe2_extregs = GRAPHICS_VER(gt_to_xe(gt)) >= 20;
struct __guc_mmio_reg_descr *extarray;
bool has_xehpg_extregs = GRAPHICS_VERx100(gt_to_xe(gt)) >= 1255;
struct drm_device *drm = >_to_xe(gt)->drm;
@@ -504,6 +549,12 @@ static void guc_capture_alloc_steered_lists(struct xe_guc *guc)
__fill_ext_reg(extarray, &xehpg_extregs[i], dss, slice, subslice);
++extarray;
}
+
+ if (has_xe2_extregs)
+ for (i = 0; i < ARRAY_SIZE(xe2_extregs); ++i) {
+ __fill_ext_reg(extarray, &xe2_extregs[i], dss, slice, subslice);
+ ++extarray;
+ }
}
extlists[0].num_regs = total;
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers
2026-10-23 6:05 ` [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers Nareshkumar Gollakoti
@ 2026-10-23 6:26 ` sashiko-bot
2026-10-26 9:15 ` Upadhyay, Tejas
1 sibling, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-10-23 6:26 UTC (permalink / raw)
To: Nareshkumar Gollakoti, intel-xe
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] drm/xe/guc: unused FF_SLICE_CS_CHICKEN2 definition and missing capture entry
- [Medium] drm/xe/guc: use xe3p_blt_inst_regs for GUC_CAPTURE_LIST_CLASS_PAGING on Xe3p
--
commit 3bf1615b3ab8603f52d531a35c295135f10f2aa4
Author: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
drm/xe/guc: capture additional engine state registers
This commit defines additional engine state register offsets in
xe_engine_regs.h and includes them in the GuC error capture lists for Xe3p
render/compute and blitter engines, while also splitting out xe2_extregs[]
for steered register capture.
> diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
> index 94033982e6944..9f328b1b18f57 100644
> --- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
> +++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
[ ... ]
> @@ -123,15 +128,21 @@
> #define FF_SLICE_CS_CHICKEN1(base) XE_REG((base) + 0xe0, XE_REG_OPTION_MASKED)
> #define FFSC_PERCTX_PREEMPT_CTRL REG_BIT(14)
>
> +#define FF_SLICE_CS_CHICKEN2(base) XE_REG((base) + 0xe4, XE_REG_OPTION_MASKED)
[ ... ]
> diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
> index 6a20eab0f8204..2e13df97e1068 100644
> --- a/drivers/gpu/drm/xe/xe_guc_capture.c
> +++ b/drivers/gpu/drm/xe/xe_guc_capture.c
[ ... ]
> @@ -200,6 +230,15 @@ static const struct __guc_mmio_reg_descr xe_lp_gsc_inst_regs[] = {
> static const struct __guc_mmio_reg_descr xe3p_rc_inst_regs[] = {
> COMMON_BASE_ENGINE_INSTANCE,
> XE3P_BASE_ENGINE_INSTANCE,
> + XE3P_CS_DEBUG_INSTANCE,
> + XE3P_RC_CS_PREEMPT_INSTANCE,
> +};
[Severity: Medium]
Was FF_SLICE_CS_CHICKEN2 (along with FF_SLICE_CS_CHICKEN1) accidentally
dropped from xe3p_rc_inst_regs[] in drivers/gpu/drm/xe/xe_guc_capture.c?
The commit message notes that the new register definitions in
drivers/gpu/drm/xe/regs/xe_engine_regs.h are included in the GuC capture
list, and the v3 changelog specifically mentions adding
XE3P_RC_SLICE_INSTANCE with FF_SLICE_CS_CHICKEN1 and FF_SLICE_CS_CHICKEN2 to
xe3p_rc_inst_regs[].
However, XE3P_RC_SLICE_INSTANCE is absent from drivers/gpu/drm/xe/xe_guc_capture.c,
which leaves FF_SLICE_CS_CHICKEN2 completely unused and omits both registers
when GuC error capture initializes xe3p_rc_inst_regs[] for
GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE.
> +
> +/* Xe3p Blitter Per-Engine-Instance */
> +static const struct __guc_mmio_reg_descr xe3p_blt_inst_regs[] = {
> + XE_BLT_INST_REGS,
> + XE3P_CS_DEBUG_INSTANCE,
> + XE3P_BCS_ONLY_INSTANCE,
> };
>
> /*
> @@ -264,7 +303,7 @@ static const struct __guc_mmio_reg_descr_group xe3p_lists[] = {
> MAKE_REGLIST(xe_vec_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
> MAKE_REGLIST(xe_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
> MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER),
> - MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
> + MAKE_REGLIST(xe3p_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
> MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
> MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
> MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_PAGING),
[Severity: Medium]
Should the GUC_CAPTURE_LIST_CLASS_PAGING entry right below this in
xe3p_lists[] also be updated from xe_blt_inst_regs to xe3p_blt_inst_regs?
In drivers/gpu/drm/xe/xe_guc_capture.c:xe3p_lists[]:
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER),
MAKE_REGLIST(xe3p_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_PAGING),
MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_PAGING),
When xe_guc_has_paging_engine() in drivers/gpu/drm/xe/xe_guc.c is true on
Xe3p platforms, xe_hwe_to_guc_class() maps the USM-reserved physical BCS
engine (gt->usm.paging_hwe0) to GUC_PAGING_CLASS, which
xe_hwe_to_guc_capture_class() maps to GUC_CAPTURE_LIST_CLASS_PAGING.
Leaving GUC_CAPTURE_LIST_CLASS_PAGING pointing to xe_blt_inst_regs means
both ADS capture list population (guc_capture_prep_lists() ->
xe_guc_capture_getlist()) and manual engine snapshots
(xe_engine_manual_capture() -> xe_guc_capture_get_reg_desc_list()) for the
paging BCS engine will omit XE3P_CS_DEBUG_INSTANCE and
XE3P_BCS_ONLY_INSTANCE.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261023060554.2643515-1-naresh.kumar.g@intel.com?part=7
^ permalink raw reply [flat|nested] 13+ messages in thread* RE: [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers
2026-10-23 6:05 ` [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers Nareshkumar Gollakoti
2026-10-23 6:26 ` sashiko-bot
@ 2026-10-26 9:15 ` Upadhyay, Tejas
1 sibling, 0 replies; 13+ messages in thread
From: Upadhyay, Tejas @ 2026-10-26 9:15 UTC (permalink / raw)
To: Kumar G, Naresh, intel-xe@lists.freedesktop.org
> -----Original Message-----
> From: Kumar G, Naresh <naresh.kumar.g@intel.com>
> Sent: 23 October 2026 11:36
> To: intel-xe@lists.freedesktop.org
> Cc: Upadhyay, Tejas <tejas.upadhyay@intel.com>; Kumar G, Naresh
> <naresh.kumar.g@intel.com>
> Subject: [PATCH v5 7/7] drm/xe/guc: capture additional engine state registers
>
> Add a wider set of engine state registers to GuC error capture to improve post-
> mortem debugging of engine hangs and reset-related failures.
>
> Define the missing register offsets in xe_engine_regs.h and include them in the
> GuC capture list. The additional registers cover reset state, front-end and back-
> end FSM state, power state, batch buffer state, instruction state, preemption
> status, and related chicken/debug controls.
>
> This provides more complete engine context in capture dumps, which should
> help root-cause analysis when investigating GuC-reported engine failures.
>
> v3:(Sashiko)
> - Move FF_SLICE_CS_CHICKEN1/2 out of
> COMMON_BASE_ENGINE_INSTANCE
> - Add XE3P_RC_SLICE_INSTANCE and include it only in xe3p_rc_inst_regs[]
> - Add XE_BCS_RCS_ENGINE_INSTANCE for registers shared only by
> BCS/RCS paths
> - Include XE_BCS_RCS_ENGINE_INSTANCE only in
> xe_blt_inst_regs[] and xe3p_rc_inst_regs[]
> - Keep COMMON_BASE_ENGINE_INSTANCE limited to registers
> valid across all engine classes
>
> v5:(Sashiko)
> - Keep RING_EXECLIST_* in COMMON_BASE_ENGINE_INSTANCE
> - Drop XE_BCS_RCS_ENGINE_INSTANCE
> - BCS_SWCTRL only on xe3p_blt_inst_regs
> - CS_DEBUG_MODE1/CS_CHICKEN1/CS_PREEMPTION_STATUS only on
> xe3p_rc_inst_regs
>
> Signed-off-by: Nareshkumar Gollakoti <naresh.kumar.g@intel.com>
> ---
> drivers/gpu/drm/xe/regs/xe_engine_regs.h | 22 +++++++++
> drivers/gpu/drm/xe/xe_guc_capture.c | 57 ++++++++++++++++++++++--
> 2 files changed, 76 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
> b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
> index 94033982e694..9f328b1b18f5 100644
> --- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
> +++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
> @@ -60,6 +60,8 @@
>
Can you check below, I see they are missed :
1. 0xe4 (FF_SLICE_CS_CHICKEN2) is defined but not wired
2. Ring buffer section: 0x14c is missing
3. BB registers section: 0x150 and 0x170 are both missing
4. Also double check mcr/non-mcr, just for double verification.
Tejas
> #define RING_START_UDW(base) XE_REG((base) +
> 0x48)
>
> +#define RING_CSFE_GLB_CHICKEN3(base) XE_REG((base) +
> 0x4c)
> +
> #define RING_PSMI_CTL(base) XE_REG((base) + 0x50,
> XE_REG_OPTION_MASKED)
> #define RC_SEMA_IDLE_MSG_DISABLE REG_BIT(12)
> #define WAIT_FOR_EVENT_POWER_DOWN_DISABLE REG_BIT(7)
> @@ -72,6 +74,7 @@
> #define RING_DMA_FADD_UDW(base) XE_REG((base) +
> 0x60)
> #define RING_IPEHR(base) XE_REG((base) + 0x68)
> #define RING_INSTDONE(base) XE_REG((base) +
> 0x6c)
> +#define RING_INSTPS(base) XE_REG((base) + 0x70)
> #define RING_ACTHD(base) XE_REG((base) + 0x74)
> #define RING_DMA_FADD(base) XE_REG((base) +
> 0x78)
> #define RING_HWS_PGA(base) XE_REG((base) + 0x80)
> @@ -102,6 +105,8 @@
> #define SELECTIVE_READ_GROUP REG_GENMASK(29,
> 23)
> #define SELECTIVE_READ_INSTANCE REG_GENMASK(22, 16)
>
> +#define RESET_CTRL(base) XE_REG((base) + 0xd0)
> +
> /*
> * CMD_CCTL read/write fields take a MOCS value and _not_ a table index.
> * The lsb of each can be considered a separate enabling bit for encryption.
> @@ -123,15 +128,21 @@
> #define FF_SLICE_CS_CHICKEN1(base) XE_REG((base) + 0xe0,
> XE_REG_OPTION_MASKED)
> #define FFSC_PERCTX_PREEMPT_CTRL REG_BIT(14)
>
> +#define FF_SLICE_CS_CHICKEN2(base) XE_REG((base) + 0xe4,
> XE_REG_OPTION_MASKED)
> +
> #define CS_DEBUG_MODE1(base) XE_REG((base) + 0xec,
> XE_REG_OPTION_MASKED)
> #define FF_DOP_CLOCK_GATE_DISABLE REG_BIT(1)
> #define REPLAY_MODE_GRANULARITY REG_BIT(0)
>
> #define INDIRECT_RING_STATE(base) XE_REG((base) + 0x108)
>
> +#define RING_BB_STATE(base) XE_REG((base) + 0x110)
> +
> #define RING_BBADDR(base) XE_REG((base) + 0x140)
> #define RING_BBADDR_UDW(base) XE_REG((base) +
> 0x168)
>
> +#define RING_BB_ADDR_DIFF(base) XE_REG((base) +
> 0x154)
> +
> #define PR_CTR_CTRL(base) XE_REG((base) + 0x178)
> #define CTR_COUNT_SELECT_FF REG_BIT(31)
> #define CTR_LOGIC_OP_MASK REG_GENMASK(30,
> 0)
> @@ -148,6 +159,8 @@
> #define BLIT_CCTL_DST_MOCS_MASK REG_GENMASK(14, 9)
> #define BLIT_CCTL_SRC_MOCS_MASK REG_GENMASK(6, 1)
>
> +#define RING_CSBEFSM3(base) XE_REG((base) +
> 0x224)
> +
> #define RING_EXECLIST_STATUS_LO(base) XE_REG((base) +
> 0x234)
> #define RING_EXECLIST_STATUS_HI(base) XE_REG((base) +
> 0x234 + 4)
>
> @@ -169,9 +182,16 @@
> #define GFX_MSIX_INTERRUPT_ENABLE REG_BIT(13)
> #define GFX_DISABLE_LEGACY_MODE REG_BIT(3)
>
> +#define RING_CSFESM(base) XE_REG((base) + 0x2a0)
> +#define RING_CSFESM2(base) XE_REG((base) + 0x2a4)
> +#define RING_CSFESM3(base) XE_REG((base) + 0x2a8)
> +#define RING_CSPWRFSM(base) XE_REG((base) +
> 0x2ac)
> +
> #define RING_CSMQDEBUG(base) XE_REG((base) +
> 0x2b0)
> #define CURRENT_ACTIVE_QUEUE_ID_MASK REG_GENMASK(7, 0)
>
> +#define RING_CSBEFSM(base) XE_REG((base) + 0x2bc)
> +
> #define RING_QUEUE_TIMESTAMP(base) XE_REG((base) +
> 0x4c0)
> #define RING_QUEUE_TIMESTAMP_UDW(base)
> XE_REG((base) + 0x4c0 + 4)
>
> @@ -217,6 +237,8 @@
> #define PREEMPT_GPGPU_LEVEL_MASK
> PREEMPT_GPGPU_LEVEL(1, 1)
> #define PREEMPT_3D_OBJECT_LEVEL REG_BIT(0)
>
> +#define CS_PREEMPTION_STATUS(base) XE_REG((base) +
> 0x5ac)
> +
> #define CS_GPR_DATA(base, n) XE_REG((base) + 0x600 + (n) *
> 4)
> #define CS_GPR_REG(base, n) CS_GPR_DATA((base), (n) * 2)
> #define CS_GPR_REG_UDW(base, n) CS_GPR_DATA((base),
> (n) * 2 + 1)
> diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c
> b/drivers/gpu/drm/xe/xe_guc_capture.c
> index 6a20eab0f820..2e13df97e106 100644
> --- a/drivers/gpu/drm/xe/xe_guc_capture.c
> +++ b/drivers/gpu/drm/xe/xe_guc_capture.c
> @@ -150,6 +150,33 @@ struct __guc_capture_parsed_output { #define
> XE3P_BASE_ENGINE_INSTANCE \
> { RING_CSMQDEBUG(0), REG_32BIT, 0, 0,
> 0, "CSMQDEBUG"}
>
> +#define XE3P_CS_DEBUG_INSTANCE \
> + { RESET_CTRL(0), REG_32BIT, 0, 0, 0,
> "RESET_CTRL"}, \
> + { RING_CSBEFSM3(0), REG_32BIT, 0, 0, 0,
> "RING_CSBEFSM3"}, \
> + { RING_CSFESM(0), REG_32BIT, 0, 0, 0,
> "RING_CSFESM"}, \
> + { RING_CSFESM2(0), REG_32BIT, 0, 0, 0,
> "RING_CSFESM2"}, \
> + { RING_CSFESM3(0), REG_32BIT, 0, 0, 0,
> "RING_CSFESM3"}, \
> + { RING_CSPWRFSM(0), REG_32BIT, 0, 0, 0,
> "RING_CSPWRFSM"}, \
> + { RING_CSBEFSM(0), REG_32BIT, 0, 0, 0,
> "RING_CSBEFSM"}, \
> + { RING_CSFE_GLB_CHICKEN3(0), REG_32BIT, 0, 0,
> 0, "RING_CSFE_GLB_CHICKEN3"}, \
> + { RING_PSMI_CTL(0), REG_32BIT, 0, 0, 0,
> "RING_PSMI_CTL"}, \
> + { RING_INSTPS(0), REG_32BIT, 0, 0, 0,
> "RING_INSTPS"}, \
> + { RING_BB_ADDR_DIFF(0), REG_32BIT, 0, 0,
> 0, "RING_BB_ADDR_DIFF"}, \
> + { RING_BB_STATE(0), REG_32BIT, 0, 0, 0,
> "RING_BB_STATE"}
> +
> +/*
> + * CS_CHICKEN1 has GPGPU/3D preempt bits; keep with RCS/CCS only.
> + * RCS+CCS share GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE, so these
> cannot
> + * be RCS-only.
> + */
> +#define XE3P_RC_CS_PREEMPT_INSTANCE \
> + { CS_DEBUG_MODE1(0), REG_32BIT, 0, 0,
> 0, "CS_DEBUG_MODE1"}, \
> + { CS_CHICKEN1(0), REG_32BIT, 0, 0, 0,
> "CS_CHICKEN1"}, \
> + { CS_PREEMPTION_STATUS(0), REG_32BIT, 0, 0, 0,
> "CS_PREEMPTION_STATUS"}
> +
> +#define XE3P_BCS_ONLY_INSTANCE \
> + { BCS_SWCTRL(0), REG_32BIT, 0, 0, 0,
> "BCS_SWCTRL"}
> +
> /* XE_LP Global */
> static const struct __guc_mmio_reg_descr xe_lp_global_regs[] = {
> COMMON_XELP_BASE_GLOBAL,
> @@ -186,9 +213,12 @@ static const struct __guc_mmio_reg_descr
> xe_vec_inst_regs[] = {
> COMMON_BASE_ENGINE_INSTANCE,
> };
>
> +#define XE_BLT_INST_REGS \
> + COMMON_BASE_ENGINE_INSTANCE
> +
> /* Blitter Per-Engine-Instance */
> static const struct __guc_mmio_reg_descr xe_blt_inst_regs[] = {
> - COMMON_BASE_ENGINE_INSTANCE,
> + XE_BLT_INST_REGS,
> };
>
> /* XE_LP - GSC Per-Engine-Instance */
> @@ -200,6 +230,15 @@ static const struct __guc_mmio_reg_descr
> xe_lp_gsc_inst_regs[] = { static const struct __guc_mmio_reg_descr
> xe3p_rc_inst_regs[] = {
> COMMON_BASE_ENGINE_INSTANCE,
> XE3P_BASE_ENGINE_INSTANCE,
> + XE3P_CS_DEBUG_INSTANCE,
> + XE3P_RC_CS_PREEMPT_INSTANCE,
> +};
> +
> +/* Xe3p Blitter Per-Engine-Instance */
> +static const struct __guc_mmio_reg_descr xe3p_blt_inst_regs[] = {
> + XE_BLT_INST_REGS,
> + XE3P_CS_DEBUG_INSTANCE,
> + XE3P_BCS_ONLY_INSTANCE,
> };
>
> /*
> @@ -264,7 +303,7 @@ static const struct __guc_mmio_reg_descr_group
> xe3p_lists[] = {
> MAKE_REGLIST(xe_vec_class_regs, PF, ENGINE_CLASS,
> GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
> MAKE_REGLIST(xe_vec_inst_regs, PF, ENGINE_INSTANCE,
> GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
> MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS,
> GUC_CAPTURE_LIST_CLASS_BLITTER),
> - MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE,
> GUC_CAPTURE_LIST_CLASS_BLITTER),
> + MAKE_REGLIST(xe3p_blt_inst_regs, PF, ENGINE_INSTANCE,
> +GUC_CAPTURE_LIST_CLASS_BLITTER),
> MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS,
> GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
> MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE,
> GUC_CAPTURE_LIST_CLASS_GSC_OTHER),
> MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS,
> GUC_CAPTURE_LIST_CLASS_PAGING), @@ -377,9 +416,12 @@ static const
> struct __ext_steer_reg xehpg_extregs[] = {
> {"SC_INSTDONE_EXTRA",
> XEHPG_SC_INSTDONE_EXTRA},
> {"SC_INSTDONE_EXTRA2",
> XEHPG_SC_INSTDONE_EXTRA2},
> {"INSTDONE_GEOM_SVGUNIT",
> XEHPG_INSTDONE_GEOM_SVGUNIT},
> +};
> +
> +static const struct __ext_steer_reg xe2_extregs[] = {
> {"ROW_INSTDONE_TDL_GFX", ROW_INSTDONE_TDL_GFX},
> {"SS_LSC_HDC_IDLE_TDL_GFX", SS_LSC_HDC_IDLE_TDL_GFX},
> - {"SLICE_ARB_STATUS", SLICE_ARB_STATUS}
> + {"SLICE_ARB_STATUS", SLICE_ARB_STATUS},
> };
>
> static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext, @@ -422,6
> +464,8 @@ static int guc_capture_get_steer_reg_num(struct xe_device *xe)
>
> if (GRAPHICS_VERx100(xe) >= 1255)
> num += ARRAY_SIZE(xehpg_extregs);
> + if (GRAPHICS_VER(xe) >= 20)
> + num += ARRAY_SIZE(xe2_extregs);
>
> return num;
> }
> @@ -434,6 +478,7 @@ static void guc_capture_alloc_steered_lists(struct
> xe_guc *guc)
> const struct __guc_mmio_reg_descr_group *lists = guc->capture-
> >reglists;
> const struct __guc_mmio_reg_descr_group *list;
> struct __guc_mmio_reg_descr_group *extlists;
> + bool has_xe2_extregs = GRAPHICS_VER(gt_to_xe(gt)) >= 20;
> struct __guc_mmio_reg_descr *extarray;
> bool has_xehpg_extregs = GRAPHICS_VERx100(gt_to_xe(gt)) >= 1255;
> struct drm_device *drm = >_to_xe(gt)->drm; @@ -504,6 +549,12
> @@ static void guc_capture_alloc_steered_lists(struct xe_guc *guc)
> __fill_ext_reg(extarray, &xehpg_extregs[i],
> dss, slice, subslice);
> ++extarray;
> }
> +
> + if (has_xe2_extregs)
> + for (i = 0; i < ARRAY_SIZE(xe2_extregs); ++i) {
> + __fill_ext_reg(extarray, &xe2_extregs[i], dss,
> slice, subslice);
> + ++extarray;
> + }
> }
>
> extlists[0].num_regs = total;
> --
> 2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread