summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2011-07-28 13:42:45 -0700
committerBen Widawsky <ben@bwidawsk.net>2011-07-28 13:48:51 -0700
commitabd7038e5a814bb29398d6ea259815b293c62a2b (patch)
tree6d321d7c75b106098907ced54d6ffb6a4a61793c
parentcac8f8b52621f246a7cff412f340a7db28cb1b99 (diff)
intel-gpu-tools/range handling: register range handling
Hooks to allow safe accesses from userspace. Can revert to old behavior by using unsafe access.
-rw-r--r--lib/Makefile.am1
-rwxr-xr-xlib/intel_chipset.h8
-rw-r--r--lib/intel_gpu_tools.h23
-rw-r--r--lib/intel_mmio.c39
4 files changed, 69 insertions, 2 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0c9380d5..4612cd53 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -8,6 +8,7 @@ libintel_tools_la_SOURCES = \
intel_mmio.c \
intel_pci.c \
intel_reg.h \
+ intel_reg_map.c \
instdone.c \
instdone.h \
drmtest.h
diff --git a/lib/intel_chipset.h b/lib/intel_chipset.h
index c3db3abc..a38f661d 100755
--- a/lib/intel_chipset.h
+++ b/lib/intel_chipset.h
@@ -168,3 +168,11 @@
#define HAS_BLT_RING(devid) (IS_GEN6(devid) || \
IS_GEN7(devid))
+
+#define IS_BROADWATER(devid) (devid == PCI_CHIP_I946_GZ || \
+ devid == PCI_CHIP_I965_G_1 || \
+ devid == PCI_CHIP_I965_Q || \
+ devid == PCI_CHIP_I965_G)
+
+#define IS_CRESTLINE(devid) (devid == PCI_CHIP_I965_GM || \
+ devid == PCI_CHIP_I965_GME)
diff --git a/lib/intel_gpu_tools.h b/lib/intel_gpu_tools.h
index 6b307782..a145fb9b 100644
--- a/lib/intel_gpu_tools.h
+++ b/lib/intel_gpu_tools.h
@@ -38,11 +38,32 @@ extern void *mmio;
void intel_get_mmio(struct pci_device *pci_dev);
/* New style register access API */
-int intel_register_access_init(struct pci_device *pci_dev);
+int intel_register_access_init(struct pci_device *pci_dev, int safe);
void intel_register_access_fini(void);
uint32_t intel_register_read(uint32_t reg);
void intel_register_write(uint32_t reg, uint32_t val);
+#define INTEL_RANGE_RSVD (0<<0) /* Shouldn't be read or written */
+#define INTEL_RANGE_READ (1<<0)
+#define INTEL_RANGE_WRITE (1<<1)
+#define INTEL_RANGE_RW (INTEL_RANGE_READ | INTEL_RANGE_WRITE)
+#define INTEL_RANGE_END (1<<31)
+
+struct intel_register_range {
+ uint32_t base;
+ uint32_t size;
+ uint32_t flags;
+};
+
+struct intel_register_map {
+ struct intel_register_range *map;
+ uint32_t top;
+ uint32_t alignment_mask;
+};
+struct intel_register_map intel_get_register_map(uint32_t devid);
+struct intel_register_range *intel_get_register_range(struct intel_register_map map, uint32_t offset, int mode);
+
+
static inline uint32_t
INREG(uint32_t reg)
{
diff --git a/lib/intel_mmio.c b/lib/intel_mmio.c
index 99d1ffd8..31967d99 100644
--- a/lib/intel_mmio.c
+++ b/lib/intel_mmio.c
@@ -51,6 +51,7 @@ static struct _mmio_data {
char debugfs_path[FILENAME_MAX];
char debugfs_forcewake_path[FILENAME_MAX];
uint32_t i915_devid;
+ struct intel_register_map map;
int key;
} mmio_data;
@@ -151,7 +152,7 @@ release_forcewake_lock(int fd)
* @safe: use safe register access tables
*/
int
-intel_register_access_init(struct pci_device *pci_dev)
+intel_register_access_init(struct pci_device *pci_dev, int safe)
{
int ret;
@@ -164,6 +165,8 @@ intel_register_access_init(struct pci_device *pci_dev)
if (mmio_data.inited)
return -1;
+ mmio_data.safe = safe != 0 ? true : false;
+
/* Find where the forcewake lock is */
ret = find_debugfs_path("/sys/kernel/debug/dri");
if (ret) {
@@ -175,6 +178,8 @@ intel_register_access_init(struct pci_device *pci_dev)
}
mmio_data.i915_devid = pci_dev->device_id;
+ if (mmio_data.safe)
+ mmio_data.map = intel_get_register_map(mmio_data.i915_devid);
mmio_data.key = get_forcewake_lock();
mmio_data.inited++;
@@ -198,6 +203,25 @@ intel_register_read(uint32_t reg)
if (IS_GEN6(mmio_data.i915_devid))
assert(mmio_data.key != -1);
+
+ if (!mmio_data.safe)
+ goto read_out;
+
+ range = intel_get_register_range(mmio_data.map,
+ reg,
+ INTEL_RANGE_READ);
+
+ if(!range) {
+ fprintf(stderr, "Register read blocked for safety "
+ "(*0x%08x)\n", reg);
+ ret = 0xffffffff;
+ goto out;
+ }
+
+read_out:
+ ret = *(volatile uint32_t *)((volatile char *)mmio + reg);
+out:
+ return ret;
}
void
@@ -210,5 +234,18 @@ intel_register_write(uint32_t reg, uint32_t val)
if (IS_GEN6(mmio_data.i915_devid))
assert(mmio_data.key != -1);
+ if (!mmio_data.safe)
+ goto write_out;
+
+ range = intel_get_register_range(mmio_data.map,
+ reg,
+ INTEL_RANGE_WRITE);
+
+ if (!range) {
+ fprintf(stderr, "Register write blocked for safety "
+ "(*0x%08x = 0x%x)\n", reg, val);
+ }
+
+write_out:
*(volatile uint32_t *)((volatile char *)mmio + reg) = val;
}