1 /* $NetBSD: kgdb_hppa.c,v 1.1 2002/06/05 01:04:20 fredette Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This software was developed by the Computer Systems Engineering group 8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * contributed to Berkeley. 10 * 11 * All advertising materials mentioning features or use of this software 12 * must display the following acknowledgement: 13 * This product includes software developed by the University of 14 * California, Lawrence Berkeley Laboratories. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 45 */ 46 47 /* 48 * Machine-dependent (hppa) part of the KGDB remote "stub" 49 */ 50 51 #include <sys/param.h> 52 #include <sys/kgdb.h> 53 54 #include <machine/frame.h> 55 #include <machine/trap.h> 56 57 /* 58 * Determine if the memory at va..(va+len) is valid. 59 */ 60 int 61 kgdb_acc(va, ulen) 62 vaddr_t va; 63 size_t ulen; 64 { 65 66 /* Just let the trap handler deal with it. */ 67 return (1); 68 } 69 70 /* 71 * Translate a trap number into a unix compatible signal value. 72 * (gdb only understands unix signal numbers). 73 */ 74 int 75 kgdb_signal(type) 76 int type; 77 { 78 int sigval; 79 80 switch (type) { 81 82 case T_HPMC: 83 case T_POWERFAIL: 84 case T_LPMC: 85 case T_INTERRUPT: 86 sigval = SIGINT; 87 break; 88 89 case T_NONEXIST: 90 case T_ILLEGAL: 91 case T_PRIV_OP: 92 case T_PRIV_REG: 93 case T_IPROT: 94 sigval = SIGILL; 95 break; 96 97 case T_IBREAK: 98 case T_DBREAK: 99 case T_TAKENBR: 100 case T_RECOVERY: 101 sigval = SIGTRAP; 102 break; 103 104 case T_EMULATION: 105 sigval = SIGEMT; 106 break; 107 108 case T_DATALIGN: 109 sigval = SIGBUS; 110 break; 111 112 case T_DATACC: 113 case T_DATAPID: 114 case T_ITLBMISS: 115 case T_DTLBMISS: 116 case T_ITLBMISSNA: 117 case T_DTLBMISSNA: 118 case T_DPROT: 119 sigval = SIGSEGV; 120 break; 121 122 #if 0 123 case T_OVERFLOW: /* overflow */ 124 case T_CONDITION: /* conditional */ 125 case T_EXCEPTION: /* assist exception */ 126 case T_TLB_DIRTY: /* TLB dirty bit */ 127 case T_PAGEREF: /* page reference */ 128 case T_HIGHERPL: /* higher-privelege transfer */ 129 case T_LOWERPL: /* lower-privilege transfer */ 130 #endif 131 default: 132 sigval = SIGILL; 133 break; 134 } 135 return (sigval); 136 } 137 138 /* 139 * Definitions exported from gdb. 140 */ 141 142 /* 143 * Translate the values stored in the kernel regs struct to/from 144 * the format understood by gdb. 145 * 146 * When configured for the PA, GDB is set up to expect a buffer 147 * of registers in the HP/UX struct save_state format, described 148 * in HP/UX's machine/save_state.h header. The register order is 149 * very different from our struct trapframe, so we have to do some 150 * moving around of values. 151 * 152 * The constants in the macro below should correspond to the 153 * register numbers in gdb's config/pa/tm-pa.h register macros. 154 */ 155 #define KGDB_MOVEREGS \ 156 /* 0 is the "save state flags", which gdb doesn't use */ \ 157 KGDB_MOVEREG(1, tf_r1); \ 158 KGDB_MOVEREG(2, tf_rp); /* r2 */ \ 159 KGDB_MOVEREG(3, tf_r3); /* frame pointer when -g */ \ 160 KGDB_MOVEREG(4, tf_r4); \ 161 KGDB_MOVEREG(5, tf_r5); \ 162 KGDB_MOVEREG(6, tf_r6); \ 163 KGDB_MOVEREG(7, tf_r7); \ 164 KGDB_MOVEREG(8, tf_r8); \ 165 KGDB_MOVEREG(9, tf_r9); \ 166 KGDB_MOVEREG(10, tf_r10); \ 167 KGDB_MOVEREG(11, tf_r11); \ 168 KGDB_MOVEREG(12, tf_r12); \ 169 KGDB_MOVEREG(13, tf_r13); \ 170 KGDB_MOVEREG(14, tf_r14); \ 171 KGDB_MOVEREG(15, tf_r15); \ 172 KGDB_MOVEREG(16, tf_r16); \ 173 KGDB_MOVEREG(17, tf_r17); \ 174 KGDB_MOVEREG(18, tf_r18); \ 175 KGDB_MOVEREG(19, tf_t4); /* r19 */ \ 176 KGDB_MOVEREG(20, tf_t3); /* r20 */ \ 177 KGDB_MOVEREG(21, tf_t2); /* r21 */ \ 178 KGDB_MOVEREG(22, tf_t1); /* r22 */ \ 179 KGDB_MOVEREG(23, tf_arg3); /* r23 */ \ 180 KGDB_MOVEREG(24, tf_arg2); /* r24 */ \ 181 KGDB_MOVEREG(25, tf_arg1); /* r25 */ \ 182 KGDB_MOVEREG(26, tf_arg0); /* r26 */ \ 183 KGDB_MOVEREG(27, tf_dp); /* r27 */ \ 184 KGDB_MOVEREG(28, tf_ret0); /* r28 */ \ 185 KGDB_MOVEREG(29, tf_ret1); /* r29 */ \ 186 KGDB_MOVEREG(30, tf_sp); /* r30 */ \ 187 KGDB_MOVEREG(31, tf_r31); \ 188 KGDB_MOVEREG(32, tf_sar); /* cr11 */ \ 189 KGDB_MOVEREG(33, tf_iioq_head); /* cr18 */ \ 190 KGDB_MOVEREG(34, tf_iisq_head); /* cr17 */ \ 191 KGDB_MOVEREG(35, tf_iioq_tail); \ 192 KGDB_MOVEREG(36, tf_iisq_tail); \ 193 KGDB_MOVEREG(37, tf_eiem); /* cr15 */ \ 194 KGDB_MOVEREG(38, tf_iir); /* cr19 */ \ 195 KGDB_MOVEREG(39, tf_isr); /* cr20 */ \ 196 KGDB_MOVEREG(40, tf_ior); /* cr21 */ \ 197 KGDB_MOVEREG(41, tf_ipsw); /* cr22 */ \ 198 /* 42 should be cr31, which we don't have available */ \ 199 KGDB_MOVEREG(43, tf_sr4); \ 200 KGDB_MOVEREG(44, tf_sr0); \ 201 KGDB_MOVEREG(45, tf_sr1); \ 202 KGDB_MOVEREG(46, tf_sr2); \ 203 KGDB_MOVEREG(47, tf_sr3); \ 204 KGDB_MOVEREG(48, tf_sr5); \ 205 KGDB_MOVEREG(49, tf_sr6); \ 206 KGDB_MOVEREG(50, tf_sr7); \ 207 KGDB_MOVEREG(51, tf_rctr); /* cr0 */ \ 208 KGDB_MOVEREG(52, tf_pidr1); /* cr8 */ \ 209 KGDB_MOVEREG(53, tf_pidr2); /* cr9 */ \ 210 KGDB_MOVEREG(54, tf_ccr); /* cr10 */ \ 211 KGDB_MOVEREG(55, tf_pidr3); /* cr12 */ \ 212 KGDB_MOVEREG(56, tf_pidr4); /* cr13 */ \ 213 KGDB_MOVEREG(57, tf_hptm); /* cr24 - DDB */ \ 214 KGDB_MOVEREG(58, tf_vtop); /* cr25 - DDB */ \ 215 /* 59 should be cr26, which we don't have available */ \ 216 /* 60 should be cr27, which we don't have available */ \ 217 KGDB_MOVEREG(61, tf_cr28); /* - DDB */ \ 218 /* 62 should be cr29, which we don't have available */ \ 219 KGDB_MOVEREG(63, tf_cr30) /* uaddr */ 220 221 void 222 kgdb_getregs(regs, gdb_regs) 223 db_regs_t *regs; 224 kgdb_reg_t *gdb_regs; 225 { 226 #define KGDB_MOVEREG(i, f) gdb_regs[i] = regs->f 227 KGDB_MOVEREGS; 228 #undef KGDB_MOVEREG 229 } 230 231 void 232 kgdb_setregs(regs, gdb_regs) 233 db_regs_t *regs; 234 kgdb_reg_t *gdb_regs; 235 { 236 #define KGDB_MOVEREG(i, f) regs->f = gdb_regs[i] 237 KGDB_MOVEREGS; 238 #undef KGDB_MOVEREG 239 } 240 241 /* 242 * Trap into kgdb to wait for debugger to connect, 243 * noting on the console why nothing else is going on. 244 */ 245 void 246 kgdb_connect(verbose) 247 int verbose; 248 { 249 250 if (kgdb_dev < 0) 251 return; 252 253 if (verbose) 254 printf("kgdb waiting..."); 255 256 __asm __volatile ("break %0, %1" 257 :: "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_KGDB)); 258 259 if (verbose) 260 printf("connected.\n"); 261 262 kgdb_debug_panic = 1; 263 } 264 265 /* 266 * Decide what to do on panic. 267 * (This is called by panic, like Debugger()) 268 */ 269 void 270 kgdb_panic() 271 { 272 if (kgdb_dev >= 0 && kgdb_debug_panic) { 273 printf("entering kgdb\n"); 274 kgdb_connect(kgdb_active == 0); 275 } 276 } 277