/* $NetBSD: kgdb_hppa.c,v 1.11 2023/09/03 20:52:13 andvar Exp $ */ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 */ /* * Machine-dependent (hppa) part of the KGDB remote "stub" */ #include __KERNEL_RCSID(0, "$NetBSD: kgdb_hppa.c,v 1.11 2023/09/03 20:52:13 andvar Exp $"); #include #include #include #include /* * Determine if the memory at va..(va+len) is valid. */ int kgdb_acc(vaddr_t va, size_t ulen) { /* Just let the trap handler deal with it. */ return 1; } /* * Translate a trap number into a unix compatible signal value. * (gdb only understands unix signal numbers). */ int kgdb_signal(int type) { int sigval; switch (type) { case T_HPMC: case T_POWERFAIL: case T_LPMC: case T_INTERRUPT: sigval = SIGINT; break; case T_NONEXIST: case T_ILLEGAL: case T_PRIV_OP: case T_PRIV_REG: case T_IPROT: sigval = SIGILL; break; case T_IBREAK: case T_DBREAK: case T_TAKENBR: case T_RECOVERY: sigval = SIGTRAP; break; case T_EMULATION: sigval = SIGEMT; break; case T_DATALIGN: sigval = SIGBUS; break; case T_DATACC: case T_DATAPID: case T_ITLBMISS: case T_DTLBMISS: case T_ITLBMISSNA: case T_DTLBMISSNA: case T_DPROT: sigval = SIGSEGV; break; #if 0 case T_OVERFLOW: /* overflow */ case T_CONDITION: /* conditional */ case T_EXCEPTION: /* assist exception */ case T_TLB_DIRTY: /* TLB dirty bit */ case T_PAGEREF: /* page reference */ case T_HIGHERPL: /* higher-privilege transfer */ case T_LOWERPL: /* lower-privilege transfer */ #endif default: sigval = SIGILL; break; } return sigval; } /* * Definitions exported from gdb. */ /* * Translate the values stored in the kernel regs struct to/from * the format understood by gdb. * * When configured for the PA, GDB is set up to expect a buffer * of registers in the HP/UX struct save_state format, described * in HP/UX's machine/save_state.h header. The register order is * very different from our struct trapframe, so we have to do some * moving around of values. * * The constants in the macro below should correspond to the * register numbers in gdb's config/pa/tm-pa.h register macros. */ #define KGDB_MOVEREGS \ /* 0 is the "save state flags", which gdb doesn't use */ \ KGDB_MOVEREG(1, tf_r1); \ KGDB_MOVEREG(2, tf_rp); /* r2 */ \ KGDB_MOVEREG(3, tf_r3); /* frame pointer when -g */ \ KGDB_MOVEREG(4, tf_r4); \ KGDB_MOVEREG(5, tf_r5); \ KGDB_MOVEREG(6, tf_r6); \ KGDB_MOVEREG(7, tf_r7); \ KGDB_MOVEREG(8, tf_r8); \ KGDB_MOVEREG(9, tf_r9); \ KGDB_MOVEREG(10, tf_r10); \ KGDB_MOVEREG(11, tf_r11); \ KGDB_MOVEREG(12, tf_r12); \ KGDB_MOVEREG(13, tf_r13); \ KGDB_MOVEREG(14, tf_r14); \ KGDB_MOVEREG(15, tf_r15); \ KGDB_MOVEREG(16, tf_r16); \ KGDB_MOVEREG(17, tf_r17); \ KGDB_MOVEREG(18, tf_r18); \ KGDB_MOVEREG(19, tf_t4); /* r19 */ \ KGDB_MOVEREG(20, tf_t3); /* r20 */ \ KGDB_MOVEREG(21, tf_t2); /* r21 */ \ KGDB_MOVEREG(22, tf_t1); /* r22 */ \ KGDB_MOVEREG(23, tf_arg3); /* r23 */ \ KGDB_MOVEREG(24, tf_arg2); /* r24 */ \ KGDB_MOVEREG(25, tf_arg1); /* r25 */ \ KGDB_MOVEREG(26, tf_arg0); /* r26 */ \ KGDB_MOVEREG(27, tf_dp); /* r27 */ \ KGDB_MOVEREG(28, tf_ret0); /* r28 */ \ KGDB_MOVEREG(29, tf_ret1); /* r29 */ \ KGDB_MOVEREG(30, tf_sp); /* r30 */ \ KGDB_MOVEREG(31, tf_r31); \ KGDB_MOVEREG(32, tf_sar); /* cr11 */ \ KGDB_MOVEREG(33, tf_iioq_head); /* cr18 */ \ KGDB_MOVEREG(34, tf_iisq_head); /* cr17 */ \ KGDB_MOVEREG(35, tf_iioq_tail); \ KGDB_MOVEREG(36, tf_iisq_tail); \ KGDB_MOVEREG(37, tf_eiem); /* cr15 */ \ KGDB_MOVEREG(38, tf_iir); /* cr19 */ \ KGDB_MOVEREG(39, tf_isr); /* cr20 */ \ KGDB_MOVEREG(40, tf_ior); /* cr21 */ \ KGDB_MOVEREG(41, tf_ipsw); /* cr22 */ \ /* 42 should be cr31, which we don't have available */ \ KGDB_MOVEREG(43, tf_sr4); \ KGDB_MOVEREG(44, tf_sr0); \ KGDB_MOVEREG(45, tf_sr1); \ KGDB_MOVEREG(46, tf_sr2); \ KGDB_MOVEREG(47, tf_sr3); \ KGDB_MOVEREG(48, tf_sr5); \ KGDB_MOVEREG(49, tf_sr6); \ KGDB_MOVEREG(50, tf_sr7); \ KGDB_MOVEREG(51, tf_rctr); /* cr0 */ \ KGDB_MOVEREG(52, tf_pidr1); /* cr8 */ \ KGDB_MOVEREG(53, tf_pidr2); /* cr9 */ \ KGDB_MOVEREG(54, tf_ccr); /* cr10 */ \ KGDB_MOVEREG(55, tf_pidr3); /* cr12 */ \ KGDB_MOVEREG(56, tf_pidr4); /* cr13 */ \ KGDB_MOVEREG(57, tf_cr24); /* cr24 - DDB */ \ KGDB_MOVEREG(58, tf_vtop); /* cr25 - DDB */ \ /* 59 should be cr26, which we don't have available */ \ KGDB_MOVEREG(60, tf_cr27); /* - DDB */ \ KGDB_MOVEREG(61, tf_cr28); /* - DDB */ \ /* 62 should be cr29, which we don't have available */ \ KGDB_MOVEREG(63, tf_cr30) /* uaddr */ void kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs) { #define KGDB_MOVEREG(i, f) gdb_regs[i] = regs->f KGDB_MOVEREGS; #undef KGDB_MOVEREG } void kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs) { #define KGDB_MOVEREG(i, f) regs->f = gdb_regs[i] KGDB_MOVEREGS; #undef KGDB_MOVEREG } /* * Trap into kgdb to wait for debugger to connect, * noting on the console why nothing else is going on. */ void kgdb_connect(int verbose) { if (kgdb_dev < 0) return; if (verbose) printf("kgdb waiting..."); __asm volatile ("break %0, %1" :: "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_KGDB)); if (verbose) printf("connected.\n"); kgdb_debug_panic = 1; } /* * Decide what to do on panic. * (This is called by panic, like Debugger()) */ void kgdb_panic(void) { if (kgdb_dev >= 0 && kgdb_debug_panic) { printf("entering kgdb\n"); kgdb_connect(kgdb_active == 0); } }