kgdb_glue.c revision 1.4 1 /* $NetBSD: kgdb_glue.c,v 1.4 2003/07/15 01:44:56 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratories.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by the University of
27 * California, Berkeley and its contributors.
28 * 4. Neither the name of the University nor the names of its contributors
29 * may be used to endorse or promote products derived from this software
30 * without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * SUCH DAMAGE.
43 *
44 * @(#)kgdb_glue.c 8.2 (Berkeley) 1/12/94
45 */
46
47 /*
48 * This file must be compiled with gcc -fno-defer-pop.
49 */
50
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: kgdb_glue.c,v 1.4 2003/07/15 01:44:56 lukem Exp $");
53
54 #include "opt_kgdb.h"
55
56 #ifdef KGDB
57
58 #include <sys/param.h>
59
60 #include <machine/frame.h>
61 #include <machine/reg.h>
62
63 #ifndef lint
64 static char rcsid[] = "$NetBSD: kgdb_glue.c,v 1.4 2003/07/15 01:44:56 lukem Exp $";
65 #endif
66
67 #define KGDB_STACKSIZE 0x800
68 #define KGDB_STACKWORDS (KGDB_STACKSIZE / sizeof(u_long))
69
70 u_long kgdb_stack[KGDB_STACKWORDS];
71
72 #define getsp(v) asm("movl %%sp, %0" : "=r" (v))
73 #define setsp(v) asm("movl %0, %%sp" :: "r" (v))
74
75 static inline void
76 copywords(src, dst, nbytes)
77 register u_long *src, *dst;
78 register u_int nbytes;
79 {
80 u_long *limit = src + (nbytes / sizeof(u_long));
81
82 do {
83 *dst++ = *src++;
84 } while (src < limit);
85 if (nbytes & 2)
86 *(u_short *)dst = *(u_short *)src;
87 }
88
89 kgdb_trap_glue(type, frame)
90 int type;
91 struct frame frame;
92 {
93 u_long osp, nsp;
94 u_int fsize, s;
95 extern short exframesize[];
96
97 /*
98 * After a kernel mode trap, the saved sp doesn't point to the right
99 * place. The correct value is the top of the frame (i.e. before the
100 * KGDB trap).
101 *
102 * XXX this may have to change if we implement an interrupt stack.
103 */
104 fsize = sizeof(frame) - sizeof(frame.F_u) + exframesize[frame.f_format];
105 frame.f_regs[SP] = (u_long)&frame + fsize;
106
107 /*
108 * Copy the interrupt context and frame to the new stack.
109 * We're throwing away trap()'s frame since we're going to do
110 * our own rte.
111 */
112 nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] -
113 roundup(fsize, sizeof(u_long));
114
115 copywords((u_long *)&frame, (u_long *)nsp, fsize);
116
117 s = splhigh();
118
119 getsp(osp);
120 setsp(nsp);
121
122 if (kgdb_trap(type, (struct frame *)nsp) == 0) {
123 /*
124 * Get back on kernel stack. This thread of control
125 * will return back up through trap(). If kgdb_trap()
126 * returns 0, it didn't handle the trap at all so
127 * the stack is still intact and everything will
128 * unwind okay from here up.
129 */
130 setsp(osp);
131 splx(s);
132 return 0;
133 }
134 /*
135 * Copy back context, which has possibly changed. Even the
136 * sp might have changed.
137 */
138 osp = ((struct frame *)nsp)->f_regs[SP] - fsize;
139 copywords((u_long *)nsp, (u_long *)osp, fsize);
140 setsp(osp);
141
142 /*
143 * Restore the possible new context from frame, pop the
144 * unneeded usp (we trapped from kernel mode) and pad word,
145 * and return to the trapped thread.
146 */
147 asm("moveml %sp@+,#0x7FFF; addql #8,sp; rte");
148 }
149
150 int kgdb_testval;
151
152 kgdb_test(i)
153 int i;
154 {
155 ++kgdb_testval;
156 return (i + 1);
157 }
158 #endif /* KGDB */
159