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