@@ -505,6 +505,7 @@ enum intel_guc_action {
INTEL_GUC_ACTION_ENTER_S_STATE = 0x501,
INTEL_GUC_ACTION_EXIT_S_STATE = 0x502,
INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003,
+ INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
INTEL_GUC_ACTION_UK_LOG_ENABLE_LOGGING = 0x0E000,
INTEL_GUC_ACTION_LIMIT
};
@@ -530,6 +530,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
intel_uc_fw_status_repr(guc_fw->fetch_status),
intel_uc_fw_status_repr(guc_fw->load_status));
+ intel_guc_auth_huc(dev_priv);
+
if (i915.enable_guc_submission) {
if (i915.guc_log_level >= 0)
gen9_enable_guc_interrupts(dev_priv);
@@ -46,7 +46,7 @@ static bool intel_guc_recv(struct intel_guc *guc, u32 *status)
int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len)
{
struct drm_i915_private *dev_priv = guc_to_i915(guc);
- u32 status;
+ u32 status = 0;
int i;
int ret;
@@ -140,3 +140,57 @@ int intel_guc_log_control(struct intel_guc *guc, u32 control_val)
return intel_guc_send(guc, action, ARRAY_SIZE(action));
}
+
+/**
+ * intel_guc_auth_huc() - authenticate ucode
+ * @dev_priv: the drm_i915_device
+ *
+ * Triggers a HuC fw authentication request to the GuC via intel_guc_action_
+ * authenticate_huc interface.
+ * interface.
+ */
+void intel_guc_auth_huc(struct drm_i915_private *dev_priv)
+{
+ struct intel_guc *guc = &dev_priv->guc;
+ struct intel_huc *huc = &dev_priv->huc;
+ struct i915_vma *vma;
+ int ret;
+ u32 data[2];
+
+ vma = i915_gem_object_ggtt_pin(huc->fw.obj, NULL, 0, 0,
+ PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
+ if (IS_ERR(vma)) {
+ DRM_DEBUG_DRIVER("failed to pin huc fw object %d\n",
+ (int)PTR_ERR(vma));
+ return;
+ }
+
+ /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+ I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+ /* Specify auth action and where public signature is. */
+ data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC;
+ data[1] = i915_ggtt_offset(vma) + huc->fw.rsa_offset;
+
+ ret = intel_guc_send(guc, data, ARRAY_SIZE(data));
+ if (ret) {
+ DRM_ERROR("HuC: GuC did not ack Auth request\n");
+ goto out;
+ }
+
+ /* Check authentication status, it should be done by now */
+ ret = intel_wait_for_register(dev_priv,
+ HUC_STATUS2,
+ HUC_FW_VERIFIED,
+ HUC_FW_VERIFIED,
+ 50);
+
+ if (ret) {
+ DRM_ERROR("HuC: Authentication failed\n");
+ goto out;
+ }
+
+ DRM_ERROR("HuC Authentication Successful!\n");
+out:
+ i915_vma_unpin(vma);
+}
@@ -190,6 +190,7 @@ int intel_guc_sample_forcewake(struct intel_guc *guc);
int intel_guc_log_flush_complete(struct intel_guc *guc);
int intel_guc_log_flush(struct intel_guc *guc);
int intel_guc_log_control(struct intel_guc *guc, u32 control_val);
+void intel_guc_auth_huc(struct drm_i915_private *dev_priv);
/* intel_guc_loader.c */
extern void intel_guc_init(struct drm_i915_private *dev_priv);