iommu/omap: Switch pagetable debugfs entry to use seq_file
The debugfs entry 'pagetable' that shows the page table entry (PTE) data currently outputs only data that can be fit into a page. Switch the entry to use the seq_file interface so that it can show all the valid page table entries. The patch also corrected the output for L2 entries, and prints the proper L2 PTE instead of the previous L1 page descriptor pointer. Signed-off-by: Suman Anna <s-anna@ti.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
c5cf5c5377
commit
9c83e9f384
1 changed files with 28 additions and 53 deletions
|
@ -85,93 +85,68 @@ static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define dump_ioptable_entry_one(lv, da, val) \
|
static void dump_ioptable(struct seq_file *s)
|
||||||
({ \
|
|
||||||
int __err = 0; \
|
|
||||||
ssize_t bytes; \
|
|
||||||
const int maxcol = 22; \
|
|
||||||
const char *str = "%d: %08x %08x\n"; \
|
|
||||||
bytes = snprintf(p, maxcol, str, lv, da, val); \
|
|
||||||
p += bytes; \
|
|
||||||
len -= bytes; \
|
|
||||||
if (len < maxcol) \
|
|
||||||
__err = -ENOMEM; \
|
|
||||||
__err; \
|
|
||||||
})
|
|
||||||
|
|
||||||
static ssize_t dump_ioptable(struct omap_iommu *obj, char *buf, ssize_t len)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i, j;
|
||||||
u32 *iopgd;
|
u32 da;
|
||||||
char *p = buf;
|
u32 *iopgd, *iopte;
|
||||||
|
struct omap_iommu *obj = s->private;
|
||||||
|
|
||||||
spin_lock(&obj->page_table_lock);
|
spin_lock(&obj->page_table_lock);
|
||||||
|
|
||||||
iopgd = iopgd_offset(obj, 0);
|
iopgd = iopgd_offset(obj, 0);
|
||||||
for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
|
for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
|
||||||
int j, err;
|
|
||||||
u32 *iopte;
|
|
||||||
u32 da;
|
|
||||||
|
|
||||||
if (!*iopgd)
|
if (!*iopgd)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(*iopgd & IOPGD_TABLE)) {
|
if (!(*iopgd & IOPGD_TABLE)) {
|
||||||
da = i << IOPGD_SHIFT;
|
da = i << IOPGD_SHIFT;
|
||||||
|
seq_printf(s, "1: 0x%08x 0x%08x\n", da, *iopgd);
|
||||||
err = dump_ioptable_entry_one(1, da, *iopgd);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
iopte = iopte_offset(iopgd, 0);
|
iopte = iopte_offset(iopgd, 0);
|
||||||
|
|
||||||
for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
|
for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
|
||||||
if (!*iopte)
|
if (!*iopte)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
|
da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
|
||||||
err = dump_ioptable_entry_one(2, da, *iopgd);
|
seq_printf(s, "2: 0x%08x 0x%08x\n", da, *iopte);
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
spin_unlock(&obj->page_table_lock);
|
spin_unlock(&obj->page_table_lock);
|
||||||
|
|
||||||
return p - buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
|
static int debug_read_pagetable(struct seq_file *s, void *data)
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
{
|
||||||
struct omap_iommu *obj = file->private_data;
|
struct omap_iommu *obj = s->private;
|
||||||
char *p, *buf;
|
|
||||||
size_t bytes;
|
|
||||||
|
|
||||||
if (is_omap_iommu_detached(obj))
|
if (is_omap_iommu_detached(obj))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
buf = (char *)__get_free_page(GFP_KERNEL);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
p = buf;
|
|
||||||
|
|
||||||
p += sprintf(p, "L: %8s %8s\n", "da:", "pa:");
|
|
||||||
p += sprintf(p, "-----------------------------------------\n");
|
|
||||||
|
|
||||||
mutex_lock(&iommu_debug_lock);
|
mutex_lock(&iommu_debug_lock);
|
||||||
|
|
||||||
bytes = PAGE_SIZE - (p - buf);
|
seq_printf(s, "L: %8s %8s\n", "da:", "pte:");
|
||||||
p += dump_ioptable(obj, p, bytes);
|
seq_puts(s, "--------------------------\n");
|
||||||
|
dump_ioptable(s);
|
||||||
bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
|
||||||
|
|
||||||
mutex_unlock(&iommu_debug_lock);
|
mutex_unlock(&iommu_debug_lock);
|
||||||
free_page((unsigned long)buf);
|
|
||||||
|
|
||||||
return bytes;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEBUG_SEQ_FOPS_RO(name) \
|
||||||
|
static int debug_open_##name(struct inode *inode, struct file *file) \
|
||||||
|
{ \
|
||||||
|
return single_open(file, debug_read_##name, inode->i_private); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static const struct file_operations debug_##name##_fops = { \
|
||||||
|
.open = debug_open_##name, \
|
||||||
|
.read = seq_read, \
|
||||||
|
.llseek = seq_lseek, \
|
||||||
|
.release = single_release, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEBUG_FOPS_RO(name) \
|
#define DEBUG_FOPS_RO(name) \
|
||||||
|
@ -183,7 +158,7 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
|
||||||
|
|
||||||
DEBUG_FOPS_RO(regs);
|
DEBUG_FOPS_RO(regs);
|
||||||
DEBUG_FOPS_RO(tlb);
|
DEBUG_FOPS_RO(tlb);
|
||||||
DEBUG_FOPS_RO(pagetable);
|
DEBUG_SEQ_FOPS_RO(pagetable);
|
||||||
|
|
||||||
#define __DEBUG_ADD_FILE(attr, mode) \
|
#define __DEBUG_ADD_FILE(attr, mode) \
|
||||||
{ \
|
{ \
|
||||||
|
|
Loading…
Add table
Reference in a new issue