1 /*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * All advertising materials mentioning features or use of this software
10 * must display the following acknowledgement:
11 * This product includes software developed by the University of
12 * California, Lawrence Berkeley Laboratories.
13 *
14 * %sccs.include.redist.c%
15 *
16 * @(#)kgdb_glue.c 8.2 (Berkeley) 01/12/94
17 */
18
19 /*
20 * This file must be compiled with gcc -fno-defer-pop.
21 */
22
23 #ifdef KGDB
24
25 #include <sys/param.h>
26
27 #include <machine/frame.h>
28 #include <machine/reg.h>
29
30 #ifndef lint
31 static char rcsid[] =
32 "@(#) $Header: /usr/src/sys/hp300/hp300/RCS/kgdb_glue.c,v 1.5 92/12/20 15:48:57 mike Exp $ (LBL)";
33 #endif
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
copywords(src,dst,nbytes)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
kgdb_trap_glue(type,frame)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 extern short exframesize[];
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 (i.e. before the
68 * KGDB trap).
69 *
70 * XXX this may have to change if we implement an interrupt stack.
71 */
72 fsize = sizeof(frame) - sizeof(frame.F_u) + exframesize[frame.f_format];
73 frame.f_regs[SP] = (u_long)&frame + fsize;
74
75 /*
76 * Copy the interrupt context and frame to the new stack.
77 * We're throwing away trap()'s frame since we're going to do
78 * our own rte.
79 */
80 nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] -
81 roundup(fsize, sizeof(u_long));
82
83 copywords((u_long *)&frame, (u_long *)nsp, fsize);
84
85 s = splhigh();
86
87 getsp(osp);
88 setsp(nsp);
89
90 if (kgdb_trap(type, (struct frame *)nsp) == 0) {
91 /*
92 * Get back on kernel stack. This thread of control
93 * will return back up through trap(). If kgdb_trap()
94 * returns 0, it didn't handle the trap at all so
95 * the stack is still intact and everything will
96 * unwind okay from here up.
97 */
98 setsp(osp);
99 splx(s);
100 return 0;
101 }
102 /*
103 * Copy back context, which has possibly changed. Even the
104 * sp might have changed.
105 */
106 osp = ((struct frame *)nsp)->f_regs[SP] - fsize;
107 copywords((u_long *)nsp, (u_long *)osp, fsize);
108 setsp(osp);
109
110 /*
111 * Restore the possible new context from frame, pop the
112 * unneeded usp (we trapped from kernel mode) and pad word,
113 * and return to the trapped thread.
114 */
115 asm("moveml sp@+,#0x7FFF; addql #8,sp; rte");
116 }
117
118 int kgdb_testval;
119
kgdb_test(i)120 kgdb_test(i)
121 int i;
122 {
123 ++kgdb_testval;
124 return (i + 1);
125 }
126 #endif /* KGDB */
127