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 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 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 120 kgdb_test(i) 121 int i; 122 { 123 ++kgdb_testval; 124 return (i + 1); 125 } 126 #endif /* KGDB */ 127