Re: [PATCH 5/6] drm/radeon: add VRAM debugfs access

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 12.12.2013 14:31, schrieb Alex Deucher:
On Thu, Dec 12, 2013 at 3:42 AM, Christian König
<deathsimple@xxxxxxxxxxx> wrote:
From: Christian König <christian.koenig@xxxxxxx>

Not very fast, but makes it possible to access even the
normally inaccessible parts of VRAM from userspace.

Signed-off-by: Christian König <christian.koenig@xxxxxxx>
---
  drivers/gpu/drm/radeon/radeon.h     |  4 +++
  drivers/gpu/drm/radeon/radeon_ttm.c | 72 ++++++++++++++++++++++++++++++++++++-
  2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b1f990d..49f210c1 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -413,6 +413,10 @@ struct radeon_mman {
         struct ttm_bo_device            bdev;
         bool                            mem_global_referenced;
         bool                            initialized;
+
+#if defined(CONFIG_DEBUG_FS)
+       struct dentry                   *vram;
+#endif
  };

  /* bo virtual address in a specific vm */
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index a2d6c4f..f5e8eed 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -39,12 +39,14 @@
  #include <linux/seq_file.h>
  #include <linux/slab.h>
  #include <linux/swiotlb.h>
+#include <linux/debugfs.h>
  #include "radeon_reg.h"
  #include "radeon.h"

  #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)

  static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
+static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);

  static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
  {
@@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)

         if (!rdev->mman.initialized)
                 return;
+       radeon_ttm_debugfs_fini(rdev);
         if (rdev->stollen_vga_memory) {
                 r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
                 if (r == 0) {
@@ -862,12 +865,70 @@ static struct drm_info_list radeon_ttm_debugfs_list[] = {
  #endif
  };

+static int radeon_ttm_mem_open(struct inode *inode, struct file *filep)
+{
+       filep->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
+                                   size_t size, loff_t *pos)
+{
+       struct radeon_device *rdev = f->private_data;
+       ssize_t result = 0;
+       int r;
+
+       if (size & 0x3 || *pos & 0x3)
+               return -EINVAL;
+
+       while (size) {
+               unsigned long flags;
+               uint32_t value;
+
+               if (*pos >= rdev->mc.mc_vram_size || *pos >= 0x7FFFFFFF)
+                       return result;
+
+               spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
+               WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);
Starting with evergreen dGPUs, there is also an MM_INDEX_HI register
at 0x18 for accessing addresses over 30 bits.

I know, but I wanted to keep that as simple and stupid as possible. I mean this code should work from r100 till CIK and except for HAINAN do we really have cards with more than 2GB or ram?

And I'm not even sure if radeon_ttm is the right place for this.

Christian.


Alex


+               value = RREG32(RADEON_MM_DATA);
+               spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
+
+               r = put_user(value, (uint32_t *)buf);
+               if (r)
+                       return r;
+
+               result += 4;
+               buf += 4;
+               *pos += 4;
+               size -= 4;
+       }
+
+       return result;
+}
+
+static const struct file_operations radeon_ttm_vram_fops = {
+       .owner = THIS_MODULE,
+       .open = radeon_ttm_mem_open,
+       .read = radeon_ttm_vram_read,
+};
+
  #endif

  static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
  {
  #if defined(CONFIG_DEBUG_FS)
-       unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list);
+       unsigned count;
+
+       struct drm_minor *minor = rdev->ddev->primary;
+       struct dentry *ent, *root = minor->debugfs_root;
+
+       ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
+                                 rdev, &radeon_ttm_vram_fops);
+       if (IS_ERR(ent))
+               return PTR_ERR(ent);
+       rdev->mman.vram = ent;
+
+       count = ARRAY_SIZE(radeon_ttm_debugfs_list);

  #ifdef CONFIG_SWIOTLB
         if (!swiotlb_nr_tbl())
@@ -880,3 +941,12 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
         return 0;
  #endif
  }
+
+static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+
+       debugfs_remove(rdev->mman.vram);
+       rdev->mman.vram = NULL;
+#endif
+}
--
1.8.1.2

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel





[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux