[PATCH 04/10] drm/i915/ggtt: Add intel_ggtt_read_entry()

Hogander, Jouni jouni.hogander at intel.com
Mon Mar 31 12:24:23 UTC 2025


On Thu, 2025-03-13 at 16:08 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> The BIOS FB takeover code wants to read out the PTEs (or at least
> one of them) to figure out wher the FB is lcoated in memory.

Couple of typos here. Consider fixing them before pushing:

Reviewed-by: Jouni Högander <jouni.hogander at intel.com>

> Currently we only do that for systems with LMEMBAR, and we've
> open coded the PTE decoding in the display code. Introduce a more
> proper abstract interface (intel_ggtt_read_entry()) for this purpose,
> and implement it for all platforms.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gt/intel_ggtt.c      | 56
> +++++++++++++++++++++++
>  drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c |  8 ++++
>  drivers/gpu/drm/i915/gt/intel_gtt.h       |  6 +++
>  3 files changed, 70 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> index f6c59f20832f..46a5aa4ab9c8 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> @@ -289,6 +289,14 @@ u64 gen8_ggtt_pte_encode(dma_addr_t addr,
>  	return pte;
>  }
>  
> +static dma_addr_t gen8_ggtt_pte_decode(u64 pte, bool *is_present,
> bool *is_local)
> +{
> +	*is_present = pte & GEN8_PAGE_PRESENT;
> +	*is_local = pte & GEN12_GGTT_PTE_LM;
> +
> +	return pte & GEN12_GGTT_PTE_ADDR_MASK;
> +}
> +
>  static bool should_update_ggtt_with_bind(struct i915_ggtt *ggtt)
>  {
>  	struct intel_gt *gt = ggtt->vm.gt;
> @@ -435,6 +443,11 @@ static void gen8_set_pte(void __iomem *addr,
> gen8_pte_t pte)
>  	writeq(pte, addr);
>  }
>  
> +static gen8_pte_t gen8_get_pte(void __iomem *addr)
> +{
> +	return readq(addr);
> +}
> +
>  static void gen8_ggtt_insert_page(struct i915_address_space *vm,
>  				  dma_addr_t addr,
>  				  u64 offset,
> @@ -450,6 +463,16 @@ static void gen8_ggtt_insert_page(struct
> i915_address_space *vm,
>  	ggtt->invalidate(ggtt);
>  }
>  
> +static dma_addr_t gen8_ggtt_read_entry(struct i915_address_space
> *vm,
> +				       u64 offset, bool *is_present,
> bool *is_local)
> +{
> +	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
> +	gen8_pte_t __iomem *pte =
> +		(gen8_pte_t __iomem *)ggtt->gsm + offset /
> I915_GTT_PAGE_SIZE;
> +
> +	return ggtt->vm.pte_decode(gen8_get_pte(pte), is_present,
> is_local);
> +}
> +
>  static void gen8_ggtt_insert_page_bind(struct i915_address_space
> *vm,
>  				       dma_addr_t addr, u64 offset,
>  				       unsigned int pat_index, u32
> flags)
> @@ -605,6 +628,17 @@ static void gen6_ggtt_insert_page(struct
> i915_address_space *vm,
>  	ggtt->invalidate(ggtt);
>  }
>  
> +static dma_addr_t gen6_ggtt_read_entry(struct i915_address_space
> *vm,
> +				       u64 offset,
> +				       bool *is_present, bool
> *is_local)
> +{
> +	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
> +	gen6_pte_t __iomem *pte =
> +		(gen6_pte_t __iomem *)ggtt->gsm + offset /
> I915_GTT_PAGE_SIZE;
> +
> +	return vm->pte_decode(ioread32(pte), is_present, is_local);
> +}
> +
>  /*
>   * Binds an object into the global gtt with the specified cache
> level.
>   * The object will be accessible to the GPU via commands whose
> operands
> @@ -769,6 +803,14 @@ void intel_ggtt_unbind_vma(struct
> i915_address_space *vm,
>  	vm->clear_range(vm, vma_res->start, vma_res->vma_size);
>  }
>  
> +dma_addr_t intel_ggtt_read_entry(struct i915_address_space *vm,
> +				 u64 offset, bool *is_present, bool
> *is_local)
> +{
> +	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
> +
> +	return ggtt->vm.read_entry(vm, offset, is_present,
> is_local);
> +}
> +
>  /*
>   * Reserve the top of the GuC address space for firmware images.
> Addresses
>   * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by
> GuC,
> @@ -1245,6 +1287,7 @@ static int gen8_gmch_probe(struct i915_ggtt
> *ggtt)
>  	ggtt->vm.scratch_range = gen8_ggtt_clear_range;
>  
>  	ggtt->vm.insert_entries = gen8_ggtt_insert_entries;
> +	ggtt->vm.read_entry = gen8_ggtt_read_entry;
>  
>  	/*
>  	 * Serialize GTT updates with aperture access on BXT if VT-d
> is on,
> @@ -1291,6 +1334,8 @@ static int gen8_gmch_probe(struct i915_ggtt
> *ggtt)
>  	else
>  		ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
>  
> +	ggtt->vm.pte_decode = gen8_ggtt_pte_decode;
> +
>  	return ggtt_probe_common(ggtt, size);
>  }
>  
> @@ -1390,6 +1435,14 @@ static u64 iris_pte_encode(dma_addr_t addr,
>  	return pte;
>  }
>  
> +static dma_addr_t gen6_pte_decode(u64 pte, bool *is_present, bool
> *is_local)
> +{
> +	*is_present = pte & GEN6_PTE_VALID;
> +	*is_local = false;
> +
> +	return ((pte & 0xff0) << 28) | (pte & ~0xfff);
> +}
> +
>  static int gen6_gmch_probe(struct i915_ggtt *ggtt)
>  {
>  	struct drm_i915_private *i915 = ggtt->vm.i915;
> @@ -1428,6 +1481,7 @@ static int gen6_gmch_probe(struct i915_ggtt
> *ggtt)
>  	ggtt->vm.scratch_range = gen6_ggtt_clear_range;
>  	ggtt->vm.insert_page = gen6_ggtt_insert_page;
>  	ggtt->vm.insert_entries = gen6_ggtt_insert_entries;
> +	ggtt->vm.read_entry = gen6_ggtt_read_entry;
>  	ggtt->vm.cleanup = gen6_gmch_remove;
>  
>  	ggtt->invalidate = gen6_ggtt_invalidate;
> @@ -1443,6 +1497,8 @@ static int gen6_gmch_probe(struct i915_ggtt
> *ggtt)
>  	else
>  		ggtt->vm.pte_encode = snb_pte_encode;
>  
> +	ggtt->vm.pte_decode = gen6_pte_decode;
> +
>  	ggtt->vm.vma_ops.bind_vma    = intel_ggtt_bind_vma;
>  	ggtt->vm.vma_ops.unbind_vma  = intel_ggtt_unbind_vma;
>  
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
> b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
> index 59eed0a0ce90..c5f5f0bdfb2c 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
> @@ -27,6 +27,13 @@ static void gmch_ggtt_insert_page(struct
> i915_address_space *vm,
>  	intel_gmch_gtt_insert_page(addr, offset >> PAGE_SHIFT,
> flags);
>  }
>  
> +static dma_addr_t gmch_ggtt_read_entry(struct i915_address_space
> *vm,
> +				       u64 offset, bool *is_present,
> bool *is_local)
> +{
> +	return intel_gmch_gtt_read_entry(offset >> PAGE_SHIFT,
> +					 is_present, is_local);
> +}
> +
>  static void gmch_ggtt_insert_entries(struct i915_address_space *vm,
>  				     struct i915_vma_resource
> *vma_res,
>  				     unsigned int pat_index,
> @@ -103,6 +110,7 @@ int intel_ggtt_gmch_probe(struct i915_ggtt *ggtt)
>  	ggtt->vm.insert_entries = gmch_ggtt_insert_entries;
>  	ggtt->vm.clear_range = gmch_ggtt_clear_range;
>  	ggtt->vm.scratch_range = gmch_ggtt_clear_range;
> +	ggtt->vm.read_entry = gmch_ggtt_read_entry;
>  	ggtt->vm.cleanup = gmch_ggtt_remove;
>  
>  	ggtt->invalidate = gmch_ggtt_invalidate;
> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h
> b/drivers/gpu/drm/i915/gt/intel_gtt.h
> index 0a36ea751b63..9d3a3ad567a0 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gtt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
> @@ -312,6 +312,7 @@ struct i915_address_space {
>  	u64 (*pte_encode)(dma_addr_t addr,
>  			  unsigned int pat_index,
>  			  u32 flags); /* Create a valid PTE */
> +	dma_addr_t (*pte_decode)(u64 pte, bool *is_present, bool
> *is_local);
>  #define PTE_READ_ONLY	BIT(0)
>  #define PTE_LM		BIT(1)
>  
> @@ -340,6 +341,8 @@ struct i915_address_space {
>  				   struct i915_vma_resource
> *vma_res,
>  				   unsigned int pat_index,
>  				   u32 flags);
> +	dma_addr_t (*read_entry)(struct i915_address_space *vm,
> +				 u64 offset, bool *is_present, bool
> *is_local);
>  	void (*cleanup)(struct i915_address_space *vm);
>  
>  	void (*foreach)(struct i915_address_space *vm,
> @@ -590,6 +593,9 @@ void intel_ggtt_bind_vma(struct
> i915_address_space *vm,
>  void intel_ggtt_unbind_vma(struct i915_address_space *vm,
>  			   struct i915_vma_resource *vma_res);
>  
> +dma_addr_t intel_ggtt_read_entry(struct i915_address_space *vm,
> +				 u64 offset, bool *is_present, bool
> *is_local);
> +
>  int i915_ggtt_probe_hw(struct drm_i915_private *i915);
>  int i915_ggtt_init_hw(struct drm_i915_private *i915);
>  int i915_ggtt_enable_hw(struct drm_i915_private *i915);



More information about the Intel-gfx mailing list