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

Christian König deathsimple at vodafone.de
Thu Dec 12 05:35:23 PST 2013


Am 12.12.2013 14:31, schrieb Alex Deucher:
> On Thu, Dec 12, 2013 at 3:42 AM, Christian König
> <deathsimple at vodafone.de> wrote:
>> From: Christian König <christian.koenig at amd.com>
>>
>> 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 at amd.com>
>> ---
>>   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 at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel



More information about the dri-devel mailing list