On the linux-mips.org TODO list, there's the $SUBJ item. Ralf B. hinted that a good starting point would be the dump_list_process function which was removed in 2.6.23 (during lib-32 & lib-64 merge?). This patch is just a copy paste from the lib-64 version of this function (with small modifications for 32 bit compatibility). Any other interesting "features" that should get in? diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 3f69725..7d705c8 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -6,6 +6,7 @@ */ #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/sched.h> #include <asm/mipsregs.h> #include <asm/page.h> @@ -109,3 +110,71 @@ void dump_tlb_all(void) { dump_tlb(0, current_cpu_data.tlbsize - 1); } + +void dump_list_process(struct task_struct *t, void *address) +{ + pgd_t *page_dir, *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte, page; + unsigned long addr, val; + int width; + +#if defined(CONFIG_64BIT) + width = 16; +#else + width = 8; +#endif + + addr = (unsigned long) address; + + printk("Addr == %0*lx\n", width, addr); + printk("tasks->mm.pgd == %0*lx\n", width, + (unsigned long) t->mm->pgd); + + page_dir = pgd_offset(t->mm, 0UL); + printk("page_dir == %0*lx\n", width, (unsigned long) page_dir); + + pgd = pgd_offset(t->mm, addr); + printk("pgd == %0*lx\n", width, (unsigned long) pgd); + + pud = pud_offset(pgd, addr); + printk("pud == %0*lx\n", width, (unsigned long) pud); + + pmd = pmd_offset(pud, addr); + printk("pmd == %0*lx\n", width, (unsigned long) pmd); + + pte = pte_offset(pmd, addr); + printk("pte == %0*lx\n", width, (long) pte); + + page = *pte; + printk("page == %08lx\n", pte_val(page)); + + val = pte_val(page); + if (val & _PAGE_PRESENT) + printk("present "); + if (val & _PAGE_READ) + printk("read "); + if (val & _PAGE_WRITE) + printk("write "); + if (val & _PAGE_ACCESSED) + printk("accessed "); + if (val & _PAGE_MODIFIED) + printk("modified "); +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) + if (val & _PAGE_R4KBUG) + printk("r4kbug "); +#endif + if (val & _PAGE_GLOBAL) + printk("global "); + if (val & _PAGE_VALID) + printk("valid "); + if (val & _PAGE_DIRTY) + printk("dirty "); + printk("\n"); +} + +void dump_list_current(void *address) +{ + dump_list_process(current, address); +}