kgdb_hppa.c revision 1.2
1/* $NetBSD: kgdb_hppa.c,v 1.2 2003/07/15 02:29:39 lukem 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/cdefs.h> 52__KERNEL_RCSID(0, "$NetBSD: kgdb_hppa.c,v 1.2 2003/07/15 02:29:39 lukem Exp $"); 53 54#include <sys/param.h> 55#include <sys/kgdb.h> 56 57#include <machine/frame.h> 58#include <machine/trap.h> 59 60/* 61 * Determine if the memory at va..(va+len) is valid. 62 */ 63int 64kgdb_acc(va, ulen) 65 vaddr_t va; 66 size_t ulen; 67{ 68 69 /* Just let the trap handler deal with it. */ 70 return (1); 71} 72 73/* 74 * Translate a trap number into a unix compatible signal value. 75 * (gdb only understands unix signal numbers). 76 */ 77int 78kgdb_signal(type) 79 int type; 80{ 81 int sigval; 82 83 switch (type) { 84 85 case T_HPMC: 86 case T_POWERFAIL: 87 case T_LPMC: 88 case T_INTERRUPT: 89 sigval = SIGINT; 90 break; 91 92 case T_NONEXIST: 93 case T_ILLEGAL: 94 case T_PRIV_OP: 95 case T_PRIV_REG: 96 case T_IPROT: 97 sigval = SIGILL; 98 break; 99 100 case T_IBREAK: 101 case T_DBREAK: 102 case T_TAKENBR: 103 case T_RECOVERY: 104 sigval = SIGTRAP; 105 break; 106 107 case T_EMULATION: 108 sigval = SIGEMT; 109 break; 110 111 case T_DATALIGN: 112 sigval = SIGBUS; 113 break; 114 115 case T_DATACC: 116 case T_DATAPID: 117 case T_ITLBMISS: 118 case T_DTLBMISS: 119 case T_ITLBMISSNA: 120 case T_DTLBMISSNA: 121 case T_DPROT: 122 sigval = SIGSEGV; 123 break; 124 125#if 0 126 case T_OVERFLOW: /* overflow */ 127 case T_CONDITION: /* conditional */ 128 case T_EXCEPTION: /* assist exception */ 129 case T_TLB_DIRTY: /* TLB dirty bit */ 130 case T_PAGEREF: /* page reference */ 131 case T_HIGHERPL: /* higher-privelege transfer */ 132 case T_LOWERPL: /* lower-privilege transfer */ 133#endif 134 default: 135 sigval = SIGILL; 136 break; 137 } 138 return (sigval); 139} 140 141/* 142 * Definitions exported from gdb. 143 */ 144 145/* 146 * Translate the values stored in the kernel regs struct to/from 147 * the format understood by gdb. 148 * 149 * When configured for the PA, GDB is set up to expect a buffer 150 * of registers in the HP/UX struct save_state format, described 151 * in HP/UX's machine/save_state.h header. The register order is 152 * very different from our struct trapframe, so we have to do some 153 * moving around of values. 154 * 155 * The constants in the macro below should correspond to the 156 * register numbers in gdb's config/pa/tm-pa.h register macros. 157 */ 158#define KGDB_MOVEREGS \ 159 /* 0 is the "save state flags", which gdb doesn't use */ \ 160 KGDB_MOVEREG(1, tf_r1); \ 161 KGDB_MOVEREG(2, tf_rp); /* r2 */ \ 162 KGDB_MOVEREG(3, tf_r3); /* frame pointer when -g */ \ 163 KGDB_MOVEREG(4, tf_r4); \ 164 KGDB_MOVEREG(5, tf_r5); \ 165 KGDB_MOVEREG(6, tf_r6); \ 166 KGDB_MOVEREG(7, tf_r7); \ 167 KGDB_MOVEREG(8, tf_r8); \ 168 KGDB_MOVEREG(9, tf_r9); \ 169 KGDB_MOVEREG(10, tf_r10); \ 170 KGDB_MOVEREG(11, tf_r11); \ 171 KGDB_MOVEREG(12, tf_r12); \ 172 KGDB_MOVEREG(13, tf_r13); \ 173 KGDB_MOVEREG(14, tf_r14); \ 174 KGDB_MOVEREG(15, tf_r15); \ 175 KGDB_MOVEREG(16, tf_r16); \ 176 KGDB_MOVEREG(17, tf_r17); \ 177 KGDB_MOVEREG(18, tf_r18); \ 178 KGDB_MOVEREG(19, tf_t4); /* r19 */ \ 179 KGDB_MOVEREG(20, tf_t3); /* r20 */ \ 180 KGDB_MOVEREG(21, tf_t2); /* r21 */ \ 181 KGDB_MOVEREG(22, tf_t1); /* r22 */ \ 182 KGDB_MOVEREG(23, tf_arg3); /* r23 */ \ 183 KGDB_MOVEREG(24, tf_arg2); /* r24 */ \ 184 KGDB_MOVEREG(25, tf_arg1); /* r25 */ \ 185 KGDB_MOVEREG(26, tf_arg0); /* r26 */ \ 186 KGDB_MOVEREG(27, tf_dp); /* r27 */ \ 187 KGDB_MOVEREG(28, tf_ret0); /* r28 */ \ 188 KGDB_MOVEREG(29, tf_ret1); /* r29 */ \ 189 KGDB_MOVEREG(30, tf_sp); /* r30 */ \ 190 KGDB_MOVEREG(31, tf_r31); \ 191 KGDB_MOVEREG(32, tf_sar); /* cr11 */ \ 192 KGDB_MOVEREG(33, tf_iioq_head); /* cr18 */ \ 193 KGDB_MOVEREG(34, tf_iisq_head); /* cr17 */ \ 194 KGDB_MOVEREG(35, tf_iioq_tail); \ 195 KGDB_MOVEREG(36, tf_iisq_tail); \ 196 KGDB_MOVEREG(37, tf_eiem); /* cr15 */ \ 197 KGDB_MOVEREG(38, tf_iir); /* cr19 */ \ 198 KGDB_MOVEREG(39, tf_isr); /* cr20 */ \ 199 KGDB_MOVEREG(40, tf_ior); /* cr21 */ \ 200 KGDB_MOVEREG(41, tf_ipsw); /* cr22 */ \ 201 /* 42 should be cr31, which we don't have available */ \ 202 KGDB_MOVEREG(43, tf_sr4); \ 203 KGDB_MOVEREG(44, tf_sr0); \ 204 KGDB_MOVEREG(45, tf_sr1); \ 205 KGDB_MOVEREG(46, tf_sr2); \ 206 KGDB_MOVEREG(47, tf_sr3); \ 207 KGDB_MOVEREG(48, tf_sr5); \ 208 KGDB_MOVEREG(49, tf_sr6); \ 209 KGDB_MOVEREG(50, tf_sr7); \ 210 KGDB_MOVEREG(51, tf_rctr); /* cr0 */ \ 211 KGDB_MOVEREG(52, tf_pidr1); /* cr8 */ \ 212 KGDB_MOVEREG(53, tf_pidr2); /* cr9 */ \ 213 KGDB_MOVEREG(54, tf_ccr); /* cr10 */ \ 214 KGDB_MOVEREG(55, tf_pidr3); /* cr12 */ \ 215 KGDB_MOVEREG(56, tf_pidr4); /* cr13 */ \ 216 KGDB_MOVEREG(57, tf_hptm); /* cr24 - DDB */ \ 217 KGDB_MOVEREG(58, tf_vtop); /* cr25 - DDB */ \ 218 /* 59 should be cr26, which we don't have available */ \ 219 /* 60 should be cr27, which we don't have available */ \ 220 KGDB_MOVEREG(61, tf_cr28); /* - DDB */ \ 221 /* 62 should be cr29, which we don't have available */ \ 222 KGDB_MOVEREG(63, tf_cr30) /* uaddr */ 223 224void 225kgdb_getregs(regs, gdb_regs) 226 db_regs_t *regs; 227 kgdb_reg_t *gdb_regs; 228{ 229#define KGDB_MOVEREG(i, f) gdb_regs[i] = regs->f 230 KGDB_MOVEREGS; 231#undef KGDB_MOVEREG 232} 233 234void 235kgdb_setregs(regs, gdb_regs) 236 db_regs_t *regs; 237 kgdb_reg_t *gdb_regs; 238{ 239#define KGDB_MOVEREG(i, f) regs->f = gdb_regs[i] 240 KGDB_MOVEREGS; 241#undef KGDB_MOVEREG 242} 243 244/* 245 * Trap into kgdb to wait for debugger to connect, 246 * noting on the console why nothing else is going on. 247 */ 248void 249kgdb_connect(verbose) 250 int verbose; 251{ 252 253 if (kgdb_dev < 0) 254 return; 255 256 if (verbose) 257 printf("kgdb waiting..."); 258 259 __asm __volatile ("break %0, %1" 260 :: "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_KGDB)); 261 262 if (verbose) 263 printf("connected.\n"); 264 265 kgdb_debug_panic = 1; 266} 267 268/* 269 * Decide what to do on panic. 270 * (This is called by panic, like Debugger()) 271 */ 272void 273kgdb_panic() 274{ 275 if (kgdb_dev >= 0 && kgdb_debug_panic) { 276 printf("entering kgdb\n"); 277 kgdb_connect(kgdb_active == 0); 278 } 279} 280