date and time created 91/05/12 22:30:02 by william
[unix-history] / usr / src / sys / i386 / i386 / kgdb_glue.c
CommitLineData
3f4b8ae4
WN
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) %G%
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
21static 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
28u_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
33static inline void
34copywords(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
47kgdb_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
111int kgdb_testval;
112
113kgdb_test(i)
114{
115 ++kgdb_testval;
116 return i + 1;
117}
118
119#endif