aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2013-12-18 15:07:39 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-12-24 16:12:47 -0500
commit2014b5694182b54c781b93d26ec993f8a12bca01 (patch)
treedca47e6c76970e557dcc420765e783a022f02ec5
parent893d6e6e122386d7aada4c71cf20c2d2794640fd (diff)
drm/radeon: add VRAM debugfs access v3
Not very fast, but makes it possible to access even the normally inaccessible parts of VRAM from userspace. v2: use MM_INDEX_HI for >2GB mem access, add default_llseek v3: set inode size in the open callback Signed-off-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c77
3 files changed, 81 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 8a4e641f0e3c..a0f63ff5a5e9 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -33,6 +33,7 @@
33#define EVERGREEN_PIF_PHY0_DATA 0xc 33#define EVERGREEN_PIF_PHY0_DATA 0xc
34#define EVERGREEN_PIF_PHY1_INDEX 0x10 34#define EVERGREEN_PIF_PHY1_INDEX 0x10
35#define EVERGREEN_PIF_PHY1_DATA 0x14 35#define EVERGREEN_PIF_PHY1_DATA 0x14
36#define EVERGREEN_MM_INDEX_HI 0x18
36 37
37#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS 0x310 38#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS 0x310
38#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH 0x324 39#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH 0x324
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b1f990d0eaa1..49f210c14796 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -413,6 +413,10 @@ struct radeon_mman {
413 struct ttm_bo_device bdev; 413 struct ttm_bo_device bdev;
414 bool mem_global_referenced; 414 bool mem_global_referenced;
415 bool initialized; 415 bool initialized;
416
417#if defined(CONFIG_DEBUG_FS)
418 struct dentry *vram;
419#endif
416}; 420};
417 421
418/* bo virtual address in a specific vm */ 422/* 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 20592378b6d0..a29d7cbd62e7 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -39,12 +39,14 @@
39#include <linux/seq_file.h> 39#include <linux/seq_file.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/swiotlb.h> 41#include <linux/swiotlb.h>
42#include <linux/debugfs.h>
42#include "radeon_reg.h" 43#include "radeon_reg.h"
43#include "radeon.h" 44#include "radeon.h"
44 45
45#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) 46#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
46 47
47static int radeon_ttm_debugfs_init(struct radeon_device *rdev); 48static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
49static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
48 50
49static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) 51static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
50{ 52{
@@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
753 755
754 if (!rdev->mman.initialized) 756 if (!rdev->mman.initialized)
755 return; 757 return;
758 radeon_ttm_debugfs_fini(rdev);
756 if (rdev->stollen_vga_memory) { 759 if (rdev->stollen_vga_memory) {
757 r = radeon_bo_reserve(rdev->stollen_vga_memory, false); 760 r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
758 if (r == 0) { 761 if (r == 0) {
@@ -862,12 +865,75 @@ static struct drm_info_list radeon_ttm_debugfs_list[] = {
862#endif 865#endif
863}; 866};
864 867
868static int radeon_ttm_vram_open(struct inode *inode, struct file *filep)
869{
870 struct radeon_device *rdev = inode->i_private;
871 i_size_write(inode, rdev->mc.mc_vram_size);
872 filep->private_data = inode->i_private;
873 return 0;
874}
875
876static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
877 size_t size, loff_t *pos)
878{
879 struct radeon_device *rdev = f->private_data;
880 ssize_t result = 0;
881 int r;
882
883 if (size & 0x3 || *pos & 0x3)
884 return -EINVAL;
885
886 while (size) {
887 unsigned long flags;
888 uint32_t value;
889
890 if (*pos >= rdev->mc.mc_vram_size)
891 return result;
892
893 spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
894 WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);
895 if (rdev->family >= CHIP_CEDAR)
896 WREG32(EVERGREEN_MM_INDEX_HI, *pos >> 31);
897 value = RREG32(RADEON_MM_DATA);
898 spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
899
900 r = put_user(value, (uint32_t *)buf);
901 if (r)
902 return r;
903
904 result += 4;
905 buf += 4;
906 *pos += 4;
907 size -= 4;
908 }
909
910 return result;
911}
912
913static const struct file_operations radeon_ttm_vram_fops = {
914 .owner = THIS_MODULE,
915 .open = radeon_ttm_vram_open,
916 .read = radeon_ttm_vram_read,
917 .llseek = default_llseek
918};
919
865#endif 920#endif
866 921
867static int radeon_ttm_debugfs_init(struct radeon_device *rdev) 922static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
868{ 923{
869#if defined(CONFIG_DEBUG_FS) 924#if defined(CONFIG_DEBUG_FS)
870 unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list); 925 unsigned count;
926
927 struct drm_minor *minor = rdev->ddev->primary;
928 struct dentry *ent, *root = minor->debugfs_root;
929
930 ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
931 rdev, &radeon_ttm_vram_fops);
932 if (IS_ERR(ent))
933 return PTR_ERR(ent);
934 rdev->mman.vram = ent;
935
936 count = ARRAY_SIZE(radeon_ttm_debugfs_list);
871 937
872#ifdef CONFIG_SWIOTLB 938#ifdef CONFIG_SWIOTLB
873 if (!swiotlb_nr_tbl()) 939 if (!swiotlb_nr_tbl())
@@ -880,3 +946,12 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
880 return 0; 946 return 0;
881#endif 947#endif
882} 948}
949
950static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
951{
952#if defined(CONFIG_DEBUG_FS)
953
954 debugfs_remove(rdev->mman.vram);
955 rdev->mman.vram = NULL;
956#endif
957}