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