From: Jackie Li <yaodong.li@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v5 5/6] drm/i915/guc: Check the locking status of GuC WOPCM registers
Date: Mon, 8 Jan 2018 10:29:15 -0800 [thread overview]
Message-ID: <1515436156-17954-5-git-send-email-yaodong.li@intel.com> (raw)
In-Reply-To: <1515436156-17954-1-git-send-email-yaodong.li@intel.com>
GuC WOPCM registers are write-once registers. Current driver code
accesses these registers without checking the accessibility to these
registers, this will lead unpredictable driver behaviors if these
registers were touch by other components (such as faulty BIOS code).
This patch moves the GuC WOPCM register updating operations into
intel_guc_wopcm.c and adds checks before and after the write to GuC
WOPCM registers to make sure the driver is in a known state before
and after writing to these write-once registers.
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Jackie Li <yaodong.li@intel.com>
---
drivers/gpu/drm/i915/intel_guc.h | 2 +-
drivers/gpu/drm/i915/intel_guc_reg.h | 1 +
drivers/gpu/drm/i915/intel_guc_wopcm.c | 66 ++++++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_guc_wopcm.h | 14 +++++++-
drivers/gpu/drm/i915/intel_uc.c | 5 +--
5 files changed, 79 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index ea35911..7ed0c17 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -118,7 +118,7 @@ static inline u32 intel_guc_ggtt_offset(struct intel_guc *guc,
{
u32 offset = i915_ggtt_offset(vma);
- GEM_BUG_ON(!guc->wopcm.valid);
+ GEM_BUG_ON(!(guc->wopcm.flags & INTEL_GUC_WOPCM_VALID));
GEM_BUG_ON(offset < guc->wopcm.top);
GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP));
diff --git a/drivers/gpu/drm/i915/intel_guc_reg.h b/drivers/gpu/drm/i915/intel_guc_reg.h
index 1f52fb8..4d52c6d 100644
--- a/drivers/gpu/drm/i915/intel_guc_reg.h
+++ b/drivers/gpu/drm/i915/intel_guc_reg.h
@@ -75,6 +75,7 @@
/* Defines WOPCM space available to GuC firmware */
#define GUC_WOPCM_SIZE _MMIO(0xc050)
+#define GUC_WOPCM_REG_LOCKED (1<<0)
/* GuC addresses above GUC_GGTT_TOP also don't map through the GTT */
#define GUC_GGTT_TOP 0xFEE00000
diff --git a/drivers/gpu/drm/i915/intel_guc_wopcm.c b/drivers/gpu/drm/i915/intel_guc_wopcm.c
index 2523fef..59d5c35 100644
--- a/drivers/gpu/drm/i915/intel_guc_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_guc_wopcm.c
@@ -89,6 +89,37 @@ static inline int guc_wopcm_size_check(struct intel_guc *guc)
return 0;
}
+static inline bool __reg_locked(struct drm_i915_private *dev_priv,
+ i915_reg_t reg)
+{
+ return !!(I915_READ(reg) & GUC_WOPCM_REG_LOCKED);
+}
+
+static inline bool guc_wopcm_locked(struct intel_guc *guc)
+{
+ struct drm_i915_private *i915 = guc_to_i915(guc);
+ bool size_reg_locked = __reg_locked(i915, GUC_WOPCM_SIZE);
+ bool offset_reg_locked = __reg_locked(i915, DMA_GUC_WOPCM_OFFSET);
+
+ return size_reg_locked && offset_reg_locked;
+}
+
+static inline void guc_wopcm_hw_update(struct intel_guc *guc)
+{
+ struct drm_i915_private *dev_priv = guc_to_i915(guc);
+
+ /* GuC WOPCM registers should be unlocked at this point. */
+ GEM_BUG_ON(__reg_locked(dev_priv, GUC_WOPCM_SIZE));
+ GEM_BUG_ON(__reg_locked(dev_priv, DMA_GUC_WOPCM_OFFSET));
+
+ I915_WRITE(GUC_WOPCM_SIZE, guc->wopcm.size);
+ I915_WRITE(DMA_GUC_WOPCM_OFFSET,
+ guc->wopcm.offset | HUC_LOADING_AGENT_GUC);
+
+ GEM_BUG_ON(!__reg_locked(dev_priv, GUC_WOPCM_SIZE));
+ GEM_BUG_ON(!__reg_locked(dev_priv, DMA_GUC_WOPCM_OFFSET));
+}
+
/*
* intel_guc_wopcm_init() - Initialize the GuC WOPCM partition.
* @guc: intel guc.
@@ -107,8 +138,7 @@ int intel_guc_wopcm_init(struct intel_guc *guc, u32 guc_fw_size,
u32 offset, size, top;
int err;
- if (guc->wopcm.valid)
- return 0;
+ GEM_BUG_ON(guc->wopcm.flags & INTEL_GUC_WOPCM_VALID);
if (!guc_fw_size)
return -EINVAL;
@@ -144,10 +174,40 @@ int intel_guc_wopcm_init(struct intel_guc *guc, u32 guc_fw_size,
if (err)
return err;
- guc->wopcm.valid = true;
+ guc->wopcm.flags |= INTEL_GUC_WOPCM_VALID;
DRM_DEBUG_DRIVER("GuC WOPCM offset %dKB, size %dKB, top %dKB\n",
offset >> 10, size >> 10, top >> 10);
return 0;
}
+
+/*
+ * intel_guc_wopcm_init_hw() - Setup GuC WOPCM registers.
+ * @guc: intel guc.
+ *
+ * Setup the GuC WOPCM size and offset registers with the stored values. It will
+ * also check the registers locking status to determine whether these registers
+ * are unlocked and can be updated.
+ */
+void intel_guc_wopcm_init_hw(struct intel_guc *guc)
+{
+ u32 locked = guc_wopcm_locked(guc);
+
+ GEM_BUG_ON(!(guc->wopcm.flags & INTEL_GUC_WOPCM_VALID));
+
+ /*
+ * Bug if driver hasn't updated the HW Registers and GuC WOPCM has been
+ * locked. Return directly if WOPCM was locked and we have updated
+ * the registers.
+ */
+ if (locked) {
+ GEM_BUG_ON(!(guc->wopcm.flags & INTEL_GUC_WOPCM_HW_UPDATED));
+ return;
+ }
+
+ /* Always update registers when GuC WOPCM is not locked. */
+ guc_wopcm_hw_update(guc);
+
+ guc->wopcm.flags |= INTEL_GUC_WOPCM_HW_UPDATED;
+}
diff --git a/drivers/gpu/drm/i915/intel_guc_wopcm.h b/drivers/gpu/drm/i915/intel_guc_wopcm.h
index 0ce31ee..dd62b6b 100644
--- a/drivers/gpu/drm/i915/intel_guc_wopcm.h
+++ b/drivers/gpu/drm/i915/intel_guc_wopcm.h
@@ -46,11 +46,22 @@ struct intel_guc;
#define GEN9_GUC_WOPCM_OFFSET (0x24000)
#define GEN10_GUC_WOPCM_OFFSET (0x4000)
+/* GuC WOPCM flags*/
+#define INTEL_GUC_WOPCM_VALID BIT(0)
+#define INTEL_GUC_WOPCM_HW_UPDATED BIT(1)
+
+/*
+ * intel_guc_wopcm - GuC WOPCM related settings.
+ * @offset: GuC WOPCM offset.
+ * @size: size of GuC WOPCM for GuC firmware.
+ * @top: start of Non GuC WOPCM memory.
+ * @flags: bitmap of INTEL_GUC_WOPCM_<foo>.
+ */
struct intel_guc_wopcm {
u32 offset;
u32 size;
u32 top;
- bool valid;
+ u32 flags;
};
/*
@@ -68,5 +79,6 @@ static inline void intel_guc_wopcm_init_early(struct intel_guc_wopcm *wopcm)
}
int intel_guc_wopcm_init(struct intel_guc *guc, u32 guc_size, u32 huc_size);
+void intel_guc_wopcm_init_hw(struct intel_guc *guc);
#endif
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 70ed297..346ba03 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -280,10 +280,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
guc_disable_communication(guc);
gen9_reset_guc_interrupts(dev_priv);
- /* init WOPCM */
- I915_WRITE(GUC_WOPCM_SIZE, guc->wopcm.size);
- I915_WRITE(DMA_GUC_WOPCM_OFFSET,
- guc->wopcm.offset | HUC_LOADING_AGENT_GUC);
+ intel_guc_wopcm_init_hw(guc);
/* WaEnableuKernelHeaderValidFix:skl */
/* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
--
2.7.4
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-01-08 18:30 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-08 18:29 [PATCH v5 1/6] drm/i915/guc: Move GuC WOPCM related code into separate files Jackie Li
2018-01-08 18:29 ` [PATCH v5 2/6] drm/i915/guc: Rename guc_ggtt_offset to intel_guc_ggtt_offset Jackie Li
2018-01-08 18:29 ` [PATCH v5 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size Jackie Li
2018-01-08 18:29 ` [PATCH v5 4/6] drm/i915/guc: Add WOPCM partitioning support for CNL Jackie Li
2018-01-08 18:29 ` Jackie Li [this message]
2018-01-08 18:29 ` [PATCH v5 6/6] HAX Enable GuC Submission for CI Jackie Li
2018-01-08 18:55 ` ✗ Fi.CI.BAT: failure for series starting with [v5,1/6] drm/i915/guc: Move GuC WOPCM related code into separate files 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=1515436156-17954-5-git-send-email-yaodong.li@intel.com \
--to=yaodong.li@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox