On Thu, Jul 09, 2015 at 07:29:09PM +0100, Dave Gordon wrote: > From: Alex Dai <yu.dai@xxxxxxxxx> > > Allocate a GEM object to hold GuC log data. A debugfs interface > (i915_guc_log_dump) is provided to print out the log content. > > v2: > Add struct members at point of use [Chris Wilson] > > v4: > Rebased > > Issue: VIZ-4884 > Signed-off-by: Alex Dai <yu.dai@xxxxxxxxx> > Signed-off-by: Dave Gordon <david.s.gordon@xxxxxxxxx> Reviewed-by: Tom O'Rourke <Tom.O'Rourke@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++++++++++ > drivers/gpu/drm/i915/i915_guc_submission.c | 46 ++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_guc.h | 1 + > 3 files changed, 76 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c > index 9ff5f17..13e37d1 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -2397,6 +2397,34 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data) > return 0; > } > > +static int i915_guc_log_dump(struct seq_file *m, void *data) > +{ > + struct drm_info_node *node = m->private; > + struct drm_device *dev = node->minor->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct drm_i915_gem_object *log_obj = dev_priv->guc.log_obj; > + u32 *log; > + int i = 0, pg; > + > + if (!log_obj) > + return 0; > + > + for (pg = 0; pg < log_obj->base.size / PAGE_SIZE; pg++) { > + log = kmap_atomic(i915_gem_object_get_page(log_obj, pg)); > + > + for (i = 0; i < PAGE_SIZE / sizeof(u32); i += 4) > + seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n", > + *(log + i), *(log + i + 1), > + *(log + i + 2), *(log + i + 3)); > + > + kunmap_atomic(log); > + } > + > + seq_putc(m, '\n'); > + > + return 0; > +} > + > static int i915_edp_psr_status(struct seq_file *m, void *data) > { > struct drm_info_node *node = m->private; > @@ -5112,6 +5140,7 @@ static const struct drm_info_list i915_debugfs_list[] = { > {"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS}, > {"i915_gem_batch_pool", i915_gem_batch_pool_info, 0}, > {"i915_guc_load_status", i915_guc_load_status_info, 0}, > + {"i915_guc_log_dump", i915_guc_log_dump, 0}, > {"i915_frequency_info", i915_frequency_info, 0}, > {"i915_hangcheck_info", i915_hangcheck_info, 0}, > {"i915_drpc_info", i915_drpc_info, 0}, > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c > index 70a0405..e9d46d6 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -75,6 +75,47 @@ static void gem_release_guc_obj(struct drm_i915_gem_object *obj) > drm_gem_object_unreference(&obj->base); > } > > +static void guc_create_log(struct intel_guc *guc) > +{ > + struct drm_i915_private *dev_priv = guc_to_i915(guc); > + struct drm_i915_gem_object *obj; > + unsigned long offset; > + uint32_t size, flags; > + > + if (i915.guc_log_level < GUC_LOG_VERBOSITY_MIN) > + return; > + > + if (i915.guc_log_level > GUC_LOG_VERBOSITY_MAX) > + i915.guc_log_level = GUC_LOG_VERBOSITY_MAX; > + > + /* The first page is to save log buffer state. Allocate one > + * extra page for others in case for overlap */ > + size = (1 + GUC_LOG_DPC_PAGES + 1 + > + GUC_LOG_ISR_PAGES + 1 + > + GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT; > + > + obj = guc->log_obj; > + if (!obj) { > + obj = gem_allocate_guc_obj(dev_priv->dev, size); > + if (!obj) { > + /* logging will be off */ > + i915.guc_log_level = -1; > + return; > + } > + > + guc->log_obj = obj; > + } > + > + /* each allocated unit is a page */ > + flags = GUC_LOG_VALID | GUC_LOG_NOTIFY_ON_HALF_FULL | > + (GUC_LOG_DPC_PAGES << GUC_LOG_DPC_SHIFT) | > + (GUC_LOG_ISR_PAGES << GUC_LOG_ISR_SHIFT) | > + (GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT); [TOR:] How does the "log half full" interrupt get handled? > + > + offset = i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT; /* in pages */ > + guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; > +} > + > /* > * Set up the memory resources to be shared with the GuC. At this point, > * we require just one object that can be mapped through the GGTT. > @@ -99,6 +140,8 @@ int i915_guc_submission_init(struct drm_device *dev) > > ida_init(&guc->ctx_ids); > > + guc_create_log(guc); > + > return 0; > } > > @@ -107,6 +150,9 @@ void i915_guc_submission_fini(struct drm_device *dev) > struct drm_i915_private *dev_priv = dev->dev_private; > struct intel_guc *guc = &dev_priv->guc; > > + gem_release_guc_obj(dev_priv->guc.log_obj); > + guc->log_obj = NULL; > + > if (guc->ctx_pool_obj) > ida_destroy(&guc->ctx_ids); > gem_release_guc_obj(guc->ctx_pool_obj); > diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h > index be3cad8..5b51b05 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -56,6 +56,7 @@ struct intel_guc { > struct intel_guc_fw guc_fw; > > uint32_t log_flags; > + struct drm_i915_gem_object *log_obj; > > struct drm_i915_gem_object *ctx_pool_obj; > struct ida ctx_ids; > -- > 1.9.1 > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx