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