xref: /titanic_44/usr/src/cmd/mdb/common/kmdb/kmdb_dpi.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * The DPI, or debugger/PROM interface, is used to isolate the debugger from the
31*7c478bd9Sstevel@tonic-gate  * means by which we use the PROM to control the machine.
32*7c478bd9Sstevel@tonic-gate  */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
35*7c478bd9Sstevel@tonic-gate #include <setjmp.h>
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_dpi_impl.h>
38*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_kdi.h>
39*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_auxv.h>
40*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_wr_impl.h>
41*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_module.h>
42*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_start.h>
43*7c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_asmutil.h>
44*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h>
45*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_err.h>
46*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h>
47*7c478bd9Sstevel@tonic-gate #include <mdb/mdb.h>
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate jmp_buf *kmdb_dpi_fault_pcb;
50*7c478bd9Sstevel@tonic-gate jmp_buf kmdb_dpi_resume_pcb;
51*7c478bd9Sstevel@tonic-gate jmp_buf kmdb_dpi_entry_pcb;
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate static int kmdb_dpi_state;
54*7c478bd9Sstevel@tonic-gate static int kmdb_dpi_state_why;
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate uint_t kmdb_dpi_resume_requested;
57*7c478bd9Sstevel@tonic-gate uint_t kmdb_dpi_switch_target = (uint_t)-1;
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate /* Used by the style-specific resume interfaces to signal the driver */
60*7c478bd9Sstevel@tonic-gate void (*kmdb_dpi_wrintr_fire)(void);
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_init(kmdb_auxv_t * kav)63*7c478bd9Sstevel@tonic-gate kmdb_dpi_init(kmdb_auxv_t *kav)
64*7c478bd9Sstevel@tonic-gate {
65*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_state = DPI_STATE_INIT;
66*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_resume_requested = 0;
67*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_wrintr_fire = kav->kav_wrintr_fire;
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi = &kmdb_dpi_ops;
70*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_init(kav));
71*7c478bd9Sstevel@tonic-gate }
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate /*ARGSUSED1*/
74*7c478bd9Sstevel@tonic-gate void
kmdb_activate(kdi_debugvec_t ** dvecp,uint_t flags)75*7c478bd9Sstevel@tonic-gate kmdb_activate(kdi_debugvec_t **dvecp, uint_t flags)
76*7c478bd9Sstevel@tonic-gate {
77*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_debugger_activate(dvecp, flags);
78*7c478bd9Sstevel@tonic-gate }
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate void
kmdb_deactivate(void)81*7c478bd9Sstevel@tonic-gate kmdb_deactivate(void)
82*7c478bd9Sstevel@tonic-gate {
83*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_debugger_deactivate();
84*7c478bd9Sstevel@tonic-gate }
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_reenter(void)87*7c478bd9Sstevel@tonic-gate kmdb_dpi_reenter(void)
88*7c478bd9Sstevel@tonic-gate {
89*7c478bd9Sstevel@tonic-gate 	int cmd;
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 	kmdb_kdi_system_claim();
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate 	if ((cmd = setjmp(kmdb_dpi_entry_pcb)) == 0) {
94*7c478bd9Sstevel@tonic-gate 		/* Direct entry from the driver */
95*7c478bd9Sstevel@tonic-gate 		if (kmdb_dpi_resume_requested)
96*7c478bd9Sstevel@tonic-gate 			longjmp(kmdb_dpi_resume_pcb, 1);
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 		kmdb_first_start();
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate 		fail("kmdb_first_start returned");
101*7c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
102*7c478bd9Sstevel@tonic-gate 	}
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "returning to driver - cmd %d%s\n", cmd,
105*7c478bd9Sstevel@tonic-gate 	    (kmdb_dpi_work_required() ? " (work required)" : ""));
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 	kmdb_kdi_system_release();
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	membar_producer();
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate 	/*
112*7c478bd9Sstevel@tonic-gate 	 * The debugger wants us to do something - it returned a command
113*7c478bd9Sstevel@tonic-gate 	 * via the setjmp().  The driver will know what to do with the
114*7c478bd9Sstevel@tonic-gate 	 * command.
115*7c478bd9Sstevel@tonic-gate 	 */
116*7c478bd9Sstevel@tonic-gate 	return (cmd);
117*7c478bd9Sstevel@tonic-gate }
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_enter_mon(void)120*7c478bd9Sstevel@tonic-gate kmdb_dpi_enter_mon(void)
121*7c478bd9Sstevel@tonic-gate {
122*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_enter_mon();
123*7c478bd9Sstevel@tonic-gate }
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_modchg_register(void (* func)(struct modctl *,int))126*7c478bd9Sstevel@tonic-gate kmdb_dpi_modchg_register(void (*func)(struct modctl *, int))
127*7c478bd9Sstevel@tonic-gate {
128*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_modchg_register(func);
129*7c478bd9Sstevel@tonic-gate }
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_modchg_cancel(void)132*7c478bd9Sstevel@tonic-gate kmdb_dpi_modchg_cancel(void)
133*7c478bd9Sstevel@tonic-gate {
134*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_modchg_cancel();
135*7c478bd9Sstevel@tonic-gate }
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_get_cpu_state(int cpuid)138*7c478bd9Sstevel@tonic-gate kmdb_dpi_get_cpu_state(int cpuid)
139*7c478bd9Sstevel@tonic-gate {
140*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_get_cpu_state(cpuid));
141*7c478bd9Sstevel@tonic-gate }
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_get_master_cpuid(void)144*7c478bd9Sstevel@tonic-gate kmdb_dpi_get_master_cpuid(void)
145*7c478bd9Sstevel@tonic-gate {
146*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_get_master_cpuid());
147*7c478bd9Sstevel@tonic-gate }
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate const mdb_tgt_gregset_t *
kmdb_dpi_get_gregs(int cpuid)150*7c478bd9Sstevel@tonic-gate kmdb_dpi_get_gregs(int cpuid)
151*7c478bd9Sstevel@tonic-gate {
152*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_get_gregs(cpuid));
153*7c478bd9Sstevel@tonic-gate }
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate jmp_buf *
kmdb_dpi_set_fault_hdlr(jmp_buf * jb)156*7c478bd9Sstevel@tonic-gate kmdb_dpi_set_fault_hdlr(jmp_buf *jb)
157*7c478bd9Sstevel@tonic-gate {
158*7c478bd9Sstevel@tonic-gate 	jmp_buf *oldpcb = kmdb_dpi_fault_pcb;
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_fault_pcb = jb;
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	return (oldpcb);
163*7c478bd9Sstevel@tonic-gate }
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_restore_fault_hdlr(jmp_buf * jb)166*7c478bd9Sstevel@tonic-gate kmdb_dpi_restore_fault_hdlr(jmp_buf *jb)
167*7c478bd9Sstevel@tonic-gate {
168*7c478bd9Sstevel@tonic-gate 	(void) kmdb_dpi_set_fault_hdlr(jb);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate /*
172*7c478bd9Sstevel@tonic-gate  * Used to tell the driver that it needs to do work after the resume.
173*7c478bd9Sstevel@tonic-gate  *
174*7c478bd9Sstevel@tonic-gate  * CAUTION: This routine may be called *after* mdb_destroy
175*7c478bd9Sstevel@tonic-gate  */
176*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_work_required(void)177*7c478bd9Sstevel@tonic-gate kmdb_dpi_work_required(void)
178*7c478bd9Sstevel@tonic-gate {
179*7c478bd9Sstevel@tonic-gate 	return (kmdb_kdi_get_unload_request() ||
180*7c478bd9Sstevel@tonic-gate 	    !kmdb_wr_driver_notify_isempty());
181*7c478bd9Sstevel@tonic-gate }
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_resume_master(void)184*7c478bd9Sstevel@tonic-gate kmdb_dpi_resume_master(void)
185*7c478bd9Sstevel@tonic-gate {
186*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_resume_common(KMDB_DPI_CMD_RESUME_MASTER);
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_resume(void)190*7c478bd9Sstevel@tonic-gate kmdb_dpi_resume(void)
191*7c478bd9Sstevel@tonic-gate {
192*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_resume_common(KMDB_DPI_CMD_RESUME_ALL);
193*7c478bd9Sstevel@tonic-gate }
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_resume_unload(void)196*7c478bd9Sstevel@tonic-gate kmdb_dpi_resume_unload(void)
197*7c478bd9Sstevel@tonic-gate {
198*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_resume_common(KMDB_DPI_CMD_RESUME_UNLOAD);
199*7c478bd9Sstevel@tonic-gate }
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_switch_master(int tgt_cpuid)202*7c478bd9Sstevel@tonic-gate kmdb_dpi_switch_master(int tgt_cpuid)
203*7c478bd9Sstevel@tonic-gate {
204*7c478bd9Sstevel@tonic-gate 	if (kmdb_dpi_get_cpu_state(tgt_cpuid) < 0)
205*7c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_switch_target = tgt_cpuid;
208*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_resume_common(KMDB_DPI_CMD_SWITCH_CPU);
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 	return (0);
211*7c478bd9Sstevel@tonic-gate }
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_flush_slave_caches(void)214*7c478bd9Sstevel@tonic-gate kmdb_dpi_flush_slave_caches(void)
215*7c478bd9Sstevel@tonic-gate {
216*7c478bd9Sstevel@tonic-gate 	kmdb_dpi_resume_common(KMDB_DPI_CMD_FLUSH_CACHES);
217*7c478bd9Sstevel@tonic-gate }
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate typedef struct work_results {
220*7c478bd9Sstevel@tonic-gate 	mdb_nv_t res_loads;
221*7c478bd9Sstevel@tonic-gate 	mdb_nv_t res_unloads;
222*7c478bd9Sstevel@tonic-gate } work_results_t;
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate static int
kmdb_dbgnotify_cb(kmdb_wr_t * wn,void * arg)225*7c478bd9Sstevel@tonic-gate kmdb_dbgnotify_cb(kmdb_wr_t *wn, void *arg)
226*7c478bd9Sstevel@tonic-gate {
227*7c478bd9Sstevel@tonic-gate 	work_results_t *res = arg;
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	switch (WR_TASK(wn)) {
230*7c478bd9Sstevel@tonic-gate 	case WNTASK_DMOD_LOAD: {
231*7c478bd9Sstevel@tonic-gate 		/*
232*7c478bd9Sstevel@tonic-gate 		 * If this is an ack, the driver finished processing a load we
233*7c478bd9Sstevel@tonic-gate 		 * requested.  We process it and free the message.  If this
234*7c478bd9Sstevel@tonic-gate 		 * isn't an ack, then it's a driver-initiated load.  We process
235*7c478bd9Sstevel@tonic-gate 		 * the message, and send it back as an ack so the driver can
236*7c478bd9Sstevel@tonic-gate 		 * free it.
237*7c478bd9Sstevel@tonic-gate 		 */
238*7c478bd9Sstevel@tonic-gate 		kmdb_wr_load_t *dlr = (kmdb_wr_load_t *)wn;
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 		mdb_dprintf(MDB_DBG_DPI, "received module load message\n");
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 		if (kmdb_module_loaded(dlr) && res != NULL) {
243*7c478bd9Sstevel@tonic-gate 			(void) mdb_nv_insert(&res->res_loads,
244*7c478bd9Sstevel@tonic-gate 			    strbasename(dlr->dlr_fname), NULL, 0, 0);
245*7c478bd9Sstevel@tonic-gate 		}
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate 		if (WR_ISACK(dlr)) {
248*7c478bd9Sstevel@tonic-gate 			kmdb_module_load_ack(dlr);
249*7c478bd9Sstevel@tonic-gate 			return (0);
250*7c478bd9Sstevel@tonic-gate 		}
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate 		/* Send it back as an ack */
253*7c478bd9Sstevel@tonic-gate 		mdb_dprintf(MDB_DBG_DPI, "Sending load request for %s back "
254*7c478bd9Sstevel@tonic-gate 		    "as an ack\n", dlr->dlr_fname);
255*7c478bd9Sstevel@tonic-gate 		WR_ACK(wn);
256*7c478bd9Sstevel@tonic-gate 		kmdb_wr_driver_notify(wn);
257*7c478bd9Sstevel@tonic-gate 		return (0);
258*7c478bd9Sstevel@tonic-gate 	}
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate 	case WNTASK_DMOD_LOAD_ALL:
261*7c478bd9Sstevel@tonic-gate 		/*
262*7c478bd9Sstevel@tonic-gate 		 * We initiated the load-all, so this must be an ack.  The
263*7c478bd9Sstevel@tonic-gate 		 * individual module load messages will arrive separately -
264*7c478bd9Sstevel@tonic-gate 		 * there's no need to do anything further with this message.
265*7c478bd9Sstevel@tonic-gate 		 */
266*7c478bd9Sstevel@tonic-gate 		ASSERT(WR_ISACK(wn));
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 		mdb_dprintf(MDB_DBG_DPI, "received module load all ack\n");
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 		kmdb_module_load_all_ack(wn);
271*7c478bd9Sstevel@tonic-gate 		return (0);
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 	case WNTASK_DMOD_UNLOAD: {
274*7c478bd9Sstevel@tonic-gate 		/*
275*7c478bd9Sstevel@tonic-gate 		 * The debugger received an unload message.  The driver isn't
276*7c478bd9Sstevel@tonic-gate 		 * supposed to initiate unloads, so we shouldn't see anything
277*7c478bd9Sstevel@tonic-gate 		 * but acks.  We tell the dmod subsystem that the module has
278*7c478bd9Sstevel@tonic-gate 		 * been unloaded, and we free the message.
279*7c478bd9Sstevel@tonic-gate 		 */
280*7c478bd9Sstevel@tonic-gate 		kmdb_wr_unload_t *dur = (kmdb_wr_unload_t *)wn;
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate 		ASSERT(WR_ISACK(dur));
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate 		mdb_dprintf(MDB_DBG_DPI, "received module unload ack\n");
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 		if (kmdb_module_unloaded(dur) && res != NULL) {
287*7c478bd9Sstevel@tonic-gate 			(void) mdb_nv_insert(&res->res_unloads,
288*7c478bd9Sstevel@tonic-gate 			    dur->dur_modname, NULL, 0, 0);
289*7c478bd9Sstevel@tonic-gate 		}
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate 		/* Done with message */
292*7c478bd9Sstevel@tonic-gate 		kmdb_module_unload_ack(dur);
293*7c478bd9Sstevel@tonic-gate 		return (0);
294*7c478bd9Sstevel@tonic-gate 	}
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	case WNTASK_DMOD_PATH_CHANGE: {
297*7c478bd9Sstevel@tonic-gate 		/*
298*7c478bd9Sstevel@tonic-gate 		 * The debugger received a path change message.  The driver
299*7c478bd9Sstevel@tonic-gate 		 * can't initiate these, so it must be an acknowledgement.
300*7c478bd9Sstevel@tonic-gate 		 * There's no processing to be done, so just free the message.
301*7c478bd9Sstevel@tonic-gate 		 */
302*7c478bd9Sstevel@tonic-gate 		kmdb_wr_path_t *dpth = (kmdb_wr_path_t *)wn;
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate 		ASSERT(WR_ISACK(dpth));
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 		mdb_dprintf(MDB_DBG_DPI, "received path change ack\n");
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate 		kmdb_module_path_ack(dpth);
309*7c478bd9Sstevel@tonic-gate 		return (0);
310*7c478bd9Sstevel@tonic-gate 	}
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate 	default:
313*7c478bd9Sstevel@tonic-gate 		mdb_warn("Received unknown message type %d from driver\n",
314*7c478bd9Sstevel@tonic-gate 		    wn->wn_task);
315*7c478bd9Sstevel@tonic-gate 		/* Ignore it */
316*7c478bd9Sstevel@tonic-gate 		return (0);
317*7c478bd9Sstevel@tonic-gate 	}
318*7c478bd9Sstevel@tonic-gate }
319*7c478bd9Sstevel@tonic-gate 
320*7c478bd9Sstevel@tonic-gate static void
print_modules(mdb_nv_t * mods)321*7c478bd9Sstevel@tonic-gate print_modules(mdb_nv_t *mods)
322*7c478bd9Sstevel@tonic-gate {
323*7c478bd9Sstevel@tonic-gate 	mdb_var_t *v;
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	mdb_nv_rewind(mods);
326*7c478bd9Sstevel@tonic-gate 	while ((v = mdb_nv_advance(mods)) != NULL)
327*7c478bd9Sstevel@tonic-gate 		mdb_printf(" %s", mdb_nv_get_name(v));
328*7c478bd9Sstevel@tonic-gate }
329*7c478bd9Sstevel@tonic-gate 
330*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_process_work_queue(void)331*7c478bd9Sstevel@tonic-gate kmdb_dpi_process_work_queue(void)
332*7c478bd9Sstevel@tonic-gate {
333*7c478bd9Sstevel@tonic-gate 	work_results_t res;
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	(void) mdb_nv_create(&res.res_loads, UM_SLEEP);
336*7c478bd9Sstevel@tonic-gate 	(void) mdb_nv_create(&res.res_unloads, UM_SLEEP);
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "processing work queue\n");
339*7c478bd9Sstevel@tonic-gate 	(void) kmdb_wr_debugger_process(kmdb_dbgnotify_cb, &res);
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate 	if (mdb_nv_size(&res.res_loads)) {
342*7c478bd9Sstevel@tonic-gate 		mdb_printf("Loaded modules: [");
343*7c478bd9Sstevel@tonic-gate 		print_modules(&res.res_loads);
344*7c478bd9Sstevel@tonic-gate 		mdb_printf(" ]\n");
345*7c478bd9Sstevel@tonic-gate 	}
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate 	if (mdb_nv_size(&res.res_unloads)) {
348*7c478bd9Sstevel@tonic-gate 		mdb_printf("Unloaded modules: [");
349*7c478bd9Sstevel@tonic-gate 		print_modules(&res.res_unloads);
350*7c478bd9Sstevel@tonic-gate 		mdb_printf(" ]\n");
351*7c478bd9Sstevel@tonic-gate 	}
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	mdb_nv_destroy(&res.res_loads);
354*7c478bd9Sstevel@tonic-gate 	mdb_nv_destroy(&res.res_unloads);
355*7c478bd9Sstevel@tonic-gate }
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_step(void)358*7c478bd9Sstevel@tonic-gate kmdb_dpi_step(void)
359*7c478bd9Sstevel@tonic-gate {
360*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_step());
361*7c478bd9Sstevel@tonic-gate }
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate uintptr_t
kmdb_dpi_call(uintptr_t func,uint_t argc,const uintptr_t * argv)364*7c478bd9Sstevel@tonic-gate kmdb_dpi_call(uintptr_t func, uint_t argc, const uintptr_t *argv)
365*7c478bd9Sstevel@tonic-gate {
366*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_call(func, argc, argv));
367*7c478bd9Sstevel@tonic-gate }
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_brkpt_arm(uintptr_t addr,mdb_instr_t * instrp)370*7c478bd9Sstevel@tonic-gate kmdb_dpi_brkpt_arm(uintptr_t addr, mdb_instr_t *instrp)
371*7c478bd9Sstevel@tonic-gate {
372*7c478bd9Sstevel@tonic-gate 	int rc;
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 	if ((rc = mdb.m_dpi->dpo_brkpt_arm(addr, instrp)) < 0)
375*7c478bd9Sstevel@tonic-gate 		mdb_warn("failed to arm breakpoint at %a", addr);
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "brkpt armed at %p %A\n", (void *)addr, addr);
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 	return (rc);
380*7c478bd9Sstevel@tonic-gate }
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_brkpt_disarm(uintptr_t addr,mdb_instr_t instrp)383*7c478bd9Sstevel@tonic-gate kmdb_dpi_brkpt_disarm(uintptr_t addr, mdb_instr_t instrp)
384*7c478bd9Sstevel@tonic-gate {
385*7c478bd9Sstevel@tonic-gate 	int rc;
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 	if ((rc = mdb.m_dpi->dpo_brkpt_disarm(addr, instrp)) < 0)
388*7c478bd9Sstevel@tonic-gate 		mdb_warn("failed to disarm breakpoint at %a", addr);
389*7c478bd9Sstevel@tonic-gate 
390*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "brkpt disarmed at %p %A\n", (void *)addr,
391*7c478bd9Sstevel@tonic-gate 	    addr);
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate 	return (rc);
394*7c478bd9Sstevel@tonic-gate }
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_wapt_validate(kmdb_wapt_t * wp)397*7c478bd9Sstevel@tonic-gate kmdb_dpi_wapt_validate(kmdb_wapt_t *wp)
398*7c478bd9Sstevel@tonic-gate {
399*7c478bd9Sstevel@tonic-gate 	if (mdb.m_dpi->dpo_wapt_validate(wp) < 0)
400*7c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 	return (0);
403*7c478bd9Sstevel@tonic-gate }
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_wapt_reserve(kmdb_wapt_t * wp)406*7c478bd9Sstevel@tonic-gate kmdb_dpi_wapt_reserve(kmdb_wapt_t *wp)
407*7c478bd9Sstevel@tonic-gate {
408*7c478bd9Sstevel@tonic-gate 	if (mdb.m_dpi->dpo_wapt_reserve(wp) < 0)
409*7c478bd9Sstevel@tonic-gate 		return (-1); /* errno is set for us */
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "wapt reserve type %d at %p, priv %p\n",
412*7c478bd9Sstevel@tonic-gate 	    wp->wp_type, (void *)wp->wp_addr, wp->wp_priv);
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate 	return (0);
415*7c478bd9Sstevel@tonic-gate }
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_wapt_release(kmdb_wapt_t * wp)418*7c478bd9Sstevel@tonic-gate kmdb_dpi_wapt_release(kmdb_wapt_t *wp)
419*7c478bd9Sstevel@tonic-gate {
420*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_wapt_release(wp);
421*7c478bd9Sstevel@tonic-gate }
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_wapt_arm(kmdb_wapt_t * wp)424*7c478bd9Sstevel@tonic-gate kmdb_dpi_wapt_arm(kmdb_wapt_t *wp)
425*7c478bd9Sstevel@tonic-gate {
426*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_wapt_arm(wp);
427*7c478bd9Sstevel@tonic-gate 
428*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "wapt armed at %p (type %d, priv %p)\n",
429*7c478bd9Sstevel@tonic-gate 	    (void *)wp->wp_addr, wp->wp_type, wp->wp_priv);
430*7c478bd9Sstevel@tonic-gate }
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_wapt_disarm(kmdb_wapt_t * wp)433*7c478bd9Sstevel@tonic-gate kmdb_dpi_wapt_disarm(kmdb_wapt_t *wp)
434*7c478bd9Sstevel@tonic-gate {
435*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_wapt_disarm(wp);
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 	mdb_dprintf(MDB_DBG_DPI, "wapt disarmed at %p (type %d, priv %p)\n",
438*7c478bd9Sstevel@tonic-gate 	    (void *)wp->wp_addr, wp->wp_type, wp->wp_priv);
439*7c478bd9Sstevel@tonic-gate }
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_wapt_match(kmdb_wapt_t * wp)442*7c478bd9Sstevel@tonic-gate kmdb_dpi_wapt_match(kmdb_wapt_t *wp)
443*7c478bd9Sstevel@tonic-gate {
444*7c478bd9Sstevel@tonic-gate 	return (mdb.m_dpi->dpo_wapt_match(wp));
445*7c478bd9Sstevel@tonic-gate }
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_set_state(int state,int why)448*7c478bd9Sstevel@tonic-gate kmdb_dpi_set_state(int state, int why)
449*7c478bd9Sstevel@tonic-gate {
450*7c478bd9Sstevel@tonic-gate 	if (kmdb_dpi_state != DPI_STATE_LOST) {
451*7c478bd9Sstevel@tonic-gate 		mdb_dprintf(MDB_DBG_DPI, "dpi_set_state %d why %d\n",
452*7c478bd9Sstevel@tonic-gate 		    state, why);
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate 		kmdb_dpi_state = state;
455*7c478bd9Sstevel@tonic-gate 		kmdb_dpi_state_why = why;
456*7c478bd9Sstevel@tonic-gate 	}
457*7c478bd9Sstevel@tonic-gate }
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate int
kmdb_dpi_get_state(int * whyp)460*7c478bd9Sstevel@tonic-gate kmdb_dpi_get_state(int *whyp)
461*7c478bd9Sstevel@tonic-gate {
462*7c478bd9Sstevel@tonic-gate 	if (whyp != NULL)
463*7c478bd9Sstevel@tonic-gate 		*whyp = kmdb_dpi_state_why;
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 	return (kmdb_dpi_state);
466*7c478bd9Sstevel@tonic-gate }
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate void
kmdb_dpi_dump_crumbs(uintptr_t addr,int cpuid)469*7c478bd9Sstevel@tonic-gate kmdb_dpi_dump_crumbs(uintptr_t addr, int cpuid)
470*7c478bd9Sstevel@tonic-gate {
471*7c478bd9Sstevel@tonic-gate 	mdb.m_dpi->dpo_dump_crumbs(addr, cpuid);
472*7c478bd9Sstevel@tonic-gate }
473