xref: /original-bsd/sys/hp300/hp300/kgdb_glue.c (revision 333da485)
1 /*
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratories.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)kgdb_glue.c	8.2 (Berkeley) 01/12/94
17  */
18 
19 /*
20  * This file must be compiled with gcc -fno-defer-pop.
21  */
22 
23 #ifdef KGDB
24 
25 #include <sys/param.h>
26 
27 #include <machine/frame.h>
28 #include <machine/reg.h>
29 
30 #ifndef lint
31 static char rcsid[] =
32     "@(#) $Header: /usr/src/sys/hp300/hp300/RCS/kgdb_glue.c,v 1.5 92/12/20 15:48:57 mike Exp $ (LBL)";
33 #endif
34 
35 #define KGDB_STACKSIZE 0x800
36 #define KGDB_STACKWORDS (KGDB_STACKSIZE / sizeof(u_long))
37 
38 u_long kgdb_stack[KGDB_STACKWORDS];
39 
40 #define getsp(v) asm("movl sp, %0" : "=r" (v))
41 #define setsp(v) asm("movl %0, sp" :: "r" (v))
42 
43 static inline void
44 copywords(src, dst, nbytes)
45 	register u_long *src, *dst;
46 	register u_int nbytes;
47 {
48 	u_long *limit = src + (nbytes / sizeof(u_long));
49 
50 	do {
51 		*dst++ = *src++;
52 	} while (src < limit);
53 	if (nbytes & 2)
54 		*(u_short *)dst = *(u_short *)src;
55 }
56 
57 kgdb_trap_glue(type, frame)
58 	int type;
59 	struct frame frame;
60 {
61 	u_long osp, nsp;
62 	u_int fsize, s;
63 	extern short exframesize[];
64 
65 	/*
66 	 * After a kernel mode trap, the saved sp doesn't point to the right
67 	 * place.  The correct value is the top of the frame (i.e. before the
68 	 * KGDB trap).
69 	 *
70 	 * XXX this may have to change if we implement an interrupt stack.
71 	 */
72 	fsize = sizeof(frame) - sizeof(frame.F_u) + exframesize[frame.f_format];
73 	frame.f_regs[SP] = (u_long)&frame + fsize;
74 
75 	/*
76 	 * Copy the interrupt context and frame to the new stack.
77 	 * We're throwing away trap()'s frame since we're going to do
78 	 * our own rte.
79 	 */
80 	nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] -
81 	      roundup(fsize, sizeof(u_long));
82 
83 	copywords((u_long *)&frame, (u_long *)nsp, fsize);
84 
85 	s = splhigh();
86 
87 	getsp(osp);
88 	setsp(nsp);
89 
90 	if (kgdb_trap(type, (struct frame *)nsp) == 0) {
91 		/*
92 		 * Get back on kernel stack.  This thread of control
93 		 * will return back up through trap().  If kgdb_trap()
94 		 * returns 0, it didn't handle the trap at all so
95 		 * the stack is still intact and everything will
96 		 * unwind okay from here up.
97 		 */
98 		setsp(osp);
99 		splx(s);
100 		return 0;
101 	}
102 	/*
103 	 * Copy back context, which has possibly changed.  Even the
104 	 * sp might have changed.
105 	 */
106 	osp = ((struct frame *)nsp)->f_regs[SP] - fsize;
107 	copywords((u_long *)nsp, (u_long *)osp, fsize);
108 	setsp(osp);
109 
110 	/*
111 	 * Restore the possible new context from frame, pop the
112 	 * unneeded usp (we trapped from kernel mode) and pad word,
113 	 * and return to the trapped thread.
114 	 */
115 	asm("moveml sp@+,#0x7FFF; addql #8,sp; rte");
116 }
117 
118 int kgdb_testval;
119 
120 kgdb_test(i)
121 	int i;
122 {
123         ++kgdb_testval;
124         return (i + 1);
125 }
126 #endif /* KGDB */
127