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