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