kvm_isadep.c revision 436:c9ab97f06761
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
70static int
71kmt_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
158void
159kmt_printregs(const mdb_tgt_gregset_t *gregs)
160{
161	mdb_v9printregs(gregs);
162}
163
164static int
165kmt_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
195int
196kmt_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
203int
204kmt_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
210int
211kmt_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
217int
218kmt_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
228ssize_t
229kmt_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*/
268ssize_t
269kmt_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*/
312ssize_t
313kmt_ioread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
314{
315	return (set_errno(EMDB_TGTHWNOTSUP));
316}
317
318/*ARGSUSED*/
319ssize_t
320kmt_iowrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
321{
322	return (set_errno(EMDB_TGTHWNOTSUP));
323}
324
325const char *
326kmt_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 */
342int
343kmt_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*/
375int
376kmt_step_branch(mdb_tgt_t *t)
377{
378	return (set_errno(EMDB_TGTHWNOTSUP));
379}
380
381static const char *
382regno2name(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 */
402int
403kmt_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
453const char *
454kmt_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
482void
483kmt_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*/
521void
522kmt_startup_isadep(mdb_tgt_t *t)
523{
524}
525