/********************************************************************* * * Copyright (C) 2002, 2009, Karlsruhe University * * File path: kdb/generic/mapping.cc * Description: Mapping database dumping * * 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: mapping.cc,v 1.2 2003/09/24 19:05:11 skoglund Exp $ * ********************************************************************/ #include <debug.h> #include <kdb/cmd.h> #include <kdb/kdb.h> #include <kdb/input.h> #include <mapping.h> #include <linear_ptab.h> static void dump_mdbmaps (mapnode_t * map, addr_t paddr, mapnode_t::pgsize_e size, rootnode_t * proot, char * spc); static void dump_mdbroot (rootnode_t * root, addr_t paddr, mapnode_t::pgsize_e size, char * spc); /* * Helper functions */ INLINE word_t mdb_arraysize (mapnode_t::pgsize_e pgsize) { return 1 << (mdb_pgshifts[pgsize+1] - mdb_pgshifts[pgsize]); } INLINE word_t mdb_get_index (mapnode_t::pgsize_e size, addr_t addr) { return ((word_t) addr >> mdb_pgshifts[size]) & (mdb_arraysize(size) - 1); } INLINE rootnode_t * mdb_index_root (mapnode_t::pgsize_e size, rootnode_t * r, addr_t addr) { return r + mdb_get_index (size, addr); } INLINE pgent_t::pgsize_e hw_pgsize (mapnode_t::pgsize_e mdb_pgsize) { pgent_t::pgsize_e s = (pgent_t::pgsize_e) 0; while (hw_pgshifts[s] < mdb_pgshifts[mdb_pgsize]) s++; return s; } /** * cmd_dump_mdb: dump mapping database */ DECLARE_CMD (cmd_dump_mdb, root, 'm', "mdb", "dump mapping database"); CMD (cmd_dump_mdb, cg) { static char spaces[] = " "; addr_t paddr = (addr_t) get_hex ("Address"); if ((word_t) paddr == ABORT_MAGIC) return CMD_NOQUIT; dump_mdbroot (mdb_index_root (mapnode_t::size_max, sigma0_mapnode->get_nextroot (), paddr), paddr, mapnode_t::size_max, spaces + sizeof (spaces)-1); return CMD_NOQUIT; } static void dump_mdbmaps (mapnode_t * map, addr_t paddr, mapnode_t::pgsize_e size, rootnode_t * proot, char * spc) { mapnode_t * pmap = NULL; while (map) { space_t * space = map->get_space (); pgent_t::pgsize_e hwsize = hw_pgsize (size); printf ("%s[%d] space=%p vaddr=%p pgent=%p (%p)\n", spc - map->get_depth () * 2, map->get_depth (), space, (pmap ? map->get_pgent (pmap)->vaddr (space, hwsize, map) : map->get_pgent (proot)->vaddr (space, hwsize, map)), pmap ? map->get_pgent(pmap) : map->get_pgent(proot), map); pmap = map; if (map->is_next_root () || (map->is_next_both () && map->get_nextroot () != NULL)) { dump_mdbroot (mdb_index_root (size-1, map->get_nextroot (), paddr), paddr, size-1, spc - 2 - map->get_depth () * 2); } map = map->get_nextmap (); } } static void dump_mdbroot (rootnode_t * root, addr_t paddr, mapnode_t::pgsize_e size, char * spc) { printf ("%s%p: %d%cB %s (%p)\n", spc, addr_mask (paddr, ~((1 << mdb_pgshifts[size]) - 1)), ((mdb_pgshifts[size] >= 30) ? 1 << (mdb_pgshifts[size] - 30) : (mdb_pgshifts[size] >= 20) ? 1 << (mdb_pgshifts[size] - 20) : 1 << (mdb_pgshifts[size] - 10)), ((mdb_pgshifts[size] >= 30) ? 'G' : (mdb_pgshifts[size] >= 20) ? 'M' : 'K'), root->is_next_both () ? "[root/map]" : root->is_next_root () ? "[root]" : "[map]", root); if (root->is_next_map () || root->is_next_both ()) dump_mdbmaps (root->get_map (), paddr, size, root, spc - 2); if (root->is_next_root () || root->is_next_both ()) dump_mdbroot (mdb_index_root (size-1, root->get_root (), paddr), paddr, size-1, spc - 2); }