l4ka-pistachio/kernel/kdb/generic/linear_ptab_dump.cc

172 lines
5.0 KiB
C++

/*********************************************************************
*
* Copyright (C) 2002-2004, 2007-2008, 2010, 2012, Karlsruhe University
*
* File path: kdb/generic/linear_ptab_dump.cc
* Description: Linear page table dump
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: linear_ptab_dump.cc,v 1.17 2006/10/19 22:57:36 ud3 Exp $
*
********************************************************************/
#include <debug.h>
#include <kdb/cmd.h>
#include <kdb/kdb.h>
#include <kdb/input.h>
#include <linear_ptab.h>
#include INC_ARCH(pgent.h)
#include INC_API(tcb.h)
void get_ptab_dump_ranges (addr_t * vaddr, word_t * num,
pgent_t::pgsize_e * max_size);
#if !defined(CONFIG_ARCH_X86)
void get_ptab_dump_ranges (addr_t * vaddr, word_t * num,
pgent_t::pgsize_e * max_size)
{
*vaddr = (addr_t) 0;
*num = page_table_size (pgent_t::size_max);
*max_size = pgent_t::size_max;
}
#endif
/**
* cmd_dump_ptab: dump page table contents
*/
DECLARE_CMD (cmd_dump_ptab, root, 'p', "ptab", "dump page table");
CMD(cmd_dump_ptab, cg)
{
static char spaces[] = " ";
char * spcptr = spaces + sizeof (spaces) - 1;
char * spcpad = spcptr - pgent_t::size_max * 2;
space_t * space;
addr_t vaddr;
word_t num, count = 0;
pgent_t * pg;
pgent_t::pgsize_e size, max_size;
// Arrays to implement recursion
pgent_t * r_pg[pgent_t::size_max];
word_t r_num[pgent_t::size_max];
// Get dump arguments
space = get_space ("Space");
size = pgent_t::size_max;
word_t cpu = get_dec("CPU id", get_current_cpu(), NULL);
if (cpu >= CONFIG_SMP_MAX_CPUS) cpu = get_current_cpu();
get_ptab_dump_ranges (&vaddr, &num, &max_size);
pg = space->pgent (page_table_index (pgent_t::size_max, vaddr), cpu);
if (!pg)
{
printf ("No page table\n");
return CMD_NOQUIT;
}
while (size != max_size)
{
if (!pg->is_subtree (space, size))
{
printf ("No subtree");
return CMD_NOQUIT;
}
pg = pg->subtree (space, size--);
pg = pg->next (space, size, page_table_index (size, vaddr));
}
while (num > 0)
{
if (((++count % 4000) == 0) && get_choice ("Continue", "y/n", 'y') == 'n')
break;
if (pg->is_valid (space, size))
{
if (pg->is_subtree (space, size))
{
// Recurse into subtree
printf ("%p [%p]:%s tree=%p\n", vaddr, pg->raw, spcptr,
pg->subtree (space, size));
size--;
r_pg[size] = pg->next (space, size+1, 1);
r_num[size] = num - 1;
spcptr -= 2;
spcpad += 2;
pg = pg->subtree (space, size+1);
num = page_table_size (size);
continue;
}
else
{
// Print valid mapping
word_t pgsz = page_size (size);
word_t rwx = pg->reference_bits (space, size, vaddr);
word_t pgentsz = sizeof(pg->raw);
printf ("%p [%p]:%s phys=%p map=%p %s%3d%cB %c%c%c "
"(%c%c%c) %s",
vaddr, pg->raw, spcptr, pg->address (space, size),
pg->mapnode (space, size, vaddr), spcpad,
(pgsz >= GB (1) ? pgsz >> 30 :
pgsz >= MB (1) ? pgsz >> 20 : pgsz >> 10),
pgsz >= GB (1) ? 'G' : pgsz >= MB (1) ? 'M' : 'K',
pg->is_readable (space, size) ? 'r' : '~',
pg->is_writable (space, size) ? 'w' : '~',
pg->is_executable (space, size) ? 'x' : '~',
rwx & 4 ? 'R' : '~',
rwx & 2 ? 'W' : '~',
rwx & 1 ? 'X' : '~',
pg->is_kernel (space, size) ? "kernel" : "user");
pg->dump_misc (space, size);
printf ("\n");
}
}
// Goto next ptab entry
vaddr = addr_offset (vaddr, page_size (size));
pg = pg->next (space, size, 1);
num--;
while (num == 0 && size < max_size)
{
// Recurse up from subtree
pg = r_pg[size];
num = r_num[size];
size++;
spcptr += 2;
spcpad -= 2;
}
}
return CMD_NOQUIT;
}