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