kgdb_hppa.c revision 1.8
11.8Sskrll/*	$NetBSD: kgdb_hppa.c,v 1.8 2011/01/22 19:35:48 skrll Exp $	*/
21.1Sfredette
31.1Sfredette/*
41.1Sfredette * Copyright (c) 1990, 1993
51.1Sfredette *	The Regents of the University of California.  All rights reserved.
61.1Sfredette *
71.1Sfredette * This software was developed by the Computer Systems Engineering group
81.1Sfredette * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
91.1Sfredette * contributed to Berkeley.
101.1Sfredette *
111.1Sfredette * All advertising materials mentioning features or use of this software
121.1Sfredette * must display the following acknowledgement:
131.1Sfredette *	This product includes software developed by the University of
141.1Sfredette *	California, Lawrence Berkeley Laboratories.
151.1Sfredette *
161.1Sfredette * Redistribution and use in source and binary forms, with or without
171.1Sfredette * modification, are permitted provided that the following conditions
181.1Sfredette * are met:
191.1Sfredette * 1. Redistributions of source code must retain the above copyright
201.1Sfredette *    notice, this list of conditions and the following disclaimer.
211.1Sfredette * 2. Redistributions in binary form must reproduce the above copyright
221.1Sfredette *    notice, this list of conditions and the following disclaimer in the
231.1Sfredette *    documentation and/or other materials provided with the distribution.
241.3Sagc * 3. Neither the name of the University nor the names of its contributors
251.1Sfredette *    may be used to endorse or promote products derived from this software
261.1Sfredette *    without specific prior written permission.
271.1Sfredette *
281.1Sfredette * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
291.1Sfredette * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
301.1Sfredette * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
311.1Sfredette * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
321.1Sfredette * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
331.1Sfredette * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
341.1Sfredette * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
351.1Sfredette * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
361.1Sfredette * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
371.1Sfredette * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
381.1Sfredette * SUCH DAMAGE.
391.1Sfredette *
401.1Sfredette *	@(#)kgdb_stub.c	8.4 (Berkeley) 1/12/94
411.1Sfredette */
421.1Sfredette
431.1Sfredette/*
441.1Sfredette * Machine-dependent (hppa) part of the KGDB remote "stub"
451.1Sfredette */
461.2Slukem
471.2Slukem#include <sys/cdefs.h>
481.8Sskrll__KERNEL_RCSID(0, "$NetBSD: kgdb_hppa.c,v 1.8 2011/01/22 19:35:48 skrll Exp $");
491.1Sfredette
501.1Sfredette#include <sys/param.h>
511.1Sfredette#include <sys/kgdb.h>
521.1Sfredette
531.1Sfredette#include <machine/frame.h>
541.1Sfredette#include <machine/trap.h>
551.1Sfredette
561.1Sfredette/*
571.1Sfredette * Determine if the memory at va..(va+len) is valid.
581.1Sfredette */
591.1Sfredetteint
601.4Schskgdb_acc(vaddr_t va, size_t ulen)
611.1Sfredette{
621.1Sfredette
631.1Sfredette	/* Just let the trap handler deal with it. */
641.7Sskrll	return 1;
651.1Sfredette}
661.1Sfredette
671.1Sfredette/*
681.1Sfredette * Translate a trap number into a unix compatible signal value.
691.1Sfredette * (gdb only understands unix signal numbers).
701.1Sfredette */
711.1Sfredetteint
721.4Schskgdb_signal(int type)
731.1Sfredette{
741.1Sfredette	int sigval;
751.1Sfredette
761.1Sfredette	switch (type) {
771.1Sfredette
781.1Sfredette	case T_HPMC:
791.1Sfredette	case T_POWERFAIL:
801.1Sfredette	case T_LPMC:
811.1Sfredette	case T_INTERRUPT:
821.1Sfredette		sigval = SIGINT;
831.1Sfredette		break;
841.1Sfredette
851.1Sfredette	case T_NONEXIST:
861.1Sfredette	case T_ILLEGAL:
871.1Sfredette	case T_PRIV_OP:
881.1Sfredette	case T_PRIV_REG:
891.1Sfredette	case T_IPROT:
901.1Sfredette		sigval = SIGILL;
911.1Sfredette		break;
921.1Sfredette
931.1Sfredette	case T_IBREAK:
941.1Sfredette	case T_DBREAK:
951.1Sfredette	case T_TAKENBR:
961.1Sfredette	case T_RECOVERY:
971.1Sfredette		sigval = SIGTRAP;
981.1Sfredette		break;
991.1Sfredette
1001.1Sfredette	case T_EMULATION:
1011.1Sfredette		sigval = SIGEMT;
1021.1Sfredette		break;
1031.1Sfredette
1041.1Sfredette	case T_DATALIGN:
1051.1Sfredette		sigval = SIGBUS;
1061.1Sfredette		break;
1071.1Sfredette
1081.1Sfredette	case T_DATACC:
1091.1Sfredette	case T_DATAPID:
1101.1Sfredette	case T_ITLBMISS:
1111.1Sfredette	case T_DTLBMISS:
1121.1Sfredette	case T_ITLBMISSNA:
1131.1Sfredette	case T_DTLBMISSNA:
1141.1Sfredette	case T_DPROT:
1151.1Sfredette		sigval = SIGSEGV;
1161.1Sfredette		break;
1171.1Sfredette
1181.1Sfredette#if 0
1191.1Sfredette	case T_OVERFLOW:	/* overflow */
1201.1Sfredette	case T_CONDITION:	/* conditional */
1211.1Sfredette	case T_EXCEPTION:	/* assist exception */
1221.1Sfredette	case T_TLB_DIRTY:	/* TLB dirty bit */
1231.1Sfredette	case T_PAGEREF:		/* page reference */
1241.1Sfredette	case T_HIGHERPL:	/* higher-privelege transfer */
1251.1Sfredette	case T_LOWERPL:		/* lower-privilege transfer */
1261.1Sfredette#endif
1271.1Sfredette	default:
1281.1Sfredette		sigval = SIGILL;
1291.1Sfredette		break;
1301.1Sfredette	}
1311.7Sskrll	return sigval;
1321.1Sfredette}
1331.1Sfredette
1341.1Sfredette/*
1351.1Sfredette * Definitions exported from gdb.
1361.1Sfredette */
1371.1Sfredette
1381.1Sfredette/*
1391.1Sfredette * Translate the values stored in the kernel regs struct to/from
1401.1Sfredette * the format understood by gdb.
1411.1Sfredette *
1421.1Sfredette * When configured for the PA, GDB is set up to expect a buffer
1431.1Sfredette * of registers in the HP/UX struct save_state format, described
1441.1Sfredette * in HP/UX's machine/save_state.h header.  The register order is
1451.1Sfredette * very different from our struct trapframe, so we have to do some
1461.1Sfredette * moving around of values.
1471.1Sfredette *
1481.1Sfredette * The constants in the macro below should correspond to the
1491.1Sfredette * register numbers in gdb's config/pa/tm-pa.h register macros.
1501.1Sfredette */
1511.1Sfredette#define KGDB_MOVEREGS						\
1521.1Sfredette	/* 0 is the "save state flags", which gdb doesn't use */	\
1531.1Sfredette	KGDB_MOVEREG(1, tf_r1);					\
1541.1Sfredette	KGDB_MOVEREG(2, tf_rp);          /* r2 */		\
1551.1Sfredette	KGDB_MOVEREG(3, tf_r3);          /* frame pointer when -g */	\
1561.1Sfredette	KGDB_MOVEREG(4, tf_r4);					\
1571.1Sfredette	KGDB_MOVEREG(5, tf_r5);					\
1581.1Sfredette	KGDB_MOVEREG(6, tf_r6);					\
1591.1Sfredette	KGDB_MOVEREG(7, tf_r7);					\
1601.1Sfredette	KGDB_MOVEREG(8, tf_r8);					\
1611.1Sfredette	KGDB_MOVEREG(9, tf_r9);					\
1621.1Sfredette	KGDB_MOVEREG(10, tf_r10);				\
1631.1Sfredette	KGDB_MOVEREG(11, tf_r11);				\
1641.1Sfredette	KGDB_MOVEREG(12, tf_r12);				\
1651.1Sfredette	KGDB_MOVEREG(13, tf_r13);				\
1661.1Sfredette	KGDB_MOVEREG(14, tf_r14);				\
1671.1Sfredette	KGDB_MOVEREG(15, tf_r15);				\
1681.1Sfredette	KGDB_MOVEREG(16, tf_r16);				\
1691.1Sfredette	KGDB_MOVEREG(17, tf_r17);				\
1701.1Sfredette	KGDB_MOVEREG(18, tf_r18);				\
1711.1Sfredette	KGDB_MOVEREG(19, tf_t4);	/* r19 */		\
1721.1Sfredette	KGDB_MOVEREG(20, tf_t3);	/* r20 */		\
1731.1Sfredette	KGDB_MOVEREG(21, tf_t2);	/* r21 */		\
1741.1Sfredette	KGDB_MOVEREG(22, tf_t1);	/* r22 */		\
1751.1Sfredette	KGDB_MOVEREG(23, tf_arg3);	/* r23 */		\
1761.1Sfredette	KGDB_MOVEREG(24, tf_arg2);	/* r24 */		\
1771.1Sfredette	KGDB_MOVEREG(25, tf_arg1);	/* r25 */		\
1781.1Sfredette	KGDB_MOVEREG(26, tf_arg0);	/* r26 */		\
1791.1Sfredette	KGDB_MOVEREG(27, tf_dp);	/* r27 */		\
1801.1Sfredette	KGDB_MOVEREG(28, tf_ret0);	/* r28 */		\
1811.1Sfredette	KGDB_MOVEREG(29, tf_ret1);	/* r29 */		\
1821.1Sfredette	KGDB_MOVEREG(30, tf_sp);	/* r30 */		\
1831.1Sfredette	KGDB_MOVEREG(31, tf_r31);				\
1841.1Sfredette	KGDB_MOVEREG(32, tf_sar);	/* cr11 */		\
1851.1Sfredette	KGDB_MOVEREG(33, tf_iioq_head);	/* cr18 */		\
1861.1Sfredette	KGDB_MOVEREG(34, tf_iisq_head);	/* cr17 */		\
1871.1Sfredette	KGDB_MOVEREG(35, tf_iioq_tail);				\
1881.1Sfredette	KGDB_MOVEREG(36, tf_iisq_tail);				\
1891.1Sfredette	KGDB_MOVEREG(37, tf_eiem);	/* cr15 */		\
1901.1Sfredette	KGDB_MOVEREG(38, tf_iir);	/* cr19 */		\
1911.1Sfredette	KGDB_MOVEREG(39, tf_isr);	/* cr20 */		\
1921.1Sfredette	KGDB_MOVEREG(40, tf_ior);	/* cr21 */		\
1931.1Sfredette	KGDB_MOVEREG(41, tf_ipsw);	/* cr22 */		\
1941.1Sfredette	/* 42 should be cr31, which we don't have available */	\
1951.1Sfredette	KGDB_MOVEREG(43, tf_sr4);				\
1961.1Sfredette	KGDB_MOVEREG(44, tf_sr0);				\
1971.1Sfredette	KGDB_MOVEREG(45, tf_sr1);				\
1981.1Sfredette	KGDB_MOVEREG(46, tf_sr2);				\
1991.1Sfredette	KGDB_MOVEREG(47, tf_sr3);				\
2001.1Sfredette	KGDB_MOVEREG(48, tf_sr5);				\
2011.1Sfredette	KGDB_MOVEREG(49, tf_sr6);				\
2021.1Sfredette	KGDB_MOVEREG(50, tf_sr7);				\
2031.1Sfredette	KGDB_MOVEREG(51, tf_rctr);	/* cr0 */		\
2041.1Sfredette	KGDB_MOVEREG(52, tf_pidr1);	/* cr8 */		\
2051.1Sfredette	KGDB_MOVEREG(53, tf_pidr2);	/* cr9 */		\
2061.1Sfredette	KGDB_MOVEREG(54, tf_ccr);	/* cr10 */		\
2071.1Sfredette	KGDB_MOVEREG(55, tf_pidr3);	/* cr12 */		\
2081.1Sfredette	KGDB_MOVEREG(56, tf_pidr4);	/* cr13 */		\
2091.1Sfredette	KGDB_MOVEREG(57, tf_hptm);	/* cr24 - DDB */	\
2101.1Sfredette	KGDB_MOVEREG(58, tf_vtop);	/* cr25 - DDB */	\
2111.1Sfredette	/* 59 should be cr26, which we don't have available */	\
2121.8Sskrll	KGDB_MOVEREG(60, tf_cr27);	/*      - DDB */	\
2131.1Sfredette	KGDB_MOVEREG(61, tf_cr28);	/*      - DDB */	\
2141.1Sfredette	/* 62 should be cr29, which we don't have available */	\
2151.1Sfredette	KGDB_MOVEREG(63, tf_cr30)	/* uaddr */
2161.1Sfredette
2171.1Sfredettevoid
2181.4Schskgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
2191.1Sfredette{
2201.1Sfredette#define	KGDB_MOVEREG(i, f) gdb_regs[i] = regs->f
2211.1Sfredette	KGDB_MOVEREGS;
2221.1Sfredette#undef	KGDB_MOVEREG
2231.1Sfredette}
2241.1Sfredette
2251.1Sfredettevoid
2261.4Schskgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
2271.1Sfredette{
2281.1Sfredette#define	KGDB_MOVEREG(i, f) regs->f = gdb_regs[i]
2291.1Sfredette	KGDB_MOVEREGS;
2301.1Sfredette#undef	KGDB_MOVEREG
2311.1Sfredette}
2321.1Sfredette
2331.1Sfredette/*
2341.1Sfredette * Trap into kgdb to wait for debugger to connect,
2351.1Sfredette * noting on the console why nothing else is going on.
2361.1Sfredette */
2371.1Sfredettevoid
2381.4Schskgdb_connect(int verbose)
2391.1Sfredette{
2401.1Sfredette
2411.1Sfredette	if (kgdb_dev < 0)
2421.1Sfredette		return;
2431.1Sfredette
2441.1Sfredette	if (verbose)
2451.1Sfredette		printf("kgdb waiting...");
2461.1Sfredette
2471.6Sperry	__asm volatile ("break        %0, %1"
2481.1Sfredette  		:: "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_KGDB));
2491.1Sfredette
2501.1Sfredette	if (verbose)
2511.1Sfredette		printf("connected.\n");
2521.1Sfredette
2531.1Sfredette	kgdb_debug_panic = 1;
2541.1Sfredette}
2551.1Sfredette
2561.1Sfredette/*
2571.1Sfredette * Decide what to do on panic.
2581.1Sfredette * (This is called by panic, like Debugger())
2591.1Sfredette */
2601.1Sfredettevoid
2611.4Schskgdb_panic(void)
2621.1Sfredette{
2631.1Sfredette	if (kgdb_dev >= 0 && kgdb_debug_panic) {
2641.1Sfredette		printf("entering kgdb\n");
2651.1Sfredette		kgdb_connect(kgdb_active == 0);
2661.1Sfredette	}
2671.1Sfredette}
268