xref: /titanic_51/usr/src/cmd/mdb/sparc/kmdb/kaif.c (revision 8a8d276f8934b606981d1c46b57c2eda30c67610)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * The debugger/PROM interface
30  */
31 
32 #include <sys/types.h>
33 #include <sys/mmu.h>
34 
35 #ifndef	sun4v
36 #include <sys/spitregs.h>
37 #endif	/* sun4v */
38 
39 #include <sys/machasi.h>
40 #include <sys/machtrap.h>
41 #include <sys/trap.h>
42 #include <sys/privregs.h>
43 
44 #include <kmdb/kaif.h>
45 #include <kmdb/kaif_regs.h>
46 #include <kmdb/kmdb_asmutil.h>
47 #include <kmdb/kmdb_kdi.h>
48 #include <kmdb/kmdb_promif_isadep.h>
49 #include <kmdb/kmdb_dpi_impl.h>
50 #include <mdb/mdb_debug.h>
51 #include <mdb/mdb_err.h>
52 #include <mdb/mdb_modapi.h>
53 #include <mdb/mdb_nv.h>
54 #include <mdb/mdb_kreg_impl.h>
55 #include <mdb/mdb_v9util.h>
56 #include <mdb/mdb.h>
57 
58 #define	KAIF_PREGNO_PSTATE	0x6		/* %pstate is priv reg 6 */
59 #define	KAIF_BRKPT_INSTR	0x91d0207e	/* ta 0x7e */
60 
61 
62 #define	OP(x)		((x) >> 30)
63 #define	OP2(x)		(((x) >> 22) & 0x07)
64 #define	OP3(x)		(((x) >> 19) & 0x3f)
65 #define	COND(x)		(((x) >> 25) & 0x0f)
66 #define	RD(x)		(((x) >> 25) & 0x1f)
67 #define	RS1(x)		(((x) >> 14) & 0x1f)
68 #define	RS2(x)		((x) & 0x1f)
69 
70 #define	OP_BRANCH	0x0
71 #define	OP_ARITH	0x2
72 
73 #define	OP2_BPcc	0x1
74 #define	OP2_Bicc	0x2
75 #define	OP2_BPr		0x3
76 #define	OP2_FBPfcc	0x5
77 #define	OP2_FBfcc	0x6
78 
79 #define	OP3_RDPR	0x2a
80 #define	OP3_WRPR	0x32
81 
82 #define	A(x)		(((x) >> 29) & 0x01)
83 #define	I(x)		(((x) >> 13) & 0x01)
84 #define	DISP16(x)	((((x) >> 6) & 0xc000) | ((x) & 0x3fff))
85 #define	DISP22(x)	((x) & 0x3fffff)
86 #define	DISP19(x)	((x) & 0x7ffff)
87 #define	SIMM13(x)	((x) & 0x1fff)
88 
89 static uint64_t		kaif_vwapt_addr;
90 static uint64_t		kaif_pwapt_addr;
91 
92 #ifndef	sun4v
93 static uint64_t		kaif_lsuctl;
94 #endif	/* sun4v */
95 
96 kaif_cpusave_t		*kaif_cpusave;
97 int			kaif_ncpusave;
98 caddr_t			kaif_dseg;
99 caddr_t			kaif_dseg_lim;
100 caddr_t			kaif_tba;		/* table currently in use */
101 caddr_t			kaif_tba_obp;		/* obp's trap table */
102 caddr_t			kaif_tba_native;	/* our table; needs khat */
103 #ifdef	sun4v
104 caddr_t			kaif_tba_kernel;	/* kernel's trap table */
105 #endif	/* sun4v */
106 size_t			kaif_tba_native_sz;
107 int			*kaif_promexitarmp;
108 int			kaif_trap_switch;
109 
110 void (*kaif_modchg_cb)(struct modctl *, int);
111 void (*kaif_ktrap_install)(int, void (*)(void));
112 void (*kaif_ktrap_restore)(void);
113 
114 static int
115 kaif_get_master_cpuid(void)
116 {
117 	return (kaif_master_cpuid);
118 }
119 
120 /*ARGSUSED*/
121 static int
122 kaif_get_nwin(int cpuid)
123 {
124 	return (get_nwin());
125 }
126 
127 static kaif_cpusave_t *
128 kaif_cpuid2save(int cpuid)
129 {
130 	kaif_cpusave_t *save;
131 
132 	if (cpuid == DPI_MASTER_CPUID)
133 		return (&kaif_cpusave[kaif_master_cpuid]);
134 
135 	if (cpuid < 0 || cpuid >= kaif_ncpusave) {
136 		(void) set_errno(EINVAL);
137 		return (NULL);
138 	}
139 
140 	save = &kaif_cpusave[cpuid];
141 
142 	if (save->krs_cpu_state != KAIF_CPU_STATE_MASTER &&
143 	    save->krs_cpu_state != KAIF_CPU_STATE_SLAVE) {
144 		(void) set_errno(EINVAL);
145 		return (NULL);
146 	}
147 
148 	return (save);
149 }
150 
151 static int
152 kaif_get_cpu_state(int cpuid)
153 {
154 	kaif_cpusave_t *save;
155 
156 	if ((save = kaif_cpuid2save(cpuid)) == NULL)
157 		return (-1); /* errno is set for us */
158 
159 	switch (save->krs_cpu_state) {
160 	case KAIF_CPU_STATE_MASTER:
161 		return (DPI_CPU_STATE_MASTER);
162 	case KAIF_CPU_STATE_SLAVE:
163 		return (DPI_CPU_STATE_SLAVE);
164 	default:
165 		return (set_errno(EINVAL));
166 	}
167 }
168 
169 static const mdb_tgt_gregset_t *
170 kaif_get_gregs(int cpuid)
171 {
172 	kaif_cpusave_t *save;
173 	mdb_tgt_gregset_t *gregs;
174 	int wp, i;
175 
176 	if ((save = kaif_cpuid2save(cpuid)) == NULL)
177 		return (NULL); /* errno is set for us */
178 
179 	gregs = &save->krs_gregs;
180 
181 	/*
182 	 * The DPI startup routine populates the register window portions of
183 	 * the kaif_cpusave_t.  We copy the current set of ins, outs, and
184 	 * locals to the gregs.  We also extract %pstate from %tstate.
185 	 */
186 	wp = gregs->kregs[KREG_CWP];
187 	for (i = 0; i < 8; i++) {
188 		gregs->kregs[KREG_L0 + i] = save->krs_rwins[wp].rw_local[i];
189 		gregs->kregs[KREG_I0 + i] = save->krs_rwins[wp].rw_in[i];
190 	}
191 
192 	gregs->kregs[KREG_PSTATE] = KREG_TSTATE_PSTATE(save->krs_tstate);
193 
194 	if (++wp == kaif_get_nwin(cpuid))
195 		wp = 0;
196 
197 	for (i = 0; i < 8; i++)
198 		gregs->kregs[KREG_O0 + i] = save->krs_rwins[wp].rw_in[i];
199 
200 	return (gregs);
201 }
202 
203 static kreg_t *
204 kaif_find_regp(kaif_cpusave_t *save, const char *regname)
205 {
206 	mdb_tgt_gregset_t *gregs;
207 	int nwin, i;
208 	int win;
209 
210 	nwin = kaif_get_nwin(DPI_MASTER_CPUID);
211 
212 	gregs = &save->krs_gregs;
213 
214 	win = gregs->kregs[KREG_CWP];
215 
216 	if (strcmp(regname, "sp") == 0)
217 		regname = "o6";
218 	else if (strcmp(regname, "fp") == 0)
219 		regname = "i6";
220 
221 	if (strlen(regname) == 2 && regname[1] >= '0' && regname[1] <= '7') {
222 		int idx = regname[1] - '0';
223 
224 		switch (regname[0]) {
225 		case 'o':
226 			if (++win == nwin)
227 				win = 0;
228 			/*FALLTHROUGH*/
229 		case 'i':
230 			return ((kreg_t *)&save->krs_rwins[win].rw_in[idx]);
231 		case 'l':
232 			return ((kreg_t *)&save->krs_rwins[win].rw_local[idx]);
233 		}
234 	}
235 
236 	for (i = 0; mdb_sparcv9_kregs[i].rd_name != NULL; i++) {
237 		const mdb_tgt_regdesc_t *rd = &mdb_sparcv9_kregs[i];
238 
239 		if (strcmp(rd->rd_name, regname) == 0)
240 			return (&gregs->kregs[rd->rd_num]);
241 	}
242 
243 	(void) set_errno(ENOENT);
244 	return (NULL);
245 }
246 
247 static int
248 kaif_get_register(const char *regname, kreg_t *valp)
249 {
250 	kaif_cpusave_t *save;
251 	kreg_t *regp;
252 
253 	save = kaif_cpuid2save(DPI_MASTER_CPUID);
254 
255 	if (strcmp(regname, "pstate") == 0) {
256 		*valp = KREG_TSTATE_PSTATE(save->krs_tstate);
257 		return (0);
258 	}
259 
260 	if ((regp = kaif_find_regp(save, regname)) == NULL)
261 		return (-1);
262 
263 	*valp = *regp;
264 
265 	return (0);
266 }
267 
268 static int
269 kaif_set_register(const char *regname, kreg_t val)
270 {
271 	kaif_cpusave_t *save;
272 	kreg_t *regp;
273 
274 	save = kaif_cpuid2save(DPI_MASTER_CPUID);
275 
276 	if (strcmp(regname, "g0") == 0) {
277 		return (0);
278 
279 	} else if (strcmp(regname, "pstate") == 0) {
280 		save->krs_tstate &= ~KREG_TSTATE_PSTATE_MASK;
281 		save->krs_tstate |= (val & KREG_PSTATE_MASK) <<
282 		    KREG_TSTATE_PSTATE_SHIFT;
283 		return (0);
284 	}
285 
286 	if ((regp = kaif_find_regp(save, regname)) == NULL)
287 		return (-1);
288 
289 	*regp = val;
290 
291 	return (0);
292 }
293 
294 static int
295 kaif_brkpt_arm(uintptr_t addr, mdb_instr_t *instrp)
296 {
297 	mdb_instr_t bkpt = KAIF_BRKPT_INSTR;
298 
299 	if (mdb_tgt_vread(mdb.m_target, instrp, sizeof (mdb_instr_t), addr) !=
300 	    sizeof (mdb_instr_t))
301 		return (-1); /* errno is set for us */
302 
303 	if (mdb_tgt_vwrite(mdb.m_target, &bkpt, sizeof (mdb_instr_t), addr) !=
304 	    sizeof (mdb_instr_t))
305 		return (-1); /* errno is set for us */
306 
307 	return (0);
308 }
309 
310 static int
311 kaif_brkpt_disarm(uintptr_t addr, mdb_instr_t instrp)
312 {
313 	if (mdb_tgt_vwrite(mdb.m_target, &instrp, sizeof (mdb_instr_t), addr) !=
314 	    sizeof (mdb_instr_t))
315 		return (-1); /* errno is set for us */
316 
317 	return (0);
318 }
319 
320 /*
321  * Calculate the watchpoint mask byte (VM or PM, as appropriate).  A 1 bit in
322  * the mask indicates that the corresponding byte in the watchpoint address
323  * should be used for activation comparison.
324  */
325 /*
326  * Sun4v doesn't have watchpoint regs
327  */
328 #ifndef	sun4v
329 static uchar_t
330 kaif_wapt_calc_mask(size_t len)
331 {
332 	int pow;
333 
334 	if (len == 8)
335 		return (0xff);
336 
337 	for (pow = 0; len > 1; len /= 256, pow++);
338 
339 	return (~((1 << pow) - 1));
340 }
341 #endif
342 
343 /*
344  * UltraSPARC processors have one physical and one virtual watchpoint.  These
345  * watchpoints are specified by setting the address in a register, and by
346  * setting a selector byte in another register to determine which bytes of the
347  * address are to be used for comparison.  For simplicity, we only support
348  * selector byte values whose bit patterns match the regexp "1+0*".  Watchpoint
349  * addresses must be 8-byte aligned on these chips, so a selector byte of 0xff
350  * indicates an 8-byte watchpoint.  Successive valid sizes are powers of 256,
351  * starting with 256.
352  */
353 static int
354 kaif_wapt_validate(kmdb_wapt_t *wp)
355 {
356 	if (wp->wp_wflags & MDB_TGT_WA_X) {
357 		warn("execute watchpoints are not supported on this "
358 		    "platform\n");
359 		return (set_errno(EMDB_TGTNOTSUP));
360 	}
361 
362 	if (wp->wp_size % 0xff != 0 && wp->wp_size != 8) {
363 		warn("watchpoint size must be 8 or a power of 256 bytes\n");
364 		return (set_errno(EINVAL));
365 	}
366 
367 	if (wp->wp_addr & (wp->wp_size - 1)) {
368 		warn("%lu-byte watchpoints must be %lu-byte aligned\n",
369 		    wp->wp_size, wp->wp_size);
370 		return (set_errno(EINVAL));
371 	}
372 
373 	if (wp->wp_type != DPI_WAPT_TYPE_PHYS &&
374 	    wp->wp_type != DPI_WAPT_TYPE_VIRT) {
375 		warn("requested watchpoint type not supported on this "
376 		    "platform\n");
377 		return (set_errno(EMDB_TGTHWNOTSUP));
378 	}
379 
380 	return (0);
381 }
382 
383 static int
384 kaif_wapt_reserve(kmdb_wapt_t *wp)
385 {
386 #ifdef	sun4v
387 #ifdef	lint
388 	ASSERT(wp == (kmdb_wapt_t *)wp);
389 #endif	/* !lint */
390 	/* Watchpoints not supported */
391 	return (set_errno(EMDB_TGTHWNOTSUP));
392 #else
393 	uint64_t *addrp;
394 
395 	if (wp->wp_type == DPI_WAPT_TYPE_PHYS)
396 		addrp = &kaif_pwapt_addr;
397 	else
398 		addrp = &kaif_vwapt_addr;
399 
400 	if (*addrp != NULL)
401 		return (set_errno(EMDB_WPTOOMANY));
402 
403 	*addrp = wp->wp_addr;
404 
405 	return (0);
406 #endif
407 }
408 
409 static void
410 kaif_wapt_release(kmdb_wapt_t *wp)
411 {
412 	uint64_t *addrp = (wp->wp_type == DPI_WAPT_TYPE_PHYS ?
413 	    &kaif_pwapt_addr : &kaif_vwapt_addr);
414 
415 	ASSERT(*addrp != NULL);
416 	*addrp = NULL;
417 }
418 
419 /*ARGSUSED*/
420 static void
421 kaif_wapt_arm(kmdb_wapt_t *wp)
422 {
423 	/*
424 	 * Sun4v doesn't have watch point regs
425 	 */
426 #ifndef	sun4v
427 	uint64_t mask = kaif_wapt_calc_mask(wp->wp_size);
428 
429 	if (wp->wp_type == DPI_WAPT_TYPE_PHYS) {
430 		kaif_lsuctl &= ~KAIF_LSUCTL_PWAPT_MASK;
431 
432 		if (wp->wp_wflags & MDB_TGT_WA_R)
433 			kaif_lsuctl |= LSU_PR;
434 		if (wp->wp_wflags & MDB_TGT_WA_W)
435 			kaif_lsuctl |= LSU_PW;
436 		kaif_lsuctl |= ((mask << LSU_PM_SHIFT) & LSU_PM);
437 
438 	} else if (wp->wp_type == DPI_WAPT_TYPE_VIRT) {
439 		kaif_lsuctl &= ~KAIF_LSUCTL_VWAPT_MASK;
440 
441 		if (wp->wp_wflags & MDB_TGT_WA_R)
442 			kaif_lsuctl |= LSU_VR;
443 		if (wp->wp_wflags & MDB_TGT_WA_W)
444 			kaif_lsuctl |= LSU_VW;
445 		kaif_lsuctl |= ((mask << LSU_VM_SHIFT) & LSU_VM);
446 	}
447 #endif	/* sun4v */
448 }
449 
450 /*ARGSUSED*/
451 static void
452 kaif_wapt_disarm(kmdb_wapt_t *wp)
453 {
454 	/*
455 	 * Sun4v doesn't have watch point regs
456 	 */
457 #ifndef	sun4v
458 	if (wp->wp_type == DPI_WAPT_TYPE_PHYS) {
459 		ASSERT(kaif_pwapt_addr != NULL);
460 		kaif_lsuctl &= ~(LSU_PR|LSU_PW);
461 	} else {
462 		ASSERT(kaif_vwapt_addr != NULL);
463 		kaif_lsuctl &= ~(LSU_VR|LSU_VW);
464 	}
465 #endif
466 }
467 
468 /*
469  * `kaif_wapt_arm' and `kaif_wapt_disarm' modify the global state we keep that
470  * indicates what the values of the wapt control registers should be.  These
471  * values must be individually set and cleared on each active CPU, a task which
472  * is performed by `kaif_wapt_clear_regs' and `kaif_wapt_set_regs', invoked as
473  * the world is stopped and resumed, respectively.  `kaif_wapt_set_regs' is also
474  * used for CPU initialization.
475  */
476 void
477 kaif_wapt_set_regs(void)
478 {
479 	/*
480 	 * Sun4v doesn't have watch point regs
481 	 */
482 #ifndef sun4v
483 	uint64_t lsu;
484 
485 	wrasi(ASI_DMMU, MMU_VAW, kaif_vwapt_addr);
486 	wrasi(ASI_DMMU, MMU_PAW, kaif_pwapt_addr);
487 
488 	ASSERT((kaif_lsuctl & ~KAIF_LSUCTL_WAPT_MASK) == NULL);
489 
490 	lsu = rdasi(ASI_LSU, NULL);
491 	lsu &= ~KAIF_LSUCTL_WAPT_MASK;
492 	lsu |= kaif_lsuctl;
493 	wrasi(ASI_LSU, NULL, lsu);
494 #endif /* sun4v */
495 }
496 
497 void
498 kaif_wapt_clear_regs(void)
499 {
500 	/*
501 	 * Sun4v doesn't have watch point regs
502 	 */
503 #ifndef sun4v
504 	uint64_t lsu = rdasi(ASI_LSU, NULL);
505 	lsu &= ~KAIF_LSUCTL_WAPT_MASK;
506 	wrasi(ASI_LSU, NULL, lsu);
507 #endif /* sun4v */
508 }
509 
510 /*
511  * UltraSPARC has one PA watchpoint and one VA watchpoint.  The trap we get will
512  * tell us which one we hit, but it won't tell us where.  We could attempt to
513  * dissect the instruction at %pc to see where it was reading from or writing
514  * to, but that gets messy in a hurry.  We can, however, make a couple of
515  * assumptions:
516  *
517  * - kaif_set_watchpoint and kaif_delete_watchpoint will enforce the limits as
518  *   to the number of watch points.  As such, at most one VA watchpoint and one
519  *   PA watchpoint will be on the active list.
520  *
521  * - We'll only be called on watchpoints that are on the active list.
522  *
523  * Taking these two assumptions, we can conclude that, if we're stopped due to
524  * a watchpoint and we're asked to match against a watchpoint, we must have
525  * stopped due to the watchpoint.  This is all very terrifying, but the
526  * alternative (taking instructions apart) is worse.
527  */
528 /*ARGSUSED*/
529 static int
530 kaif_wapt_match(kmdb_wapt_t *wp)
531 {
532 	int state, why, deswhy;
533 
534 	state = kmdb_dpi_get_state(&why);
535 
536 	if (wp->wp_type == DPI_WAPT_TYPE_PHYS)
537 		deswhy = DPI_STATE_WHY_P_WAPT;
538 	else
539 		deswhy = DPI_STATE_WHY_V_WAPT;
540 
541 	return (state == DPI_STATE_FAULTED && why == deswhy);
542 }
543 
544 static const char *
545 regno2name(int idx)
546 {
547 	const mdb_tgt_regdesc_t *rd;
548 
549 	for (rd = mdb_sparcv9_kregs; rd->rd_name != NULL; rd++) {
550 		if (idx == rd->rd_num)
551 			return (rd->rd_name);
552 	}
553 
554 	ASSERT(rd->rd_name != NULL);
555 
556 	return ("unknown");
557 }
558 
559 /*
560  * UltraSPARC doesn't support single-step natively, so we have to do it
561  * ourselves, by placing breakpoints at the instruction after the current one.
562  * Note that "after" will be %npc in the simple case, but can be one of
563  * several places if %pc is a branch.
564  *
565  * If %pc is an unconditional annulled branch, we put a breakpoint at the branch
566  * target.  If it is a conditional annulled branch, we put breakpoints at %pc +
567  * 8 and the branch target.  For all other branches, %npc will be set correctly
568  * as determined by the branch condition, and thus we can step through the
569  * branch by putting a breakpoint at %npc.  If %pc contains a non-branch
570  * instruction (with the exception of certain rdpr and wrpr instructions,
571  * described more below), we step over it by placing a breakpoint at %npc.
572  */
573 static int
574 kaif_step(void)
575 {
576 	kreg_t pc, npc, brtgt, pstate, tt;
577 	int bptgt = 0, bpnpc = 0, bppc8 = 0;
578 	mdb_instr_t svtgt = 0, svnpc = 0, svpc8 = 0;
579 	mdb_instr_t instr;
580 	int ie, err;
581 
582 	(void) kmdb_dpi_get_register("pc", &pc);
583 	(void) kmdb_dpi_get_register("npc", &npc);
584 
585 	if (mdb_tgt_vread(mdb.m_target, &instr, sizeof (instr), pc) !=
586 	    sizeof (instr)) {
587 		warn("failed to read %%pc at %p for step", (void *)pc);
588 		return (-1);
589 	}
590 
591 	/*
592 	 * If the current instruction is a read or write of PSTATE we need
593 	 * to emulate it because we've taken over management of PSTATE and
594 	 * we need keep interrupts disabled. If it's a branch, we may need
595 	 * to set two breakpoints -- one at the target and one at the
596 	 * subsequent instruction.
597 	 */
598 	if (OP(instr) == OP_ARITH) {
599 		if (OP3(instr) == OP3_RDPR &&
600 		    RS1(instr) == KAIF_PREGNO_PSTATE) {
601 			const char *tgtreg =
602 			    mdb_sparcv9_kregs[RD(instr)].rd_name;
603 			kreg_t pstate;
604 
605 			(void) kmdb_dpi_get_register("pstate", &pstate);
606 			(void) kmdb_dpi_set_register(tgtreg, pstate);
607 
608 			(void) kmdb_dpi_set_register("pc", npc);
609 			(void) kmdb_dpi_set_register("npc", npc + 4);
610 			return (0);
611 
612 		} else if (OP3(instr) == OP3_WRPR &&
613 		    RD(instr) == KAIF_PREGNO_PSTATE) {
614 			kreg_t rs1, rs2, val;
615 
616 			(void) kmdb_dpi_get_register(regno2name(RS1(instr)),
617 			    &rs1);
618 
619 			if (I(instr)) {
620 				int imm = SIMM13(instr);
621 				imm <<= 19;
622 				imm >>= 19;
623 				rs2 = imm;
624 			} else {
625 				(void) kmdb_dpi_get_register(
626 				    regno2name(RS2(instr)), &rs2);
627 			}
628 
629 			val = rs1 ^ rs2;
630 
631 			(void) kmdb_dpi_set_register("pstate", val);
632 
633 			(void) kmdb_dpi_set_register("pc", npc);
634 			(void) kmdb_dpi_set_register("npc", npc + 4);
635 			return (0);
636 
637 		}
638 
639 		bpnpc = 1;
640 
641 	} else if (OP(instr) == OP_BRANCH) {
642 		int disp, cond, annul;
643 
644 		switch (OP2(instr)) {
645 		case OP2_BPcc:
646 		case OP2_FBPfcc:
647 			cond = (COND(instr) != 8);
648 
649 			disp = DISP19(instr);
650 			disp <<= 13;
651 			disp >>= 11;
652 			break;
653 
654 		case OP2_Bicc:
655 		case OP2_FBfcc:
656 			cond = (COND(instr) != 8);
657 
658 			disp = DISP22(instr);
659 			disp <<= 10;
660 			disp >>= 8;
661 			break;
662 
663 		case OP2_BPr:
664 			cond = 1;
665 
666 			disp = DISP16(instr);
667 			disp <<= 16;
668 			disp >>= 14;
669 			break;
670 
671 		default:
672 			bpnpc = 1;
673 		}
674 
675 		if (!bpnpc) {
676 			annul = A(instr);
677 
678 			if (!cond && annul) {
679 				brtgt = pc + disp;
680 				bptgt = 1;
681 			} else {
682 				bpnpc = 1;
683 
684 				if (cond && annul)
685 					bppc8 = 1;
686 			}
687 		}
688 
689 	} else {
690 		bpnpc = 1;
691 	}
692 
693 	/*
694 	 * Place the breakpoints and resume this CPU with IE off.  We'll come
695 	 * back after having encountered either one of the breakpoints we placed
696 	 * or a trap.
697 	 */
698 	err = 0;
699 	if ((bpnpc && kaif_brkpt_arm(npc, &svnpc) != 0) ||
700 	    (bppc8 && kaif_brkpt_arm(pc + 8, &svpc8) != 0) ||
701 	    (bptgt && kaif_brkpt_arm(brtgt, &svtgt) != 0)) {
702 		err = errno;
703 		goto step_done;
704 	}
705 
706 	(void) kmdb_dpi_get_register("pstate", &pstate);
707 	ie = pstate & KREG_PSTATE_IE_MASK;
708 	(void) kmdb_dpi_set_register("pstate", (pstate & ~KREG_PSTATE_IE_MASK));
709 
710 	kmdb_dpi_resume_master(); /* ... there and back again ... */
711 
712 	(void) kmdb_dpi_get_register("pstate", &pstate);
713 	(void) kmdb_dpi_set_register("pstate",
714 	    ((pstate & ~KREG_PSTATE_IE_MASK) | ie));
715 
716 	(void) kmdb_dpi_get_register("tt", &tt);
717 
718 step_done:
719 	if (svnpc)
720 		(void) kaif_brkpt_disarm(npc, svnpc);
721 	if (svpc8)
722 		(void) kaif_brkpt_disarm(pc + 8, svpc8);
723 	if (svtgt)
724 		(void) kaif_brkpt_disarm(brtgt, svtgt);
725 
726 	return (err == 0 ? 0 : set_errno(err));
727 }
728 
729 static uintptr_t
730 kaif_call(uintptr_t funcva, uint_t argc, const uintptr_t *argv)
731 {
732 	kreg_t g6, g7;
733 
734 	(void) kmdb_dpi_get_register("g6", &g6);
735 	(void) kmdb_dpi_get_register("g7", &g7);
736 
737 	return (kaif_invoke(funcva, argc, argv, g6, g7));
738 }
739 
740 static const mdb_bitmask_t krm_flag_bits[] = {
741 	{ "M_W",	KAIF_CRUMB_F_MAIN_OBPWAPT, KAIF_CRUMB_F_MAIN_OBPWAPT },
742 	{ "M_PE",	KAIF_CRUMB_F_MAIN_OBPPENT, KAIF_CRUMB_F_MAIN_OBPPENT },
743 	{ "M_NRM",	KAIF_CRUMB_F_MAIN_NORMAL, KAIF_CRUMB_F_MAIN_NORMAL },
744 	{ "I_RE",	KAIF_CRUMB_F_IVEC_REENTER, KAIF_CRUMB_F_IVEC_REENTER },
745 	{ "I_OBP", 	KAIF_CRUMB_F_IVEC_INOBP, KAIF_CRUMB_F_IVEC_INOBP },
746 	{ "I_NRM",	KAIF_CRUMB_F_IVEC_NORMAL, KAIF_CRUMB_F_IVEC_NORMAL },
747 	{ "O_NRM",	KAIF_CRUMB_F_OBP_NORMAL, KAIF_CRUMB_F_OBP_NORMAL },
748 	{ "O_REVEC",	KAIF_CRUMB_F_OBP_REVECT, KAIF_CRUMB_F_OBP_REVECT },
749 	{ NULL }
750 };
751 
752 static void
753 dump_crumb(kaif_crumb_t *krmp)
754 {
755 	kaif_crumb_t krm;
756 
757 	if (mdb_vread(&krm, sizeof (kaif_crumb_t), (uintptr_t)krmp) !=
758 	    sizeof (kaif_crumb_t)) {
759 		warn("failed to read crumb at %p", krmp);
760 		return;
761 	}
762 
763 	mdb_printf(" src: ");
764 	switch (krm.krm_src) {
765 	case KAIF_CRUMB_SRC_OBP:
766 		mdb_printf("O");
767 		break;
768 	case KAIF_CRUMB_SRC_IVEC:
769 		mdb_printf("I");
770 		break;
771 	case KAIF_CRUMB_SRC_MAIN:
772 		mdb_printf("M");
773 		break;
774 	case 0:
775 		mdb_printf("-");
776 		break;
777 	default:
778 		mdb_printf("%d", krm.krm_src);
779 	}
780 
781 	mdb_printf(" tt %3x pc %8p %-20A <%b>\n",
782 	    krm.krm_tt, krm.krm_pc, krm.krm_pc, krm.krm_flag, krm_flag_bits);
783 }
784 
785 static void
786 dump_crumbs(kaif_cpusave_t *save)
787 {
788 	int i;
789 
790 	for (i = KAIF_NCRUMBS; i > 0; i--) {
791 		uint_t idx = (save->krs_curcrumbidx + i) % KAIF_NCRUMBS;
792 		dump_crumb(&save->krs_crumbs[idx]);
793 	}
794 }
795 
796 static void
797 kaif_dump_crumbs(uintptr_t addr, int cpuid)
798 {
799 	int i;
800 
801 	if (addr != NULL) {
802 		/* dump_crumb will protect us from bogus addresses */
803 		dump_crumb((kaif_crumb_t *)addr);
804 
805 	} else if (cpuid != -1) {
806 		if (cpuid >= kaif_ncpusave)
807 			return;
808 
809 		dump_crumbs(&kaif_cpusave[cpuid]);
810 
811 	} else {
812 		for (i = 0; i < kaif_ncpusave; i++) {
813 			kaif_cpusave_t *save = &kaif_cpusave[i];
814 
815 			if (save->krs_cpu_state == KAIF_CPU_STATE_NONE)
816 				continue;
817 
818 			mdb_printf("%sCPU %d crumbs: (curidx %d)\n",
819 			    (i == 0 ? "" : "\n"), i, save->krs_curcrumbidx);
820 
821 			dump_crumbs(save);
822 		}
823 	}
824 }
825 
826 static int
827 kaif_get_rwin(int cpuid, int win, struct rwindow *rwin)
828 {
829 	kaif_cpusave_t *save;
830 
831 	if ((save = kaif_cpuid2save(cpuid)) == NULL)
832 		return (-1); /* errno is set for us */
833 
834 	if (win < 0 || win >= kaif_get_nwin(cpuid))
835 		return (-1);
836 
837 	bcopy(&save->krs_rwins[win], rwin, sizeof (struct rwindow));
838 
839 	return (0);
840 }
841 
842 static void
843 kaif_enter_mon(void)
844 {
845 	kmdb_prom_enter_mon();
846 	kaif_prom_rearm();
847 	kaif_slave_loop_barrier();
848 }
849 
850 static void
851 kaif_modchg_register(void (*func)(struct modctl *, int))
852 {
853 	kaif_modchg_cb = func;
854 }
855 
856 static void
857 kaif_modchg_cancel(void)
858 {
859 	ASSERT(kaif_modchg_cb != NULL);
860 
861 	kaif_modchg_cb = NULL;
862 }
863 
864 void
865 kaif_mod_loaded(struct modctl *modp)
866 {
867 	if (kaif_modchg_cb != NULL)
868 		kaif_modchg_cb(modp, 1);
869 }
870 
871 void
872 kaif_mod_unloading(struct modctl *modp)
873 {
874 	if (kaif_modchg_cb != NULL)
875 		kaif_modchg_cb(modp, 0);
876 }
877 
878 void
879 kaif_trap_set_debugger(void)
880 {
881 	set_tba(kaif_tba);
882 }
883 
884 void
885 kaif_trap_set_saved(kaif_cpusave_t *save)
886 {
887 	set_tba((caddr_t)save->krs_gregs.kregs[KREG_TBA]);
888 }
889 
890 static void
891 kaif_kernpanic(int cpuid)
892 {
893 	struct regs regs;
894 
895 	/*
896 	 * We're going to try to panic the system by using the same entry point
897 	 * used by the PROM when told to `sync'.  The kernel wants a
898 	 * fully-populated struct regs, which we're going to build using the
899 	 * state captured at the time of the debugger fault.  Said state lives
900 	 * in kaif_cb_save, since we haven't yet copied it over to the cpusave
901 	 * structure for the current master.
902 	 */
903 
904 	regs.r_tstate = kaif_cb_save.krs_tstate;
905 
906 	regs.r_g1 = kaif_cb_save.krs_gregs.kregs[KREG_G1];
907 	regs.r_g2 = kaif_cb_save.krs_gregs.kregs[KREG_G2];
908 	regs.r_g3 = kaif_cb_save.krs_gregs.kregs[KREG_G3];
909 	regs.r_g4 = kaif_cb_save.krs_gregs.kregs[KREG_G4];
910 	regs.r_g5 = kaif_cb_save.krs_gregs.kregs[KREG_G5];
911 	regs.r_g6 = kaif_cb_save.krs_gregs.kregs[KREG_G6];
912 	regs.r_g7 = kaif_cb_save.krs_gregs.kregs[KREG_G7];
913 
914 	regs.r_o0 = kaif_cb_save.krs_gregs.kregs[KREG_O0];
915 	regs.r_o1 = kaif_cb_save.krs_gregs.kregs[KREG_O1];
916 	regs.r_o2 = kaif_cb_save.krs_gregs.kregs[KREG_O2];
917 	regs.r_o3 = kaif_cb_save.krs_gregs.kregs[KREG_O3];
918 	regs.r_o4 = kaif_cb_save.krs_gregs.kregs[KREG_O4];
919 	regs.r_o5 = kaif_cb_save.krs_gregs.kregs[KREG_O5];
920 	regs.r_o6 = kaif_cb_save.krs_gregs.kregs[KREG_O6];
921 	regs.r_o7 = kaif_cb_save.krs_gregs.kregs[KREG_O7];
922 
923 	regs.r_pc = kaif_cb_save.krs_gregs.kregs[KREG_PC];
924 	regs.r_npc = kaif_cb_save.krs_gregs.kregs[KREG_NPC];
925 	regs.r_y = kaif_cb_save.krs_gregs.kregs[KREG_Y];
926 
927 	/*
928 	 * The %tba is, as ever, different.  We don't want the %tba from the
929 	 * time of the fault -- that'll be the debugger's.  We want the %tba
930 	 * saved when the debugger was initially entered.  It'll be saved in
931 	 * the cpusave area for the current CPU.
932 	 */
933 	set_tba((caddr_t)kaif_cpusave[cpuid].krs_gregs.kregs[KREG_TBA]);
934 
935 	kmdb_kdi_kernpanic(&regs, kaif_cb_save.krs_gregs.kregs[KREG_TT]);
936 }
937 
938 static int
939 kaif_init(kmdb_auxv_t *kav)
940 {
941 	struct rwindow *rwins;
942 	int nwin = get_nwin();
943 	int i;
944 
945 	kaif_vwapt_addr = kaif_pwapt_addr = 0;
946 
947 	kaif_tba = kav->kav_tba_active;
948 	kaif_tba_obp = kav->kav_tba_obp;
949 	kaif_tba_native = kav->kav_tba_native;
950 	kaif_tba_native_sz = kav->kav_tba_native_sz;
951 #ifdef	sun4v
952 	kaif_tba_kernel = kav->kav_tba_kernel;
953 #endif
954 
955 	/* Allocate the per-CPU save areas */
956 	kaif_cpusave = mdb_zalloc(sizeof (kaif_cpusave_t) * kav->kav_ncpu,
957 	    UM_SLEEP);
958 	kaif_ncpusave = kav->kav_ncpu;
959 
960 	rwins = mdb_zalloc(sizeof (struct rwindow) * nwin * kav->kav_ncpu,
961 	    UM_SLEEP);
962 
963 	for (i = 0; i < kaif_ncpusave; i++) {
964 		kaif_cpusave_t *save = &kaif_cpusave[i];
965 
966 		save->krs_cpu_id = i;
967 		save->krs_rwins = &rwins[nwin * i];
968 		save->krs_curcrumbidx = KAIF_NCRUMBS - 1;
969 		save->krs_curcrumb = &save->krs_crumbs[save->krs_curcrumbidx];
970 	}
971 
972 	kaif_dseg = kav->kav_dseg;
973 	kaif_dseg_lim = kav->kav_dseg + kav->kav_dseg_size;
974 
975 	kaif_promexitarmp = kav->kav_promexitarmp;
976 
977 	kaif_ktrap_install = kav->kav_ktrap_install;
978 	kaif_ktrap_restore = kav->kav_ktrap_restore;
979 
980 	kaif_modchg_cb = NULL;
981 
982 	kaif_trap_switch = (kav->kav_flags & KMDB_AUXV_FL_NOTRPSWTCH) == 0;
983 
984 	return (0);
985 }
986 
987 dpi_ops_t kmdb_dpi_ops = {
988 	kaif_init,
989 	kaif_activate,
990 	kaif_deactivate,
991 	kaif_enter_mon,
992 	kaif_modchg_register,
993 	kaif_modchg_cancel,
994 	kaif_get_cpu_state,
995 	kaif_get_master_cpuid,
996 	kaif_get_gregs,
997 	kaif_get_register,
998 	kaif_set_register,
999 	kaif_get_rwin,
1000 	kaif_get_nwin,
1001 	kaif_brkpt_arm,
1002 	kaif_brkpt_disarm,
1003 	kaif_wapt_validate,
1004 	kaif_wapt_reserve,
1005 	kaif_wapt_release,
1006 	kaif_wapt_arm,
1007 	kaif_wapt_disarm,
1008 	kaif_wapt_match,
1009 	kaif_step,
1010 	kaif_call,
1011 	kaif_dump_crumbs,
1012 	kaif_kernpanic
1013 };
1014