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