xref: /original-bsd/sys/hp300/hp300/kgdb_glue.c (revision 086b3864)
1 /*
2  * Copyright (c) 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)kgdb_glue.c	7.2 (Berkeley) 10/11/92
8  */
9 
10 /*
11  * This file must be compiled with gcc -fno-defer-pop.
12  */
13 
14 #ifdef KGDB
15 
16 #include <sys/param.h>
17 
18 #include <machine/frame.h>
19 #include <machine/reg.h>
20 
21 #ifndef lint
22 static char rcsid[] =
23     "@(#) $Header: kgdb_glue.c,v 1.4 91/03/08 07:02:37 van Exp $ (LBL)";
24 #endif
25 
26 /*
27  * # of additional bytes in 680x0 exception frame format n.
28  */
29 static int frame_bytes[16] = {
30 	0, 0, sizeof(struct fmt2), 0,
31 	0, 0, 0, 0,
32 	0, sizeof(struct fmt9), sizeof(struct fmtA), sizeof(struct fmtB),
33 	0, 0, 0, 0
34 };
35 
36 #define KGDB_STACKSIZE 0x800
37 #define KGDB_STACKWORDS (KGDB_STACKSIZE / sizeof(u_long))
38 
39 u_long kgdb_stack[KGDB_STACKWORDS];
40 
41 #define getsp(v) asm("movl sp, %0" : "=r" (v))
42 #define setsp(v) asm("movl %0, sp" :: "r" (v))
43 
44 static inline void
45 copywords(src, dst, nbytes)
46 	register u_long *src, *dst;
47 	register u_int nbytes;
48 {
49 	u_long *limit = src + (nbytes / sizeof(u_long));
50 
51 	do {
52 		*dst++ = *src++;
53 	} while (src < limit);
54 	if (nbytes & 2)
55 		*(u_short *)dst = *(u_short *)src;
56 }
57 
58 kgdb_trap_glue(type, frame)
59 	int type;
60 	struct frame frame;
61 {
62 	u_long osp, nsp;
63 	u_int fsize, s;
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.
68 	 */
69 	fsize = sizeof(frame) - sizeof(frame.F_u) + frame_bytes[frame.f_format];
70 	frame.f_regs[SP] = (u_long)&frame + fsize;
71 
72 	/*
73 	 * Copy the interrupt context and frame to the new stack.
74 	 * We're throwing away trap()'s frame since we're going to do
75 	 * our own rte.
76 	 */
77 	nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] -
78 	      roundup(fsize, sizeof(u_long));
79 
80 	copywords((u_long *)&frame, (u_long *)nsp, fsize);
81 
82 	s = splhigh();
83 
84 	getsp(osp);
85 	setsp(nsp);
86 
87 	if (kgdb_trap(type, (struct frame *)nsp) == 0) {
88 		/*
89 		 * Get back on kernel stack.  This thread of control
90 		 * will return back up through trap().  If kgdb_trap()
91 		 * returns 0, it didn't handle the trap at all so
92 		 * the stack is still intact and everything will
93 		 * unwind okay from here up.
94 		 */
95 		setsp(osp);
96 		splx(s);
97 		return 0;
98 	}
99 	/*
100 	 * Copy back context, which has possibly changed.  Even the
101 	 * sp might have changed.
102 	 */
103 	osp = ((struct frame *)nsp)->f_regs[SP] - fsize;
104 	copywords((u_long *)nsp, (u_long *)osp, fsize);
105 	setsp(osp);
106 
107 	/*
108 	 * Restore the possible new context from frame, pop the
109 	 * unneeded usp (we trapped from kernel mode) and pad word,
110 	 * and return to the trapped thread.
111 	 */
112 	asm("moveml sp@+,#0x7FFF; addql #6,sp; rte");
113 }
114 
115 int kgdb_testval;
116 
117 kgdb_test(i)
118 {
119         ++kgdb_testval;
120         return i + 1;
121 }
122 
123 #endif
124