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. 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