diff options
author | Christian König <christian.koenig@amd.com> | 2013-12-18 15:07:39 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-12-24 16:12:47 -0500 |
commit | 2014b5694182b54c781b93d26ec993f8a12bca01 (patch) | |
tree | dca47e6c76970e557dcc420765e783a022f02ec5 | |
parent | 893d6e6e122386d7aada4c71cf20c2d2794640fd (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.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ttm.c | 77 |
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 | ||
47 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev); | 48 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev); |
49 | static void radeon_ttm_debugfs_fini(struct radeon_device *rdev); | ||
48 | 50 | ||
49 | static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) | 51 | static 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 | ||
868 | static 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 | |||
876 | static 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 | |||
913 | static 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 | ||
867 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev) | 922 | static 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 | |||
950 | static 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 | } | ||