kgdb_machdep.c revision 1.8 1 /* $NetBSD: kgdb_machdep.c,v 1.8 2002/05/09 12:29:16 uch Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 2002 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 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Copyright (c) 1996 Matthias Pfaller.
42 * All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by Matthias Pfaller.
55 * 4. The name of the author may not be used to endorse or promote products
56 * derived from this software without specific prior written permission
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
59 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
60 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
61 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
62 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
63 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
64 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
65 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
67 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68 */
69
70 #include "opt_ddb.h"
71
72 #if defined(DDB)
73 #error "Can't build DDB and KGDB together."
74 #endif
75
76 /*
77 * Machine-dependent functions for remote KGDB. Originally written
78 * for NetBSD/pc532 by Matthias Pfaller. Modified for NetBSD/i386
79 * by Jason R. Thorpe. Modified for NetBSD/mips by Ethan Solomita.
80 * Modified for NetBSD/sh3 by UCHIYAMA Yasushi.
81 */
82
83 #include <sys/types.h>
84 #include <sys/systm.h>
85 #include <sys/param.h>
86 #include <sys/proc.h>
87 #include <sys/user.h>
88 #include <sys/reboot.h>
89 #include <sys/kgdb.h>
90
91 #include <uvm/uvm_extern.h>
92
93 #include <sh3/cpu.h>
94
95 #include <machine/db_machdep.h>
96 #include <ddb/db_access.h>
97
98 /*
99 * Is kva a valid address to access? This is used by KGDB.
100 */
101 static int
102 kvacc(vaddr_t kva)
103 {
104 pt_entry_t *pte;
105
106 if (kva < SH3_P1SEG_BASE)
107 return (0);
108
109 if (kva < SH3_P2SEG_BASE)
110 return (1);
111
112 if (kva >= VM_MAX_KERNEL_ADDRESS)
113 return (0);
114
115 /* check kva is kernel virtual. */
116 if ((kva < VM_MIN_KERNEL_ADDRESS) ||
117 (kva >= VM_MAX_KERNEL_ADDRESS))
118 return (0);
119
120 /* check page which related kva is valid. */
121 pte = __pmap_kpte_lookup(kva);
122 if (!(*pte & PG_V))
123 return (0);
124
125 return (1);
126 }
127
128 /*
129 * Determine if the memory at va..(va+len) is valid.
130 */
131 int
132 kgdb_acc(vaddr_t va, size_t len)
133 {
134 vaddr_t last_va;
135
136 last_va = va + len + NBPG - 1;
137 va &= ~PGOFSET;
138 last_va &= ~PGOFSET;
139
140 for (; va < last_va; va += NBPG) {
141 if (kvacc(va) == 0)
142 return 0;
143 }
144
145 return (1);
146 }
147
148 /*
149 * Translate a trap number into a unix compatible signal value.
150 * (gdb only understands unix signal numbers).
151 */
152 int
153 kgdb_signal(int type)
154 {
155
156 switch (type) {
157 case EXPEVT_TLB_MISS_LD:
158 case EXPEVT_TLB_MISS_ST:
159 case EXPEVT_TLB_MOD:
160 case EXPEVT_TLB_PROT_LD:
161 case EXPEVT_TLB_PROT_ST:
162 case EXPEVT_ADDR_ERR_LD:
163 case EXPEVT_ADDR_ERR_ST:
164 case EXPEVT_TLB_MISS_LD | EXP_USER:
165 case EXPEVT_TLB_MISS_ST | EXP_USER:
166 case EXPEVT_TLB_MOD | EXP_USER:
167 case EXPEVT_TLB_PROT_LD | EXP_USER:
168 case EXPEVT_TLB_PROT_ST | EXP_USER:
169 case EXPEVT_ADDR_ERR_LD | EXP_USER:
170 case EXPEVT_ADDR_ERR_ST | EXP_USER:
171 return (SIGSEGV);
172
173 case EXPEVT_TRAPA:
174 case EXPEVT_BREAK:
175 case EXPEVT_TRAPA | EXP_USER:
176 case EXPEVT_BREAK | EXP_USER:
177 return (SIGTRAP);
178
179 case EXPEVT_RES_INST:
180 case EXPEVT_SLOT_INST:
181 case EXPEVT_RES_INST | EXP_USER:
182 case EXPEVT_SLOT_INST | EXP_USER:
183 return (SIGILL);
184
185 default:
186 return (SIGEMT);
187 }
188 }
189
190 /*
191 * Translate the values stored in the db_regs_t struct to the format
192 * understood by gdb. (gdb-5.1.1/gdb/config/sh/tm-sh.h)
193 */
194 void
195 kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
196 {
197 u_int32_t r;
198
199 memset(gdb_regs, 0, KGDB_NUMREGS * sizeof(kgdb_reg_t));
200 gdb_regs[ 0] = regs->tf_r0;
201 gdb_regs[ 1] = regs->tf_r1;
202 gdb_regs[ 2] = regs->tf_r2;
203 gdb_regs[ 3] = regs->tf_r3;
204 gdb_regs[ 4] = regs->tf_r4;
205 gdb_regs[ 5] = regs->tf_r5;
206 gdb_regs[ 6] = regs->tf_r6;
207 gdb_regs[ 7] = regs->tf_r7;
208 gdb_regs[ 8] = regs->tf_r8;
209 gdb_regs[ 9] = regs->tf_r9;
210 gdb_regs[10] = regs->tf_r10;
211 gdb_regs[11] = regs->tf_r11;
212 gdb_regs[12] = regs->tf_r12;
213 gdb_regs[13] = regs->tf_r13;
214 gdb_regs[14] = regs->tf_r14;
215 gdb_regs[15] = regs->tf_r15;
216 gdb_regs[16] = regs->tf_spc;
217 gdb_regs[17] = regs->tf_pr;
218 __asm__ __volatile__("stc vbr, %0" : "=r"(r));
219 gdb_regs[19] = r;
220 gdb_regs[20] = regs->tf_mach;
221 gdb_regs[21] = regs->tf_macl;
222 gdb_regs[22] = regs->tf_ssr;
223
224 /* How treat register bank 1 ? */
225 }
226
227 /*
228 * Reverse the above.
229 */
230 void
231 kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
232 {
233
234 regs->tf_r0 = gdb_regs[ 0];
235 regs->tf_r1 = gdb_regs[ 1];
236 regs->tf_r2 = gdb_regs[ 2];
237 regs->tf_r3 = gdb_regs[ 3];
238 regs->tf_r4 = gdb_regs[ 4];
239 regs->tf_r5 = gdb_regs[ 5];
240 regs->tf_r6 = gdb_regs[ 6];
241 regs->tf_r7 = gdb_regs[ 7];
242 regs->tf_r8 = gdb_regs[ 8];
243 regs->tf_r9 = gdb_regs[ 9];
244 regs->tf_r10 = gdb_regs[10];
245 regs->tf_r11 = gdb_regs[11];
246 regs->tf_r12 = gdb_regs[12];
247 regs->tf_r13 = gdb_regs[13];
248 regs->tf_r14 = gdb_regs[14];
249 regs->tf_r15 = gdb_regs[15];
250 regs->tf_spc = gdb_regs[16];
251 regs->tf_pr = gdb_regs[17];
252 __asm__ __volatile__("ldc %0, vbr" :: "r"(gdb_regs[19]));
253 regs->tf_mach = gdb_regs[20];
254 regs->tf_macl = gdb_regs[21];
255 regs->tf_ssr = gdb_regs[22];
256 }
257
258 /*
259 * Trap into kgdb to wait for debugger to connect,
260 * noting on the console why nothing else is going on.
261 */
262 void
263 kgdb_connect(int verbose)
264 {
265
266 if (kgdb_dev < 0) {
267 printf("kgdb_dev=%d\n", kgdb_dev);
268 return;
269 }
270
271 if (verbose)
272 printf("kgdb waiting...");
273
274 __asm__ __volatile__("trapa %0" :: "i"(_SH_TRA_BREAK));
275
276 if (verbose)
277 printf("connected.\n");
278
279 kgdb_debug_panic = 1;
280 }
281
282 /*
283 * Decide what to do on panic.
284 * (This is called by panic, like Debugger())
285 */
286 void
287 kgdb_panic()
288 {
289
290 if (kgdb_dev >= 0 && kgdb_debug_panic) {
291 printf("entering kgdb\n");
292 kgdb_connect(kgdb_active == 0);
293 }
294 }
295