xref: /original-bsd/sys/hp300/hp300/kgdb_glue.c (revision 95a66346)
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	1.1 (Berkeley) 03/12/91
8  */
9 
10 /*
11  * This file must be compiled with gcc -fno-defer-pop.
12  */
13 
14 #ifdef KGDB
15 
16 #include "param.h"
17 #include "frame.h"
18 #include "machine/reg.h"
19 
20 #ifndef lint
21 static char rcsid[] =
22     "@(#) $Header: kgdb_glue.c,v 1.4 91/03/08 07:02:37 van Exp $ (LBL)";
23 #endif
24 
25 /*
26  * # of additional bytes in 680x0 exception frame format n.
27  */
28 static int frame_bytes[16] = {
29 	0, 0, sizeof(struct fmt2), 0,
30 	0, 0, 0, 0,
31 	0, sizeof(struct fmt9), sizeof(struct fmtA), sizeof(struct fmtB),
32 	0, 0, 0, 0
33 };
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 /*
58  * Decide what to do on panic.
59  * For now, wait for debugger if kgdb_debug_init is set.
60  */
61 kgdb_panic()
62 {
63 	extern int kgdb_debug_init;
64 
65 	if (kgdb_debug_init)		/* XXX, need boot flag/sysctl */
66 		asm("trap #15");
67 }
68 
69 kgdb_trap_glue(type, frame)
70 	int type;
71 	struct frame frame;
72 {
73 	u_long osp, nsp;
74 	u_int fsize, s;
75 
76 	/*
77 	 * After a kernel mode trap, the saved sp doesn't point to the right
78 	 * place.  The correct value is the top of the frame.
79 	 */
80 	fsize = sizeof(frame) - sizeof(frame.F_u) + frame_bytes[frame.f_format];
81 	frame.f_regs[SP] = (u_long)&frame + fsize;
82 
83 	/*
84 	 * Copy the interrupt context and frame to the new stack.
85 	 * We're throwing away trap()'s frame since we're going to do
86 	 * our own rte.
87 	 */
88 	nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] -
89 	      roundup(fsize, sizeof(u_long));
90 
91 	copywords((u_long *)&frame, (u_long *)nsp, fsize);
92 
93 	s = splhigh();
94 
95 	getsp(osp);
96 	setsp(nsp);
97 
98 	if (kgdb_trap(type, (struct frame *)nsp) == 0) {
99 		/*
100 		 * Get back on kernel stack.  This thread of control
101 		 * will return back up through trap().  If kgdb_trap()
102 		 * returns 0, it didn't handle the trap at all so
103 		 * the stack is still intact and everything will
104 		 * unwind okay from here up.
105 		 */
106 		setsp(osp);
107 		splx(s);
108 		return 0;
109 	}
110 	/*
111 	 * Copy back context, which has possibly changed.  Even the
112 	 * sp might have changed.
113 	 */
114 	osp = ((struct frame *)nsp)->f_regs[SP] - fsize;
115 	copywords((u_long *)nsp, (u_long *)osp, fsize);
116 	setsp(osp);
117 
118 	/*
119 	 * Restore the possible new context from frame, pop the
120 	 * unneeded usp (we trapped from kernel mode) and pad word,
121 	 * and return to the trapped thread.
122 	 */
123 	asm("moveml sp@+,#0x7FFF; addql #6,sp; rte");
124 }
125 
126 int kgdb_testval;
127 
128 kgdb_test(i)
129 {
130         ++kgdb_testval;
131         return i + 1;
132 }
133 
134 #endif
135