xref: /original-bsd/sys/i386/i386/kgdb_glue.c (revision 3b6250d9)
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) 05/13/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 "machine/frame.h"
18 #include "machine/reg.h"
19 
20 #ifndef lint
21 static char rcsid[] =
22     "@(#) $Header: /u/donn/c/gdb/kernel/RCS/kgdb_glue.c,v 1.2 91/03/31 16:04:52 donn Exp Locker: donn $ (LBL)";
23 #endif
24 
25 #define KGDB_STACKSIZE 0x800
26 #define KGDB_STACKWORDS (KGDB_STACKSIZE / sizeof(u_long))
27 
28 u_long kgdb_stack[KGDB_STACKWORDS];
29 
30 #define getsp(v) asm volatile ("movl %%esp,%0" : "=r" (v))
31 #define setsp(v) asm volatile ("movl %0,%%esp" :: "r" (v))
32 
33 static inline void
34 copywords(src, dst, nbytes)
35 	register u_long *src, *dst;
36 	register u_int nbytes;
37 {
38 	u_long *limit = src + (nbytes / sizeof(u_long));
39 
40 	do {
41 		*dst++ = *src++;
42 	} while (src < limit);
43 	if (nbytes & 2)
44 		*(u_short *)dst = *(u_short *)src;
45 }
46 
47 kgdb_trap_glue(frame)
48 	struct trapframe frame;
49 {
50 	u_long osp, nsp;
51 	u_int s;
52 
53 	/*
54 	 * On internal traps, the hardware doesn't push ss and esp.
55 	 */
56 	u_int fsize = sizeof frame - 2 * sizeof (int);
57 #ifdef DONN
58 	extern int kgdb_debug;
59 
60 	if (kgdb_debug > 3)
61 		pg("kgdb_trap_glue: entered, fsize = %d\n", fsize);
62 #endif
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 	frame.tf_isp = (u_long)(&frame) + fsize;
69 
70 	/*
71 	 * Copy the interrupt context and frame to the new stack.
72 	 * We're throwing away trap()'s frame since we're going to do
73 	 * our own iret.
74 	 */
75 	nsp = (u_long)(&kgdb_stack[KGDB_STACKWORDS]) - fsize;
76 
77 	copywords((u_long *)&frame, (u_long *)nsp, fsize);
78 
79 	s = splhigh();
80 
81 	getsp(osp);
82 	setsp(nsp);
83 
84 	if (kgdb_trap(frame.tf_trapno, (struct frame *)nsp) == 0) {
85 		/*
86 		 * Get back on kernel stack.  This thread of control
87 		 * will return back up through trap().  If kgdb_trap()
88 		 * returns 0, it didn't handle the trap at all so
89 		 * the stack is still intact and everything will
90 		 * unwind okay from here up.
91 		 */
92 		setsp(osp);
93 		splx(s);
94 		return 0;
95 	}
96 
97 	/*
98 	 * Copy back context, which has possibly changed.  Even the
99 	 * sp might have changed.
100 	 */
101 	osp = ((struct trapframe *)nsp)->tf_isp - fsize;
102 	copywords((u_long *)nsp, (u_long *)osp, fsize);
103 	setsp(osp);
104 
105 	/*
106 	 * Restore the possible new context from frame.
107 	 */
108 	asm volatile ("pop %es; pop %ds; popal; nop; addl $8,%esp; iret");
109 }
110 
111 int kgdb_testval;
112 
113 kgdb_test(i)
114 {
115         ++kgdb_testval;
116         return i + 1;
117 }
118 
119 #endif
120