xref: /titanic_44/usr/src/cmd/mdb/sparc/kmdb/kvm_isadep.c (revision fe0e7ec4d916b05b52d8c7cc8a3e6a1b28e77b6f)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * isa-dependent portions of the kmdb target
31  */
32 
33 #include <mdb/mdb_kreg_impl.h>
34 #include <mdb/mdb_debug.h>
35 #include <mdb/mdb_modapi.h>
36 #include <mdb/mdb_v9util.h>
37 #include <mdb/mdb_target_impl.h>
38 #include <mdb/mdb_err.h>
39 #include <mdb/mdb_umem.h>
40 #include <kmdb/kmdb_kdi.h>
41 #include <kmdb/kmdb_dpi.h>
42 #include <kmdb/kmdb_promif.h>
43 #include <kmdb/kmdb_asmutil.h>
44 #include <kmdb/kvm.h>
45 #include <mdb/mdb.h>
46 
47 #include <sys/types.h>
48 #include <sys/stack.h>
49 #include <sys/regset.h>
50 #include <sys/sysmacros.h>
51 #include <sys/bitmap.h>
52 #include <sys/machtrap.h>
53 #include <sys/trap.h>
54 
55 /* Higher than the highest trap number for which we have a specific specifier */
56 #define	KMT_MAXTRAPNO	0x1ff
57 
58 #define	OP(x)		((x) >> 30)
59 #define	OP3(x)		(((x) >> 19) & 0x3f)
60 #define	RD(x)		(((x) >> 25) & 0x1f)
61 #define	RS1(x)		(((x) >> 14) & 0x1f)
62 #define	RS2(x)		((x) & 0x1f)
63 
64 #define	OP_ARITH	0x2
65 
66 #define	OP3_OR		0x02
67 #define	OP3_SAVE	0x3c
68 #define	OP3_RESTORE	0x3d
69 
70 static int
71 kmt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
72     mdb_tgt_stack_f *func, void *arg, int cpu)
73 {
74 	mdb_tgt_gregset_t gregs;
75 	kreg_t *kregs = &gregs.kregs[0];
76 	long nwin, stopwin, canrestore, wp, i, sp;
77 	long argv[6];
78 
79 	/*
80 	 * If gsp isn't null, we were asked to dump a trace from a
81 	 * specific location.  The normal iterator can handle that.
82 	 */
83 	if (gsp != NULL) {
84 		if (cpu != DPI_MASTER_CPUID)
85 			warn("register set provided - ignoring cpu argument\n");
86 		return (mdb_kvm_v9stack_iter(t, gsp, func, arg));
87 	}
88 
89 	if (kmdb_dpi_get_cpu_state(cpu) < 0) {
90 		warn("failed to iterate through stack for cpu %u", cpu);
91 		return (DCMD_ERR);
92 	}
93 
94 	/*
95 	 * We're being asked to dump the trace for the current CPU.
96 	 * To do that, we need to iterate first through the saved
97 	 * register windors.  If there's more to the trace than that,
98 	 * we'll hand off to the normal iterator.
99 	 */
100 	bcopy(kmdb_dpi_get_gregs(cpu), &gregs, sizeof (mdb_tgt_gregset_t));
101 
102 	wp = kregs[KREG_CWP];
103 	canrestore = kregs[KREG_CANRESTORE];
104 	nwin = kmdb_dpi_get_nwin(cpu);
105 	stopwin = ((wp + nwin) - canrestore - 1) % nwin;
106 
107 	mdb_dprintf(MDB_DBG_KMOD, "dumping cwp = %lu, canrestore = %lu, "
108 	    "stopwin = %lu\n", wp, canrestore, stopwin);
109 
110 	for (;;) {
111 		struct rwindow rwin;
112 
113 		for (i = 0; i < 6; i++)
114 			argv[i] = kregs[KREG_I0 + i];
115 
116 		if (kregs[KREG_PC] != 0 &&
117 		    func(arg, kregs[KREG_PC], 6, argv, &gregs) != 0)
118 			return (0);
119 
120 		kregs[KREG_PC] = kregs[KREG_I7];
121 		kregs[KREG_NPC] = kregs[KREG_PC] + 4;
122 
123 		if ((sp = kregs[KREG_FP] + STACK_BIAS) == STACK_BIAS || sp == 0)
124 			return (0); /* Stop if we're at the end of stack */
125 
126 		if (sp & (STACK_ALIGN - 1))
127 			return (set_errno(EMDB_STKALIGN));
128 
129 		wp = (wp + nwin - 1) % nwin;
130 
131 		if (wp == stopwin)
132 			break;
133 
134 		bcopy(&kregs[KREG_I0], &kregs[KREG_O0], 8 * sizeof (kreg_t));
135 
136 		if (kmdb_dpi_get_rwin(cpu, wp, &rwin) < 0) {
137 			warn("unable to get registers from window %ld\n", wp);
138 			return (-1);
139 		}
140 
141 		for (i = 0; i < 8; i++)
142 			kregs[KREG_L0 + i] = (uintptr_t)rwin.rw_local[i];
143 		for (i = 0; i < 8; i++)
144 			kregs[KREG_I0 + i] = (uintptr_t)rwin.rw_in[i];
145 	}
146 
147 	mdb_dprintf(MDB_DBG_KMOD, "dumping wp %ld and beyond normally\n", wp);
148 
149 	/*
150 	 * hack - if we null out pc here, iterator won't print the frame
151 	 * that corresponds to the current set of registers.  That's what we
152 	 * want because we just printed them above.
153 	 */
154 	kregs[KREG_PC] = 0;
155 	return (mdb_kvm_v9stack_iter(t, &gregs, func, arg));
156 }
157 
158 void
159 kmt_printregs(const mdb_tgt_gregset_t *gregs)
160 {
161 	mdb_v9printregs(gregs);
162 }
163 
164 static int
165 kmt_stack_common(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv,
166     int cpuid, mdb_tgt_stack_f *func, kreg_t saved_pc)
167 {
168 	mdb_tgt_gregset_t *grp = NULL;
169 	mdb_tgt_gregset_t gregs;
170 	void *arg = (void *)(uintptr_t)mdb.m_nargs;
171 
172 	if (flags & DCMD_ADDRSPEC) {
173 		bzero(&gregs, sizeof (gregs));
174 		gregs.kregs[KREG_FP] = addr;
175 		gregs.kregs[KREG_I7] = saved_pc;
176 		grp = &gregs;
177 	}
178 
179 	if (argc != 0) {
180 		if (argv->a_type == MDB_TYPE_CHAR || argc > 1)
181 			return (DCMD_USAGE);
182 
183 		if (argv->a_type == MDB_TYPE_STRING)
184 			arg = (void *)(uintptr_t)(uint_t)
185 			    mdb_strtoull(argv->a_un.a_str);
186 		else
187 			arg = (void *)(uintptr_t)(uint_t)argv->a_un.a_val;
188 	}
189 
190 	(void) kmt_stack_iter(mdb.m_target, grp, func, arg, cpuid);
191 
192 	return (DCMD_OK);
193 }
194 
195 int
196 kmt_cpustack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv,
197     int cpuid, int verbose)
198 {
199 	return (kmt_stack_common(addr, flags, argc, argv, cpuid,
200 	    (verbose ? mdb_kvm_v9framev : mdb_kvm_v9frame), 0));
201 }
202 
203 int
204 kmt_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
205 {
206 	return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID,
207 	    mdb_kvm_v9frame, 0));
208 }
209 
210 int
211 kmt_stackv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
212 {
213 	return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID,
214 	    mdb_kvm_v9framev, 0));
215 }
216 
217 int
218 kmt_stackr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
219 {
220 	/*
221 	 * Force printing of the first register window by setting the saved
222 	 * pc (%i7) to PC_FAKE.
223 	 */
224 	return (kmt_stack_common(addr, flags, argc, argv, DPI_MASTER_CPUID,
225 	    mdb_kvm_v9framer, PC_FAKE));
226 }
227 
228 ssize_t
229 kmt_write_page(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
230 {
231 	jmp_buf *oldpcb = NULL;
232 	jmp_buf pcb;
233 	physaddr_t pa;
234 
235 	/*
236 	 * Can we write to this page?
237 	 */
238 	if (!(t->t_flags & MDB_TGT_F_ALLOWIO) &&
239 	    (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 1)) == 0)
240 		return (set_errno(EMDB_NOMAP));
241 
242 	/*
243 	 * The OBP va>pa call returns a protection value that's right only some
244 	 * of the time.  We can, however, tell if we failed a write due to a
245 	 * protection violation.  If we get such an error, we'll retry the
246 	 * write using pwrite.
247 	 */
248 	if (setjmp(pcb) != 0) {
249 		/* We failed the write */
250 		kmdb_dpi_restore_fault_hdlr(oldpcb);
251 
252 		if (errno == EACCES && kmdb_prom_vtop(addr, &pa) == 0)
253 			return (kmt_pwrite(t, buf, nbytes, pa));
254 		return (-1); /* errno is set for us */
255 	}
256 
257 	mdb_dprintf(MDB_DBG_KMOD, "copying %lu bytes from %p to %p\n", nbytes,
258 	    buf, (void *)addr);
259 
260 	oldpcb = kmdb_dpi_set_fault_hdlr(&pcb);
261 	(void) kmt_writer((void *)buf, nbytes, addr);
262 	kmdb_dpi_restore_fault_hdlr(oldpcb);
263 
264 	return (nbytes);
265 }
266 
267 /*ARGSUSED*/
268 ssize_t
269 kmt_write(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
270 {
271 	size_t ntowrite, nwritten, n;
272 	int rc;
273 
274 	kmdb_prom_check_interrupt();
275 
276 	if (nbytes == 0)
277 		return (0);
278 
279 	/*
280 	 * Break the writes up into page-sized chunks.  First, the leading page
281 	 * fragment (if any), then the subsequent pages.
282 	 */
283 
284 	if ((n = (addr & (mdb.m_pagesize - 1))) != 0) {
285 		ntowrite = MIN(mdb.m_pagesize - n, nbytes);
286 
287 		if ((rc = kmt_write_page(t, buf, ntowrite, addr)) != ntowrite)
288 			return (rc);
289 
290 		addr = roundup(addr, mdb.m_pagesize);
291 		nbytes -= ntowrite;
292 		nwritten = ntowrite;
293 		buf = ((caddr_t)buf + ntowrite);
294 	}
295 
296 	while (nbytes > 0) {
297 		ntowrite = MIN(mdb.m_pagesize, nbytes);
298 
299 		if ((rc = kmt_write_page(t, buf, ntowrite, addr)) != ntowrite)
300 			return (rc < 0 ? rc : rc + nwritten);
301 
302 		addr += mdb.m_pagesize;
303 		nbytes -= ntowrite;
304 		nwritten += ntowrite;
305 		buf = ((caddr_t)buf + ntowrite);
306 	}
307 
308 	return (rc);
309 }
310 
311 /*ARGSUSED*/
312 ssize_t
313 kmt_ioread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
314 {
315 	return (set_errno(EMDB_TGTHWNOTSUP));
316 }
317 
318 /*ARGSUSED*/
319 ssize_t
320 kmt_iowrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
321 {
322 	return (set_errno(EMDB_TGTHWNOTSUP));
323 }
324 
325 const char *
326 kmt_def_dismode(void)
327 {
328 #ifdef __sparcv9
329 	return ("v9plus");
330 #else
331 	return ("v8");
332 #endif
333 }
334 
335 /*
336  * If we are stopped on a save instruction or at the first instruction of a
337  * known function, return %o7 as the step-out address; otherwise return the
338  * current frame's return address (%i7).  Significantly better handling of
339  * step out in leaf routines could be accomplished by implementing more
340  * complex decoding of the current function and our current state.
341  */
342 int
343 kmt_step_out(mdb_tgt_t *t, uintptr_t *p)
344 {
345 	kreg_t pc, i7, o7;
346 	GElf_Sym func;
347 
348 	(void) kmdb_dpi_get_register("pc", &pc);
349 	(void) kmdb_dpi_get_register("i7", &i7);
350 	(void) kmdb_dpi_get_register("o7", &o7);
351 
352 	if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0,
353 	    &func, NULL) == 0 && func.st_value == pc)
354 		*p = o7 + 2 * sizeof (mdb_instr_t);
355 	else {
356 		mdb_instr_t instr;
357 
358 		if (mdb_tgt_vread(t, &instr, sizeof (instr), pc) !=
359 		    sizeof (instr)) {
360 			warn("failed to read instruction at %p for step out",
361 			    (void *)pc);
362 			return (-1);
363 		}
364 
365 		if (OP(instr) == OP_ARITH && OP3(instr) == OP3_SAVE)
366 			*p = o7 + 2 * sizeof (mdb_instr_t);
367 		else
368 			*p = i7 + 2 * sizeof (mdb_instr_t);
369 	}
370 
371 	return (0);
372 }
373 
374 /*ARGSUSED*/
375 int
376 kmt_step_branch(mdb_tgt_t *t)
377 {
378 	return (set_errno(EMDB_TGTHWNOTSUP));
379 }
380 
381 static const char *
382 regno2name(int idx)
383 {
384 	const mdb_tgt_regdesc_t *rd;
385 
386 	for (rd = mdb_sparcv9_kregs; rd->rd_name != NULL; rd++) {
387 		if (idx == rd->rd_num)
388 			return (rd->rd_name);
389 	}
390 
391 	ASSERT(rd->rd_name != NULL);
392 
393 	return ("unknown");
394 }
395 
396 /*
397  * Step over call and jmpl by returning the address of the position where a
398  * temporary breakpoint can be set to catch return from the control transfer.
399  * This function does not currently provide advanced decoding of DCTI couples
400  * or any other complex special case; we just fall back to single-step.
401  */
402 int
403 kmt_next(mdb_tgt_t *t, uintptr_t *p)
404 {
405 	kreg_t pc, npc;
406 	GElf_Sym func;
407 
408 	(void) kmdb_dpi_get_register("pc", &pc);
409 	(void) kmdb_dpi_get_register("npc", &npc);
410 
411 	if (mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY, NULL, 0,
412 	    &func, NULL) != 0)
413 		return (-1);
414 
415 	if (npc < func.st_value || func.st_value + func.st_size <= npc) {
416 		mdb_instr_t instr;
417 		kreg_t reg;
418 
419 		/*
420 		 * We're about to transfer control outside this function, so we
421 		 * want to stop when control returns from the other function.
422 		 * Normally the return address will be in %o7, tail-calls being
423 		 * the exception.  We try to discover if this is a tail-call and
424 		 * compute the return address in that case.
425 		 */
426 		if (mdb_tgt_vread(t, &instr, sizeof (instr), pc) !=
427 		    sizeof (instr)) {
428 			warn("failed to read instruction at %p for next",
429 			    (void *)pc);
430 			return (-1);
431 		}
432 
433 		if (OP(instr) == OP_ARITH && OP3(instr) == OP3_RESTORE) {
434 			(void) kmdb_dpi_get_register("i7", &reg);
435 		} else if (OP(instr) == OP_ARITH && OP3(instr) == OP3_OR &&
436 		    RD(instr) == KREG_O7) {
437 			if (RS1(instr) == KREG_G0)
438 				return (set_errno(EAGAIN));
439 
440 			(void) kmdb_dpi_get_register(regno2name(RS2(instr)),
441 			    &reg);
442 		} else
443 			(void) kmdb_dpi_get_register("o7", &reg);
444 
445 		*p = reg + 2 * sizeof (mdb_instr_t);
446 
447 		return (0);
448 	}
449 
450 	return (set_errno(EAGAIN));
451 }
452 
453 const char *
454 kmt_trapname(int trapnum)
455 {
456 	static char trapname[11];
457 
458 	switch (trapnum) {
459 	case T_INSTR_EXCEPTION:
460 		return ("instruction access error trap");
461 	case T_ALIGNMENT:
462 		return ("improper alignment trap");
463 	case T_UNIMP_INSTR:
464 		return ("illegal instruction trap");
465 	case T_IDIV0:
466 		return ("division by zero trap");
467 	case T_FAST_INSTR_MMU_MISS:
468 		return ("instruction access MMU miss trap");
469 	case T_FAST_DATA_MMU_MISS:
470 		return ("data access MMU miss trap");
471 	case ST_KMDB_TRAP|T_SOFTWARE_TRAP:
472 		return ("debugger entry trap");
473 	case ST_KMDB_BREAKPOINT|T_SOFTWARE_TRAP:
474 		return ("breakpoint trap");
475 	default:
476 		(void) mdb_snprintf(trapname, sizeof (trapname), "trap %#x",
477 		    trapnum);
478 		return (trapname);
479 	}
480 }
481 
482 void
483 kmt_init_isadep(mdb_tgt_t *t)
484 {
485 	kmt_data_t *kmt = t->t_data;
486 
487 	kmt->kmt_rds = mdb_sparcv9_kregs;
488 
489 	kmt->kmt_trapmax = KMT_MAXTRAPNO;
490 	kmt->kmt_trapmap = mdb_zalloc(BT_SIZEOFMAP(kmt->kmt_trapmax), UM_SLEEP);
491 
492 	/* Traps for which we want to provide an explicit message */
493 	(void) mdb_tgt_add_fault(t, T_INSTR_EXCEPTION, MDB_TGT_SPEC_INTERNAL,
494 	    no_se_f, NULL);
495 	(void) mdb_tgt_add_fault(t, T_ALIGNMENT, MDB_TGT_SPEC_INTERNAL,
496 	    no_se_f, NULL);
497 	(void) mdb_tgt_add_fault(t, T_UNIMP_INSTR, MDB_TGT_SPEC_INTERNAL,
498 	    no_se_f, NULL);
499 	(void) mdb_tgt_add_fault(t, T_IDIV0, MDB_TGT_SPEC_INTERNAL,
500 	    no_se_f, NULL);
501 	(void) mdb_tgt_add_fault(t, T_FAST_INSTR_MMU_MISS,
502 	    MDB_TGT_SPEC_INTERNAL, no_se_f, NULL);
503 	(void) mdb_tgt_add_fault(t, T_FAST_DATA_MMU_MISS, MDB_TGT_SPEC_INTERNAL,
504 	    no_se_f, NULL);
505 
506 	/*
507 	 * Traps which will be handled elsewhere, and which therefore don't
508 	 * need the trap-based message.
509 	 */
510 	BT_SET(kmt->kmt_trapmap, ST_KMDB_TRAP|T_SOFTWARE_TRAP);
511 	BT_SET(kmt->kmt_trapmap, ST_KMDB_BREAKPOINT|T_SOFTWARE_TRAP);
512 	BT_SET(kmt->kmt_trapmap, T_PA_WATCHPOINT);
513 	BT_SET(kmt->kmt_trapmap, T_VA_WATCHPOINT);
514 
515 	/* Catch-all for traps not explicitly listed here */
516 	(void) mdb_tgt_add_fault(t, KMT_TRAP_NOTENUM, MDB_TGT_SPEC_INTERNAL,
517 	    no_se_f, NULL);
518 }
519 
520 /*ARGSUSED*/
521 void
522 kmt_startup_isadep(mdb_tgt_t *t)
523 {
524 }
525