On Thu, Dec 12, 2013 at 8:35 AM, Christian König <deathsimple@xxxxxxxxxxx> wrote: > 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? Most Hawaii boards are shipping with 4GB and a number of workstation cards have large amounts of memory. Alex > > 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