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