xref: /original-bsd/sys/hp300/hp300/kgdb_glue.c (revision e59fb703)
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.1 (Berkeley) 04/20/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 "../include/frame.h"
18 #include "../include/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 kgdb_trap_glue(type, frame)
58 	int type;
59 	struct frame frame;
60 {
61 	u_long osp, nsp;
62 	u_int fsize, s;
63 
64 	/*
65 	 * After a kernel mode trap, the saved sp doesn't point to the right
66 	 * place.  The correct value is the top of the frame.
67 	 */
68 	fsize = sizeof(frame) - sizeof(frame.F_u) + frame_bytes[frame.f_format];
69 	frame.f_regs[SP] = (u_long)&frame + fsize;
70 
71 	/*
72 	 * Copy the interrupt context and frame to the new stack.
73 	 * We're throwing away trap()'s frame since we're going to do
74 	 * our own rte.
75 	 */
76 	nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] -
77 	      roundup(fsize, sizeof(u_long));
78 
79 	copywords((u_long *)&frame, (u_long *)nsp, fsize);
80 
81 	s = splhigh();
82 
83 	getsp(osp);
84 	setsp(nsp);
85 
86 	if (kgdb_trap(type, (struct frame *)nsp) == 0) {
87 		/*
88 		 * Get back on kernel stack.  This thread of control
89 		 * will return back up through trap().  If kgdb_trap()
90 		 * returns 0, it didn't handle the trap at all so
91 		 * the stack is still intact and everything will
92 		 * unwind okay from here up.
93 		 */
94 		setsp(osp);
95 		splx(s);
96 		return 0;
97 	}
98 	/*
99 	 * Copy back context, which has possibly changed.  Even the
100 	 * sp might have changed.
101 	 */
102 	osp = ((struct frame *)nsp)->f_regs[SP] - fsize;
103 	copywords((u_long *)nsp, (u_long *)osp, fsize);
104 	setsp(osp);
105 
106 	/*
107 	 * Restore the possible new context from frame, pop the
108 	 * unneeded usp (we trapped from kernel mode) and pad word,
109 	 * and return to the trapped thread.
110 	 */
111 	asm("moveml sp@+,#0x7FFF; addql #6,sp; rte");
112 }
113 
114 int kgdb_testval;
115 
116 kgdb_test(i)
117 {
118         ++kgdb_testval;
119         return i + 1;
120 }
121 
122 #endif
123