xref: /titanic_51/usr/src/cmd/mdb/sun4v/modules/ldc/ldc.c (revision 20ae46ebaff1237662e05edf9db61538aa85d448)
13895f3e6Snarayan /*
23895f3e6Snarayan  * CDDL HEADER START
33895f3e6Snarayan  *
43895f3e6Snarayan  * The contents of this file are subject to the terms of the
53895f3e6Snarayan  * Common Development and Distribution License (the "License").
63895f3e6Snarayan  * You may not use this file except in compliance with the License.
73895f3e6Snarayan  *
83895f3e6Snarayan  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93895f3e6Snarayan  * or http://www.opensolaris.org/os/licensing.
103895f3e6Snarayan  * See the License for the specific language governing permissions
113895f3e6Snarayan  * and limitations under the License.
123895f3e6Snarayan  *
133895f3e6Snarayan  * When distributing Covered Code, include this CDDL HEADER in each
143895f3e6Snarayan  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153895f3e6Snarayan  * If applicable, add the following below this CDDL HEADER, with the
163895f3e6Snarayan  * fields enclosed by brackets "[]" replaced with your own identifying
173895f3e6Snarayan  * information: Portions Copyright [yyyy] [name of copyright owner]
183895f3e6Snarayan  *
193895f3e6Snarayan  * CDDL HEADER END
203895f3e6Snarayan  */
213895f3e6Snarayan 
223895f3e6Snarayan /*
2358283286Sha137994  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
243895f3e6Snarayan  * Use is subject to license terms.
253895f3e6Snarayan  */
263895f3e6Snarayan 
273895f3e6Snarayan #pragma ident	"%Z%%M%	%I%	%E% SMI"
283895f3e6Snarayan 
293895f3e6Snarayan /*
303895f3e6Snarayan  * This module provides debugging tools for the LDoms channels (ldc)
313895f3e6Snarayan  */
323895f3e6Snarayan 
333895f3e6Snarayan #include <sys/mdb_modapi.h>
343895f3e6Snarayan #include <sys/ldc.h>
353895f3e6Snarayan #include <sys/ldc_impl.h>
363895f3e6Snarayan #include <sys/hypervisor_api.h>
373895f3e6Snarayan 
383895f3e6Snarayan #define	ALLBITS	(u_longlong_t)-1
393895f3e6Snarayan 
403895f3e6Snarayan const mdb_bitmask_t ldc_mode_bits[] = {
413895f3e6Snarayan 	{ "raw   ", ALLBITS, LDC_MODE_RAW },
423895f3e6Snarayan 	{ "unrel ", ALLBITS, LDC_MODE_UNRELIABLE },
43*20ae46ebSha137994 	{ "rel   ", ALLBITS, LDC_MODE_RELIABLE },
443895f3e6Snarayan 	{ NULL, 0, 0}
453895f3e6Snarayan };
463895f3e6Snarayan 
473895f3e6Snarayan const mdb_bitmask_t ldc_status_bits[] = {
483895f3e6Snarayan 	{ "init  ", ALLBITS, LDC_INIT },
493895f3e6Snarayan 	{ "open  ", ALLBITS, LDC_OPEN },
503895f3e6Snarayan 	{ "ready ", ALLBITS, LDC_READY },
513895f3e6Snarayan 	{ "up    ", ALLBITS, LDC_UP },
523895f3e6Snarayan 	{ NULL, 0, 0}
533895f3e6Snarayan };
543895f3e6Snarayan 
553895f3e6Snarayan const mdb_bitmask_t ldc_tstate_bits[] = {
563895f3e6Snarayan 	{ "txq", TS_TXQ_RDY, TS_TXQ_RDY },
573895f3e6Snarayan 	{ "rxq", TS_RXQ_RDY, TS_RXQ_RDY },
583895f3e6Snarayan 	{ "hv_qconf", TS_QCONF_RDY, TS_QCONF_RDY },
593895f3e6Snarayan 	{ "cnex_reg", TS_CNEX_RDY, TS_CNEX_RDY },
603895f3e6Snarayan 	{ "hv_link_rdy", TS_LINK_READY, TS_LINK_READY },
613895f3e6Snarayan 	{ "ver_done", TS_VER_DONE, TS_VER_DONE },
623895f3e6Snarayan 	{ "hs_done", TS_HSHAKE_DONE, TS_HSHAKE_DONE },
633895f3e6Snarayan 	{ NULL, 0, 0}
643895f3e6Snarayan };
653895f3e6Snarayan 
663895f3e6Snarayan const mdb_bitmask_t ldc_hstate_bits[] = {
673895f3e6Snarayan 	{ "snt_ver", TS_SENT_VER, TS_SENT_VER },
683895f3e6Snarayan 	{ "snt_rts", TS_SENT_RTS, TS_SENT_RTS },
693895f3e6Snarayan 	{ "rcv_rtr", TS_RCVD_RTR, TS_RCVD_RTR },
703895f3e6Snarayan 	{ "snt_rdx", TS_SENT_RDX, TS_SENT_RDX },
713895f3e6Snarayan 	{ "rcv_ver", TS_RCVD_VER, TS_RCVD_VER },
723895f3e6Snarayan 	{ "rcv_rts", TS_RCVD_RTS, TS_RCVD_RTS },
733895f3e6Snarayan 	{ "snt_rtr", TS_SENT_RTR, TS_SENT_RTR },
743895f3e6Snarayan 	{ "rcv_rdx", TS_RCVD_RDX, TS_RCVD_RDX },
753895f3e6Snarayan 	{ NULL, 0, 0}
763895f3e6Snarayan };
773895f3e6Snarayan 
783895f3e6Snarayan const mdb_bitmask_t ldc_class_bits[] = {
793895f3e6Snarayan 	{ "generic ", ALLBITS, LDC_DEV_GENERIC },
803895f3e6Snarayan 	{ "blk     ", ALLBITS, LDC_DEV_BLK },
813895f3e6Snarayan 	{ "blk_svc ", ALLBITS, LDC_DEV_BLK_SVC },
823895f3e6Snarayan 	{ "net     ", ALLBITS, LDC_DEV_NT },
833895f3e6Snarayan 	{ "net_svc ", ALLBITS, LDC_DEV_NT_SVC },
843895f3e6Snarayan 	{ "serial  ", ALLBITS, LDC_DEV_SERIAL },
853895f3e6Snarayan 	{ NULL, 0, 0}
863895f3e6Snarayan };
873895f3e6Snarayan 
883895f3e6Snarayan const mdb_bitmask_t ldc_intrstate_bits[] = {
893895f3e6Snarayan 	{ "none   ", ALLBITS, LDC_INTR_NONE },
903895f3e6Snarayan 	{ "active ", ALLBITS, LDC_INTR_ACTIVE },
913895f3e6Snarayan 	{ "pending", ALLBITS, LDC_INTR_PEND },
923895f3e6Snarayan 	{ NULL, 0, 0}
933895f3e6Snarayan };
943895f3e6Snarayan 
953895f3e6Snarayan const mdb_bitmask_t ldc_linkstate_bits[] = {
963895f3e6Snarayan 	{ "down ", ALLBITS, LDC_CHANNEL_DOWN },
973895f3e6Snarayan 	{ "reset", ALLBITS, LDC_CHANNEL_RESET },
983895f3e6Snarayan 	{ "up   ", ALLBITS, LDC_CHANNEL_UP },
993895f3e6Snarayan 	{ NULL, 0, 0}
1003895f3e6Snarayan };
1013895f3e6Snarayan 
1023895f3e6Snarayan const mdb_bitmask_t msg_type_bits[] = {
1033895f3e6Snarayan 	{ "ctrl", ALLBITS, LDC_CTRL },
1043895f3e6Snarayan 	{ "data", ALLBITS, LDC_DATA },
1053895f3e6Snarayan 	{ "err ", ALLBITS, LDC_ERR },
1063895f3e6Snarayan 	{ NULL, 0, 0}
1073895f3e6Snarayan };
1083895f3e6Snarayan 
1093895f3e6Snarayan const mdb_bitmask_t msg_stype_bits[] = {
1103895f3e6Snarayan 	{ "info ", ALLBITS, LDC_INFO },
1113895f3e6Snarayan 	{ "ack  ", ALLBITS, LDC_ACK },
1123895f3e6Snarayan 	{ "nack ", ALLBITS, LDC_NACK },
1133895f3e6Snarayan 	{ NULL, 0, 0}
1143895f3e6Snarayan };
1153895f3e6Snarayan 
1163895f3e6Snarayan const mdb_bitmask_t msg_ctrl_bits[] = {
1173895f3e6Snarayan 	{ "ver ", ALLBITS, LDC_VER },
1183895f3e6Snarayan 	{ "rts ", ALLBITS, LDC_RTS },
1193895f3e6Snarayan 	{ "rtr ", ALLBITS, LDC_RTR },
1203895f3e6Snarayan 	{ "rdx ", ALLBITS, LDC_RDX },
1213895f3e6Snarayan 	{ NULL, 0, 0}
1223895f3e6Snarayan };
1233895f3e6Snarayan 
1243895f3e6Snarayan const mdb_bitmask_t mhdl_status_bits[] = {
1253895f3e6Snarayan 	{ "unbound", ALLBITS, LDC_UNBOUND },
1263895f3e6Snarayan 	{ "bound  ", LDC_BOUND, LDC_BOUND },
1273895f3e6Snarayan 	{ "mapped ", LDC_MAPPED, LDC_MAPPED },
1283895f3e6Snarayan 	{ NULL, 0, 0}
1293895f3e6Snarayan };
1303895f3e6Snarayan 
1313895f3e6Snarayan const mdb_bitmask_t mhdl_type_bits[] = {
1323895f3e6Snarayan 	{ "shadow ", ALLBITS, LDC_SHADOW_MAP },
1333895f3e6Snarayan 	{ "direct ", ALLBITS, LDC_DIRECT_MAP },
1343895f3e6Snarayan 	{ "io     ", ALLBITS, LDC_IO_MAP },
1353895f3e6Snarayan 	{ NULL, 0, 0}
1363895f3e6Snarayan };
1373895f3e6Snarayan 
1383895f3e6Snarayan const mdb_bitmask_t mhdl_perm_bits[] = {
1393895f3e6Snarayan 	{ "r-- ", ALLBITS, LDC_MEM_R },
1403895f3e6Snarayan 	{ "-w- ", ALLBITS, LDC_MEM_W },
1413895f3e6Snarayan 	{ "--x ", ALLBITS, LDC_MEM_X },
1423895f3e6Snarayan 	{ "rw- ", ALLBITS, LDC_MEM_RW },
1433895f3e6Snarayan 	{ "rwx ", ALLBITS, LDC_MEM_RWX },
1443895f3e6Snarayan 	{ NULL, 0, 0}
1453895f3e6Snarayan };
1463895f3e6Snarayan 
1473895f3e6Snarayan 
1483895f3e6Snarayan /*
1493895f3e6Snarayan  * Print LDC channel information
1503895f3e6Snarayan  */
1513895f3e6Snarayan int
1523895f3e6Snarayan ldcinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1533895f3e6Snarayan {
1543895f3e6Snarayan 	uint_t		verbose = FALSE;
1553895f3e6Snarayan 	ldc_chan_t	ldcp;
1563895f3e6Snarayan 
1573895f3e6Snarayan 	/*
1583895f3e6Snarayan 	 * If no ldc_chan_t address was specified on the command line,
1593895f3e6Snarayan 	 * we can print out all ldc channels by invoking the
1603895f3e6Snarayan 	 * walker, using this dcmd itself as the callback.
1613895f3e6Snarayan 	 */
1623895f3e6Snarayan 	if (!(flags & DCMD_ADDRSPEC)) {
1633895f3e6Snarayan 		if (mdb_walk_dcmd("ldcinfo", "ldcinfo", argc, argv) == -1) {
1643895f3e6Snarayan 			mdb_warn("failed to walk 'ldcinfo'");
1653895f3e6Snarayan 			return (DCMD_ERR);
1663895f3e6Snarayan 		}
1673895f3e6Snarayan 		return (DCMD_OK);
1683895f3e6Snarayan 	}
1693895f3e6Snarayan 
1703895f3e6Snarayan 
1713895f3e6Snarayan 	if (mdb_vread(&ldcp, sizeof (ldcp), addr) != sizeof (ldcp)) {
1723895f3e6Snarayan 		mdb_warn("failed to read ldc_chan_t at %p", addr);
1733895f3e6Snarayan 		return (DCMD_ERR);
1743895f3e6Snarayan 	}
1753895f3e6Snarayan 
1763895f3e6Snarayan 
1773895f3e6Snarayan 	if (mdb_getopts(argc, argv,
1783895f3e6Snarayan 	    'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) {
1793895f3e6Snarayan 		return (DCMD_USAGE);
1803895f3e6Snarayan 	}
1813895f3e6Snarayan 
1823895f3e6Snarayan 	if (DCMD_HDRSPEC(flags)) {
1833895f3e6Snarayan 		mdb_printf("%-5s %-13s  %-6s  %-8s  %-6s  %-6s  %-6s  %-8s\n",
1843895f3e6Snarayan 		    "ID", "ADDR", "MODE", "DEVCLASS", "STATUS", "TSTATE",
1853895f3e6Snarayan 		    "HSTATE", "HV_LINK");
1863895f3e6Snarayan 	}
1873895f3e6Snarayan 
1883895f3e6Snarayan 	mdb_printf("0x%-3x 0x%p  %b  %b  %b  0x%-4x  0x%-4x  %b\n",
1893895f3e6Snarayan 	    ldcp.id, addr, ldcp.mode, ldc_mode_bits,
1903895f3e6Snarayan 	    ldcp.devclass, ldc_class_bits,
1913895f3e6Snarayan 	    ldcp.status, ldc_status_bits, ldcp.tstate, ldcp.hstate,
1923895f3e6Snarayan 	    ldcp.link_state, ldc_linkstate_bits);
1933895f3e6Snarayan 
1943895f3e6Snarayan 	if (verbose) {
1953895f3e6Snarayan 		mdb_printf("Link State: %b\n", ldcp.tstate, ldc_tstate_bits);
1963895f3e6Snarayan 		mdb_printf("Hshake State: %b\n", ldcp.hstate, ldc_hstate_bits);
1973895f3e6Snarayan 		mdb_printf("Callback: %a(0x%p) - %s\n",
1983895f3e6Snarayan 		    ldcp.cb, ldcp.cb_arg,
1993895f3e6Snarayan 		    (ldcp.cb_enabled == 1) ? "enabled" : "disabled");
2003895f3e6Snarayan 		mdb_printf("Tx Info: 0x%p len=0x%lx hd=0x%lx tl=0x%lx "
2013895f3e6Snarayan 		    "intr=%b\n", ldcp.tx_q_va, ldcp.tx_q_entries, ldcp.tx_head,
2023895f3e6Snarayan 		    ldcp.tx_tail, ldcp.tx_intr_state, ldc_intrstate_bits);
2033895f3e6Snarayan 		mdb_printf("Rx Info: 0x%p len=0x%lx intr=%b\n",
2043895f3e6Snarayan 		    ldcp.rx_q_va, ldcp.rx_q_entries,
2053895f3e6Snarayan 		    ldcp.rx_intr_state, ldc_intrstate_bits);
206*20ae46ebSha137994 		if (ldcp.mode == LDC_MODE_RELIABLE) {
20758283286Sha137994 			mdb_printf("Rx Dq Info: 0x%p len=0x%lx hd=0x%lx "
20858283286Sha137994 			    "tl=0x%lx ackhd=0x%lx", ldcp.rx_dq_va,
20958283286Sha137994 			    ldcp.rx_dq_entries, ldcp.rx_dq_head,
21058283286Sha137994 			    ldcp.rx_dq_tail, ldcp.rx_ack_head);
2113895f3e6Snarayan 			mdb_printf("Stream: buf=0x%p off=0x%lx remains=0x%lx\n",
2123895f3e6Snarayan 			    ldcp.stream_bufferp, ldcp.stream_offset,
2133895f3e6Snarayan 			    ldcp.stream_remains);
2143895f3e6Snarayan 		}
2153895f3e6Snarayan 		if (ldcp.mtbl != NULL || ldcp.mhdl_list != NULL)
2163895f3e6Snarayan 			mdb_printf("Memory: mtbl=0x%p mhdl_list=0x%p\n",
2173895f3e6Snarayan 			    ldcp.mtbl, ldcp.mhdl_list);
2183895f3e6Snarayan 		if (ldcp.exp_dring_list != NULL || ldcp.imp_dring_list != NULL)
2193895f3e6Snarayan 			mdb_printf("Desc Ring: exported=0x%p imported=0x%p\n",
2203895f3e6Snarayan 			    ldcp.exp_dring_list, ldcp.imp_dring_list);
2213895f3e6Snarayan 		mdb_printf("\n");
2223895f3e6Snarayan 	}
2233895f3e6Snarayan 	return (DCMD_OK);
2243895f3e6Snarayan }
2253895f3e6Snarayan 
2263895f3e6Snarayan 
2273895f3e6Snarayan /*
2283895f3e6Snarayan  * ldcinfo walker initialization
2293895f3e6Snarayan  */
2303895f3e6Snarayan int
2313895f3e6Snarayan ldc_walk_init(mdb_walk_state_t *wsp)
2323895f3e6Snarayan {
2333895f3e6Snarayan 	ldc_soft_state_t	softstate;
2343895f3e6Snarayan 
2353895f3e6Snarayan 	/* Must have a start addr.  */
2363895f3e6Snarayan 	if (wsp->walk_addr == NULL) {
2373895f3e6Snarayan 		if (mdb_readvar(&wsp->walk_addr, "ldcssp") == -1) {
2383895f3e6Snarayan 			mdb_warn("failed to read 'ldcssp'");
2393895f3e6Snarayan 			return (WALK_ERR);
2403895f3e6Snarayan 		}
2413895f3e6Snarayan 
2423895f3e6Snarayan 		if (wsp->walk_addr == NULL)
2433895f3e6Snarayan 			return (WALK_DONE);
2443895f3e6Snarayan 
2453895f3e6Snarayan 		if (mdb_vread(&softstate, sizeof (softstate), wsp->walk_addr)
2463895f3e6Snarayan 		    != sizeof (softstate)) {
2473895f3e6Snarayan 			mdb_warn("failed to read softstate %p", wsp->walk_addr);
2483895f3e6Snarayan 			return (WALK_ERR);
2493895f3e6Snarayan 		}
2503895f3e6Snarayan 
2513895f3e6Snarayan 		wsp->walk_addr = (uintptr_t)softstate.chan_list;
2523895f3e6Snarayan 	}
2533895f3e6Snarayan 
2543895f3e6Snarayan 	return (WALK_NEXT);
2553895f3e6Snarayan }
2563895f3e6Snarayan 
2573895f3e6Snarayan /*
2583895f3e6Snarayan  * ldcinfo walker step routine.
2593895f3e6Snarayan  */
2603895f3e6Snarayan int
2613895f3e6Snarayan ldc_walk_step(mdb_walk_state_t *wsp)
2623895f3e6Snarayan {
2633895f3e6Snarayan 	int			status;
2643895f3e6Snarayan 	ldc_chan_t		ldcp;
2653895f3e6Snarayan 
2663895f3e6Snarayan 	if (wsp->walk_addr == NULL)
2673895f3e6Snarayan 		return (WALK_DONE);
2683895f3e6Snarayan 
2693895f3e6Snarayan 	if (mdb_vread(&ldcp, sizeof (ldc_chan_t), wsp->walk_addr) == -1) {
2703895f3e6Snarayan 		mdb_warn("failed to read at %p", wsp->walk_addr);
2713895f3e6Snarayan 
2723895f3e6Snarayan 		return (WALK_ERR);
2733895f3e6Snarayan 	}
2743895f3e6Snarayan 
2753895f3e6Snarayan 	status = wsp->walk_callback(wsp->walk_addr, &ldcp,
2763895f3e6Snarayan 	    wsp->walk_cbdata);
2773895f3e6Snarayan 	wsp->walk_addr = (uintptr_t)ldcp.next;
2783895f3e6Snarayan 
2793895f3e6Snarayan 	return (status);
2803895f3e6Snarayan }
2813895f3e6Snarayan 
2823895f3e6Snarayan 
2833895f3e6Snarayan /*
2843895f3e6Snarayan  * dcmd to print ldc packet information
2853895f3e6Snarayan  *
2863895f3e6Snarayan  * arg0 - count (number of pkts to print)
2873895f3e6Snarayan  */
2883895f3e6Snarayan int
2893895f3e6Snarayan ldcmsg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2903895f3e6Snarayan {
2913895f3e6Snarayan 	ldc_msg_t	msg;
2923895f3e6Snarayan 	uint64_t 	count = 1;
2933895f3e6Snarayan 	int		i;
2943895f3e6Snarayan 
2953895f3e6Snarayan 	/*
2963895f3e6Snarayan 	 * If no ldc_msg_t address was specified on the command line,
2973895f3e6Snarayan 	 * print usage.
2983895f3e6Snarayan 	 */
2993895f3e6Snarayan 	if (!(flags & DCMD_ADDRSPEC)) {
3003895f3e6Snarayan 		return (DCMD_USAGE);
3013895f3e6Snarayan 	}
3023895f3e6Snarayan 
3033895f3e6Snarayan 	/* chk if we need to print more that one pkt */
3043895f3e6Snarayan 	if (argc != 0) {
3053895f3e6Snarayan 		const mdb_arg_t *arg = &argv[0];
3063895f3e6Snarayan 
3073895f3e6Snarayan 		if (arg->a_type == MDB_TYPE_IMMEDIATE)
3083895f3e6Snarayan 			count = arg->a_un.a_val;
3093895f3e6Snarayan 		else
3103895f3e6Snarayan 			count = (uint64_t)mdb_strtoull(arg->a_un.a_str);
3113895f3e6Snarayan 	}
3123895f3e6Snarayan 
3133895f3e6Snarayan 	/* print header */
3143895f3e6Snarayan 	mdb_printf("%-13s %-10s %-4s %-5s %-4s %-11s %-4s %-10s\n",
3153895f3e6Snarayan 	    "ADDR", "SEQID", "TYPE", "STYPE", "CTRL", "ENVELOPE",
3163895f3e6Snarayan 	    "SIZE", "ACKID");
3173895f3e6Snarayan 
3183895f3e6Snarayan 	/* print pkt */
3193895f3e6Snarayan 	for (i = 0; i < count; i++) {
3203895f3e6Snarayan 
3213895f3e6Snarayan 		if (mdb_vread(&msg, sizeof (msg), addr) != sizeof (msg)) {
3223895f3e6Snarayan 			mdb_warn("failed to read ldc_msg_t at %p", addr);
3233895f3e6Snarayan 			return (DCMD_ERR);
3243895f3e6Snarayan 		}
3253895f3e6Snarayan 
3263895f3e6Snarayan 		mdb_printf("0x%p 0x%-8x %b %b", addr, msg.seqid,
3273895f3e6Snarayan 		    msg.type, msg_type_bits, msg.stype, msg_stype_bits);
3283895f3e6Snarayan 
3293895f3e6Snarayan 		if (msg.type == LDC_CTRL)
3303895f3e6Snarayan 			mdb_printf(" %b ", msg.ctrl, msg_ctrl_bits);
3313895f3e6Snarayan 		else
3323895f3e6Snarayan 			mdb_printf(" %-4s ", "--");
3333895f3e6Snarayan 
3343895f3e6Snarayan 		mdb_printf("%-5s %-5s",
3353895f3e6Snarayan 		    ((msg.env & LDC_FRAG_START) != 0) ? "start" : "--",
3363895f3e6Snarayan 		    ((msg.env & LDC_FRAG_STOP) != 0) ? "stop" : "--");
3373895f3e6Snarayan 
3383895f3e6Snarayan 		/* print size */
3393895f3e6Snarayan 		if (msg.type == LDC_DATA && msg.stype == LDC_INFO)
3403895f3e6Snarayan 			mdb_printf(" 0x%-2x ", (msg.env & LDC_LEN_MASK));
3413895f3e6Snarayan 		else
3423895f3e6Snarayan 			mdb_printf(" %-4s ", "--");
3433895f3e6Snarayan 
3443895f3e6Snarayan 		/* print ackid if data/ack */
3453895f3e6Snarayan 		if (msg.type == LDC_DATA && msg.stype == LDC_ACK)
3463895f3e6Snarayan 			mdb_printf("0x%-8x\n", msg.ackid);
3473895f3e6Snarayan 		else
3483895f3e6Snarayan 			mdb_printf("%-10s\n", "--");
3493895f3e6Snarayan 
3503895f3e6Snarayan 		/* next packet */
3513895f3e6Snarayan 		addr = addr + LDC_PACKET_SIZE;
3523895f3e6Snarayan 	}
3533895f3e6Snarayan 
3543895f3e6Snarayan 	return (DCMD_OK);
3553895f3e6Snarayan }
3563895f3e6Snarayan 
3573895f3e6Snarayan 
3583895f3e6Snarayan /*
3593895f3e6Snarayan  * Print LDC map table information
3603895f3e6Snarayan  */
3613895f3e6Snarayan int
3623895f3e6Snarayan ldcmtbl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3633895f3e6Snarayan {
3643895f3e6Snarayan 	uint_t		verbose = FALSE;
3653895f3e6Snarayan 	ldc_mtbl_t	mtbl;
3663895f3e6Snarayan 	ldc_mte_slot_t	mte;
3673895f3e6Snarayan 	uintptr_t	mteaddr;
3683895f3e6Snarayan 	int		i;
3693895f3e6Snarayan 
3703895f3e6Snarayan 	/*
3713895f3e6Snarayan 	 * If no ldc_mtbl_t address was specified on the command line,
3723895f3e6Snarayan 	 * print usage.
3733895f3e6Snarayan 	 */
3743895f3e6Snarayan 	if (!(flags & DCMD_ADDRSPEC)) {
3753895f3e6Snarayan 		return (DCMD_USAGE);
3763895f3e6Snarayan 	}
3773895f3e6Snarayan 
3783895f3e6Snarayan 	if (mdb_vread(&mtbl, sizeof (mtbl), addr) != sizeof (mtbl)) {
3793895f3e6Snarayan 		mdb_warn("failed to read ldc_mtbl_t at %p", addr);
3803895f3e6Snarayan 		return (DCMD_ERR);
3813895f3e6Snarayan 	}
3823895f3e6Snarayan 
3833895f3e6Snarayan 	mdb_printf("Map Table: addr=0x%p total=%ld free=%ld tbl_base=0x%p\n",
3843895f3e6Snarayan 	    addr, mtbl.num_entries, mtbl.num_avail, mtbl.table);
3853895f3e6Snarayan 
3863895f3e6Snarayan 	if (mdb_getopts(argc, argv,
3873895f3e6Snarayan 	    'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) {
3883895f3e6Snarayan 		return (DCMD_USAGE);
3893895f3e6Snarayan 	}
3903895f3e6Snarayan 	if (!verbose)
3913895f3e6Snarayan 		return (DCMD_OK);
3923895f3e6Snarayan 
3933895f3e6Snarayan 	/* print table header */
3943895f3e6Snarayan 	mdb_printf("\n%-4s  %-13s %-2s %-2s %-2s %-2s %-2s %-2s %-2s %-5s\n",
3953895f3e6Snarayan 	    "IDX", "RA_PFN", "CW", "CR", "IW", "IR", "X", "W", "R", "PGSZC");
3963895f3e6Snarayan 
3973895f3e6Snarayan 	/* print each table entry */
3983895f3e6Snarayan 	mteaddr = (uintptr_t)mtbl.table;
3993895f3e6Snarayan 	for (i = 0; i < mtbl.num_entries; i++) {
4003895f3e6Snarayan 		if (mdb_vread(&mte, sizeof (mte), mteaddr) != sizeof (mte)) {
4013895f3e6Snarayan 			return (DCMD_ABORT);
4023895f3e6Snarayan 		}
4033895f3e6Snarayan 
4043895f3e6Snarayan 		/* skip empty entries */
4053895f3e6Snarayan 		if (mte.entry.ll != 0) {
4063895f3e6Snarayan 			mdb_printf("%-4d  0x%-11x %-2d %-2d %-2d %-2d "
4073895f3e6Snarayan 			    "%-2d %-2d %-2d 0x%-2x\n",
4083895f3e6Snarayan 			    i, mte.entry.mte_bit.rpfn, mte.entry.mte_bit.cw,
4093895f3e6Snarayan 			    mte.entry.mte_bit.cr, mte.entry.mte_bit.iw,
4103895f3e6Snarayan 			    mte.entry.mte_bit.ir, mte.entry.mte_bit.x,
4113895f3e6Snarayan 			    mte.entry.mte_bit.w, mte.entry.mte_bit.r,
4123895f3e6Snarayan 			    mte.entry.mte_bit.pgszc);
4133895f3e6Snarayan 		}
4143895f3e6Snarayan 		mteaddr = mteaddr + sizeof (ldc_mte_slot_t);
4153895f3e6Snarayan 	}
4163895f3e6Snarayan 	return (DCMD_OK);
4173895f3e6Snarayan }
4183895f3e6Snarayan 
4193895f3e6Snarayan 
4203895f3e6Snarayan 
4213895f3e6Snarayan /*
4223895f3e6Snarayan  * Print LDC channel memory handle information
4233895f3e6Snarayan  */
4243895f3e6Snarayan int
4253895f3e6Snarayan ldcmhdl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4263895f3e6Snarayan {
4273895f3e6Snarayan 	ldc_mhdl_t	mhdl;
4283895f3e6Snarayan 	ldc_memseg_t	memseg;
4293895f3e6Snarayan 	uint64_t	count = 1;
4303895f3e6Snarayan 	int		i;
4313895f3e6Snarayan 
4323895f3e6Snarayan 	/*
4333895f3e6Snarayan 	 * If no ldc_msg_t address was specified on the command line,
4343895f3e6Snarayan 	 * print usage.
4353895f3e6Snarayan 	 */
4363895f3e6Snarayan 	if (!(flags & DCMD_ADDRSPEC)) {
4373895f3e6Snarayan 		return (DCMD_USAGE);
4383895f3e6Snarayan 	}
4393895f3e6Snarayan 
4403895f3e6Snarayan 	/* chk if we need to print more that one pkt */
4413895f3e6Snarayan 	if (argc != 0) {
4423895f3e6Snarayan 		const mdb_arg_t *arg = &argv[0];
4433895f3e6Snarayan 
4443895f3e6Snarayan 		if (arg->a_type == MDB_TYPE_IMMEDIATE)
4453895f3e6Snarayan 			count = arg->a_un.a_val;
4463895f3e6Snarayan 		else
4473895f3e6Snarayan 			count = (uint64_t)mdb_strtoull(arg->a_un.a_str);
4483895f3e6Snarayan 	}
4493895f3e6Snarayan 
4503895f3e6Snarayan 	mdb_printf("%-13s  %-7s %-7s %-4s %-13s %-13s %-10s\n",
4513895f3e6Snarayan 	    "ADDR", "STATUS", "MAPTYPE", "PERM", "MEMSEG", "VADDR", "SIZE");
4523895f3e6Snarayan 
4533895f3e6Snarayan 	/* print pkt */
4543895f3e6Snarayan 	for (i = 0; i < count; i++) {
4553895f3e6Snarayan 
4563895f3e6Snarayan 		if (mdb_vread(&mhdl, sizeof (mhdl), addr) != sizeof (mhdl)) {
4573895f3e6Snarayan 			mdb_warn("failed to read ldc_mhdl_t at %p", addr);
4583895f3e6Snarayan 			return (DCMD_ERR);
4593895f3e6Snarayan 		}
4603895f3e6Snarayan 
4613895f3e6Snarayan 		mdb_printf("0x%p  %b %b %b 0x%p ",
4623895f3e6Snarayan 		    addr, mhdl.status, mhdl_status_bits,
4633895f3e6Snarayan 		    mhdl.mtype, mhdl_type_bits, mhdl.perm, mhdl_perm_bits,
4643895f3e6Snarayan 		    mhdl.memseg);
4653895f3e6Snarayan 
4663895f3e6Snarayan 		if (mhdl.memseg != NULL) {
4673895f3e6Snarayan 			if (mdb_vread(&memseg, sizeof (memseg),
4683895f3e6Snarayan 			    (uintptr_t)mhdl.memseg) != sizeof (memseg)) {
4693895f3e6Snarayan 				mdb_warn("failed to read ldc_memseg_t at %p",
4703895f3e6Snarayan 				    mhdl.memseg);
4713895f3e6Snarayan 				return (DCMD_ERR);
4723895f3e6Snarayan 			}
4733895f3e6Snarayan 
4743895f3e6Snarayan 			mdb_printf("0x%p 0x%-8lx\n", memseg.vaddr, memseg.size);
4753895f3e6Snarayan 		} else {
4763895f3e6Snarayan 			mdb_printf("\n");
4773895f3e6Snarayan 		}
4783895f3e6Snarayan 
4793895f3e6Snarayan 		if ((addr = (uintptr_t)mhdl.next) == NULL)
4803895f3e6Snarayan 			break;
4813895f3e6Snarayan 	}
4823895f3e6Snarayan 
4833895f3e6Snarayan 	return (DCMD_OK);
4843895f3e6Snarayan }
4853895f3e6Snarayan 
4863895f3e6Snarayan 
4873895f3e6Snarayan /*
4883895f3e6Snarayan  * MDB module linkage information:
4893895f3e6Snarayan  */
4903895f3e6Snarayan static const mdb_dcmd_t dcmds[] = {
4913895f3e6Snarayan 	{ "ldcinfo", "?[-v]",  "LDom channel information", ldcinfo },
4923895f3e6Snarayan 	{ "ldcmsg",  ":[cnt]", "LDom channel message", ldcmsg },
4933895f3e6Snarayan 	{ "ldcmtbl", ":[-v]",  "LDom channel map table", ldcmtbl },
4943895f3e6Snarayan 	{ "ldcmhdl", ":[cnt]", "LDom channel memory handles", ldcmhdl },
4953895f3e6Snarayan 	{ NULL }
4963895f3e6Snarayan };
4973895f3e6Snarayan 
4983895f3e6Snarayan static const mdb_walker_t walkers[] = {
4993895f3e6Snarayan 	{ "ldcinfo", "List all LDom channels",
5003895f3e6Snarayan 	    ldc_walk_init, ldc_walk_step, NULL },
5013895f3e6Snarayan 	{ NULL }
5023895f3e6Snarayan };
5033895f3e6Snarayan 
5043895f3e6Snarayan static const mdb_modinfo_t modinfo = {
5053895f3e6Snarayan 	MDB_API_VERSION, dcmds, walkers
5063895f3e6Snarayan };
5073895f3e6Snarayan 
5083895f3e6Snarayan const mdb_modinfo_t *
5093895f3e6Snarayan _mdb_init(void)
5103895f3e6Snarayan {
5113895f3e6Snarayan 	return (&modinfo);
5123895f3e6Snarayan }
513