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