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