1*a60fc142Srf157361 /* 2*a60fc142Srf157361 * CDDL HEADER START 3*a60fc142Srf157361 * 4*a60fc142Srf157361 * The contents of this file are subject to the terms of the 5*a60fc142Srf157361 * Common Development and Distribution License (the "License"). 6*a60fc142Srf157361 * You may not use this file except in compliance with the License. 7*a60fc142Srf157361 * 8*a60fc142Srf157361 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*a60fc142Srf157361 * or http://www.opensolaris.org/os/licensing. 10*a60fc142Srf157361 * See the License for the specific language governing permissions 11*a60fc142Srf157361 * and limitations under the License. 12*a60fc142Srf157361 * 13*a60fc142Srf157361 * When distributing Covered Code, include this CDDL HEADER in each 14*a60fc142Srf157361 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*a60fc142Srf157361 * If applicable, add the following below this CDDL HEADER, with the 16*a60fc142Srf157361 * fields enclosed by brackets "[]" replaced with your own identifying 17*a60fc142Srf157361 * information: Portions Copyright [yyyy] [name of copyright owner] 18*a60fc142Srf157361 * 19*a60fc142Srf157361 * CDDL HEADER END 20*a60fc142Srf157361 */ 21*a60fc142Srf157361 /* 22*a60fc142Srf157361 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*a60fc142Srf157361 * Use is subject to license terms. 24*a60fc142Srf157361 */ 25*a60fc142Srf157361 26*a60fc142Srf157361 #pragma ident "%Z%%M% %I% %E% SMI" 27*a60fc142Srf157361 28*a60fc142Srf157361 #include <sys/types.h> 29*a60fc142Srf157361 #include <sys/time.h> 30*a60fc142Srf157361 #include <sys/sysmacros.h> 31*a60fc142Srf157361 #include <ctype.h> 32*a60fc142Srf157361 #include <sys/mdb_modapi.h> 33*a60fc142Srf157361 #include <sys/mach_descrip.h> 34*a60fc142Srf157361 #include <sys/mdesc.h> 35*a60fc142Srf157361 #include <sys/mdesc_impl.h> 36*a60fc142Srf157361 37*a60fc142Srf157361 /*ARGSUSED*/ 38*a60fc142Srf157361 int 39*a60fc142Srf157361 mdhdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 40*a60fc142Srf157361 { 41*a60fc142Srf157361 uint_t verbose = 0; 42*a60fc142Srf157361 uintptr_t mdp; 43*a60fc142Srf157361 machine_descrip_t md; 44*a60fc142Srf157361 45*a60fc142Srf157361 if (flags & DCMD_ADDRSPEC) 46*a60fc142Srf157361 return (DCMD_USAGE); 47*a60fc142Srf157361 48*a60fc142Srf157361 if (mdb_getopts(argc, argv, 49*a60fc142Srf157361 'v', MDB_OPT_SETBITS, 1, &verbose, NULL) != argc) 50*a60fc142Srf157361 return (DCMD_USAGE); 51*a60fc142Srf157361 52*a60fc142Srf157361 /* curr_mach_descrip normally points to /dev/mdesc */ 53*a60fc142Srf157361 if (mdb_readvar(&mdp, "curr_mach_descrip") == -1) { 54*a60fc142Srf157361 mdb_warn("failed to read 'curr_mach_descrip'"); 55*a60fc142Srf157361 return (DCMD_ERR); 56*a60fc142Srf157361 } 57*a60fc142Srf157361 58*a60fc142Srf157361 if (verbose) 59*a60fc142Srf157361 mdb_printf("ADDRESS VA MEMOPS SIZE\n"); 60*a60fc142Srf157361 61*a60fc142Srf157361 do { 62*a60fc142Srf157361 if (mdb_vread(&md, sizeof (md), mdp) == -1) { 63*a60fc142Srf157361 mdb_warn("failed to read machine_descrip_t at %p", mdp); 64*a60fc142Srf157361 return (DCMD_ERR); 65*a60fc142Srf157361 } 66*a60fc142Srf157361 67*a60fc142Srf157361 if (verbose) 68*a60fc142Srf157361 mdb_printf("%-11lx %-11lx %-11lx %-11lx\n", 69*a60fc142Srf157361 mdp, md.va, md.memops, md.size); 70*a60fc142Srf157361 else 71*a60fc142Srf157361 mdb_printf("%p\n", mdp); 72*a60fc142Srf157361 73*a60fc142Srf157361 } while ((mdp = (uintptr_t)md.next) != NULL); 74*a60fc142Srf157361 75*a60fc142Srf157361 return (DCMD_OK); 76*a60fc142Srf157361 } 77*a60fc142Srf157361 78*a60fc142Srf157361 /*ARGSUSED*/ 79*a60fc142Srf157361 int 80*a60fc142Srf157361 mdinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 81*a60fc142Srf157361 { 82*a60fc142Srf157361 md_header_t mh; 83*a60fc142Srf157361 machine_descrip_t md; 84*a60fc142Srf157361 md_element_t *mdep; 85*a60fc142Srf157361 char *namep; 86*a60fc142Srf157361 uint8_t *datap; 87*a60fc142Srf157361 int mdesize, namesize, datasize; 88*a60fc142Srf157361 uintptr_t mdp; 89*a60fc142Srf157361 md_element_t *mdeptr, *eof; 90*a60fc142Srf157361 uintptr_t vaddr; 91*a60fc142Srf157361 92*a60fc142Srf157361 if (flags & DCMD_ADDRSPEC) { 93*a60fc142Srf157361 if ((addr & 7) != 0) { 94*a60fc142Srf157361 mdb_warn("misaligned address at %p", addr); 95*a60fc142Srf157361 return (DCMD_ERR); 96*a60fc142Srf157361 } 97*a60fc142Srf157361 vaddr = addr; 98*a60fc142Srf157361 } else { 99*a60fc142Srf157361 /* curr_mach_descrip normally points to /dev/mdesc */ 100*a60fc142Srf157361 if (mdb_readvar(&mdp, "curr_mach_descrip") == -1) { 101*a60fc142Srf157361 mdb_warn("failed to read 'curr_mach_descrip'"); 102*a60fc142Srf157361 return (DCMD_ERR); 103*a60fc142Srf157361 } 104*a60fc142Srf157361 if (mdb_vread(&md, sizeof (md), mdp) == -1) { 105*a60fc142Srf157361 mdb_warn("failed to read machine_descrip_t at %p", mdp); 106*a60fc142Srf157361 return (DCMD_ERR); 107*a60fc142Srf157361 } 108*a60fc142Srf157361 vaddr = (uintptr_t)md.va; 109*a60fc142Srf157361 } 110*a60fc142Srf157361 111*a60fc142Srf157361 if (mdb_vread(&mh, sizeof (mh), vaddr) == -1) { 112*a60fc142Srf157361 mdb_warn("failed to read md_header_t at %p", vaddr); 113*a60fc142Srf157361 return (DCMD_ERR); 114*a60fc142Srf157361 } 115*a60fc142Srf157361 116*a60fc142Srf157361 mdesize = mh.node_blk_sz; 117*a60fc142Srf157361 namesize = mh.name_blk_sz; 118*a60fc142Srf157361 datasize = mh.data_blk_sz; 119*a60fc142Srf157361 120*a60fc142Srf157361 /* find space for each section of the MD */ 121*a60fc142Srf157361 if ((mdep = mdb_alloc(mdesize, UM_NOSLEEP)) == NULL) { 122*a60fc142Srf157361 mdb_warn("failed to allocate memory for mde block"); 123*a60fc142Srf157361 return (DCMD_ERR); 124*a60fc142Srf157361 } 125*a60fc142Srf157361 if ((namep = mdb_alloc(namesize, UM_NOSLEEP)) == NULL) { 126*a60fc142Srf157361 mdb_warn("failed to allocate memory for name block"); 127*a60fc142Srf157361 mdb_free(mdep, mdesize); 128*a60fc142Srf157361 return (DCMD_ERR); 129*a60fc142Srf157361 } 130*a60fc142Srf157361 if ((datap = mdb_alloc(datasize, UM_NOSLEEP)) == NULL) { 131*a60fc142Srf157361 mdb_warn("failed to allocate memory for data block"); 132*a60fc142Srf157361 mdb_free(namep, namesize); 133*a60fc142Srf157361 mdb_free(mdep, mdesize); 134*a60fc142Srf157361 return (DCMD_ERR); 135*a60fc142Srf157361 } 136*a60fc142Srf157361 137*a60fc142Srf157361 /* store each of the MD sections */ 138*a60fc142Srf157361 if (mdb_vread(mdep, mdesize, vaddr + MD_HEADER_SIZE) != mdesize) { 139*a60fc142Srf157361 mdb_warn("failed to read node block %p", vaddr 140*a60fc142Srf157361 + MD_HEADER_SIZE); 141*a60fc142Srf157361 mdb_free(datap, datasize); 142*a60fc142Srf157361 mdb_free(namep, namesize); 143*a60fc142Srf157361 mdb_free(mdep, mdesize); 144*a60fc142Srf157361 return (DCMD_ERR); 145*a60fc142Srf157361 } 146*a60fc142Srf157361 if (mdb_vread(namep, namesize, vaddr + MD_HEADER_SIZE + mdesize) 147*a60fc142Srf157361 != namesize) { 148*a60fc142Srf157361 mdb_warn("failed to read node block %p", vaddr + MD_HEADER_SIZE 149*a60fc142Srf157361 + mdesize); 150*a60fc142Srf157361 mdb_free(datap, datasize); 151*a60fc142Srf157361 mdb_free(namep, namesize); 152*a60fc142Srf157361 mdb_free(mdep, mdesize); 153*a60fc142Srf157361 return (DCMD_ERR); 154*a60fc142Srf157361 } 155*a60fc142Srf157361 if (mdb_vread(datap, datasize, vaddr + MD_HEADER_SIZE + mdesize 156*a60fc142Srf157361 + namesize) != datasize) { 157*a60fc142Srf157361 mdb_warn("failed to read node block %p", vaddr + MD_HEADER_SIZE 158*a60fc142Srf157361 + mdesize + namesize); 159*a60fc142Srf157361 mdb_free(datap, datasize); 160*a60fc142Srf157361 mdb_free(namep, namesize); 161*a60fc142Srf157361 mdb_free(mdep, mdesize); 162*a60fc142Srf157361 return (DCMD_ERR); 163*a60fc142Srf157361 } 164*a60fc142Srf157361 165*a60fc142Srf157361 mdb_printf("TYPE OFFSET NAME PROPERTY\n"); 166*a60fc142Srf157361 eof = mdep + (mdesize / sizeof (md_element_t)); 167*a60fc142Srf157361 for (mdeptr = mdep; mdeptr < eof; ++mdeptr) { 168*a60fc142Srf157361 switch (MDE_TAG(mdeptr)) { 169*a60fc142Srf157361 case MDET_NODE: 170*a60fc142Srf157361 mdb_printf("node %-6x %-22s idx=%-11lx\n", 171*a60fc142Srf157361 MDE_NAME(mdeptr), namep + mdeptr->name_offset, 172*a60fc142Srf157361 MDE_PROP_INDEX(mdeptr)); 173*a60fc142Srf157361 break; 174*a60fc142Srf157361 case MDET_PROP_ARC: 175*a60fc142Srf157361 mdb_printf("arc %-6x %-22s idx=%-11lx\n", 176*a60fc142Srf157361 MDE_NAME(mdeptr), namep + mdeptr->name_offset, 177*a60fc142Srf157361 MDE_PROP_INDEX(mdeptr)); 178*a60fc142Srf157361 break; 179*a60fc142Srf157361 case MDET_PROP_DAT: 180*a60fc142Srf157361 mdb_printf("data %-6x %-22s len=%x, offset=%x\n", 181*a60fc142Srf157361 MDE_NAME(mdeptr), namep + mdeptr->name_offset, 182*a60fc142Srf157361 MDE_PROP_DATA_LEN(mdeptr), 183*a60fc142Srf157361 MDE_PROP_DATA_OFFSET(mdeptr)); 184*a60fc142Srf157361 break; 185*a60fc142Srf157361 case MDET_PROP_STR: 186*a60fc142Srf157361 mdb_printf("str %-6x %-22s len=%x, offset=%x\n", 187*a60fc142Srf157361 MDE_NAME(mdeptr), namep + mdeptr->name_offset, 188*a60fc142Srf157361 MDE_PROP_DATA_LEN(mdeptr), 189*a60fc142Srf157361 MDE_PROP_DATA_OFFSET(mdeptr)); 190*a60fc142Srf157361 break; 191*a60fc142Srf157361 case MDET_PROP_VAL: 192*a60fc142Srf157361 mdb_printf("val %-6x %-22s val=%-11lx\n", 193*a60fc142Srf157361 MDE_NAME(mdeptr), namep + mdeptr->name_offset, 194*a60fc142Srf157361 MDE_PROP_VALUE(mdeptr)); 195*a60fc142Srf157361 break; 196*a60fc142Srf157361 case MDET_NODE_END: 197*a60fc142Srf157361 mdb_printf("end\n"); 198*a60fc142Srf157361 break; 199*a60fc142Srf157361 case MDET_NULL: 200*a60fc142Srf157361 mdb_printf("null\n"); 201*a60fc142Srf157361 break; 202*a60fc142Srf157361 case MDET_LIST_END: 203*a60fc142Srf157361 mdb_printf("end of list\n"); 204*a60fc142Srf157361 break; 205*a60fc142Srf157361 default: 206*a60fc142Srf157361 mdb_printf("unkown tag=%x\n", MDE_TAG(mdeptr)); 207*a60fc142Srf157361 break; 208*a60fc142Srf157361 } 209*a60fc142Srf157361 } 210*a60fc142Srf157361 211*a60fc142Srf157361 mdb_free(datap, datasize); 212*a60fc142Srf157361 mdb_free(namep, namesize); 213*a60fc142Srf157361 mdb_free(mdep, mdesize); 214*a60fc142Srf157361 return (DCMD_OK); 215*a60fc142Srf157361 } 216*a60fc142Srf157361 217*a60fc142Srf157361 /*ARGSUSED*/ 218*a60fc142Srf157361 int 219*a60fc142Srf157361 mdformat(uintptr_t addr, int size, int indent) 220*a60fc142Srf157361 { 221*a60fc142Srf157361 mdb_inc_indent(indent); 222*a60fc142Srf157361 if (mdb_dumpptr((uintptr_t)addr, size, 223*a60fc142Srf157361 MDB_DUMP_RELATIVE | MDB_DUMP_TRIM | MDB_DUMP_ASCII | 224*a60fc142Srf157361 MDB_DUMP_HEADER | MDB_DUMP_GROUP(4), 225*a60fc142Srf157361 (mdb_dumpptr_cb_t)mdb_vread, NULL)) { 226*a60fc142Srf157361 mdb_dec_indent(indent); 227*a60fc142Srf157361 return (DCMD_ERR); 228*a60fc142Srf157361 } 229*a60fc142Srf157361 mdb_dec_indent(indent); 230*a60fc142Srf157361 return (DCMD_OK); 231*a60fc142Srf157361 } 232*a60fc142Srf157361 233*a60fc142Srf157361 /*ARGSUSED*/ 234*a60fc142Srf157361 int 235*a60fc142Srf157361 mddump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 236*a60fc142Srf157361 { 237*a60fc142Srf157361 uintptr_t mdp, mdep, namep, datap; 238*a60fc142Srf157361 machine_descrip_t md; 239*a60fc142Srf157361 md_header_t mh; 240*a60fc142Srf157361 uintptr_t vaddr; 241*a60fc142Srf157361 242*a60fc142Srf157361 if (flags & DCMD_ADDRSPEC) { 243*a60fc142Srf157361 if ((addr & 7) != 0) { 244*a60fc142Srf157361 mdb_warn("misaligned address at %p", addr); 245*a60fc142Srf157361 return (DCMD_ERR); 246*a60fc142Srf157361 } 247*a60fc142Srf157361 vaddr = addr; 248*a60fc142Srf157361 } else { 249*a60fc142Srf157361 /* curr_mach_descrip normally points to /dev/mdesc */ 250*a60fc142Srf157361 if (mdb_readvar(&mdp, "curr_mach_descrip") == -1) { 251*a60fc142Srf157361 mdb_warn("failed to read 'curr_mach_descrip'"); 252*a60fc142Srf157361 return (DCMD_ERR); 253*a60fc142Srf157361 } 254*a60fc142Srf157361 if (mdb_vread(&md, sizeof (md), mdp) == -1) { 255*a60fc142Srf157361 mdb_warn("failed to read machine_descrip_t at %p", mdp); 256*a60fc142Srf157361 return (DCMD_ERR); 257*a60fc142Srf157361 } 258*a60fc142Srf157361 vaddr = (uintptr_t)md.va; 259*a60fc142Srf157361 } 260*a60fc142Srf157361 261*a60fc142Srf157361 if (mdb_vread(&mh, sizeof (mh), (uintptr_t)vaddr) == -1) { 262*a60fc142Srf157361 mdb_warn("failed to read md_header_t at %p", vaddr); 263*a60fc142Srf157361 return (DCMD_ERR); 264*a60fc142Srf157361 } 265*a60fc142Srf157361 266*a60fc142Srf157361 mdep = (uintptr_t)vaddr + MD_HEADER_SIZE; 267*a60fc142Srf157361 namep = mdep + mh.node_blk_sz; 268*a60fc142Srf157361 datap = namep + mh.name_blk_sz; 269*a60fc142Srf157361 270*a60fc142Srf157361 mdb_printf("header (md_header_t) section at %lx:\n", vaddr); 271*a60fc142Srf157361 if (mdformat((uintptr_t)md.va, MD_HEADER_SIZE, 4) != DCMD_OK) 272*a60fc142Srf157361 return (DCMD_ERR); 273*a60fc142Srf157361 274*a60fc142Srf157361 mdb_printf("\nnode (md_element_t) section at %lx:\n", mdep); 275*a60fc142Srf157361 if (mdformat(mdep, mh.node_blk_sz, 2) != DCMD_OK) 276*a60fc142Srf157361 return (DCMD_ERR); 277*a60fc142Srf157361 278*a60fc142Srf157361 mdb_printf("\nname section at %lx:\n", namep); 279*a60fc142Srf157361 if (mdformat(namep, mh.name_blk_sz, 2) != DCMD_OK) 280*a60fc142Srf157361 return (DCMD_ERR); 281*a60fc142Srf157361 282*a60fc142Srf157361 mdb_printf("\ndata section at %lx:\n", datap); 283*a60fc142Srf157361 if (mdformat(datap, mh.data_blk_sz, 2) != DCMD_OK) 284*a60fc142Srf157361 return (DCMD_ERR); 285*a60fc142Srf157361 286*a60fc142Srf157361 return (DCMD_OK); 287*a60fc142Srf157361 } 288*a60fc142Srf157361 289*a60fc142Srf157361 /* 290*a60fc142Srf157361 * MDB module linkage information: 291*a60fc142Srf157361 * 292*a60fc142Srf157361 * Declare a list of structures describing dcmds, and a function 293*a60fc142Srf157361 * named _mdb_init to return a pointer to module information. 294*a60fc142Srf157361 */ 295*a60fc142Srf157361 296*a60fc142Srf157361 static const mdb_dcmd_t dcmds[] = { 297*a60fc142Srf157361 { "mdeschdr", "[-v]", "addr of current sun4v MD header", mdhdr }, 298*a60fc142Srf157361 { "mdescinfo", "?", "print md_elements with names from sun4v MD", 299*a60fc142Srf157361 mdinfo }, 300*a60fc142Srf157361 { "mdescdump", "?", "dump node, name, data sections of sun4v MD", 301*a60fc142Srf157361 mddump }, 302*a60fc142Srf157361 { NULL } 303*a60fc142Srf157361 }; 304*a60fc142Srf157361 305*a60fc142Srf157361 static const mdb_modinfo_t modinfo = { 306*a60fc142Srf157361 MDB_API_VERSION, dcmds, NULL 307*a60fc142Srf157361 }; 308*a60fc142Srf157361 309*a60fc142Srf157361 const mdb_modinfo_t * 310*a60fc142Srf157361 _mdb_init(void) 311*a60fc142Srf157361 { 312*a60fc142Srf157361 return (&modinfo); 313*a60fc142Srf157361 } 314