xref: /titanic_51/usr/src/cmd/mdb/sun4v/modules/mdesc/mdesc.c (revision a60fc142342386d0b786e65fba901234400d7020)
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