1 /*	$NetBSD: kgdb_machdep.c,v 1.18 2016/07/11 16:15:36 matt Exp $	*/
2 
3 /*-
4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1996 Matthias Pfaller.
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
50  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
55  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56  */
57 
58 #include <sys/cdefs.h>
59 __KERNEL_RCSID(0, "$NetBSD: kgdb_machdep.c,v 1.18 2016/07/11 16:15:36 matt Exp $");
60 
61 #include "opt_ddb.h"
62 
63 #if defined(DDB)
64 #error "Can't build DDB and KGDB together."
65 #endif
66 
67 /*
68  * Machine-dependent functions for remote KGDB.  Originally written
69  * for NetBSD/pc532 by Matthias Pfaller.  Modified for NetBSD/i386
70  * by Jason R. Thorpe.  Modified for NetBSD/mips by Ethan Solomita
71  */
72 
73 #include "opt_cputype.h"	/* which mips CPUs do we support? */
74 
75 #include <sys/types.h>
76 #include <sys/systm.h>
77 #include <sys/param.h>
78 #include <sys/proc.h>
79 #include <sys/reboot.h>
80 #include <sys/kgdb.h>
81 
82 #include <uvm/uvm_extern.h>
83 
84 #include <mips/pte.h>
85 #include <mips/cpu.h>
86 #include <mips/locore.h>
87 #include <mips/mips_opcode.h>
88 #include <mips/reg.h>
89 #include <mips/trap.h>
90 #include <dev/cons.h>
91 
92 #include <machine/db_machdep.h>
93 #include <ddb/db_access.h>
94 
95 /*
96  * Is kva a valid address to access?  This is used by KGDB.
97  */
98 static int
kvacc(vaddr_t kva)99 kvacc(vaddr_t kva)
100 {
101 	if (pmap_md_direct_mapped_vaddr_p(kva))
102 		return 1;
103 
104 	if (kva < VM_MIN_KERNEL_ADDRESS || kva >= VM_MAX_KERNEL_ADDRESS)
105 		return 0;
106 
107 	const pt_entry_t * const ptep = pmap_pte_lookup(pmap_kernel(), kva);
108 	return ptep != NULL && pte_valid_p(*pte);
109 }
110 
111 /*
112  * Determine if the memory at va..(va+len) is valid.
113  */
114 int
kgdb_acc(vaddr_t va,size_t len)115 kgdb_acc(vaddr_t va, size_t len)
116 {
117 	vaddr_t last_va;
118 
119 	last_va = va + len + PAGE_SIZE - 1;
120 	va  &= ~PGOFSET;
121 	last_va &= ~PGOFSET;
122 
123 	for (; va < last_va; va += PAGE_SIZE) {
124 		if (kvacc(va) == 0)
125 			return 0;
126 	}
127 
128 	return (1);
129 }
130 
131 /*
132  * Translate a trap number into a unix compatible signal value.
133  * (gdb only understands unix signal numbers).
134  */
135 int
kgdb_signal(int type)136 kgdb_signal(int type)
137 {
138 	switch (type) {
139 	case T_TLB_MOD:
140 	case T_TLB_MOD+T_USER:
141 	case T_TLB_LD_MISS:
142 	case T_TLB_ST_MISS:
143 	case T_TLB_LD_MISS+T_USER:
144 	case T_TLB_ST_MISS+T_USER:
145 	case T_ADDR_ERR_LD:	/* misaligned access */
146 	case T_ADDR_ERR_ST:	/* misaligned access */
147 	case T_BUS_ERR_LD_ST:	/* BERR asserted to CPU */
148 	case T_ADDR_ERR_LD+T_USER:	/* misaligned or kseg access */
149 	case T_ADDR_ERR_ST+T_USER:	/* misaligned or kseg access */
150 	case T_BUS_ERR_IFETCH+T_USER:	/* BERR asserted to CPU */
151 	case T_BUS_ERR_LD_ST+T_USER:	/* BERR asserted to CPU */
152 		return (SIGSEGV);
153 
154 	case T_BREAK:
155 	case T_BREAK+T_USER:
156 		return (SIGTRAP);
157 
158 	case T_RES_INST+T_USER:
159 	case T_COP_UNUSABLE+T_USER:
160 		return (SIGILL);
161 
162 	case T_FPE+T_USER:
163 	case T_OVFLOW+T_USER:
164 		return (SIGFPE);
165 
166 	default:
167 		return (SIGEMT);
168 	}
169 }
170 
171 mips_reg_t kgdb_cause, kgdb_vaddr; /* set by trap() */
172 
173 /*
174  * Translate the values stored in the db_regs_t struct to the format
175  * understood by gdb.
176  */
177 void
kgdb_getregs(db_regs_t * regs,kgdb_reg_t * gdb_regs)178 kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
179 {
180 	memset(gdb_regs, 0, KGDB_NUMREGS * sizeof(kgdb_reg_t));
181 	gdb_regs[ 1] = regs->r_regs[_R_AST];	/* AT */
182 	gdb_regs[ 2] = regs->r_regs[_R_V0];	/* V0 */
183 	gdb_regs[ 3] = regs->r_regs[_R_V1];	/* V1 */
184 	gdb_regs[ 4] = regs->r_regs[_R_A0];	/* A0 */
185 	gdb_regs[ 5] = regs->r_regs[_R_A1];	/* A1 */
186 	gdb_regs[ 6] = regs->r_regs[_R_A2];	/* A2 */
187 	gdb_regs[ 7] = regs->r_regs[_R_A3];	/* A3 */
188 	gdb_regs[ 8] = regs->r_regs[_R_T0];	/* T0 */
189 	gdb_regs[ 9] = regs->r_regs[_R_T1];	/* T1 */
190 	gdb_regs[10] = regs->r_regs[_R_T2];	/* T2 */
191 	gdb_regs[11] = regs->r_regs[_R_T3];	/* T3 */
192 	gdb_regs[12] = regs->r_regs[_R_T4];	/* T4 */
193 	gdb_regs[13] = regs->r_regs[_R_T5];	/* T5 */
194 	gdb_regs[14] = regs->r_regs[_R_T6];	/* T6 */
195 	gdb_regs[15] = regs->r_regs[_R_T7];	/* T7 */
196 	gdb_regs[16] = regs->r_regs[_R_S0];	/* S0 */
197 	gdb_regs[17] = regs->r_regs[_R_S1];	/* S1 */
198 	gdb_regs[18] = regs->r_regs[_R_S2];	/* S2 */
199 	gdb_regs[19] = regs->r_regs[_R_S3];	/* S3 */
200 	gdb_regs[20] = regs->r_regs[_R_S4];	/* S4 */
201 	gdb_regs[21] = regs->r_regs[_R_S5];	/* S5 */
202 	gdb_regs[22] = regs->r_regs[_R_S6];	/* S6 */
203 	gdb_regs[23] = regs->r_regs[_R_S7];	/* S7 */
204 	gdb_regs[24] = regs->r_regs[_R_T8];	/* T8 */
205 	gdb_regs[25] = regs->r_regs[_R_T9];	/* T9 */
206 	gdb_regs[28] = regs->r_regs[_R_GP];	/* GP */
207 	gdb_regs[29] = regs->r_regs[_R_SP];	/* SP */
208 	gdb_regs[30] = regs->r_regs[_R_S8];	/* S8 */
209 	gdb_regs[31] = regs->r_regs[_R_RA];	/* RA */
210 	gdb_regs[32] = regs->r_regs[_R_SR];	/* SR */
211 	gdb_regs[33] = regs->r_regs[_R_MULLO];	/* MULLO */
212 	gdb_regs[34] = regs->r_regs[_R_MULHI];	/* MULHI */
213 	gdb_regs[35] = kgdb_vaddr;		/* BAD VADDR */
214 	gdb_regs[36] = kgdb_cause;		/* CAUSE */
215 	gdb_regs[37] = regs->r_regs[_R_PC];	/* PC */
216 }
217 
218 /*
219  * Reverse the above.
220  */
221 void
kgdb_setregs(db_regs_t * regs,kgdb_reg_t * gdb_regs)222 kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
223 {
224 	regs->r_regs[_R_PC] = gdb_regs[37];   /* PC */
225 }
226 
227 /*
228  * Trap into kgdb to wait for debugger to connect,
229  * noting on the console why nothing else is going on.
230  */
231 void
kgdb_connect(int verbose)232 kgdb_connect(int verbose)
233 {
234 	if (kgdb_dev < 0)
235 		return;
236 
237 	if (verbose)
238 		printf("kgdb waiting...");
239 
240 	__asm("break");
241 
242 	if (verbose)
243 		printf("connected.\n");
244 
245 	kgdb_debug_panic = 1;
246 }
247 
248 /*
249  * Decide what to do on panic.
250  * (This is called by panic, like Debugger())
251  */
252 void
kgdb_panic(void)253 kgdb_panic(void)
254 {
255 	if (kgdb_dev != NODEV && kgdb_debug_panic) {
256 		printf("entering kgdb\n");
257 		kgdb_connect(kgdb_active == 0);
258 	}
259 }
260