From: Tony Lindgren <tony@atomide.com>
To: linux-arm-kernel@lists.arm.linux.org.uk
Cc: linux-omap@vger.kernel.org, Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Subject: [PATCH 02/10] OMAP: iommu: add initial debugfs support
Date: Wed, 12 Aug 2009 15:13:24 +0300 [thread overview]
Message-ID: <20090812121324.17601.39083.stgit@localhost> (raw)
In-Reply-To: <20090812120926.17601.85860.stgit@localhost>
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
This enables to peek the following data.
$ /debug/iommu/isp# ls
mem nr_tlb_entries regs
mmap pagetable tlb
$ /debug/iommu/isp# head pagetable
L: da: pa:
-----------------------------------------
2: 00001000 8ae4a002
2: 00002000 8e7bb002
2: 00003000 8ae49002
2: 00004000 8ae65002
.....
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/plat-omap/Kconfig | 4
arch/arm/plat-omap/Makefile | 1
arch/arm/plat-omap/iommu-debug.c | 334 ++++++++++++++++++++++++++++++++++++++
3 files changed, 339 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-omap/iommu-debug.c
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index efe85d0..ab9f9ef 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -120,6 +120,10 @@ config OMAP_MBOX_FWK
config OMAP_IOMMU
tristate
+config OMAP_IOMMU_DEBUG
+ depends on OMAP_IOMMU
+ tristate
+
choice
prompt "System timer"
default OMAP_MPU_TIMER
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index a832795..769a4c2 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
+obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
diff --git a/arch/arm/plat-omap/iommu-debug.c b/arch/arm/plat-omap/iommu-debug.c
new file mode 100644
index 0000000..9811c19
--- /dev/null
+++ b/arch/arm/plat-omap/iommu-debug.c
@@ -0,0 +1,334 @@
+/*
+ * omap iommu: debugfs interface
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+
+#include <mach/iommu.h>
+#include <mach/iovmm.h>
+
+#include "iopgtable.h"
+
+#define MAXCOLUMN 100 /* for short messages */
+
+static DEFINE_MUTEX(iommu_debug_lock);
+static char local_buffer[SZ_4K];
+
+static struct dentry *iommu_debug_root;
+
+static ssize_t debug_read_ver(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ u32 ver = iommu_arch_version();
+ char buf[MAXCOLUMN], *p = buf;
+
+ p += sprintf(p, "H/W version: %d.%d\n", (ver >> 4) & 0xf , ver & 0xf);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+}
+
+static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p = local_buffer;
+ ssize_t bytes;
+
+ mutex_lock(&iommu_debug_lock);
+ p += iommu_dump_ctx(obj, p);
+ bytes = simple_read_from_buffer(userbuf, count, ppos, local_buffer,
+ p - local_buffer);
+ mutex_unlock(&iommu_debug_lock);
+ return bytes;
+}
+
+static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p = local_buffer;
+ ssize_t bytes;
+
+ mutex_lock(&iommu_debug_lock);
+ p += sprintf(p, "%8s %8s\n", "cam:", "ram:");
+ p += sprintf(p, "-----------------------------------------\n");
+ p += dump_tlb_entries(obj, p);
+ bytes = simple_read_from_buffer(userbuf, count, ppos, local_buffer,
+ p - local_buffer);
+ mutex_unlock(&iommu_debug_lock);
+ return bytes;
+}
+
+static ssize_t debug_write_pagetable(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct iotlb_entry e;
+ struct cr_regs cr;
+ int err;
+ struct iommu *obj = file->private_data;
+ char buf[MAXCOLUMN], *p = buf;
+
+ count = min(count, sizeof(buf));
+
+ mutex_lock(&iommu_debug_lock);
+ if (copy_from_user(p, userbuf, count)) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EFAULT;
+ }
+
+ sscanf(p, "%x %x", &cr.cam, &cr.ram);
+ if (!cr.cam || !cr.ram) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EINVAL;
+ }
+
+ iotlb_cr_to_e(&cr, &e);
+ err = iopgtable_store_entry(obj, &e);
+ if (err)
+ dev_err(obj->dev, "%s: fail to store cr\n", __func__);
+
+ mutex_unlock(&iommu_debug_lock);
+ return count;
+}
+
+static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ int i;
+ u32 *iopgd;
+ struct iommu *obj = file->private_data;
+ char *p = local_buffer;
+ ssize_t bytes;
+
+ mutex_lock(&iommu_debug_lock);
+
+ p += sprintf(p, "L: %8s %8s\n", "da:", "pa:");
+ p += sprintf(p, "-----------------------------------------\n");
+
+ spin_lock(&obj->page_table_lock);
+
+ iopgd = iopgd_offset(obj, 0);
+ for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
+ int j;
+ u32 *iopte;
+
+ if (!*iopgd)
+ continue;
+
+ if (!(*iopgd & IOPGD_TABLE)) {
+ u32 da;
+
+ da = i << IOPGD_SHIFT;
+ p += sprintf(p, "1: %08x %08x\n", da, *iopgd);
+ continue;
+ }
+
+ iopte = iopte_offset(iopgd, 0);
+
+ for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
+ u32 da;
+
+ if (!*iopte)
+ continue;
+
+ da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
+ p += sprintf(p, "2: %08x %08x\n", da, *iopte);
+ }
+ }
+ spin_unlock(&obj->page_table_lock);
+
+ bytes = simple_read_from_buffer(userbuf, count, ppos, local_buffer,
+ p - local_buffer);
+ mutex_unlock(&iommu_debug_lock);
+ return bytes;
+}
+
+static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p = local_buffer;
+ struct iovm_struct *tmp;
+ int uninitialized_var(i);
+ ssize_t bytes;
+
+ mutex_lock(&iommu_debug_lock);
+
+ p += sprintf(p, "%-3s %-8s %-8s %6s %8s\n",
+ "No", "start", "end", "size", "flags");
+ p += sprintf(p, "-------------------------------------------------\n");
+
+ list_for_each_entry(tmp, &obj->mmap, list) {
+ size_t len;
+
+ len = tmp->da_end - tmp->da_start;
+ p += sprintf(p, "%3d %08x-%08x %6x %8x\n",
+ i, tmp->da_start, tmp->da_end, len, tmp->flags);
+ i++;
+ }
+ bytes = simple_read_from_buffer(userbuf, count, ppos, local_buffer,
+ p - local_buffer);
+ mutex_unlock(&iommu_debug_lock);
+ return bytes;
+}
+
+static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p = local_buffer;
+ struct iovm_struct *area;
+ ssize_t bytes;
+
+ mutex_lock(&iommu_debug_lock);
+
+ area = find_iovm_area(obj, (u32)ppos);
+ if (IS_ERR(area)) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EINVAL;
+ }
+ memcpy(p, area->va, count);
+ p += count;
+
+ bytes = simple_read_from_buffer(userbuf, count, ppos, local_buffer,
+ p - local_buffer);
+ mutex_unlock(&iommu_debug_lock);
+ return bytes;
+}
+
+static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ struct iovm_struct *area;
+ char *p = local_buffer;
+
+ count = min(count, sizeof(local_buffer));
+
+ mutex_lock(&iommu_debug_lock);
+
+ if (copy_from_user(p, userbuf, count)) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EFAULT;
+ }
+
+ area = find_iovm_area(obj, (u32)ppos);
+ if (IS_ERR(area)) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EINVAL;
+ }
+ memcpy(area->va, p, count);
+ mutex_unlock(&iommu_debug_lock);
+ return count;
+}
+
+static int debug_open_generic(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+#define DEBUG_FOPS(name) \
+ static const struct file_operations debug_##name##_fops = { \
+ .open = debug_open_generic, \
+ .read = debug_read_##name, \
+ .write = debug_write_##name, \
+ };
+
+#define DEBUG_FOPS_RO(name) \
+ static const struct file_operations debug_##name##_fops = { \
+ .open = debug_open_generic, \
+ .read = debug_read_##name, \
+ };
+
+DEBUG_FOPS_RO(ver);
+DEBUG_FOPS_RO(regs);
+DEBUG_FOPS_RO(tlb);
+DEBUG_FOPS(pagetable);
+DEBUG_FOPS_RO(mmap);
+DEBUG_FOPS(mem);
+
+#define __DEBUG_ADD_FILE(attr, mode) \
+ { \
+ struct dentry *dent; \
+ dent = debugfs_create_file(#attr, mode, parent, \
+ obj, &debug_##attr##_fops); \
+ if (!dent) \
+ return -ENOMEM; \
+ }
+
+#define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 600)
+#define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 400)
+
+static int iommu_debug_register(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct iommu *obj = platform_get_drvdata(pdev);
+ struct dentry *d, *parent;
+
+ if (!obj || !obj->dev)
+ return -EINVAL;
+
+ d = debugfs_create_dir(obj->name, iommu_debug_root);
+ if (!d)
+ return -ENOMEM;
+ parent = d;
+
+ d = debugfs_create_u8("nr_tlb_entries", 400, parent,
+ (u8 *)&obj->nr_tlb_entries);
+ if (!d)
+ return -ENOMEM;
+
+ DEBUG_ADD_FILE_RO(ver);
+ DEBUG_ADD_FILE_RO(regs);
+ DEBUG_ADD_FILE_RO(tlb);
+ DEBUG_ADD_FILE(pagetable);
+ DEBUG_ADD_FILE_RO(mmap);
+ DEBUG_ADD_FILE(mem);
+
+ return 0;
+}
+
+static int __init iommu_debug_init(void)
+{
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("iommu", NULL);
+ if (!d)
+ return -ENOMEM;
+ iommu_debug_root = d;
+
+ err = foreach_iommu_device(d, iommu_debug_register);
+ if (err)
+ goto err_out;
+ return 0;
+
+err_out:
+ debugfs_remove_recursive(iommu_debug_root);
+ return err;
+}
+module_init(iommu_debug_init)
+
+static void __exit iommu_debugfs_exit(void)
+{
+ debugfs_remove_recursive(iommu_debug_root);
+}
+module_exit(iommu_debugfs_exit)
+
+MODULE_DESCRIPTION("omap iommu: debugfs interface");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_LICENSE("GPL v2");
next prev parent reply other threads:[~2009-08-12 12:13 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-12 12:10 [PATCH 00/10] Omap3 updates for upcoming 2.6.32 merge window Tony Lindgren
2009-08-12 12:12 ` [PATCH 01/10] OMAP: iommu: fix wrong argument in flush_cache_vmap() Tony Lindgren
2009-08-13 9:21 ` Russell King - ARM Linux
2009-08-12 12:13 ` Tony Lindgren [this message]
2009-08-13 9:23 ` [PATCH 02/10] OMAP: iommu: add initial debugfs support Russell King - ARM Linux
2009-08-15 12:06 ` Hiroshi DOYU
2009-08-16 15:13 ` Tony Lindgren
2009-08-16 20:47 ` Russell King - ARM Linux
2009-08-17 4:19 ` Hiroshi DOYU
2009-08-17 7:28 ` Hiroshi DOYU
2009-08-27 7:25 ` Hiroshi DOYU
2009-08-28 18:24 ` Tony Lindgren
2009-08-12 12:14 ` [PATCH 03/10] OMAP2/3: Pass irqflags to 8250 driver Tony Lindgren
2009-08-12 12:16 ` [PATCH 04/10] OMAP3: 3430SDP: Fix defconfig Tony Lindgren
2009-08-13 9:24 ` Russell King - ARM Linux
2009-08-12 12:17 ` [PATCH 05/10] OMAP3: rx51_defconfig: add twl4030 to rx51 default configuration Tony Lindgren
2009-08-13 9:24 ` Russell King - ARM Linux
2009-08-12 12:18 ` [PATCH 06/10] OMAP3: MMC: Add mux for pins Tony Lindgren
2009-08-13 9:26 ` Russell King - ARM Linux
2009-08-16 15:25 ` [PATCH 06/10] OMAP3: MMC: Add mux for pins, v2 Tony Lindgren
2009-08-12 12:20 ` [PATCH 07/10] OMAP3: Zoom2: Add TWL4030 support Tony Lindgren
2009-08-13 9:27 ` Russell King - ARM Linux
2009-08-16 15:28 ` [PATCH 07/10] OMAP3: Zoom2: Add TWL4030 support,v 2 Tony Lindgren
2009-08-12 12:21 ` [PATCH 08/10] OMAP3: Zoom2: Update board defconfig Tony Lindgren
2009-08-13 9:28 ` Russell King - ARM Linux
2009-08-12 12:22 ` [PATCH 09/10] OMAP3: beagle: add missing twl4030 usb platform_data Tony Lindgren
2009-08-13 9:28 ` Russell King - ARM Linux
2009-08-12 12:24 ` [PATCH 10/10] OMAP3: update OMAP3 Beagle defconfig Tony Lindgren
2009-08-12 12:27 ` Felipe Balbi
2009-08-12 16:52 ` [PATCH 10/10] OMAP3: update OMAP3 Beagle defconfig, v2 Tony Lindgren
2009-08-12 17:20 ` Kevin Hilman
2009-08-12 19:11 ` Felipe Balbi
2009-08-13 7:02 ` Tony Lindgren
2009-08-16 1:48 ` Eric Witcher
2009-08-16 15:42 ` [PATCH 10/10] OMAP3: update OMAP3 Beagle defconfig, v3 Tony Lindgren
2009-08-16 17:07 ` Felipe Balbi
2009-08-16 17:22 ` Tony Lindgren
2009-08-19 13:40 ` Felipe Balbi
2009-08-24 13:05 ` [PATCH 00/10] Omap3 updates for upcoming 2.6.32 merge window Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090812121324.17601.39083.stgit@localhost \
--to=tony@atomide.com \
--cc=Hiroshi.DOYU@nokia.com \
--cc=linux-arm-kernel@lists.arm.linux.org.uk \
--cc=linux-omap@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.