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