sfmmu.c revision 1bd453f385f392a0415fad0b14efc9f5a545320f
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/machparam.h>
#include <vm/hat_sfmmu.h>
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_target.h>
/*
* sfmmu mdb support
*/
#define SFMMU_VTOP_DBG_SYMBOL 1
#define SFMMU_VTOP_DBG_VERBOSE 2
#define SFMMU_VTOP_DBG_DEBUG 4
struct hme_blks_max {
struct hme_blk hmx_hmeblk;
};
static void sfmmu_vtop_print_hmeblk(struct hme_blk *);
int sfmmu_vtop_dbg_wanted = 0; /* set this as desired */
int sfmmu_vtop_dbg = 0;
/*
* ::sfmmu_vtop [[-v] -a as]
* Extended version of the vtop builtin. The optional <as> argument is
* used as base address space for translating a virtual address into a
* physical address. The verbose option ("-v") shows intermediate
* translation steps. If <as> or kas is ommitted, the builtin ::vtop
* dcmd is called.
*/
int
{
int ret;
int verbose = 0;
return (DCMD_USAGE);
mdb_warn("-v requires -a option\n");
return (DCMD_USAGE);
}
}
mdb_warn("couldn't find 'kas'\n");
return (DCMD_ERR);
} else {
}
} else {
}
}
if (asp == 0) {
SFMMU_VTOP_DBG_DBG("sfmmu_vtop: call standard vtop\n");
}
return (DCMD_ERR);
}
if (ret == 0) {
mdb_printf("address space %p: virtual %lr mapped to physical "
} else {
return (DCMD_ERR);
}
return (DCMD_OK);
}
static int
{
int ret;
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (ret);
}
static int
{
struct hmehash_bucket *uhme_hash;
struct hmehash_bucket *khme_hash;
int uhmehash_num;
int khmehash_num;
struct hmehash_bucket mbucket;
struct hmehash_bucket *hmebp;
struct hmehash_bucket *shmebp;
int hmeshift;
int hashno = 1;
struct hme_blks_max mhmeblkmax;
int i;
int sfhmeinx = 0;
int ret = -1;
return (DCMD_ERR);
}
SFMMU_VTOP_DBG_VRB("ism_blkp=%p inx=%d\n",
sism_blkp, i);
SFMMU_VTOP_DBG_DBG("ism map=%p ism hat=%p "
"addr=%llx\n",
break;
}
}
}
do {
#ifdef __sparcv9
SFMMU_VTOP_DBG_DBG("hblktag=%lx %lx\n",
#else
SFMMU_VTOP_DBG_DBG("hblktag=%llx\n",
#endif
return (DCMD_ERR);
}
break;
mdb_warn("couldn't read hme_blk at %p\n",
hmeblkp);
return (DCMD_ERR);
}
/* found hme_blk */
break;
}
}
&sfhmeinx);
if (sfhmeinx > 0) {
thmeblkp) == -1) {
mdb_warn("couldn't read msfhme at %p\n",
sfhmep);
return (DCMD_ERR);
}
}
SFMMU_VTOP_DBG_VRB("sfmmup=%p hmebp=%p hmeblkp=%p\n",
if (TTE_IS_VALID(&tte)) {
0;
SFMMU_VTOP_DBG_VRB("pfn=%lx pp=%p\n",
ret = 0;
}
break;
}
hashno++;
return (ret);
}
static void
{
return;
#ifdef __sparcv9
#else
#endif
if (hmeblkp->hblk_shw_bit == 0) {
} else {
}
}
static struct sf_hment *
{
int index = 0;
}
if (hmenump) {
}
}
/*
* memseg walker based callback function: used internal and for ::page_num2pp
*/
struct pfn2pp {
};
/*ARGSUSED*/
int
{
return (DCMD_ERR);
}
return (WALK_DONE);
}
return (WALK_NEXT);
}
/*
* ::page_num2pp dcmd
*/
/*ARGSUSED*/
int
{
if ((flags & DCMD_ADDRSPEC) == 0) {
mdb_warn("page frame number missing\n");
return (DCMD_USAGE);
}
(void *)&pfn2pp) == -1) {
mdb_warn("can't walk memseg");
return (DCMD_ERR);
}
return (DCMD_ERR);
return (DCMD_ERR);
}
mdb_warn("WARNING! Found page structure contains "
}
return (DCMD_OK);
}
/*
* ::memseg_list dcmd
*/
/*ARGSUSED*/
int
{
if (!(flags & DCMD_ADDRSPEC)) {
0, NULL, 0) == -1) {
mdb_warn("can't walk memseg");
return (DCMD_ERR);
}
return (DCMD_OK);
}
if (DCMD_HDRSPEC(flags))
"PAGES", "EPAGES", "BASE", "END");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* walk the memseg structures
*/
int
{
mdb_warn("memseg only supports global walks\n");
return (WALK_ERR);
}
mdb_warn("symbol 'memsegs' not found");
return (WALK_ERR);
}
return (WALK_NEXT);
}
int
{
int status;
return (WALK_DONE);
}
return (WALK_DONE);
}
wsp->walk_cbdata);
return (status);
}
void
{
}
int
{
int rv;
SFMMU_VTOP_DBG_DBG("platform_vtop: called.\n");
return (DCMD_ERR);
}
}
return (rv);
}
/*
* ::tsbinfo help
*/
void
tsbinfo_help(void)
{
mdb_printf("-l\tlist valid TSB entries.\n"
"-a\tlist all TSB entries. Can only be used with -l.\n");
}
/*
* ::tsbinfo dcmd
*/
int
{
unsigned int entries = 0;
char tsbsize[16];
#define FLAGS_SIZE sizeof ("RELOC,FLUSH,SWAPPED")
static const mdb_bitmask_t ttesz_mask_bits[] = {
{ NULL, 0, 0 }
};
static const mdb_bitmask_t flags_bits[] = {
{ NULL, 0, 0 }
};
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_USAGE);
}
return (DCMD_USAGE);
}
/* -a only valid with -l */
return (DCMD_USAGE);
}
/* Print header? */
}
return (DCMD_ERR);
}
/* Print a "-" if the TSB is swapped out. */
} else {
}
#define KB 1024
} else {
}
} else {
}
/* Print TSB entries? */
if (lflag) {
UM_SLEEP);
mdb_warn("failed to read TSB at %p",
return (DCMD_ERR);
}
"TSB @ %lx (%d entries)\n"
"%-?s %-17s %s\n"
"%<u>%-?s %1s %1s %-11s "
"%1s %1s %1s %1s %1s %1s %8s "
"%1s %1s %1s %1s %1s %1s %1s "
"%1s %1s %1s %1s %1s %1s%</u>\n",
"ADDR", "I", "L", "VA 63:22",
"V", "S", "N", "I", "H", "S", "PA 42:13",
"N", "U", "R", "W", "E", "X", "L",
"P", "V", "E", "P", "W", "G");
if (aflag ||
<< 32) +
mdb_printf("%0?lx %-1u %-1u %011lx "
"%1u %-1u %-1u %-1u %-1u %1u %08x "
"%1u %1u %1u %1u %1u %1u %1u "
"%1u %1u %1u %1u %1u %1u\n",
* sizeof (struct tsbe),
#ifdef sun4v
0,
#else
#endif
pa,
#ifdef sun4v
0,
#else
#endif
#ifdef sun4v
0
#else
#endif
/*CSTYLED*/
);
}
}
} else {
mdb_printf("TSB swapped out\n");
}
}
return (DCMD_OK);
}