1 /* $NetBSD: kgdb_machdep.c,v 1.2 2001/11/20 08:43:19 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 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. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Machine-dependent functions for remote KGDB. 41 */ 42 43 #include "opt_kgdb.h" 44 45 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 46 47 __KERNEL_RCSID(0, "$NetBSD: kgdb_machdep.c,v 1.2 2001/11/20 08:43:19 lukem Exp $"); 48 49 #include "com.h" 50 51 #include <sys/param.h> 52 #include <sys/kgdb.h> 53 #include <sys/systm.h> 54 #include <sys/termios.h> 55 56 #include <machine/bus.h> 57 #include <machine/db_machdep.h> 58 59 #include <uvm/uvm_extern.h> 60 61 #if NCOM > 0 62 #include <dev/ic/comreg.h> 63 #include <dev/ic/comvar.h> 64 #endif /* NCOM > 0 */ 65 66 #ifndef KGDB_DEVNAME 67 #error Must define KGDB_DEVNAME 68 #endif 69 const char kgdb_devname[] = KGDB_DEVNAME; 70 71 #ifndef KGDB_DEVADDR 72 #error Must define KGDB_DEVADDR 73 #endif 74 int kgdb_devaddr = KGDB_DEVADDR; 75 76 #ifndef KGDB_DEVRATE 77 #define KGDB_DEVRATE TTYDEF_SPEED 78 #endif 79 int kgdb_devrate = KGDB_DEVRATE; 80 81 #ifndef KGDB_DEVMODE 82 /* 8N1 */ 83 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) 84 #endif 85 int kgdb_devmode = KGDB_DEVMODE; 86 87 /* 88 * alpha_kgdb_init: 89 * 90 * Initialize KGDB -- connect to the device. 91 */ 92 void 93 alpha_kgdb_init(const char **valid_devs, struct alpha_bus_space *bst) 94 { 95 int i; 96 97 for (i = 0; valid_devs[i] != NULL; i++) { 98 if (strcmp(kgdb_devname, valid_devs[i]) == 0) 99 break; 100 } 101 if (valid_devs[i] == NULL) { 102 printf("%s is not a valid KGDB device for this platform\n", 103 kgdb_devname); 104 return; 105 } 106 107 #if NCOM > 0 108 if (strcmp(kgdb_devname, "com") == 0) { 109 com_kgdb_attach(bst, kgdb_devaddr, kgdb_devrate, COM_FREQ, 110 kgdb_devmode); 111 return; 112 } 113 #endif /* NCOM > 0 */ 114 115 printf("The %s driver is not configured into the kernel; " 116 "KGDB not attached\n", kgdb_devname); 117 } 118 119 /* 120 * kgdb_acc: 121 * 122 * Determine if the mapping at va..(va+len) is valid. 123 */ 124 int 125 kgdb_acc(vaddr_t va, size_t len) 126 { 127 vaddr_t last_va; 128 pt_entry_t *pte; 129 130 va = trunc_page(va); 131 last_va = round_page(va + len); 132 133 do { 134 if (va < VM_MIN_KERNEL_ADDRESS) 135 return (0); 136 pte = pmap_l3pte(pmap_kernel(), va, NULL); 137 if (pte == NULL || pmap_pte_v(pte) == 0) 138 return (0); 139 va += PAGE_SIZE; 140 } while (va < last_va); 141 142 return (1); 143 } 144 145 /* 146 * kgdb_signal: 147 * 148 * Translate a trap number into a Unix-compatible signal number. 149 * (GDB only understands Unix signal numbers.) 150 */ 151 int 152 kgdb_signal(int type) 153 { 154 155 switch (type) { 156 case ALPHA_KENTRY_UNA: 157 return (SIGBUS); 158 159 case ALPHA_KENTRY_ARITH: 160 return (SIGFPE); 161 162 case ALPHA_KENTRY_IF: 163 return (SIGILL); 164 165 case ALPHA_KENTRY_MM: 166 return (SIGSEGV); 167 168 default: 169 return (SIGEMT); 170 } 171 } 172 173 /* 174 * kgdb_getregs: 175 * 176 * Translate the kernel debugger register format into 177 * the GDB register format. 178 */ 179 void 180 kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs) 181 { 182 183 memset(gdb_regs, 0, sizeof(kgdb_reg_t) * KGDB_NUMREGS); 184 185 gdb_regs[KGDB_REG_V0 ] = regs->tf_regs[FRAME_V0]; 186 gdb_regs[KGDB_REG_T0 ] = regs->tf_regs[FRAME_T0]; 187 gdb_regs[KGDB_REG_T1 ] = regs->tf_regs[FRAME_T1]; 188 gdb_regs[KGDB_REG_T2 ] = regs->tf_regs[FRAME_T2]; 189 gdb_regs[KGDB_REG_T3 ] = regs->tf_regs[FRAME_T3]; 190 gdb_regs[KGDB_REG_T4 ] = regs->tf_regs[FRAME_T4]; 191 gdb_regs[KGDB_REG_T5 ] = regs->tf_regs[FRAME_T5]; 192 gdb_regs[KGDB_REG_T6 ] = regs->tf_regs[FRAME_T6]; 193 gdb_regs[KGDB_REG_T7 ] = regs->tf_regs[FRAME_T7]; 194 gdb_regs[KGDB_REG_S0 ] = regs->tf_regs[FRAME_S0]; 195 gdb_regs[KGDB_REG_S1 ] = regs->tf_regs[FRAME_S1]; 196 gdb_regs[KGDB_REG_S2 ] = regs->tf_regs[FRAME_S2]; 197 gdb_regs[KGDB_REG_S3 ] = regs->tf_regs[FRAME_S3]; 198 gdb_regs[KGDB_REG_S4 ] = regs->tf_regs[FRAME_S4]; 199 gdb_regs[KGDB_REG_S5 ] = regs->tf_regs[FRAME_S5]; 200 gdb_regs[KGDB_REG_S6 ] = regs->tf_regs[FRAME_S6]; 201 gdb_regs[KGDB_REG_A0 ] = regs->tf_regs[FRAME_A0]; 202 gdb_regs[KGDB_REG_A1 ] = regs->tf_regs[FRAME_A1]; 203 gdb_regs[KGDB_REG_A2 ] = regs->tf_regs[FRAME_A2]; 204 gdb_regs[KGDB_REG_A3 ] = regs->tf_regs[FRAME_A3]; 205 gdb_regs[KGDB_REG_A4 ] = regs->tf_regs[FRAME_A4]; 206 gdb_regs[KGDB_REG_A5 ] = regs->tf_regs[FRAME_A5]; 207 gdb_regs[KGDB_REG_T8 ] = regs->tf_regs[FRAME_T8]; 208 gdb_regs[KGDB_REG_T9 ] = regs->tf_regs[FRAME_T9]; 209 gdb_regs[KGDB_REG_T10] = regs->tf_regs[FRAME_T10]; 210 gdb_regs[KGDB_REG_T11] = regs->tf_regs[FRAME_T11]; 211 gdb_regs[KGDB_REG_RA ] = regs->tf_regs[FRAME_RA]; 212 gdb_regs[KGDB_REG_T12] = regs->tf_regs[FRAME_T12]; 213 gdb_regs[KGDB_REG_AT ] = regs->tf_regs[FRAME_AT]; 214 gdb_regs[KGDB_REG_GP ] = regs->tf_regs[FRAME_GP]; 215 gdb_regs[KGDB_REG_SP ] = regs->tf_regs[FRAME_SP]; 216 gdb_regs[KGDB_REG_PC ] = regs->tf_regs[FRAME_PC]; 217 } 218 219 /* 220 * kgdb_setregs: 221 * 222 * Translate the GDB register format into the kernel 223 * debugger register format. 224 */ 225 void 226 kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs) 227 { 228 229 regs->tf_regs[FRAME_V0 ] = gdb_regs[KGDB_REG_V0]; 230 regs->tf_regs[FRAME_T0 ] = gdb_regs[KGDB_REG_T0]; 231 regs->tf_regs[FRAME_T1 ] = gdb_regs[KGDB_REG_T1]; 232 regs->tf_regs[FRAME_T2 ] = gdb_regs[KGDB_REG_T2]; 233 regs->tf_regs[FRAME_T3 ] = gdb_regs[KGDB_REG_T3]; 234 regs->tf_regs[FRAME_T4 ] = gdb_regs[KGDB_REG_T4]; 235 regs->tf_regs[FRAME_T5 ] = gdb_regs[KGDB_REG_T5]; 236 regs->tf_regs[FRAME_T6 ] = gdb_regs[KGDB_REG_T6]; 237 regs->tf_regs[FRAME_T7 ] = gdb_regs[KGDB_REG_T7]; 238 regs->tf_regs[FRAME_S0 ] = gdb_regs[KGDB_REG_S0]; 239 regs->tf_regs[FRAME_S1 ] = gdb_regs[KGDB_REG_S1]; 240 regs->tf_regs[FRAME_S2 ] = gdb_regs[KGDB_REG_S2]; 241 regs->tf_regs[FRAME_S3 ] = gdb_regs[KGDB_REG_S3]; 242 regs->tf_regs[FRAME_S4 ] = gdb_regs[KGDB_REG_S4]; 243 regs->tf_regs[FRAME_S5 ] = gdb_regs[KGDB_REG_S5]; 244 regs->tf_regs[FRAME_S6 ] = gdb_regs[KGDB_REG_S6]; 245 regs->tf_regs[FRAME_A0 ] = gdb_regs[KGDB_REG_A0]; 246 regs->tf_regs[FRAME_A1 ] = gdb_regs[KGDB_REG_A1]; 247 regs->tf_regs[FRAME_A2 ] = gdb_regs[KGDB_REG_A2]; 248 regs->tf_regs[FRAME_A3 ] = gdb_regs[KGDB_REG_A3]; 249 regs->tf_regs[FRAME_A4 ] = gdb_regs[KGDB_REG_A4]; 250 regs->tf_regs[FRAME_A5 ] = gdb_regs[KGDB_REG_A5]; 251 regs->tf_regs[FRAME_T8 ] = gdb_regs[KGDB_REG_T8]; 252 regs->tf_regs[FRAME_T9 ] = gdb_regs[KGDB_REG_T9]; 253 regs->tf_regs[FRAME_T10] = gdb_regs[KGDB_REG_T10]; 254 regs->tf_regs[FRAME_T11] = gdb_regs[KGDB_REG_T11]; 255 regs->tf_regs[FRAME_RA ] = gdb_regs[KGDB_REG_RA]; 256 regs->tf_regs[FRAME_T12] = gdb_regs[KGDB_REG_T12]; 257 regs->tf_regs[FRAME_AT ] = gdb_regs[KGDB_REG_AT]; 258 regs->tf_regs[FRAME_GP ] = gdb_regs[KGDB_REG_GP]; 259 regs->tf_regs[FRAME_SP ] = gdb_regs[KGDB_REG_SP]; 260 regs->tf_regs[FRAME_PC ] = gdb_regs[KGDB_REG_PC]; 261 } 262 263 /* 264 * kgdb_connect: 265 * 266 * Trap into KGDB and wait for the remote debugger to 267 * connect. Display a message on the console indicating 268 * why nothing else is happening. 269 */ 270 void 271 kgdb_connect(int verbose) 272 { 273 274 if (kgdb_dev < 0) 275 return; 276 277 if (verbose) 278 printf("kgdb waiting..."); 279 280 __asm __volatile("call_pal 0x81"); /* bugchk */ 281 282 if (verbose) 283 printf("connected.\n"); 284 285 kgdb_debug_panic = 1; 286 } 287 288 /* 289 * kgdb_panic: 290 * 291 * Decide what to do on panic. (This is called by panic(), 292 * like Debugger().) 293 */ 294 void 295 kgdb_panic(void) 296 { 297 if (kgdb_dev >= 0 && kgdb_debug_panic) { 298 printf("entering kgdb\n"); 299 kgdb_connect(kgdb_active == 0); 300 } 301 } 302